00001 #ifndef DG_SET_H
00002 #define DG_SET_H
00003
00009 #ifndef CTL_TREE_H
00010 #include "ctl/tree.h"
00011 #endif
00012
00013
00014
00015
00016
00017
00018
00019
00028 #define ctl_declare_set(label,type) ctl_declare_set_base(label,type,ctlt_unique)
00029
00037 #define ctl_implement_set(label,type) ctl_implement_set_base(label,type,ctlt_unique)
00038
00047 #define ctl_declare_set(label,type) ctl_declare_set_base(label,type,ctlt_unique)
00048
00056 #define ctl_implement_set(label,type) ctl_implement_set_base(label,type,ctlt_unique)
00057
00066 #define ctl_set_foreach(label, instance, iterator ) \
00067 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00068 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00069 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00070
00079 #define ctl_set_foreach_const(label, instance, iterator ) \
00080 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00081 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00082 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00083
00092 #define ctl_set_foreach_reverse(label, instance, iterator ) \
00093 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00094 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00095 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00096
00105 #define ctl_set_foreach_const_reverse(label, instance, iterator ) \
00106 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00107 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique,iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00108 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00109
00110
00119 #define ctl_set_from(label, instance, key, iterator )\
00120 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00121 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00122 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00123
00126 #define ctl_set_from_const(label, instance, key, iterator )\
00127 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00128 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00129 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00130
00133 #define ctl_set_from_reverse(label, instance, key, iterator )\
00134 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00135 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00136 for ( ; iterator; iterator = (ppConcat(label,_type)*)(ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00137
00140 #define ctl_set_from_const_reverse(label, instance, key, iterator )\
00141 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00142 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00143 for ( ; iterator; iterator = (const ppConcat(label,_type)*)(ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00144
00156 #define ctl_set_from_to(label, instance, keyfrom, keyto, iterator )\
00157 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00158 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00159 for( ; iterator && (instance)->compare(iterator,(keyto)) < 0; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00160
00163 #define ctl_set_from_to_const(label, instance, keyfrom, keyto, iterator )\
00164 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00165 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00166 for( ; iterator && (instance)->compare(iterator,(keyto)) < 0; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &ppConcat(stack_,iterator) ) )
00167
00170 #define ctl_set_from_to_reverse(label, instance, keyfrom, keyto, iterator )\
00171 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00172 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00173 for( ; iterator && (instance)->compare(iterator,(keyto)) > 0; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00174
00178 #define ctl_set_from_to_const_reverse(label, instance, keyfrom, keyto, iterator )\
00179 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00180 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00181 for( ; iterator && (instance)->compare(iterator,(keyto)) > 0; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_unique, iterator_prev)( &ppConcat(stack_,iterator) ) )
00182
00183
00184
00185
00186
00187
00188
00196 #define ctl_declare_multiset(label,type) ctl_declare_set_base(label,type,ctlt_multiple)
00197
00204 #define ctl_implement_multiset(label,type) ctl_implement_set_base(label,type,ctlt_multiple)
00205
00214 #define ctl_multiset_foreach(label, instance, iterator ) \
00215 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00216 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00217 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00218
00227 #define ctl_multiset_foreach_const(label, instance, iterator ) \
00228 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00229 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_begin)( &ppConcat(stack_,iterator), (instance) );\
00230 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00231
00240 #define ctl_multiset_foreach_reverse(label, instance, iterator ) \
00241 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00242 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00243 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00244
00253 #define ctl_multiset_foreach_const_reverse(label, instance, iterator ) \
00254 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00255 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple,iterator_rbegin)( &ppConcat(stack_,iterator), (instance) );\
00256 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00257
00258
00267 #define ctl_multiset_from(label, instance, key, iterator )\
00268 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00269 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00270 for ( ; iterator; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00271
00274 #define ctl_multiset_from_const(label, instance, key, iterator )\
00275 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00276 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00277 for ( ; iterator; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00278
00281 #define ctl_multiset_from_reverse(label, instance, key, iterator )\
00282 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00283 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00284 for ( ; iterator; iterator = (ppConcat(label,_type)*)(ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00285
00288 #define ctl_multiset_from_const_reverse(label, instance, key, iterator )\
00289 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00290 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (key) );\
00291 for ( ; iterator; iterator = (const ppConcat(label,_type)*)(ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00292
00304 #define ctl_multiset_from_to(label, instance, keyfrom, keyto, iterator )\
00305 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00306 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00307 for( ; iterator && (instance)->compare(iterator,(keyto)) < 0; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00308
00311 #define ctl_multiset_from_to_const(label, instance, keyfrom, keyto, iterator )\
00312 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00313 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_begin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00314 for( ; iterator && (instance)->compare(iterator,(keyto)) < 0; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_next)( &ppConcat(stack_,iterator) ) )
00315
00318 #define ctl_multiset_from_to_reverse(label, instance, keyfrom, keyto, iterator )\
00319 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00320 ppConcat(label,_type)* iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00321 for( ; iterator && (instance)->compare(iterator,(keyto)) > 0; iterator = (ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00322
00326 #define ctl_multiset_from_to_const_reverse(label, instance, keyfrom, keyto, iterator )\
00327 ppConcat(label,_iterator) ppConcat(stack_,iterator);\
00328 const ppConcat(label,_type)* iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_rbegin_from)( &ppConcat(stack_,iterator), (instance), (keyfrom) );\
00329 for( ; iterator && (instance)->compare(iterator,(keyto)) > 0; iterator = (const ppConcat(label,_type)*)ctl_tree_(ctlt_after,ctlt_multiple, iterator_prev)( &ppConcat(stack_,iterator) ) )
00330
00331
00332
00333
00334
00335
00336
00337
00341 #define ctl_declare_set_base(label,type,ctlt_unique)\
00342 typedef struct ppConcat(label,_node)\
00343 {\
00344 ctlt_node_type(ctlt_after,ctlt_unique) link;\
00345 type obj; \
00346 ppDebug(struct label* container;) \
00347 } ppConcat(label,_node);\
00348 typedef ctl_tree(ctlt_after,ctlt_unique) label;\
00349 \
00350 extern ctl_pool(ppConcat(label,_node)) ppConcat(label,_pool);\
00351 \
00352 typedef type ppConcat(label,_type);\
00353 typedef ctl_tree_(ctlt_after,ctlt_unique, iterator ) ppConcat(label,_iterator);\
00354 \
00355 ctl_datagen_declare_functions(label);\
00356 \
00357 void ppConcat(label,_sort)( label* self, int (*compare)(const type* p1, const type* p2) );\
00358 \
00359 size_t ppConcat(label,_count)( const label* self);\
00360 \
00361 bool ppConcat(label,_ismember)( const label* self, const type* mbr );\
00362 \
00363 void ppConcat(label,_clear)( label* self );\
00364 \
00365 type* ppConcat(label,_back)(const label* self);\
00366 \
00367 type* ppConcat(label,_front)(const label* self);\
00368 \
00369 void ppConcat(label,_pop_back)(label* self);\
00370 \
00371 void ppConcat(label,_pop_front)(label* self);\
00372 \
00373 type* ppConcat(label,_insert)( label* self, const type* key );\
00374 \
00375 type* ppConcat(label,_at)(const label* self, const type* key );\
00376 \
00377 void ppConcat(label,_erase)(label* self, type* mbr );\
00378 \
00379 void ppConcat(label,_erase_key)(label* self, type* key );\
00380 \
00381 void ppConcat(label,_splice)( label* self, label* from );\
00382
00383
00384
00385
00386
00387
00388
00389 #ifndef CTL_POOL_DELTA
00390
00396 #define CTL_POOL_DELTA 16
00397 #endif
00398
00402 #define ctl_implement_set_base(label,type,ctlt_unique)\
00403 const bool ppConcat(label,_isscalar) = false;\
00404 ctl_pool_auto(ppConcat(label,_node),ppConcat(label,_pool),CTL_POOL_DELTA);\
00405 \
00406 void ppConcat(label,_init)( label* self )\
00407 {\
00408 assertobjptr(self);\
00409 ctl_tree_init(ctlt_after,ctlt_unique, ppConcat(type,_compare), self );\
00410 }\
00411 \
00412 void ppConcat(label,_copy)( label* dst, const label* src )\
00413 {\
00414 assertobjptr(dst);\
00415 assertobjconst(src);\
00416 assertcodeptr(src->compare);\
00417 ppConcat(label,_init)( dst );\
00418 dst->compare = src->compare;\
00419 {\
00420 ppConcat(label,_iterator) stack_curr;\
00421 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, src );\
00422 while( curr )\
00423 {\
00424 ppConcat(label,_insert)(dst,curr);\
00425 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00426 }\
00427 }\
00428 }\
00429 \
00430 void ppConcat(label,_move)( label* dst, label* src )\
00431 {\
00432 assertobjptr(dst);\
00433 assertobjptr(src);\
00434 *dst = *src;\
00435 ppConcat(label,_init)( src );\
00436 ppDebug( {\
00437 ppConcat(label,_iterator) stack_curr;\
00438 type* curr = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, dst );\
00439 while( curr )\
00440 {\
00441 dereference(ppConcat(label,_node),obj,curr)->container = (struct label*)dst;\
00442 curr = (type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00443 }\
00444 } )\
00445 }\
00446 \
00447 void ppConcat(label,_swap)( label* p1, label* p2 )\
00448 {\
00449 assertobjptr(p1);\
00450 assertobjptr(p2);\
00451 {\
00452 label tmp = *p1;\
00453 *p1 = *p2;\
00454 *p2 = tmp;\
00455 }\
00456 ppDebug( {\
00457 ppConcat(label,_iterator) stack_curr;\
00458 type* curr = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, p1 );\
00459 while( curr )\
00460 {\
00461 dereference(ppConcat(label,_node),obj,curr)->container = (struct label*)p1;\
00462 curr = (type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00463 }\
00464 } )\
00465 ppDebug( {\
00466 ppConcat(label,_iterator) stack_curr;\
00467 type* curr = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, p2 );\
00468 while( curr )\
00469 {\
00470 dereference(ppConcat(label,_node),obj,curr)->container = (struct label*)p2;\
00471 curr = (type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00472 }\
00473 } )\
00474 }\
00475 \
00476 void ppConcat(label,_destroy)( label* self )\
00477 {\
00478 ppConcat(label,_clear)( self );\
00479 }\
00480 \
00481 int ppConcat(label,_rcompare)( const label* p1, const label* p2 ) { return ppConcat(label,_compare)( p2,p1 ); }\
00482 \
00483 int ppConcat(label,_compare)( const label* p1, const label* p2 )\
00484 {\
00485 if( NULL == p1 )\
00486 {\
00487 if( NULL == p2 )\
00488 return 0;\
00489 return -1;\
00490 }\
00491 else if( NULL == p2 )\
00492 return 1;\
00493 assertobjconst(p1);\
00494 assertobjconst(p2);\
00495 {\
00496 size_t compareLen = min(p1->size,p2->size);\
00497 ppConcat(label,_iterator) p1s;\
00498 ppConcat(label,_iterator) p2s;\
00499 type* v1 = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &p1s, p1 );\
00500 type* v2 = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &p2s, p2 );\
00501 while( compareLen-- && v1 && v2 )\
00502 {\
00503 int result = ppConcat(type,_compare)( v1,v2 );\
00504 if( result )\
00505 return result;\
00506 v1 = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_next)( &p1s );\
00507 v2 = (type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_next)( &p2s );\
00508 }\
00509 \
00510 assert(compareLen == -1);\
00511 if( p1->size < p2->size )\
00512 return -1;\
00513 if( p1->size > p2->size )\
00514 return 1;\
00515 return 0;\
00516 }\
00517 }\
00518 \
00519 bool ppConcat(label,_valid)( const label* self )\
00520 {\
00521 if( !self )\
00522 return false;\
00523 assertobjconst(self);\
00524 assertcodeptr(self->compare);\
00525 return ((NULL != self->root && self->size) || (NULL == self->root && 0 == self->size));\
00526 }\
00527 \
00528 size_t ppConcat(label,_size)( const label* self )\
00529 {\
00530 assertobjconst(self);\
00531 if( ppConcat(type,_isscalar) )\
00532 {\
00533 return sizeof(*self) + (self->size * sizeof(ppConcat(label,_node)));\
00534 }\
00535 else\
00536 {\
00537 size_t ret = sizeof(*self);\
00538 ppConcat(label,_iterator) stack_curr;\
00539 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00540 while( curr )\
00541 {\
00542 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,curr);\
00543 ret += ppConcat(type,_size)(&node->obj) + sizeof(ppConcat(label,_node))-sizeof(type);\
00544 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00545 }\
00546 return ret;\
00547 }\
00548 }\
00549 \
00550 size_t ppConcat(label,_serial_size)( const label* self )\
00551 {\
00552 assertobjconst(self);\
00553 if( ppConcat(type,_isscalar) )\
00554 {\
00555 return ctl_serial_size_size( self->size ) + (self->size * ppConcat(type,_serial_size)(&dereference(ppConcat(label,_node),link,self->root)->obj));\
00556 }\
00557 else\
00558 {\
00559 size_t total = ctl_serial_size_size( self->size );\
00560 ppConcat(label,_iterator) stack_curr;\
00561 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00562 while( curr )\
00563 {\
00564 total += ppConcat(type,_serial_size)(curr);\
00565 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00566 }\
00567 return total;\
00568 }\
00569 }\
00570 \
00571 void ppConcat(label,_serial_write)( const label* self, ctl_serial* serial )\
00572 {\
00573 assertobjconst(self);\
00574 assertobjptr(serial);\
00575 ctl_serial_writesize( self->size, serial ); \
00576 {\
00577 ppConcat(label,_iterator) stack_curr;\
00578 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00579 while( curr )\
00580 {\
00581 ppConcat(type,_serial_write)(curr,serial);\
00582 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00583 }\
00584 }\
00585 }\
00586 \
00587 void ppConcat(label,_serial_read)( label* self, ctl_serial* serial )\
00588 {\
00589 assertobjptr(self);\
00590 assertobjptr(serial);\
00591 {\
00592 size_t readsize = ctl_serial_readsize( serial ); \
00593 while( readsize-- )\
00594 {\
00595 type value;\
00596 ppConcat(type,_init)(&value);\
00597 ppConcat(type,_serial_read)(&value,serial);\
00598 ppConcat(label,_insert)(self,&value);\
00599 ppConcat(type,_destroy)(&value);\
00600 }\
00601 }\
00602 }\
00603 \
00604 size_t ppConcat(label,_record_size)( const label* self, const char* szlabel )\
00605 {\
00606 assertobjconst(self);\
00607 assertconst(szlabel,1);\
00608 if( self->size )\
00609 {\
00610 size_t result = ctl_record_objarray_head_size( szlabel, "container", #type );\
00611 if( ppConcat(type,_isscalar) )\
00612 {\
00613 result += self->size * ppConcat(type,_record_size)(&dereference(ppConcat(label,_node),link,self->root)->obj,szlabel);\
00614 }\
00615 else\
00616 {\
00617 ppConcat(label,_iterator) stack_curr;\
00618 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00619 while( curr )\
00620 {\
00621 result += ppConcat(type,_record_size)(curr,szlabel); \
00622 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00623 }\
00624 }\
00625 return result;\
00626 }\
00627 return 0;\
00628 }\
00629 \
00630 void ppConcat(label,_record_write)( const label* self, ctl_serial* serial, const char* szlabel )\
00631 {\
00632 assertobjconst(self);\
00633 assertobjptr(serial);\
00634 assertconst(szlabel,1);\
00635 if( self->size )\
00636 {\
00637 uint8* rectemp = ctl_record_write_container_begin( "container", #type, 0,self->size, serial, szlabel );\
00638 ppConcat(label,_iterator) stack_curr;\
00639 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00640 while( curr )\
00641 {\
00642 ppConcat(type,_record_write)(curr,serial,szlabel); \
00643 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00644 }\
00645 ctl_record_write_end( rectemp, serial );\
00646 }\
00647 }\
00648 \
00649 bool ppConcat(label,_record_read)( label* self, ctl_serial* serial, const char* szlabel )\
00650 {\
00651 assertobjptr(self);\
00652 assertobjptr(serial);\
00653 assertconst(szlabel,1);\
00654 {\
00655 ctl_serial pserial = *serial;\
00656 ppConcat(label,_clear)(self);\
00657 if( ctl_record_find( &pserial, szlabel ) )\
00658 {\
00659 size_t count = ctl_record_container_validatedata( &pserial, "container", #type );\
00660 while( count-- )\
00661 {\
00662 type value;\
00663 ppConcat(type,_init)(&value);\
00664 ppConcat(type,_record_read)(&value, &pserial, szlabel );\
00665 ppConcat(label,_insert)(self,&value);\
00666 ppConcat(type,_destroy)(&value);\
00667 ctl_record_next( &pserial );\
00668 }\
00669 if( pserial.curr != pserial.end )\
00670 ctl_serial_except( &pserial, szconst(char,#label) szconst(char,"_record_read: Wrong data length!") );\
00671 return true;\
00672 }\
00673 }\
00674 return false;\
00675 }\
00676 \
00677 void ppConcat(label,_xml_write)( const label* self, ctl_xmlwrite* xml, const char* szlabel )\
00678 {\
00679 assertobjconst(self);\
00680 assertobjptr(xml);\
00681 assertconst(szlabel,1);\
00682 if( self->size )\
00683 {\
00684 ctl_xmlwrite_containertag( xml, #type, self->size, szlabel ); \
00685 ctl_xmlwrite_indent( xml );\
00686 {\
00687 ppConcat(label,_iterator) stack_curr;\
00688 const type* curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack_curr, self );\
00689 while( curr )\
00690 {\
00691 ppConcat(type,_xml_write)(curr,xml,NULL); \
00692 curr = (const type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack_curr );\
00693 }\
00694 }\
00695 ctl_xmlwrite_outdent( xml );\
00696 ctl_xmlwrite_endtag( xml, #type, szlabel ); \
00697 }\
00698 }\
00699 \
00700 bool ppConcat(label,_xml_read)( label* self, ctl_xmlread* xml, const char* szlabel )\
00701 {\
00702 assertobjptr(self);\
00703 assertobjptr(xml);\
00704 assertconst(szlabel,1);\
00705 if( ctl_xmlread_find( xml, szlabel ) )\
00706 {\
00707 int32 count = 0;\
00708 if( ctl_xmlread_getattribute_int( xml, CTL_LABEL_COUNT, &count ) )\
00709 {\
00710 ctl_xmlread arraydata;\
00711 ctl_xmlread_recurse(&arraydata,xml);\
00712 while( count-- )\
00713 {\
00714 type value;\
00715 ppConcat(type,_init)(&value);\
00716 ppConcat(type,_xml_read)(&value, &arraydata, NULL );\
00717 ppConcat(label,_insert)(self,&value);\
00718 ppConcat(type,_destroy)(&value);\
00719 ctl_xmlread_next(&arraydata);\
00720 }\
00721 }\
00722 else\
00723 {\
00724 xml->except( xml, szconst(char,#label) szconst(char,"_xml_read: Missing size attribute!"), xml->szpCurr, NULL );\
00725 }\
00726 return true;\
00727 }\
00728 return false;\
00729 }\
00730 \
00731 void ppConcat(label,_sort)( label* self, int (*compare)(const type* p1, const type* p2) )\
00732 {\
00733 assertobjptr(self);\
00734 assertcodeptr(compare);\
00735 if( self->size )\
00736 {\
00737 label tmp;\
00738 ppConcat(label,_move)( &tmp, self );\
00739 self->compare = (tree_compare)compare;\
00740 ppConcat(label,_splice)( self, &tmp );\
00741 }\
00742 else\
00743 {\
00744 self->compare = (tree_compare)compare;\
00745 }\
00746 }\
00747 \
00748 size_t ppConcat(label,_count)( const label* self)\
00749 {\
00750 assertobjconst(self);\
00751 return self->size;\
00752 }\
00753 \
00754 bool ppConcat(label,_ismember)( const label* self, const type* data )\
00755 {\
00756 assertobjconst(self);\
00757 if( NULL == data )\
00758 return false;\
00759 assertobjconst(data);\
00760 {\
00761 ppDebug(return dereference(ppConcat(label,_node),obj,data)->container == (struct label*)self; )\
00762 ppRelease (\
00763 \
00764 ppConcat(label,_iterator) stack;\
00765 const type* key = (const type*)ctl_tree_(ctlt_after,ctlt_unique,iterator_begin)( &stack, self );\
00766 while( key && !ppConcat(type,_compare)(key, data ) )\
00767 {\
00768 if( key == data )\
00769 return true;\
00770 key = (type*)ctl_tree_(ctlt_after,ctlt_unique, iterator_next)( &stack );\
00771 }\
00772 return false;\
00773 )\
00774 }\
00775 }\
00776 \
00777 void ppConcat(label,_recurse_clear)( ppConcat(label,_node)* node )\
00778 {\
00779 if( node->link.left )\
00780 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)node->link.left );\
00781 if( node->link.right )\
00782 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)node->link.right );\
00783 ppConcat(type,_destroy)(&node->obj);\
00784 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00785 }\
00786 \
00787 void ppConcat(label,_clear)( label* self )\
00788 {\
00789 assertobjptr(self);\
00790 if( self->root )\
00791 ppConcat(label,_recurse_clear)( (ppConcat(label,_node)*)self->root );\
00792 self->size = 0;\
00793 self->root = NULL;\
00794 }\
00795 \
00796 type* ppConcat(label,_back)(const label* self)\
00797 {\
00798 assertobjconst(self);\
00799 return (type*)ctl_tree_(ctlt_after,ctlt_unique, back)( self );\
00800 }\
00801 \
00802 type* ppConcat(label,_front)(const label* self)\
00803 {\
00804 assertobjconst(self);\
00805 return (type*)ctl_tree_(ctlt_after,ctlt_unique, front)( self );\
00806 }\
00807 \
00808 void ppConcat(label,_pop_back)(label* self)\
00809 {\
00810 assertobjptr(self);\
00811 {\
00812 type* obj = (type*)ctl_tree_(ctlt_after,ctlt_unique, pop_back)( self );\
00813 if( obj )\
00814 {\
00815 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,obj);\
00816 ppConcat(type,_destroy)(&node->obj);\
00817 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00818 }\
00819 }\
00820 }\
00821 \
00822 void ppConcat(label,_pop_front)(label* self)\
00823 {\
00824 assertobjptr(self);\
00825 {\
00826 type* obj = (type*)ctl_tree_(ctlt_after,ctlt_unique, pop_front)( self );\
00827 if( obj )\
00828 {\
00829 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,obj);\
00830 ppConcat(type,_destroy)(&node->obj);\
00831 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00832 }\
00833 }\
00834 }\
00835 \
00836 type* ppConcat(label,_insert)( label* self, const type* key )\
00837 {\
00838 assertobjptr(self);\
00839 assertobjconst(key);\
00840 {\
00841 ppConcat(label,_node)* newnode;\
00842 ctl_pool_alloc(ppConcat(label,_node),&ppConcat(label,_pool), newnode);\
00843 ppConcat(type,_copy)(&newnode->obj, key);\
00844 {\
00845 type* foundkey = (type*)ctl_tree_(ctlt_after,ctlt_unique, insert)( self, &newnode->obj );\
00846 if( foundkey != &newnode->obj )\
00847 {\
00848 ppConcat(type,_destroy)(&newnode->obj);\
00849 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), newnode);\
00850 return foundkey;\
00851 }\
00852 }\
00853 ppDebug(newnode->container = (struct label*)self;)\
00854 return &newnode->obj;\
00855 }\
00856 }\
00857 \
00858 type* ppConcat(label,_at)(const label* self, const type* key )\
00859 {\
00860 assertobjconst(self);\
00861 assertobjconst(key);\
00862 return (type*)ctl_tree_(ctlt_after,ctlt_unique, find)( self, key );\
00863 }\
00864 \
00865 void ppConcat(label,_erase)(label* self, type* mbr )\
00866 {\
00867 assertobjptr(self);\
00868 assertobjptr(mbr);\
00869 {\
00870 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,mbr);\
00871 assert( (label*)node->container == self );\
00872 {\
00873 type* key = (type*)ctl_tree_(ctlt_after,ctlt_unique, unlink)( self, &node->obj );\
00874 if( key )\
00875 {\
00876 node = dereference(ppConcat(label,_node),obj,key);\
00877 ppConcat(type,_destroy)(&node->obj);\
00878 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00879 }\
00880 }\
00881 }\
00882 }\
00883 \
00884 void ppConcat(label,_erase_key)(label* self, type* key )\
00885 {\
00886 assertobjptr(self);\
00887 assertobjptr(key);\
00888 {\
00889 type* found = (type*)ctl_tree_(ctlt_after,ctlt_unique, remove)( self, key );\
00890 if( found )\
00891 {\
00892 ppConcat(label,_node)* node = dereference(ppConcat(label,_node),obj,found);\
00893 ppConcat(type,_destroy)(&node->obj);\
00894 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00895 }\
00896 }\
00897 }\
00898 \
00899 void ppConcat(label,_splice)( label* self, label* from )\
00900 {\
00901 assertobjptr(self);\
00902 assertobjptr(from);\
00903 while( from->root )\
00904 {\
00905 ppConcat(label,_node)* node = (ppConcat(label,_node)*)from->root;\
00906 ctl_tree_(ctlt_after,ctlt_unique, remove)( from, &node->obj );\
00907 if( &node->obj != ctl_tree_(ctlt_after,ctlt_unique, insert)( self, &node->obj ) )\
00908 {\
00909 \
00910 ppConcat(type,_destroy)(&node->obj);\
00911 ctl_pool_free(ppConcat(label,_node),&ppConcat(label,_pool), node);\
00912 }\
00913 ppDebug(else node->container = (struct label*)self;)\
00914 }\
00915 ppConcat(label,_destroy)(from);\
00916 }\
00917
00918 #endif