00001 #ifndef DG_MAP_H
00002 #define DG_MAP_H
00003
00009 #ifndef CTL_TREE_H
00010 #include "ctl/tree.h"
00011 #endif
00012
00013
00014
00015
00016
00017
00018
00028 #define ctl_declare_map(label,keytype,type) ctl_declare_map_base(label,keytype,type,ctlt_unique)
00029
00038 #define ctl_implement_map(label,keytype,type) ctl_implement_map_base(label,keytype,type,ctlt_unique)
00039
00048 #define ctl_map_foreach(label, instance, iterator ) \
00049 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00050 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00051 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00052 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00053
00062 #define ctl_map_foreach_const(label, instance, iterator ) \
00063 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00064 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00065 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00066 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00067
00076 #define ctl_map_foreach_reverse(label, instance, iterator ) \
00077 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00078 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00079 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00080 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)(ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator=ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00081
00090 #define ctl_map_foreach_const_reverse(label, instance, iterator ) \
00091 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00092 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00093 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00094 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)(ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator=ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00095
00096
00105 #define ctl_map_from(label, instance, key, iterator )\
00106 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00107 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00108 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00109 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00110
00113 #define ctl_map_from_const(label, instance, key, iterator )\
00114 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00115 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00116 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00117 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00118
00121 #define ctl_map_from_reverse(label, instance, key, iterator )\
00122 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00123 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00124 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00125 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00126
00129 #define ctl_map_from_const_reverse(label, instance, key, iterator )\
00130 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00131 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00132 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00133 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00134
00146 #define ctl_map_from_to(label, instance, keyfrom, keyto, iterator )\
00147 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00148 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00149 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00150 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) < 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00151
00154 #define ctl_map_from_to_const(label, instance, keyfrom, keyto, iterator )\
00155 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00156 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00157 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00158 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) < 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00159
00162 #define ctl_map_from_to_reverse(label, instance, keyfrom, keyto, iterator )\
00163 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00164 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00165 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00166 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) > 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00167
00171 #define ctl_map_from_to_const_reverse(label, instance, keyfrom, keyto, iterator )\
00172 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00173 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00174 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00175 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) > 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00176
00177
00178
00179
00180
00181
00182
00191 #define ctl_declare_multimap(label,keytype,type) ctl_declare_map_base(label,keytype,type,ctlt_multiple)
00192
00200 #define ctl_implement_multimap(label,keytype,type) ctl_implement_map_base(label,keytype,type,ctlt_multiple)
00201
00210 #define ctl_multimap_foreach(label, instance, iterator ) \
00211 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00212 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00213 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00214 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00215
00224 #define ctl_multimap_foreach_const(label, instance, iterator ) \
00225 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00226 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00227 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00228 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00229
00238 #define ctl_multimap_foreach_reverse(label, instance, iterator ) \
00239 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00240 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00241 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00242 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)(ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator=ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00243
00252 #define ctl_multimap_foreach_const_reverse(label, instance, iterator ) \
00253 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00254 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00255 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00256 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)(ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator=ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00257
00258
00267 #define ctl_multimap_from(label, instance, key, iterator )\
00268 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00269 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00270 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00271 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00272
00275 #define ctl_multimap_from_const(label, instance, key, iterator )\
00276 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00277 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00278 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00279 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00280
00283 #define ctl_multimap_from_reverse(label, instance, key, iterator )\
00284 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00285 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00286 ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00287 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00288
00291 #define ctl_multimap_from_const_reverse(label, instance, key, iterator )\
00292 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00293 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00294 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00295 for ( ; ppConcat(iterator,_key); ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00296
00308 #define ctl_multimap_from_to(label, instance, keyfrom, keyto, iterator )\
00309 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00310 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00311 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00312 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) < 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00313
00316 #define ctl_multimap_from_to_const(label, instance, keyfrom, keyto, iterator )\
00317 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00318 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00319 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00320 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) < 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00321
00324 #define ctl_multimap_from_to_reverse(label, instance, keyfrom, keyto, iterator )\
00325 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00326 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00327 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00328 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) > 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00329
00333 #define ctl_multimap_from_to_const_reverse(label, instance, keyfrom, keyto, iterator )\
00334 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00335 const ppConcat(label,_keytype)* ppConcat(iterator,_key) = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00336 const ppConcat(label,_type)* iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) );\
00337 for( ; ppConcat(iterator,_key) && (instance)->compare(ppConcat(iterator,_key),(keyto)) > 0; ppConcat(iterator,_key) = (ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ), iterator = ppConcat(label,_obj_from_key)( ppConcat(iterator,_key) ) )
00338
00339
00340
00341
00342
00343
00344
00345
00349 #define ctl_declare_map_base(label,keytype,type,ctlt_unique)\
00350 typedef struct ppConcat(label,_node)\
00351 {\
00352 ctlt_node_type(ctlt_after,ctlt_unique) link;\
00353 keytype key; \
00354 type obj; \
00355 ppDebug(struct label* container;) \
00356 } ppConcat(label,_node);\
00357 typedef ctl_tree(ctlt_after,ctlt_unique) label;\
00358 \
00359 extern ctl_pool(ppConcat(label,_node)) ppConcat(label,_pool);\
00360 \
00361 typedef type ppConcat(label,_type);\
00362 typedef keytype ppConcat(label,_keytype);\
00363 typedef ctl_tree_(ctlt_after,ctlt_unique, iterator ) ppConcat(label,_iterator);\
00364 \
00365 ctl_datagen_declare_functions(label);\
00366 \
00367 void ppConcat(label,_sort)( label* self, int (*compare)(const keytype* p1, const keytype* p2) );\
00368 \
00369 size_t ppConcat(label,_count)( const label* self);\
00370 \
00371 bool ppConcat(label,_ismember)( const label* self, const type* mbr );\
00372 \
00373 type* ppConcat(label,_obj_from_key)( const keytype* key );\
00374 \
00375 keytype* ppConcat(label,_key_from_obj)( const type* mbr );\
00376 \
00377 void ppConcat(label,_clear)( label* self );\
00378 \
00379 type* ppConcat(label,_back)(const label* self);\
00380 \
00381 type* ppConcat(label,_front)(const label* self);\
00382 \
00383 void ppConcat(label,_pop_back)(label* self);\
00384 \
00385 void ppConcat(label,_pop_front)(label* self);\
00386 \
00387 type* ppConcat(label,_insert)( label* self, const keytype* key );\
00388 \
00389 type* ppConcat(label,_at)(const label* self, const keytype* key );\
00390 \
00391 void ppConcat(label,_erase)(label* self, type* mbr );\
00392 \
00393 void ppConcat(label,_erase_key)(label* self, keytype* key );\
00394 \
00395 void ppConcat(label,_splice)( label* self, label* from );\
00396
00397
00398
00399
00400
00401
00402
00403 #ifndef CTL_POOL_DELTA
00404
00410 #define CTL_POOL_DELTA 16
00411 #endif
00412
00416 #define ctl_implement_map_base(label,keytype,type,ctlt_unique)\
00417 const bool ppConcat(label,_isscalar) = false;\
00418 ctl_pool_auto(ppConcat(label,_node),ppConcat(label,_pool),CTL_POOL_DELTA);\
00419 \
00420 void ppConcat(label,_init)( label* self )\
00421 {\
00422 assertobjptr(self);\
00423 ctl_tree_init(ctlt_after,ctlt_unique, ppConcat(keytype,_compare), self );\
00424 }\
00425 \
00426 void ppConcat(label,_copy)( label* dst, const label* src )\
00427 {\
00428 assertobjptr(dst);\
00429 assertobjconst(src);\
00430 ppConcat(label,_init)( dst );\
00431 dst->compare = src->compare;\
00432 {\
00433 ppConcat(label,_iterator) stack_curr;\
00434 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, src );\
00435 while( curr_key )\
00436 {\
00437 ppConcat(type,_copy)(ppConcat(label,_insert)(dst,curr_key),ppConcat(label,_obj_from_key)( curr_key ));\
00438 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00439 }\
00440 }\
00441 }\
00442 \
00443 void ppConcat(label,_move)( label* dst, label* src )\
00444 {\
00445 assertobjptr(dst);\
00446 assertobjptr(src);\
00447 *dst = *src;\
00448 ppConcat(label,_init)( src );\
00449 ppDebug( {\
00450 ppConcat(label,_iterator) stack_curr;\
00451 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, dst );\
00452 while( curr_key )\
00453 {\
00454 dereference(ppConcat(label,_node),key,curr_key)->container = (struct label*)dst;\
00455 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00456 }\
00457 } )\
00458 }\
00459 \
00460 void ppConcat(label,_swap)( label* p1, label* p2 )\
00461 {\
00462 assertobjptr(p1);\
00463 assertobjptr(p2);\
00464 {\
00465 label tmp = *p1;\
00466 *p1 = *p2;\
00467 *p2 = tmp;\
00468 }\
00469 ppDebug( {\
00470 ppConcat(label,_iterator) stack_curr;\
00471 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, p1 );\
00472 while( curr_key )\
00473 {\
00474 dereference(ppConcat(label,_node),key,curr_key)->container = (struct label*)p1;\
00475 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00476 }\
00477 } )\
00478 ppDebug( {\
00479 ppConcat(label,_iterator) stack_curr;\
00480 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, p2 );\
00481 while( curr_key )\
00482 {\
00483 dereference(ppConcat(label,_node),key,curr_key)->container = (struct label*)p2;\
00484 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00485 }\
00486 } )\
00487 }\
00488 \
00489 void ppConcat(label,_destroy)( label* self )\
00490 {\
00491 ppConcat(label,_clear)( self );\
00492 }\
00493 \
00494 int ppConcat(label,_rcompare)( const label* p1, const label* p2 ) { return ppConcat(label,_compare)( p2,p1 ); }\
00495 \
00496 int ppConcat(label,_compare)( const label* p1, const label* p2 )\
00497 {\
00498 if( !p1 && !p2 )\
00499 return 0;\
00500 assertobjconst(p1);\
00501 assertobjconst(p2);\
00502 {\
00503 size_t compareLen = min(p1->size,p2->size);\
00504 ppConcat(label,_iterator) p1s;\
00505 ppConcat(label,_iterator) p2s;\
00506 const keytype* k1 = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &p1s, p1 );\
00507 const keytype* k2 = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &p2s, p2 );\
00508 while( compareLen-- && k1 && k2 )\
00509 {\
00510 int result = ppConcat(keytype,_compare)( k1,k2 );\
00511 if( result )\
00512 return result;\
00513 result = ppConcat(type,_compare)( ppConcat(label,_obj_from_key)(k1),ppConcat(label,_obj_from_key)(k2) );\
00514 if( result )\
00515 return result;\
00516 k1 = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_next)( &p1s );\
00517 k2 = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_next)( &p2s );\
00518 }\
00519 \
00520 assert(compareLen == -1);\
00521 if( p1->size < p2->size )\
00522 return -1;\
00523 if( p1->size > p2->size )\
00524 return 1;\
00525 return 0;\
00526 }\
00527 }\
00528 \
00529 bool ppConcat(label,_valid)( const label* self )\
00530 {\
00531 if( !self )\
00532 return false;\
00533 assertobjconst(self);\
00534 return self->compare && ((self->root && self->size) || (NULL == self->root && 0 == self->size));\
00535 }\
00536 \
00537 size_t ppConcat(label,_size)( const label* self )\
00538 {\
00539 assertobjconst(self);\
00540 if( ppConcat(type,_isscalar) )\
00541 {\
00542 return sizeof(*self) + (self->size * sizeof(ppConcat(label,_node)));\
00543 }\
00544 else\
00545 {\
00546 size_t ret = sizeof(*self);\
00547 ppConcat(label,_iterator) stack_curr;\
00548 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00549 while( curr_key )\
00550 {\
00551 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00552 ret += ppConcat(keytype,_size)(&node->key) + ppConcat(type,_size)(&node->obj) + sizeof(ppConcat(label,_node))-sizeof(type)-sizeof(keytype);\
00553 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00554 }\
00555 return ret;\
00556 }\
00557 }\
00558 \
00559 size_t ppConcat(label,_serial_size)( const label* self )\
00560 {\
00561 assertobjconst(self);\
00562 if( ppConcat(type,_isscalar) )\
00563 {\
00564 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),link,self->root);\
00565 return ctl_serial_size_size( self->size ) + (self->size * (ppConcat(keytype,_serial_size)(&node->key) + ppConcat(type,_serial_size)(&node->obj)));\
00566 }\
00567 else\
00568 {\
00569 size_t total = ctl_serial_size_size( self->size );\
00570 ppConcat(label,_iterator) stack_curr;\
00571 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00572 while( curr_key )\
00573 {\
00574 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00575 total += ppConcat(keytype,_serial_size)(&node->key);\
00576 total += ppConcat(type,_serial_size)(&node->obj);\
00577 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00578 }\
00579 return total;\
00580 }\
00581 }\
00582 \
00583 void ppConcat(label,_serial_write)( const label* self, ctl_serial* serial )\
00584 {\
00585 assertobjconst(self);\
00586 assertobjptr(serial);\
00587 ctl_serial_writesize( self->size, serial ); \
00588 {\
00589 ppConcat(label,_iterator) stack_curr;\
00590 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00591 while( curr_key )\
00592 {\
00593 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00594 ppConcat(keytype,_serial_write)(&node->key,serial);\
00595 ppConcat(type,_serial_write)(&node->obj,serial);\
00596 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00597 }\
00598 }\
00599 }\
00600 \
00601 void ppConcat(label,_serial_read)( label* self, ctl_serial* serial )\
00602 {\
00603 assertobjptr(self);\
00604 assertobjptr(serial);\
00605 {\
00606 size_t readsize = ctl_serial_readsize( serial ); \
00607 while( readsize-- )\
00608 {\
00609 keytype key;\
00610 ppConcat(keytype,_init)(&key);\
00611 ppConcat(keytype,_serial_read)(&key,serial);\
00612 ppConcat(type,_serial_read)( ppConcat(label,_insert)(self,&key), serial );\
00613 ppConcat(keytype,_destroy)(&key);\
00614 }\
00615 }\
00616 }\
00617 \
00618 size_t ppConcat(label,_record_size)( const label* self, const char* szlabel )\
00619 {\
00620 assertobjconst(self);\
00621 assertconst(szlabel,1);\
00622 if( self->size )\
00623 {\
00624 size_t result = ctl_record_objarray_head_size( szlabel, "container", #keytype "_" #type );\
00625 if( ppConcat(type,_isscalar) )\
00626 {\
00627 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),link,self->root);\
00628 result += self->size * (ppConcat(keytype,_record_size)(&node->key,"key") + ppConcat(type,_record_size)(&node->obj,"obj"));\
00629 }\
00630 else\
00631 {\
00632 ppConcat(label,_iterator) stack_curr;\
00633 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00634 while( curr_key )\
00635 {\
00636 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00637 result += ppConcat(keytype,_record_size)(curr_key,"key"); \
00638 result += ppConcat(type,_record_size)(&node->obj,"obj"); \
00639 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00640 }\
00641 }\
00642 return result;\
00643 }\
00644 return 0;\
00645 }\
00646 \
00647 void ppConcat(label,_record_write)( const label* self, ctl_serial* serial, const char* szlabel )\
00648 {\
00649 assertobjconst(self);\
00650 assertobjptr(serial);\
00651 assertconst(szlabel,1);\
00652 if( self->size )\
00653 {\
00654 uint8* rectemp = ctl_record_write_container_begin( "container", #keytype "_" #type, 0,self->size, serial, szlabel );\
00655 { \
00656 ppConcat(label,_iterator) stack_curr;\
00657 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00658 while( curr_key )\
00659 {\
00660 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00661 ppConcat(keytype,_record_write)(curr_key,serial,"key"); \
00662 ppConcat(type,_record_write)(&node->obj,serial,"obj"); \
00663 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00664 }\
00665 }\
00666 ctl_record_write_end( rectemp, serial );\
00667 }\
00668 }\
00669 \
00670 bool ppConcat(label,_record_read)( label* self, ctl_serial* serial, const char* szlabel )\
00671 {\
00672 assertobjptr(self);\
00673 assertobjptr(serial);\
00674 assertconst(szlabel,1);\
00675 {\
00676 ctl_serial pserial = *serial;\
00677 ppConcat(label,_clear)(self);\
00678 if( ctl_record_find( &pserial, szlabel ) )\
00679 {\
00680 size_t count = ctl_record_container_validatedata( &pserial, "container", #keytype "_" #type );\
00681 while( count-- )\
00682 {\
00683 keytype key;\
00684 ppConcat(keytype,_init)(&key);\
00685 ppConcat(keytype,_record_read)(&key, &pserial, "key");\
00686 ctl_record_next( &pserial );\
00687 ppConcat(type,_record_read)( ppConcat(label,_insert)(self,&key), &pserial, "obj" );\
00688 ctl_record_next( &pserial );\
00689 ppConcat(keytype,_destroy)(&key);\
00690 }\
00691 if( pserial.curr != pserial.end )\
00692 ctl_serial_except( &pserial, szconst(char,#label) szconst(char,"_record_read: Wrong data length!") );\
00693 return true;\
00694 }\
00695 }\
00696 return false;\
00697 }\
00698 \
00699 void ppConcat(label,_xml_write)( const label* self, ctl_xmlwrite* xml, const char* szlabel )\
00700 {\
00701 assertobjconst(self);\
00702 assertobjptr(xml);\
00703 assertconst(szlabel,1);\
00704 if( self->size )\
00705 {\
00706 ctl_xmlwrite_containertag( xml, #keytype "_" #type, self->size, szlabel ); \
00707 ctl_xmlwrite_indent( xml );\
00708 {\
00709 ppConcat(label,_iterator) stack_curr;\
00710 const keytype* curr_key = (const keytype*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00711 while( curr_key )\
00712 {\
00713 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,curr_key);\
00714 ctl_xmlwrite_generaltag( xml, #keytype "_" #type, #keytype "_" #type);\
00715 ctl_xmlwrite_indent( xml );\
00716 ppConcat(keytype,_xml_write)(curr_key,xml,"key");\
00717 ppConcat(type,_xml_write)(&node->obj,xml,"obj");\
00718 ctl_xmlwrite_outdent( xml );\
00719 ctl_xmlwrite_endtag( xml, #keytype "_" #type, #keytype "_" #type ); \
00720 curr_key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00721 }\
00722 }\
00723 ctl_xmlwrite_outdent( xml );\
00724 ctl_xmlwrite_endtag( xml, #type, szlabel ); \
00725 }\
00726 }\
00727 \
00728 bool ppConcat(label,_xml_read)( label* self, ctl_xmlread* xml, const char* szlabel )\
00729 {\
00730 assertobjptr(self);\
00731 assertobjptr(xml);\
00732 assertconst(szlabel,1);\
00733 if( ctl_xmlread_find( xml, szlabel ) )\
00734 {\
00735 int32 count = 0;\
00736 if( ctl_xmlread_getattribute_int( xml, CTL_LABEL_COUNT, &count ) )\
00737 {\
00738 ctl_xmlread arraydata;\
00739 ctl_xmlread_recurse(&arraydata,xml);\
00740 while( count-- )\
00741 {\
00742 ctl_xmlread keyobj;\
00743 if( ctl_xmlread_recurse(&keyobj,&arraydata) )\
00744 {\
00745 keytype key;\
00746 ppConcat(keytype,_init)(&key);\
00747 ppConcat(keytype,_xml_read)(&key, &keyobj, "key");\
00748 ppConcat(type,_xml_read)(ppConcat(label,_insert)(self,&key), &keyobj, "obj");\
00749 ppConcat(keytype,_destroy)(&key);\
00750 }\
00751 ctl_xmlread_next(&arraydata);\
00752 }\
00753 }\
00754 else\
00755 {\
00756 xml->except( xml, szconst(char,#label) szconst(char,"_xml_read: Missing size attribute!"), xml->szpCurr, NULL );\
00757 }\
00758 return true;\
00759 }\
00760 return false;\
00761 }\
00762 \
00763 void ppConcat(label,_sort)( label* self, int (*compare)(const keytype* p1, const keytype* p2) )\
00764 {\
00765 assertobjptr(self);\
00766 assertcodeptr(compare);\
00767 if( self->size )\
00768 {\
00769 label tmp;\
00770 ppConcat(label,_move)( &tmp, self );\
00771 self->compare = (tree_compare)compare;\
00772 ppConcat(label,_splice)( self, &tmp );\
00773 }\
00774 else\
00775 {\
00776 self->compare = (tree_compare)compare;\
00777 }\
00778 }\
00779 \
00780 size_t ppConcat(label,_count)( const label* self)\
00781 {\
00782 assertobjconst(self);\
00783 return self->size;\
00784 }\
00785 \
00786 bool ppConcat(label,_ismember)( const label* self, const type* data )\
00787 {\
00788 assertobjconst(self);\
00789 if( !data )\
00790 return false;\
00791 assertobjconst(data);\
00792 {\
00793 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,data);\
00794 ppDebug(return node->container == (struct label*)self; )\
00795 ppRelease (\
00796 \
00797 ppConcat(label,_iterator) stack;\
00798 const keytype* key = (const ppConcat(label,_keytype)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack, self );\
00799 while( key && !ppConcat(keytype,_compare)(key, &node->key ) )\
00800 {\
00801 if( key == &node->key )\
00802 return true;\
00803 key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack );\
00804 }\
00805 return false;\
00806 )\
00807 }\
00808 }\
00809 \
00810 type* ppConcat(label,_obj_from_key)( const keytype* key )\
00811 {\
00812 if( key )\
00813 {\
00814 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,key);\
00815 return (type*)&node->obj;\
00816 }\
00817 return NULL;\
00818 }\
00819 \
00820 keytype* ppConcat(label,_key_from_obj)( const type* mbr )\
00821 {\
00822 if( mbr )\
00823 {\
00824 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,mbr);\
00825 return (keytype*)&node->key;\
00826 }\
00827 return NULL;\
00828 }\
00829 \
00830 void ppConcat(label,_recurse_clear)( ppConcat(label,_node)* node )\
00831 {\
00832 if( node->link.left )\
00833 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)node->link.left );\
00834 if( node->link.right )\
00835 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)node->link.right );\
00836 ppConcat(keytype,_destroy)(&node->key);\
00837 ppConcat(type,_destroy)(&node->obj);\
00838 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00839 }\
00840 \
00841 void ppConcat(label,_clear)( label* self )\
00842 {\
00843 assertobjptr(self);\
00844 if( self->root )\
00845 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)self->root );\
00846 self->size = 0;\
00847 self->root = NULL;\
00848 }\
00849 \
00850 type* ppConcat(label,_back)(const label* self)\
00851 {\
00852 assertobjconst(self);\
00853 {\
00854 keytype* key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, back)( self );\
00855 return ppConcat(label,_obj_from_key)( key );\
00856 }\
00857 }\
00858 \
00859 type* ppConcat(label,_front)(const label* self)\
00860 {\
00861 assertobjconst(self);\
00862 {\
00863 keytype* key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, front)( self );\
00864 return ppConcat(label,_obj_from_key)( key );\
00865 }\
00866 }\
00867 \
00868 void ppConcat(label,_pop_back)(label* self)\
00869 {\
00870 assertobjptr(self);\
00871 {\
00872 keytype* key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, pop_back)( self );\
00873 if( key )\
00874 {\
00875 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,key);\
00876 ppConcat(keytype,_destroy)(&node->key);\
00877 ppConcat(type,_destroy)(&node->obj);\
00878 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00879 }\
00880 }\
00881 }\
00882 \
00883 void ppConcat(label,_pop_front)(label* self)\
00884 {\
00885 assertobjptr(self);\
00886 {\
00887 keytype* key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, pop_front)( self );\
00888 if( key )\
00889 {\
00890 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,key);\
00891 ppConcat(keytype,_destroy)(&node->key);\
00892 ppConcat(type,_destroy)(&node->obj);\
00893 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00894 }\
00895 }\
00896 }\
00897 \
00898 type* ppConcat(label,_insert)( label* self, const keytype* key )\
00899 {\
00900 assertobjptr(self);\
00901 assertobjconst(key);\
00902 {\
00903 ppConcat(label,_node)* newnode;\
00904 ctl_pool_alloc(ppConcat(label,_node),&ppConcat(label,_pool), newnode);\
00905 ppConcat(keytype,_copy)(&newnode->key, key);\
00906 {\
00907 keytype* foundkey = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, insert)( self, &newnode->key );\
00908 if( foundkey != &newnode->key )\
00909 {\
00910 ppConcat(keytype,_destroy)(&newnode->key);\
00911 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), newnode);\
00912 return ppConcat(label,_obj_from_key)(foundkey);\
00913 }\
00914 }\
00915 ppDebug(newnode->container = (struct label*)self;)\
00916 ppConcat(type,_init)(&newnode->obj);\
00917 return &newnode->obj;\
00918 }\
00919 }\
00920 \
00921 type* ppConcat(label,_at)(const label* self, const keytype* key )\
00922 {\
00923 assertobjconst(self);\
00924 assertobjconst(key);\
00925 return ppConcat(label,_obj_from_key)( (keytype*)ctl_tree_(ctlt_after,ctlt_unique, find)( self, key ) );\
00926 }\
00927 \
00928 void ppConcat(label,_erase)(label* self, type* mbr )\
00929 {\
00930 assertobjptr(self);\
00931 assertobjptr(mbr);\
00932 {\
00933 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,mbr);\
00934 assert( (label*)node->container == self );\
00935 {\
00936 keytype* key = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, unlink)( self, &node->key );\
00937 if( key )\
00938 {\
00939 node = dereference(ppConcat(label,_node),key,key);\
00940 ppConcat(keytype,_destroy)(&node->key);\
00941 ppConcat(type,_destroy)(&node->obj);\
00942 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00943 }\
00944 }\
00945 }\
00946 }\
00947 \
00948 void ppConcat(label,_erase_key)(label* self, keytype* key )\
00949 {\
00950 assertobjptr(self);\
00951 assertobjptr(key);\
00952 {\
00953 keytype* found = (keytype*)ctl_tree_(ctlt_after,ctlt_unique, remove)( self, key );\
00954 if( found )\
00955 {\
00956 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),key,found);\
00957 ppConcat(keytype,_destroy)(&node->key);\
00958 ppConcat(type,_destroy)(&node->obj);\
00959 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00960 }\
00961 }\
00962 }\
00963 \
00964 void ppConcat(label,_splice)( label* self, label* from )\
00965 {\
00966 assertobjptr(self);\
00967 assertobjptr(from);\
00968 while( from->root )\
00969 {\
00970 ppConcat(label,_node)* node = (ppConcat(label,_node)*)from->root;\
00971 ctl_tree_(ctlt_after,ctlt_unique, remove)( from, &node->key );\
00972 if( &node->key != ctl_tree_(ctlt_after,ctlt_unique, insert)( self, &node->key ) )\
00973 {\
00974 \
00975 ppConcat(keytype,_destroy)(&node->key);\
00976 ppConcat(type,_destroy)(&node->obj);\
00977 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00978 }\
00979 ppDebug(else node->container = (struct label*)self;)\
00980 }\
00981 ppConcat(label,_destroy)(from);\
00982 }\
00983
00984 #endif