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