00001 #ifndef DG_ARRAY_H
00002 #define DG_ARRAY_H
00003
00010 #ifndef CTL_ALGORITHM_H
00011 #include "ctl/algorithm.h"
00012 #endif
00013 #ifndef CTL_ALGORITHM_TEMP_H
00014 #include "ctl/algorithm.temp.h"
00015 #endif
00016
00025 #define ctl_declare_array(label,type,size)\
00026 typedef type ppConcat(label,_type);\
00027 typedef struct label\
00028 {\
00029 size_t count; \
00030 type array[size];\
00031 } label;\
00032 \
00033 ctl_datagen_declare_functions(label);\
00034 \
00035 size_t ppConcat(label,_count)( const label* self);\
00036 \
00037 bool ppConcat(label,_ismember)( const label* self, const type* mbr );\
00038 \
00039 void ppConcat(label,_clear)( label* self );\
00040 \
00041 type* ppConcat(label,_back)(const label* self);\
00042 \
00043 type* ppConcat(label,_front)(const label* self);\
00044 \
00045 type* ppConcat(label,_prev)(const label* self, const type* curr);\
00046 \
00047 type* ppConcat(label,_next)(const label* self, const type* curr );\
00048 \
00049 type* ppConcat(label,_at)(label* self, int index);\
00050 \
00051 type* ppConcat(label,_push_back)(label* self);\
00052 \
00053 type* ppConcat(label,_push_front)(label* self);\
00054 \
00055 type* ppConcat(label,_insert)(label* self, type* mbr );\
00056 \
00057 type* ppConcat(label,_insert_range)(label* self, type* mbr, size_t count );\
00058 \
00059 void ppConcat(label,_pop_back)(label* self);\
00060 \
00061 void ppConcat(label,_pop_front)(label* self);\
00062 \
00063 void ppConcat(label,_erase)(label* self, type* mbr );\
00064 \
00065 void ppConcat(label,_erase_range)(label* self, type* mbr, size_t count );\
00066 \
00067 void ppConcat(label,_bag_erase)(label* self, type* mbr );\
00068 \
00069 void ppConcat(label,_sort)( label* self, int (*compare)(const type* p1, const type* p2) );\
00070 \
00071 void ppConcat(label,_splice)( label* self, label* from )
00072
00083 #define ctl_array_foreach_const( label, instance, iterator ) \
00084 const ppConcat(label,_type)* iterator = (instance)->array;\
00085 const ppConcat(label,_type)* ppConcat(end_,iterator) = iterator + (instance)->count;\
00086 for( ; iterator < ppConcat(end_,iterator); iterator++ )
00087
00098 #define ctl_array_foreach_const_reverse( label, instance, iterator )\
00099 const ppConcat(label,_type)* ppConcat(end_,iterator) = (instance)->array;\
00100 const ppConcat(label,_type)* iterator = ppConcat(end_,iterator) + (instance)->count;\
00101 while( iterator-- > ppConcat(end_,iterator) )
00102
00114 #define ctl_array_foreach( label, instance, iterator ) \
00115 ppConcat(label,_type)* iterator = (instance)->array;\
00116 const ppConcat(label,_type)* ppConcat(end_,iterator) = iterator + (instance)->count;\
00117 for( ; iterator < ppConcat(end_,iterator); iterator++ )
00118
00130 #define ctl_array_foreach_reverse( label, instance, iterator )\
00131 ppConcat(label,_type)* ppConcat(end_,iterator) = (instance)->array;\
00132 const ppConcat(label,_type)* iterator = ppConcat(end_,iterator) + (instance)->count;\
00133 while( iterator-- > ppConcat(end_,iterator) )
00134
00144 #define ctl_array_foreach_mutable( label, instance, iterator ) \
00145 ppConcat(label,_type)* iterator;\
00146 int ppConcat(index_,iterator);\
00147 label* ppConcat(instance_,iterator) = (instance);\
00148 for( ppConcat(index_,iterator) = 0; ppConcat(index_,iterator) < (int)ppConcat(instance_,iterator)->count && intentional_assignment(iterator=ppConcat(instance_,iterator)->array + ppConcat(index_,iterator)); ppConcat(index_,iterator)++ )
00149
00159 #define ctl_array_foreach_mutable_reverse( label, instance, iterator )\
00160 ppConcat(label,_type)* iterator;\
00161 int ppConcat(index_,iterator);\
00162 label* ppConcat(instance_,iterator) = (instance);\
00163 for( ppConcat(index_,iterator) = (int)ppConcat(instance_,iterator)->count; ppConcat(index_,iterator) > 0 && intentional_assignment(iterator=ppConcat(instance_,iterator)->array + ppConcat(index_,iterator)-1); ppConcat(index_,iterator) = min(ppConcat(index_,iterator)-1,(int)ppConcat(instance_,iterator)->count) )
00164
00170 #define ctl_cooked(text) text
00171
00177 #define ctl_raw(text)
00178
00186 #define ctl_implement_array(label,type,rawcook)\
00187 const bool ppConcat(label,_isscalar) = false;\
00188 \
00189 void ppConcat(label,_init)( label* self ) \
00190 {\
00191 assertobjptr(self);\
00192 self->count = 0;\
00193 }\
00194 \
00195 void ppConcat(label,_copy)( label* dst, const label* src ) \
00196 {\
00197 assertobjptr(dst);\
00198 assertobjconst(src);\
00199 ppConcat(label,_init)(dst);\
00200 {\
00201 ctl_array_foreach_const( label, src, curr )\
00202 ppConcat(type,_copy)(ppConcat(label,_push_back)(dst),curr);\
00203 }\
00204 }\
00205 \
00206 void ppConcat(label,_move)( label* dst, label* src ) \
00207 {\
00208 assertobjptr(dst);\
00209 assertobjptr(src);\
00210 ppConcat(label,_init)(dst);\
00211 {\
00212 ctl_array_foreach( label, src, curr )\
00213 ppConcat(type,_move)(ppConcat(label,_push_back)(dst),curr);\
00214 }\
00215 dst->count = src->count;\
00216 ppConcat(label,_destroy)(src);\
00217 }\
00218 \
00219 void ppConcat(label,_destroy)( label* self ) \
00220 {\
00221 assertobjptr(self);\
00222 ppConcat(label,_clear)(self);\
00223 }\
00224 \
00225 void ppConcat(label,_swap)( label* p1, label* p2 )\
00226 {\
00227 type *pbig, *pless;\
00228 size_t bigger, lesser;\
00229 assertobjptr(p1);\
00230 assertobjptr(p2);\
00231 if( p1->count > p2->count )\
00232 {\
00233 pbig = p1->array;\
00234 pless = p2->array;\
00235 lesser = p2->count;\
00236 bigger = p1->count - lesser;\
00237 }\
00238 else\
00239 {\
00240 pbig = p2->array;\
00241 pless = p1->array;\
00242 lesser = p1->count;\
00243 bigger = p2->count - lesser;\
00244 }\
00245 while( lesser-- )\
00246 { \
00247 ppConcat(type,_swap)(pless,pbig);\
00248 pbig++;pless++;\
00249 }\
00250 while( bigger-- )\
00251 { \
00252 ppConcat(type,_copy)(pless,pbig);\
00253 pbig++;pless++;\
00254 }\
00255 {\
00256 size_t c1 = p1->count;\
00257 p1->count = p2->count;\
00258 p2->count = c1;\
00259 }\
00260 }\
00261 \
00262 int ppConcat(label,_rcompare)( const label* p1, const label* p2 ) { return ppConcat(label,_compare)( p2,p1 ); }\
00263 \
00264 int ppConcat(label,_compare)( const label* p1, const label* p2 )\
00265 {\
00266 if( NULL == p1 )\
00267 {\
00268 if( NULL == p2 )\
00269 return 0;\
00270 return -1;\
00271 }\
00272 else if( NULL == p2 )\
00273 return 1;\
00274 assertobjconst(p1);\
00275 assertobjconst(p2);\
00276 {\
00277 size_t compareLen = min(p1->count,p2->count);\
00278 const type* p1curr = p1->array; \
00279 const type* p2curr = p2->array; \
00280 while( compareLen-- ) \
00281 {\
00282 int result = ppConcat(type,_compare)(p1curr++,p2curr++);\
00283 if( result )\
00284 return result;\
00285 }\
00286 if( p1->count < p2->count )\
00287 return -1;\
00288 if( p1->count > p2->count )\
00289 return 1;\
00290 return 0;\
00291 }\
00292 }\
00293 \
00294 bool ppConcat(label,_valid)( const label* self ) \
00295 {\
00296 if( !self )\
00297 return false;\
00298 assertobjconst(self);\
00299 if( self->count > countof(self->array) )\
00300 return false;\
00301 {\
00302 ctl_array_foreach_const( label, self, curr )\
00303 if( !ppConcat(type,_valid)(curr) )\
00304 return false;\
00305 }\
00306 return true;\
00307 }\
00308 \
00309 size_t ppConcat(label,_size)( const label* self )\
00310 {\
00311 if( ppConcat(type,_isscalar) )\
00312 {\
00313 return sizeof(*self);\
00314 }\
00315 else\
00316 {\
00317 size_t total = sizeof(*self);\
00318 ctl_array_foreach_const( label, self, curr )\
00319 total += ppConcat(type,_size)(curr);\
00320 return total;\
00321 }\
00322 }\
00323 \
00324 size_t ppConcat(label,_serial_size)( const label* self ) \
00325 {\
00326 size_t total;\
00327 assertobjconst(self);\
00328 total = ctl_serial_size_size( self->count );\
00329 if( ppConcat(type,_isscalar) )\
00330 {\
00331 total += (self->count * ppConcat(type,_serial_size)(ppConcat(label,_front)(self)));\
00332 }\
00333 else\
00334 {\
00335 ctl_array_foreach_const( label, self, curr )\
00336 total += ppConcat(type,_serial_size)(curr);\
00337 }\
00338 return total;\
00339 }\
00340 \
00341 void ppConcat(label,_serial_write)( const label* self, ctl_serial* serial ) \
00342 {\
00343 assertobjconst(self);\
00344 assertobjptr(serial);\
00345 ctl_serial_writesize( self->count, serial ); \
00346 {\
00347 ctl_array_foreach_const( label, self, curr )\
00348 ppConcat(type,_serial_write)(curr,serial);\
00349 }\
00350 }\
00351 \
00352 void ppConcat(label,_serial_read)( label* self, ctl_serial* serial ) \
00353 {\
00354 size_t readsize; \
00355 assertobjptr(self);\
00356 assertobjptr(serial);\
00357 readsize = ctl_serial_readsize( serial ); \
00358 if( countof(self->array) < readsize )\
00359 readsize = countof(self->array);\
00360 while( readsize-- )\
00361 ppConcat(type,_serial_read)( ppConcat(label,_push_back)(self), serial );\
00362 }\
00363 \
00364 size_t ppConcat(label,_record_size)( const label* self, const char* szlabel ) \
00365 {\
00366 size_t result;\
00367 assertobjconst(self);\
00368 assertconst(szlabel,1);\
00369 result = ctl_record_objarray_head_size( szlabel, "container", #type );\
00370 if( ppConcat(type,_isscalar) )\
00371 {\
00372 result += (self->count * ppConcat(type,_record_size)(ppConcat(label,_front)(self),szlabel));\
00373 }\
00374 else\
00375 { \
00376 ctl_array_foreach_const(label,self,curr) \
00377 result += ppConcat(type,_record_size)(curr,szlabel); \
00378 }\
00379 return result;\
00380 }\
00381 \
00382 void ppConcat(label,_record_write)( const label* self, ctl_serial* serial, const char* szlabel ) \
00383 {\
00384 uint8* rectemp;\
00385 assertobjconst(self);\
00386 assertobjptr(serial);\
00387 assertconst(szlabel,1);\
00388 rectemp = ctl_record_write_container_begin( "container", #type, 0,self->count, serial, szlabel );\
00389 { \
00390 ctl_array_foreach_const(label,self,curr) \
00391 ppConcat(type,_record_write)(curr,serial,szlabel); \
00392 }\
00393 ctl_record_write_end( rectemp, serial );\
00394 }\
00395 \
00396 bool ppConcat(label,_record_read)( label* self, ctl_serial* serial, const char* szlabel ) \
00397 {\
00398 ctl_serial pserial;\
00399 assertobjptr(self);\
00400 assertobjptr(serial);\
00401 assertconst(szlabel,1);\
00402 pserial = *serial;\
00403 if( ctl_record_find( &pserial, szlabel ) )\
00404 {\
00405 size_t count = ctl_record_container_validatedata( &pserial, "container", szconst(char,#type) );\
00406 if( countof(self->array) < count )\
00407 count = countof(self->array);\
00408 while( count-- && pserial.curr < pserial.end )\
00409 {\
00410 ppConcat(type,_record_read)( ppConcat(label,_push_back)(self), &pserial, szlabel );\
00411 ctl_record_next( &pserial );\
00412 }\
00413 if( pserial.curr != pserial.end )\
00414 ctl_serial_except( &pserial, szconst(char,#label) szconst(char,"_record_read: Wrong data length!") );\
00415 return true;\
00416 }\
00417 return false;\
00418 }\
00419 \
00420 void ppConcat(label,_xml_write)( const label* self, ctl_xmlwrite* xml, const char* szlabel ) \
00421 {\
00422 assertobjconst(self);\
00423 assertobjptr(xml);\
00424 assertconst(szlabel,1);\
00425 ctl_xmlwrite_containertag( xml, #type, self->count, szlabel ); \
00426 ctl_xmlwrite_indent( xml );\
00427 {\
00428 ctl_array_foreach_const(label,self, curr ) \
00429 ppConcat(type,_xml_write)(curr,xml,NULL);\
00430 } \
00431 ctl_xmlwrite_outdent( xml );\
00432 ctl_xmlwrite_endtag( xml, #type, szlabel ); \
00433 }\
00434 \
00435 bool ppConcat(label,_xml_read)( label* self, struct ctl_xmlread* xml, const char* szlabel ) \
00436 {\
00437 assertobjptr(self);\
00438 assertobjptr(xml);\
00439 assertconst(szlabel,1);\
00440 if( ctl_xmlread_find( xml, szlabel ) )\
00441 {\
00442 int32 count = 0;\
00443 if( ctl_xmlread_getattribute_int( xml, CTL_LABEL_COUNT, &count ) )\
00444 {\
00445 ctl_xmlread arraydata;\
00446 ctl_xmlread_recurse(&arraydata,xml);\
00447 if( countof(self->array) < count )\
00448 count = countof(self->array);\
00449 while( count-- && ppConcat(type,_xml_read)( ppConcat(label,_push_back)(self), &arraydata, NULL ) )\
00450 ctl_xmlread_next(&arraydata);\
00451 }\
00452 else\
00453 {\
00454 xml->except( xml, szconst(char,#label) szconst(char,"_xml_read: Missing size attribute!"), xml->szpCurr, NULL );\
00455 }\
00456 return true;\
00457 }\
00458 return false;\
00459 }\
00460 \
00461 size_t ppConcat(label,_count)( const label* self)\
00462 {\
00463 assertobjconst(self);\
00464 return self->count;\
00465 }\
00466 \
00467 bool ppConcat(label,_ismember)( const label* self, const type* mbr )\
00468 {\
00469 assertobjconst(self);\
00470 return mbr >= self->array && mbr < self->array + self->count;\
00471 }\
00472 \
00473 void ppConcat(label,_clear)( label* self )\
00474 {\
00475 assertobjptr(self);\
00476 rawcook( { ctl_array_foreach( label, self, curr ) ppConcat( type,_destroy )(curr); } )\
00477 self->count = 0;\
00478 }\
00479 \
00480 type* ppConcat(label,_push_back)(label* self)\
00481 {\
00482 assertobjptr(self);\
00483 if(self->count+1 <= countof(self->array) )\
00484 {\
00485 type* ret = self->array+self->count++;\
00486 rawcook( ppConcat( type,_init )(ret); )\
00487 return ret;\
00488 }\
00489 throwassert("Out of bounds");\
00490 return NULL;\
00491 }\
00492 \
00493 type* ppConcat(label,_push_front)(label* self)\
00494 {\
00495 assertobjptr(self);\
00496 if(self->count+1 <= countof(self->array) )\
00497 {\
00498 type* curr = self->array + self->count++;\
00499 while( curr-- > self->array )\
00500 ppConcat(type,_move)( curr+1,curr );\
00501 rawcook( ppConcat( type,_init )(self->array); )\
00502 return self->array;\
00503 }\
00504 throwassert("Out of bounds");\
00505 return NULL;\
00506 }\
00507 \
00508 type* ppConcat(label,_back)(const label* self)\
00509 {\
00510 assertobjconst(self);\
00511 if( self->count > 0 )\
00512 return (type*)(self->array + (self->count-1));\
00513 return (type*)self->array;\
00514 }\
00515 \
00516 type* ppConcat(label,_front)(const label* self)\
00517 {\
00518 assertobjconst(self);\
00519 return (type*)self->array;\
00520 }\
00521 \
00522 type* ppConcat(label,_prev)(const label* self, const type* curr)\
00523 {\
00524 assertobjconst(self);\
00525 if( curr )\
00526 {\
00527 assert( ppConcat(label,_ismember)(self,curr) );\
00528 if( --curr >= self->array )\
00529 return (type*)curr;\
00530 }\
00531 return NULL;\
00532 }\
00533 \
00534 type* ppConcat(label,_next)(const label* self, const type* curr )\
00535 {\
00536 assertobjconst(self);\
00537 if( curr )\
00538 {\
00539 assert( ppConcat(label,_ismember)(self,curr) );\
00540 if( ++curr < self->array + self->count )\
00541 return (type*)curr;\
00542 }\
00543 return NULL;\
00544 }\
00545 \
00546 void ppConcat(label,_pop_back)(label* self)\
00547 {\
00548 assertobjptr(self);\
00549 assert(self->count > 0 );\
00550 if( self->count > 0 )\
00551 {\
00552 --self->count;\
00553 ctl_cooked( ppConcat( type,_destroy )( self->array + self->count); )\
00554 }\
00555 }\
00556 \
00557 void ppConcat(label,_pop_front)(label* self)\
00558 {\
00559 assert(self->count > 0 );\
00560 if(self->count > 0 )\
00561 {\
00562 type* curr = self->array;\
00563 type* end = self->array + self->count;\
00564 rawcook(ppConcat( type,_destroy )(curr++);)\
00565 while( curr < end )\
00566 {\
00567 ppConcat(type,_move)( curr,curr+1 );\
00568 curr++;\
00569 }\
00570 }\
00571 }\
00572 \
00573 type* ppConcat(label,_at)(label* self, int index)\
00574 {\
00575 assertobjptr(self);\
00576 if( index < 0 || index >= countof(self->array) )\
00577 {\
00578 throwassert("Out of bounds");\
00579 return NULL;\
00580 }\
00581 if( index >= (int)self->count )\
00582 {\
00583 rawcook( type* end = self->array + index + 1; )\
00584 rawcook( type* curr = self->array + self->count; )\
00585 rawcook( while( curr < end ) { ppConcat( type,_init )(curr); curr++; } )\
00586 self->count = 1+index;\
00587 }\
00588 return (type*)self->array + index;\
00589 }\
00590 \
00591 type* ppConcat(label,_insert)(label* self, type* mbr )\
00592 {\
00593 assertobjptr(self);\
00594 if( ppConcat(label,_ismember)( self, mbr ) )\
00595 {\
00596 size_t ombr = indexof(self->array,mbr);\
00597 if(self->count+1 <= countof(self->array) )\
00598 {\
00599 mbr = self->array + ombr;\
00600 {\
00601 type* curr = self->array + self->count++;\
00602 while( curr-- > mbr )\
00603 ppConcat(type,_move)( curr+1,curr );\
00604 }\
00605 rawcook(ppConcat( type,_init )(mbr));\
00606 return mbr;\
00607 }\
00608 }\
00609 throwassert("Out of bounds");\
00610 return NULL;\
00611 }\
00612 \
00613 type* ppConcat(label,_insert_range)(label* self, type* mbr, size_t count )\
00614 {\
00615 assertobjptr(self);\
00616 assertconst(mbr,count*sizeof(type));\
00617 if( ppConcat(label,_ismember)( self, mbr ) )\
00618 {\
00619 size_t ombr = indexof(self->array,mbr);\
00620 if(self->count+count <= countof(self->array) )\
00621 {\
00622 mbr = self->array + ombr;\
00623 {\
00624 type* dst = self->array + self->count + count;\
00625 type* src = self->array + self->count;\
00626 while( src > mbr )\
00627 ppConcat(type,_move)( --dst,--src );\
00628 self->count += count;\
00629 rawcook( dst = mbr; )\
00630 rawcook( while( count-- ) ppConcat( type,_init )(dst++); )\
00631 }\
00632 return mbr;\
00633 }\
00634 }\
00635 throwassert("Out of bounds");\
00636 return NULL;\
00637 }\
00638 \
00639 void ppConcat(label,_erase)(label* self, type* mbr )\
00640 {\
00641 assertobjptr(self);\
00642 if( ppConcat(label,_ismember)( self, mbr ) )\
00643 {\
00644 type* curr = mbr;\
00645 type* end = self->array + self->count;\
00646 ppConcat( type,_destroy )(curr++);\
00647 while( curr < end )\
00648 {\
00649 ppConcat(type,_move)( curr,curr+1 );\
00650 curr++;\
00651 }\
00652 rawcook( ppConcat( type,_destroy )(curr); )\
00653 self->count--;\
00654 }\
00655 }\
00656 \
00657 void ppConcat(label,_erase_range)(label* self, type* mbr, size_t count )\
00658 {\
00659 assertobjptr(self);\
00660 if( ppConcat(label,_ismember)( self, mbr ) && (mbr+count <= self->array+self->count) )\
00661 {\
00662 type* dst = mbr;\
00663 type* src = mbr + count;\
00664 type* end = self->array + self->count;\
00665 rawcook( \
00666 while( dst < src )\
00667 {\
00668 ppConcat(type,_destroy)( dst );\
00669 dst++;\
00670 }\
00671 dst = mbr;\
00672 )\
00673 while( src < end )\
00674 ppConcat(type,_move)( dst++,src++ );\
00675 self->count -= count;\
00676 }\
00677 }\
00678 \
00679 void ppConcat(label,_bag_erase)(label* self, type* mbr )\
00680 {\
00681 assertobjptr(self);\
00682 if( ppConcat(label,_ismember)( self, mbr ) )\
00683 {\
00684 type* end = self->array + self->count - 1;\
00685 if( end != mbr )\
00686 {\
00687 rawcook( ppConcat( type,_destroy )(mbr); )\
00688 ppConcat( type,_move )(mbr,end);\
00689 }\
00690 }\
00691 }\
00692 \
00693 void ppConcat(label,_bag_erase_range)(label* self, type* mbr, size_t count )\
00694 {\
00695 assertobjptr(self);\
00696 if( ppConcat(label,_ismember)( self, mbr ) && (mbr+count <= self->array+self->count) )\
00697 {\
00698 type* dst = mbr;\
00699 type* end = self->array + self->count;\
00700 type* src = end - count;\
00701 while( src < end )\
00702 {\
00703 rawcook( ppConcat( type,_destroy )(dst); )\
00704 ppConcat( type,_move )(dst++,src++);\
00705 }\
00706 }\
00707 }\
00708 \
00709 void ppConcat(label,_sort)( label* self, int (*compare)(const type* p1, const type* p2) )\
00710 {\
00711 assertobjptr(self);\
00712 assertcodeptr(compare);\
00713 ppConcat(type,_array_qsort)( self->array, self->array + self->count - 1, compare );\
00714 }\
00715 \
00716 type* ppConcat(label,_bsearch)( const label* self, const type* key, int (*compare)(const type* p1, const type* p2) )\
00717 {\
00718 assertobjconst(self);\
00719 assertconst(key,sizeof(*key));\
00720 assertcodeptr(compare);\
00721 return (type*)bsearch( &key, self->array, self->count, sizeof(type), (int (*)(const void*,const void*))compare );\
00722 }\
00723 \
00724 type* ppConcat(label,_lsearch)( const label* self, const type* key, int (*compare)(const type* p1, const type* p2) )\
00725 {\
00726 assertobjconst(self);\
00727 assertconst(key,sizeof(*key));\
00728 assertcodeptr(compare);\
00729 {\
00730 ctl_array_foreach_const( label, self, curr )\
00731 if( !compare(curr,key) )\
00732 return (type*)curr;\
00733 }\
00734 return NULL;\
00735 }\
00736 \
00737 void ppConcat(label,_splice)( label* self, label* from )\
00738 {\
00739 assertobjptr(self);\
00740 assertobjptr(from);\
00741 if(self->count+from->count <= countof(self->array) )\
00742 {\
00743 ctl_array_foreach( label, from, curr )\
00744 ppConcat(type,_move)( ppConcat(label,_push_back)(self), curr );\
00745 }\
00746 from->count = 0;\
00747 ppConcat(label,_clear)(from);\
00748 }\
00749
00750 #endif