39 #pragma warning(disable: 4702)
40 #pragma warning(disable: 4706)
41 #pragma warning(disable: 4127)
42 #pragma warning(disable: 4133)
48 #if __STDC_VERSION__ >= 199901L
49 #define RESTRICT restrict
51 #if defined(_MSC_VER) && _MSC_VER>=1400
52 #define RESTRICT __restrict
55 #define RESTRICT __restrict
66 #if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
70 #define INLINE __inline
73 #define INLINE __inline
85 #define NOINLINE __attribute__ ((noinline))
86 #elif defined(_MSC_VER)
87 #define NOINLINE __declspec(noinline)
98 #define DEBUGINLINE INLINE
100 #define DEBUGINLINE NOINLINE
111 #ifndef NEDTRIEUSEMACROS
113 #define NEDTRIEUSEMACROS 0
115 #define NEDTRIEUSEMACROS 1
125 #define NEDTRIEDEBUG 1
127 #define NEDTRIEDEBUG 0
132 #define NEDTRIEDEBUG 0
142 #if (defined(_MSC_VER) && _MSC_VER<=1500) || (defined(__GNUC__) && !defined(HAVE_CPP0X))
146 template<
class T> T &move(T &a) {
return a; }
147 template<
class T> T &move(
const T &a) {
return const_cast<T &
>(a); }
148 template<
class T,
class A> T &forward(A &a) {
return a; }
153 static INLINE unsigned nedtriebitscanr(
size_t value)
156 #if defined(_MSC_VER) && !defined(__cplusplus_cli)
158 unsigned long bitpos;
159 #if defined(_M_IA64) || defined(_M_X64) || defined(WIN64)
160 assert(8==
sizeof(
size_t));
161 _BitScanReverse64(&bitpos, value);
163 assert(4==
sizeof(
size_t));
164 _BitScanReverse(&bitpos, value);
166 return (
unsigned) bitpos;
168 #elif defined(__GNUC__)
169 return sizeof(value)*CHAR_BIT - 1 - (
unsigned) __builtin_clzl(value);
173 #if !defined(__cplusplus_cli)
180 asDouble = (double)value + 0.5;
181 n = (asInt[0 ] >> 20) - 1023;
183 #pragma message(__FILE__ ": WARNING: Make sure you change the line above me if your CPU is big endian!")
185 #warning Make sure you change the line above me if your CPU is big endian!
190 #error CHAR_BIT is not eight, and therefore this generic bitscan routine will need adjusting!
198 if(16 <
sizeof(x)*CHAR_BIT) x = x | (x >>16);
199 if(32 <
sizeof(x)*CHAR_BIT) x = x | (x >>32);
201 x = x - ((x >> 1) & (SIZE_MAX/3));
202 x = (x & (SIZE_MAX/15*3)) + ((x >> 2) & (SIZE_MAX/15*3));
203 x = ((x + (x >> 4)) & (SIZE_MAX/UCHAR_MAX*15)) * (SIZE_MAX/UCHAR_MAX);
204 x = (CHAR_BIT*
sizeof(x)-1) - (x >> (CHAR_BIT*(
sizeof(x)-1)));
217 #define NEDTRIE_INDEXBINS (8*sizeof(void *))
221 #define NEDTRIE_HEAD2(name, type) \
224 type *triebins[NEDTRIE_INDEXBINS]; \
227 #define NEDTRIE_HEAD(name, type) NEDTRIE_HEAD2(name, struct type)
231 #define NEDTRIE_ENTRY(type) \
233 struct type *trie_parent; \
234 struct type *trie_child[2]; \
235 struct type *trie_prev, *trie_next; \
237 #define NEDTRIE_INITIALIZER(root)
241 #define NEDTRIE_INIT(root) do { memset((root), 0, sizeof(*(root))); } while(0)
245 #define NEDTRIE_EMPTY(head) (!(head)->count)
249 #define NEDTRIE_COUNT(head) ((head)->count)
268 return (head->nobbledir=!head->nobbledir);
273 #define NEDTRIE_NOBBLEZEROS(name) nedtries::trienobblezeros<name>
277 #define NEDTRIE_NOBBLEONES(name) nedtries::trienobbleones<name>
281 #define NEDTRIE_NOBBLEEQUALLY(name) nedtries::trienobbleequally<name>
282 #define NEDTRIE_GENERATE_NOBBLES(proto, name, type, field, keyfunct)
284 #define NEDTRIE_NOBBLEZEROS(name) name##_nobblezeros
285 #define NEDTRIE_NOBBLEONES(name) name##_nobbleones
286 #define NEDTRIE_NOBBLEEQUALLY(name) name##_nobbleequally
287 #define NEDTRIE_GENERATE_NOBBLES(proto, name, type, field, keyfunct) \
288 static INLINE int name##_nobblezeros(struct name *head) { (void) head; return 0; } \
289 static INLINE int name##_nobbleones(struct name *head) { (void) head; return 1; } \
290 static INLINE int name##_nobbleequally(struct name *head) { return (head->nobbledir=!head->nobbledir); }
299 template<
class trietype,
class type,
size_t fieldoffset,
size_t (*keyfunct)(const type *RESTRICT)>
DEBUGINLINE void triecheckvalidity(trietype *head);
300 namespace testtrielinksize {
304 static char test_sizeof_trielink_t_equal[
sizeof(
foo1)==
sizeof(
foo2)];
312 #define NEDTRIEFIELDOFFSET2(type, field) __builtin_offsetof(type, field)
314 #define NEDTRIEFIELDOFFSET2(type, field) ((size_t) &(((type *)0)->field))
316 #define NEDTRIEFIELDOFFSET(type, field) NEDTRIEFIELDOFFSET2(struct type, field)
324 size_t rkey=keyfunct(r), keybit, nodekey;
330 bitidx=nedtriebitscanr(rkey);
332 if(!(node=head->triebins[bitidx]))
335 head->triebins[bitidx]=r;
339 keybit=(size_t) 1<<bitidx;
340 for(;;node=childnode)
343 nodekey=keyfunct(node);
354 keybitset=!!(rkey&keybit);
366 triecheckvalidity<trietype, type, fieldoffset, keyfunct>(head);
372 #define NEDTRIE_GENERATE_INSERT(proto, name, type, field, keyfunct) \
373 proto INLINE void name##_NEDTRIE_INSERT(struct name *RESTRICT head, struct type *RESTRICT r) \
375 struct type *RESTRICT node, *RESTRICT childnode; \
376 size_t rkey=keyfunct(r), keybit, nodekey; \
380 memset(&r->field, 0, sizeof(r->field)); \
381 bitidx=nedtriebitscanr(rkey); \
382 assert(bitidx<NEDTRIE_INDEXBINS); \
383 if(!(node=head->triebins[bitidx])) \
385 r->field.trie_parent=(struct type *RESTRICT)(size_t)(3|(bitidx<<2)); \
386 head->triebins[bitidx]=r; \
390 keybit=(size_t) 1<<bitidx; \
391 for(;;node=childnode) \
393 nodekey=keyfunct(node); \
396 r->field.trie_parent=0; \
397 r->field.trie_prev=node; \
398 r->field.trie_next=node->field.trie_next; \
399 node->field.trie_next=r; \
400 if(r->field.trie_next) r->field.trie_next->field.trie_prev=r; \
404 keybitset=!!(rkey&keybit); \
405 childnode=node->field.trie_child[keybitset]; \
408 r->field.trie_parent=node; \
409 node->field.trie_child[keybitset]=r; \
417 #define NEDTRIE_GENERATE_INSERT(proto, name, type, field, keyfunct) \
418 proto INLINE void name##_NEDTRIE_INSERT(struct name *RESTRICT head, struct type *RESTRICT r) \
420 nedtries::trieinsert<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
426 template<
class trietype,
class type,
size_t fieldoffset,
size_t (*keyfunct)(const type *RESTRICT),
int (*nobblefunct)(trietype *head)>
DEBUGINLINE void trieremove(trietype *
RESTRICT head, type *
RESTRICT r)
428 type *
RESTRICT node, **myaddrinparent=0;
453 bitidx=(unsigned)(((
size_t) rlink->
trie_parent)>>2);
454 assert(head->triebins[bitidx]==r);
456 myaddrinparent=&head->triebins[bitidx];
464 assert(*myaddrinparent==r);
483 int nobbledir=nobblefunct(head);
484 while(*(newchildaddrinparent=&(((
TrieLink_t<type> *
RESTRICT)((
size_t) *childaddrinparent + fieldoffset))->trie_child[nobbledir]))
485 || *(newchildaddrinparent=&(((
TrieLink_t<type> *RESTRICT)((
size_t) *childaddrinparent + fieldoffset))->trie_child[!nobbledir])))
486 childaddrinparent=newchildaddrinparent;
487 node=*childaddrinparent;
488 *childaddrinparent=0;
509 *myaddrinparent=node;
513 triecheckvalidity<trietype, type, fieldoffset, keyfunct>(head);
519 #define NEDTRIE_GENERATE_REMOVE(proto, name, type, field, keyfunct, nobblefunct) \
520 proto INLINE void name##_NEDTRIE_REMOVE(struct name *RESTRICT head, struct type *RESTRICT r) \
522 struct type *RESTRICT node, **myaddrinparent=0; \
526 if(r->field.trie_prev) \
528 assert(!r->field.trie_parent); \
529 node=r->field.trie_prev; \
530 node->field.trie_next=r->field.trie_next; \
531 if(r->field.trie_next) \
533 r->field.trie_next->field.trie_prev=node; \
538 assert(r->field.trie_parent); \
539 assert(!r->field.trie_prev); \
541 if(((size_t) r->field.trie_parent & 3)==3) \
543 bitidx=(unsigned)(((size_t) r->field.trie_parent)>>2); \
544 assert(head->triebins[bitidx]==r); \
546 myaddrinparent=&head->triebins[bitidx]; \
550 node=r->field.trie_parent; \
551 myaddrinparent=(node->field.trie_child[0]==r) ? &node->field.trie_child[0] : &node->field.trie_child[1]; \
553 assert(*myaddrinparent==r); \
556 if(r->field.trie_next) \
558 node=r->field.trie_next; \
559 assert(node->field.trie_prev==r); \
560 node->field.trie_prev=0; \
564 if(!r->field.trie_child[0] && !r->field.trie_child[1]) \
570 struct type *RESTRICT *RESTRICT childaddrinparent=myaddrinparent, *RESTRICT *RESTRICT newchildaddrinparent; \
571 int nobbledir=nobblefunct(head); \
572 while(*(newchildaddrinparent=&(*childaddrinparent)->field.trie_child[nobbledir]) \
573 || *(newchildaddrinparent=&(*childaddrinparent)->field.trie_child[!nobbledir])) \
574 childaddrinparent=newchildaddrinparent; \
575 node=*childaddrinparent; \
576 *childaddrinparent=0; \
581 assert(!node->field.trie_child[0] && !node->field.trie_child[1]); \
582 node->field.trie_parent=r->field.trie_parent; \
583 node->field.trie_child[0]=r->field.trie_child[0]; \
584 node->field.trie_child[1]=r->field.trie_child[1]; \
585 if(node->field.trie_child[0]) \
587 node->field.trie_child[0]->field.trie_parent=node; \
589 if(node->field.trie_child[1]) \
591 node->field.trie_child[1]->field.trie_parent=node; \
594 *myaddrinparent=node; \
599 #define NEDTRIE_GENERATE_REMOVE(proto, name, type, field, keyfunct, nobblefunct) \
600 proto INLINE void name##_NEDTRIE_REMOVE(struct name *RESTRICT head, struct type *RESTRICT r) \
602 nedtries::trieremove<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct, nobblefunct>(head, r); \
612 size_t rkey=keyfunct(r), keybit, nodekey;
616 if(!head->count)
return 0;
618 bitidx=nedtriebitscanr(rkey);
620 if(!(node=head->triebins[bitidx]))
623 keybit=(size_t) 1<<bitidx;
624 for(;;node=childnode)
627 nodekey=keyfunct(node);
631 keybitset=!!(rkey&keybit);
643 #define NEDTRIE_GENERATE_FIND(proto, name, type, field, keyfunct) \
644 proto INLINE struct type * name##_NEDTRIE_FIND(struct name *RESTRICT head, struct type *RESTRICT r) \
646 struct type *RESTRICT node, *RESTRICT childnode; \
647 size_t rkey=keyfunct(r), keybit, nodekey; \
651 if(!head->count) return 0; \
652 bitidx=nedtriebitscanr(rkey); \
653 assert(bitidx<NEDTRIE_INDEXBINS); \
654 if(!(node=head->triebins[bitidx])) \
657 keybit=(size_t) 1<<bitidx; \
658 for(;;node=childnode) \
660 nodekey=keyfunct(node); \
664 keybitset=!!(rkey&keybit); \
665 childnode=node->field.trie_child[keybitset]; \
671 return node->field.trie_next ? node->field.trie_next : node; \
674 #define NEDTRIE_GENERATE_FIND(proto, name, type, field, keyfunct) \
675 proto INLINE struct type * name##_NEDTRIE_FIND(struct name *RESTRICT head, struct type *RESTRICT r) \
677 return nedtries::triefind<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
688 if(!head->count)
return 0;
689 if(!(node=triefind<trietype, type, fieldoffset, keyfunct>(head, r)))
return 0;
694 if(node==r)
return 1;
703 #define NEDTRIE_GENERATE_EXACTFIND(proto, name, type, field, keyfunct) \
704 proto INLINE int name##_NEDTRIE_EXACTFIND(struct name *RESTRICT head, struct type *RESTRICT r) \
706 struct type *RESTRICT node; \
708 if(!head->count) return 0; \
709 if(!(node=name##_NEDTRIE_FIND(head, r))) return 0; \
710 if(node->field.trie_prev) node=node->field.trie_prev; \
713 if(node==r) return 1; \
714 node=node->field.trie_next; \
719 #define NEDTRIE_GENERATE_EXACTFIND(proto, name, type, field, keyfunct) \
720 proto INLINE int name##_NEDTRIE_EXACTFIND(struct name *RESTRICT head, struct type *RESTRICT r) \
722 return nedtries::trieexactfind<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
728 template<
class trietype,
class type,
size_t fieldoffset,
size_t (*keyfunct)(const type *RESTRICT)>
DEBUGINLINE type *
trieCfind(
const trietype *
RESTRICT head,
const type *
RESTRICT r,
int rounds)
732 size_t rkey=keyfunct(r), keybit, nodekey;
736 if(!head->count)
return 0;
738 binbitidx=nedtriebitscanr(rkey);
742 size_t retkey=(size_t)-1;
751 keybit=(size_t) 1<<bitidx;
753 nodekey=keyfunct(node);
755 if(nodekey>=rkey && nodekey-rkey<retkey)
760 if(rounds--<=0 && ret)
return (type *) ret;
761 for(;;node=childnode)
768 if(nodekey>=rkey && nodekey-rkey<retkey)
777 if(nodekey>=rkey && nodekey-rkey<retkey)
783 if(rounds--<=0 && ret)
return (type *) ret;
786 keybitset=!!(rkey&keybit);
789 if(!childnode && !keybitset)
791 if(!childnode)
break;
809 #define NEDTRIE_GENERATE_CFIND(proto, name, type, field, keyfunct) \
810 proto INLINE struct type * name##_NEDTRIE_CFIND(struct name *RESTRICT head, struct type *RESTRICT r, int rounds) \
812 struct type *RESTRICT node=0, *RESTRICT childnode, *RESTRICT ret=0; \
813 size_t rkey=keyfunct(r), keybit, nodekey; \
814 unsigned binbitidx; \
817 if(!head->count) return 0; \
818 binbitidx=nedtriebitscanr(rkey); \
819 assert(binbitidx<NEDTRIE_INDEXBINS); \
822 size_t retkey=(size_t)-1; \
825 while(binbitidx<NEDTRIE_INDEXBINS && !(node=head->triebins[binbitidx])) \
827 if(binbitidx>=NEDTRIE_INDEXBINS) \
831 keybit=(size_t) 1<<bitidx; \
832 nodekey=keyfunct(node); \
834 if(nodekey>=rkey && nodekey-rkey<retkey) \
837 retkey=nodekey-rkey; \
839 if(rounds--<=0 && ret) return ret; \
840 for(;;node=childnode) \
843 if(node->field.trie_child[0]) \
845 nodekey=keyfunct(node->field.trie_child[0]); \
846 if(nodekey>=rkey && nodekey-rkey<retkey) \
848 ret=node->field.trie_child[0]; \
849 retkey=nodekey-rkey; \
852 if(node->field.trie_child[1]) \
854 nodekey=keyfunct(node->field.trie_child[1]); \
855 if(nodekey>=rkey && nodekey-rkey<retkey) \
857 ret=node->field.trie_child[1]; \
858 retkey=nodekey-rkey; \
861 if(rounds--<=0 && ret) return ret; \
864 keybitset=!!(rkey&keybit); \
865 childnode=node->field.trie_child[keybitset]; \
867 if(!childnode && !keybitset) \
868 childnode=node->field.trie_child[1]; \
869 if(!childnode) break; \
881 return ret->field.trie_next ? ret->field.trie_next : ret; \
884 #define NEDTRIE_GENERATE_CFIND(proto, name, type, field, keyfunct) \
885 proto INLINE struct type * name##_NEDTRIE_CFIND(struct name *RESTRICT head, struct type *RESTRICT r, int rounds) \
887 return nedtries::trieCfind<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r, rounds); \
893 template<
class trietype,
class type,
size_t fieldoffset,
size_t (*keyfunct)(const type *RESTRICT)>
DEBUGINLINE type *
trieminmax(
const trietype *
RESTRICT head,
const unsigned dir)
898 if(!head->count)
return 0;
901 for(bitidx=0; bitidx<
NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx++);
903 return (type *) node;
920 return (type *) node;
925 #define NEDTRIE_GENERATE_MINMAX(proto, name, type, field, keyfunct) \
926 proto INLINE struct type * name##_NEDTRIE_MINMAX(struct name *RESTRICT head, const unsigned dir) \
928 struct type *RESTRICT node=0, *RESTRICT child; \
930 if(!head->count) return 0; \
933 for(bitidx=0; bitidx<NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx++); \
938 for(bitidx=NEDTRIE_INDEXBINS-1; bitidx<NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx--); \
940 while((child=node->field.trie_child[1] ? node->field.trie_child[1] : node->field.trie_child[0])) \
945 while(node->field.trie_next) \
947 node=node->field.trie_next; \
952 #define NEDTRIE_GENERATE_MINMAX(proto, name, type, field, keyfunct) \
953 proto INLINE struct type * name##_NEDTRIE_MINMAX(struct name *RESTRICT head, unsigned dir) \
955 return nedtries::trieminmax<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, dir); \
997 return (type *) node;
1000 if(rlinkaddr) *rlinkaddr=rlink;
1010 if((node=triebranchprev<trietype, type, fieldoffset, keyfunct>(r, &rlink)) || !rlink)
return (type *) node;
1012 bitidx=(unsigned)(((
size_t) rlink->
trie_parent)>>2);
1013 assert(head->triebins[bitidx]==r);
1014 for(bitidx--; bitidx<
NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx--);
1029 return (type *) node;
1033 #if NEDTRIEUSEMACROS
1034 #define NEDTRIE_GENERATE_PREV(proto, name, type, field, keyfunct) \
1035 proto INLINE struct type * name##_NEDTRIE_BRANCHPREV(struct type *RESTRICT *RESTRICT r) \
1037 struct type *RESTRICT node=0, *RESTRICT child; \
1040 if((*r)->field.trie_prev) \
1042 assert(!(*r)->field.trie_parent); \
1043 return (*r)->field.trie_prev; \
1046 while(((size_t) (*r)->field.trie_parent & 3)!=3) \
1048 node=(*r)->field.trie_parent; \
1050 if(node->field.trie_child[1]==(*r) && node->field.trie_child[0]) \
1052 node=node->field.trie_child[0]; \
1054 while((child=node->field.trie_child[1] ? node->field.trie_child[1] : node->field.trie_child[0])) \
1061 while(node->field.trie_next) \
1063 node=node->field.trie_next; \
1070 proto INLINE struct type * name##_NEDTRIE_PREV(struct name *RESTRICT head, struct type *RESTRICT r) \
1072 struct type *RESTRICT node=0, *RESTRICT child; \
1075 if((node=name##_NEDTRIE_BRANCHPREV(&r))) return node; \
1077 bitidx=(unsigned)(((size_t) r->field.trie_parent)>>2); \
1078 assert(head->triebins[bitidx]==r); \
1079 for(bitidx--; bitidx<NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx--); \
1080 if(bitidx>=NEDTRIE_INDEXBINS) return 0; \
1082 while((child=node->field.trie_child[1] ? node->field.trie_child[1] : node->field.trie_child[0])) \
1087 while(node->field.trie_next) \
1089 node=node->field.trie_next; \
1094 #define NEDTRIE_GENERATE_PREV(proto, name, type, field, keyfunct) \
1095 proto INLINE struct type * name##_NEDTRIE_PREV(struct name *RESTRICT head, struct type *RESTRICT r) \
1097 return nedtries::trieprev<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
1123 return (type *) node;
1138 if(rlinkaddr) *rlinkaddr=rlink;
1148 if((node=triebranchnext<trietype, type, fieldoffset, keyfunct>(r, &rlink)))
return (type *) node;
1150 bitidx=(unsigned)(((
size_t) rlink->
trie_parent)>>2);
1151 for(bitidx++; bitidx<
NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx++);
1153 return (type *) node;
1157 #if NEDTRIEUSEMACROS
1158 #define NEDTRIE_GENERATE_NEXT(proto, name, type, field, keyfunct) \
1159 proto INLINE struct type * name##_NEDTRIE_BRANCHNEXT(struct type *RESTRICT *RESTRICT r) \
1161 struct type *RESTRICT node; \
1164 if((*r)->field.trie_next) \
1165 return (*r)->field.trie_next; \
1167 while(!(*r)->field.trie_parent) \
1169 (*r)=(*r)->field.trie_prev; \
1172 if((node=(*r)->field.trie_child[0] ? (*r)->field.trie_child[0] : (*r)->field.trie_child[1])) \
1174 assert(node->field.trie_parent==(*r)); \
1178 while(((size_t) (*r)->field.trie_parent & 3)!=3) \
1180 node=(*r)->field.trie_parent; \
1181 if(node->field.trie_child[0]==(*r) && node->field.trie_child[1]) \
1183 return node->field.trie_child[1]; \
1189 proto INLINE struct type * name##_NEDTRIE_NEXT(struct name *RESTRICT head, struct type *RESTRICT r) \
1191 struct type *RESTRICT node; \
1194 if((node=name##_NEDTRIE_BRANCHNEXT(&r))) return node; \
1196 bitidx=(unsigned)(((size_t) r->field.trie_parent)>>2); \
1197 assert(head->triebins[bitidx]==r); \
1198 for(bitidx++; bitidx<NEDTRIE_INDEXBINS && !(node=head->triebins[bitidx]); bitidx++); \
1199 if(bitidx>=NEDTRIE_INDEXBINS) return 0; \
1203 #define NEDTRIE_GENERATE_NEXT(proto, name, type, field, keyfunct) \
1204 proto INLINE struct type * name##_NEDTRIE_NEXT(struct name *RESTRICT head, struct type *RESTRICT r) \
1206 return nedtries::trienext<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
1214 const type *
RESTRICT node=0, *
RESTRICT ret=trieCfind<trietype, type, fieldoffset, keyfunct>(head, r, INT_MAX), *
RESTRICT stop;
1216 size_t rkey=keyfunct(r), retkey, nodekey;
1219 if(!(retkey=keyfunct(ret)-rkey))
return (type *) ret;
1226 stop=rlink->trie_parent;
1227 for(node=triebranchnext<trietype, type, fieldoffset, keyfunct>(ret, 0); node && node!=stop; node=triebranchnext<trietype, type, fieldoffset, keyfunct>(node, 0))
1229 nodekey=keyfunct(node);
1231 if(nodekey>=rkey && nodekey-rkey<retkey)
1234 retkey=nodekey-rkey;
1237 return (type *) ret;
1241 #if NEDTRIEUSEMACROS
1242 #define NEDTRIE_GENERATE_NFIND(proto, name, type, field, keyfunct) \
1243 proto INLINE struct type * name##_NEDTRIE_NFIND(struct name *RESTRICT head, struct type *RESTRICT r) \
1245 struct type *RESTRICT node=0, *RESTRICT ret=name##_NEDTRIE_CFIND(head, r, INT_MAX), *RESTRICT stop; \
1246 size_t rkey=keyfunct(r), retkey, nodekey; \
1248 if(!ret) return 0; \
1249 if(!(retkey=keyfunct(ret)-rkey)) return ret; \
1255 stop=r->field.trie_parent; \
1256 for(node=ret, node=name##_NEDTRIE_BRANCHNEXT(&node); node && node!=stop; node=name##_NEDTRIE_BRANCHNEXT(&node)) \
1258 nodekey=keyfunct(node); \
1260 if(nodekey>=rkey && nodekey-rkey<retkey) \
1263 retkey=nodekey-rkey; \
1269 #define NEDTRIE_GENERATE_NFIND(proto, name, type, field, keyfunct) \
1270 proto INLINE struct type * name##_NEDTRIE_NFIND(struct name *RESTRICT head, struct type *RESTRICT r) \
1272 return nedtries::trieNfind<struct name, struct type, NEDTRIEFIELDOFFSET(type, field), keyfunct>(head, r); \
1280 #define NEDTRIE_GENERATE(proto, name, type, field, keyfunct, nobblefunct) \
1281 NEDTRIE_GENERATE_NOBBLES (proto, name, type, field, keyfunct) \
1282 NEDTRIE_GENERATE_INSERT (proto, name, type, field, keyfunct) \
1283 NEDTRIE_GENERATE_REMOVE (proto, name, type, field, keyfunct, nobblefunct) \
1284 NEDTRIE_GENERATE_FIND (proto, name, type, field, keyfunct) \
1285 NEDTRIE_GENERATE_EXACTFIND(proto, name, type, field, keyfunct) \
1286 NEDTRIE_GENERATE_CFIND (proto, name, type, field, keyfunct) \
1287 NEDTRIE_GENERATE_MINMAX (proto, name, type, field, keyfunct) \
1288 NEDTRIE_GENERATE_PREV (proto, name, type, field, keyfunct) \
1289 NEDTRIE_GENERATE_NEXT (proto, name, type, field, keyfunct) \
1290 NEDTRIE_GENERATE_NFIND (proto, name, type, field, keyfunct) \
1291 proto INLINE struct type * name##_NEDTRIE_PREVLEAF(struct type *r) { return (r)->field.trie_prev; } \
1292 proto INLINE struct type * name##_NEDTRIE_NEXTLEAF(struct type *r) { return (r)->field.trie_next; }
1297 #define NEDTRIE_INSERT(name, x, y) name##_NEDTRIE_INSERT(x, y)
1301 #define NEDTRIE_REMOVE(name, x, y) name##_NEDTRIE_REMOVE(x, y)
1305 #define NEDTRIE_FIND(name, x, y) name##_NEDTRIE_FIND(x, y)
1309 #define NEDTRIE_EXACTFIND(name, x, y) name##_NEDTRIE_EXACTFIND(x, y)
1317 #define NEDTRIE_CFIND(name, x, y, rounds) name##_NEDTRIE_CFIND(x, y, rounds)
1322 #define NEDTRIE_NFIND(name, x, y) name##_NEDTRIE_NFIND(x, y)
1326 #define NEDTRIE_PREV(name, x, y) name##_NEDTRIE_PREV(x, y)
1330 #define NEDTRIE_NEXT(name, x, y) name##_NEDTRIE_NEXT(x, y)
1334 #define NEDTRIE_PREVLEAF(name, x) name##_NEDTRIE_PREVLEAF(x)
1338 #define NEDTRIE_NEXTLEAF(name, x) name##_NEDTRIE_NEXTLEAF(x)
1342 #define NEDTRIE_MIN(name, x) name##_NEDTRIE_MINMAX(x, 0)
1346 #define NEDTRIE_MAX(name, x) name##_NEDTRIE_MINMAX(x, 1)
1352 #define NEDTRIE_FOREACH(x, name, head) \
1353 for ((x) = NEDTRIE_MIN(name, head); \
1355 (x) = NEDTRIE_NEXT(name, head, x))
1362 #define NEDTRIE_FOREACH_SAFE(x, name, head, y) \
1363 for ((x) = NEDTRIE_MIN(name, head); \
1364 (x) != NULL && ((y) = NEDTRIE_NEXT(name, head, x), 1); \
1371 #define NEDTRIE_FOREACH_REVERSE(x, name, head) \
1372 for ((x) = NEDTRIE_MAX(name, head); \
1374 (x) = NEDTRIE_PREV(name, head, x))
1381 #define NEDTRIE_FOREACH_REVERSE_SAFE(x, name, head, y) \
1382 for ((x) = NEDTRIE_MAX(name, head); \
1383 (x) != NULL && ((y) = NEDTRIE_PREV(name, head, x), 1); \
1389 #define NEDTRIE_HASNODEHEADER(treevar, node, link) ((node)->link.trie_parent || (node)->link.trie_prev)
1392 #include <functional>
1401 template<
class trietype,
class type,
size_t fieldoffset,
size_t (*keyfunct)(const type *RESTRICT)>
DEBUGINLINE
1406 size_t nodekey=keyfunct(node);
1415 assert(node==childlink->
trie_child[!!(nodekey & ((
size_t) 1<<bitidx))]);
1434 triecheckvaliditybranch<trietype, type, fieldoffset, keyfunct>(head, nodelink->
trie_child[0], bitidx-1, state);
1439 triecheckvaliditybranch<trietype, type, fieldoffset, keyfunct>(head, nodelink->
trie_child[1], bitidx-1, state);
1452 if((node=head->triebins[n]))
1454 size_t nodekey=keyfunct(node);
1457 bitidx=(unsigned)(((
size_t) nodelink->
trie_parent)>>2);
1459 assert(head->triebins[bitidx]==node);
1460 assert(!nodekey || ((((
size_t)-1)<<bitidx) & nodekey)==((
size_t) 1<<bitidx));
1481 triecheckvaliditybranch<trietype, type, fieldoffset, keyfunct>(head, nodelink->
trie_child[0], bitidx-1, state);
1483 assert(state.
largestkey<(
size_t)1<<(bitidx+1));
1490 triecheckvaliditybranch<trietype, type, fieldoffset, keyfunct>(head, nodelink->
trie_child[1], bitidx-1, state);
1492 assert(state.
largestkey<(
size_t)1<<(bitidx+1));
1496 assert(state.
count==head->count);
1497 for(state.
count=0, node=trieminmax<trietype, type, fieldoffset, keyfunct>(head, 0); node; (node=trienext<trietype, type, fieldoffset, keyfunct>(head, node)), state.
count++)
1499 printf(
"%p\n", node)
1502 if(state.
count!=head->count)
1504 assert(state.
count==head->count);
1509 for(state.
count=0, node=trieminmax<trietype, type, fieldoffset, keyfunct>(head, 1); node; (node=trieprev<trietype, type, fieldoffset, keyfunct>(head, node)), state.
count++)
1511 printf(
"%p\n", node)
1514 if(state.
count!=head->count)
1516 assert(state.
count==head->count);
1521 #if !defined(NDEBUG) && 0
1523 printf(
"Of count %u, tops %.2lf%%, lefts %.2lf%%, rights %.2lf%%, leafs %.2lf%%\n", count, 100.0*tops/count, 100.0*lefts/count, 100.0*rights/count, 100.0*leafs/count);
1528 #if NEDTRIE_ENABLE_STL_CONTAINERS
1537 #if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER>=1600) || defined(HAVE_CPP0X)
1538 #undef HAVE_CPP0XRVALUEREFS
1539 #define HAVE_CPP0XRVALUEREFS 1
1540 #undef HAVE_CPP0XTYPETRAITS
1541 #define HAVE_CPP0XTYPETRAITS 1
1550 template<
class triemaptype>
class nobblezeros
1553 template<
class trietype>
static int trie_nobblefunction(trietype *)
1561 template<
class triemaptype>
class nobbleones
1564 template<
class trietype>
static int trie_nobblefunction(trietype *)
1572 template<
class triemaptype>
class nobbleequally
1575 template<
class trietype>
static int trie_nobblefunction(trietype *head)
1577 return (head->nobbledir=!head->nobbledir);
1582 template<
class keytype,
class type,
class keyfunct,
class iteratortype>
struct trie_maptype;
1604 template<
class keytype,
class type>
struct trie_keyfunct :
public std::unary_function<type, keytype>
1606 #ifdef HAVE_CPP0XRVALUEREFS
1607 keytype operator()(
const type &v)
const
1609 static_assert(
typeid(type)==
typeid(type),
"trie_keyfunct has not been specialised for this type");
1613 keytype operator()(
const type &)
const;
1616 template<
class keytype,
class type>
struct trie_maptype_keyfunct :
public std::unary_function<type, keytype>
1618 template<
class maptype> keytype operator()(
const maptype &v)
const
1620 return v.trie_keyvalue;
1624 template<
class type>
struct noconstiteratortype :
public type { };
1625 template<
class keyfunct_,
class mapvaluetype>
size_t to_Ckeyfunct(
const mapvaluetype *
RESTRICT v)
1627 return keyfunct_()(*v);
1630 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
1631 class iteratortype,
int dir,
class mapvaluetype,
class constiteratortype=intern::noconstiteratortype<iteratortype> >
class trie_iterator;
1632 template<
class keytype,
class type,
class keyfunct=trie_maptype_keyfunct<keytype, type>,
1633 class allocator=std::allocator<trie_maptype<keytype, type, keyfunct, std::list<
size_t>::iterator> >,
1634 template<
class>
class nobblepolicy=nedpolicy::nobblezeros,
1635 class stlcontainer=std::list<trie_maptype<keytype, type, keyfunct, std::list<size_t>::iterator>, allocator> >
class trie_map;
1636 template<
class keytype,
class type,
class keyfunct=trie_keyfunct<keytype, type>,
1637 class allocator=std::allocator<trie_maptype<keytype, type, keyfunct, std::list<
size_t>::iterator> >,
1638 template<
class>
class nobblepolicy=nedpolicy::nobblezeros,
1639 class stlcontainer=std::list<trie_maptype<keytype, type, keyfunct, std::list<size_t>::iterator>, allocator> >
class trie_multimap;
1648 template<
class keytype,
class type,
class keyfunct,
class iteratortype>
struct trie_maptype
1650 template<
class keytype_,
class type_>
friend struct trie_keyfunct;
1651 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
1652 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_map;
1653 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_multimap;
1654 typedef keytype trie_key_type;
1655 typedef type trie_value_type;
1656 typedef keyfunct trie_keyfunct_type;
1657 typedef iteratortype trie_iterator_type;
1659 iteratortype trie_iterator;
1660 TrieLink_t<type> trie_link;
1663 template<
class keytype,
class type,
class keyfunct,
class iteratortype>
struct trie_maptype
1666 template<
class keytype_,
class type_>
friend struct trie_keyfunct;
1667 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
1668 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_map;
1669 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_multimap;
1670 typedef keytype trie_key_type;
1671 typedef type trie_value_type;
1672 typedef keyfunct trie_keyfunct_type;
1673 typedef iteratortype trie_iterator_type;
1674 typedef fake::trie_maptype<keytype, type, keyfunct, iteratortype> fakemirrorofme_type;
1676 iteratortype trie_iterator;
1677 TrieLink_t<type> trie_link;
1680 trie_maptype(
const type &v) : trie_value(v)
1682 static char ensure_trie_link_offset_is_bounded[trie_link_offset+
sizeof(trie_link)<=
sizeof(*
this)];
1684 template<
class keytype_,
class type_,
class keyfunct_,
class iteratortype_> trie_maptype(
const trie_maptype<keytype_, type_, keyfunct_, iteratortype_> &o) : trie_value(o.trie_value) { }
1685 #ifdef HAVE_CPP0XRVALUEREFS
1686 template<
class keytype_,
class type_,
class keyfunct_,
class iteratortype_> trie_maptype(trie_maptype<keytype_, type_, keyfunct_, iteratortype_> &&o) : trie_value(
std::move(o.trie_value)) { }
1688 operator const type &()
const {
return trie_value; }
1692 template<
class keytype,
class type,
class iteratortype>
struct trie_maptype2
1694 template<
class keytype_,
class type_>
friend struct trie_keyfunct;
1695 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
1696 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_map;
1697 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_multimap;
1698 template<
class keytype_,
class type_>
friend struct trie_maptype_keyfunct;
1699 typedef keytype trie_key_type;
1700 typedef type trie_value_type;
1701 typedef trie_maptype_keyfunct<keytype, type> trie_keyfunct_type;
1702 typedef iteratortype trie_iterator_type;
1704 keytype trie_keyvalue;
1705 iteratortype trie_iterator;
1706 TrieLink_t<type> trie_link;
1709 template<
class keytype,
class type,
class iteratortype>
struct trie_maptype<keytype, type, trie_maptype_keyfunct<keytype, type>, iteratortype>
1712 template<
class keytype_,
class type_>
friend struct trie_keyfunct;
1713 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
1714 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_map;
1715 template<
class keytype_,
class type_,
class keyfunct_,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
friend class trie_multimap;
1716 template<
class keytype_,
class type_>
friend struct trie_maptype_keyfunct;
1717 typedef keytype trie_key_type;
1718 typedef type trie_value_type;
1719 typedef trie_maptype_keyfunct<keytype, type> trie_keyfunct_type;
1720 typedef iteratortype trie_iterator_type;
1721 typedef fake::trie_maptype2<keytype, type, iteratortype> fakemirrorofme_type;
1723 keytype trie_keyvalue;
1724 iteratortype trie_iterator;
1725 TrieLink_t<type> trie_link;
1728 trie_maptype(
const type &v) : trie_value(v)
1730 static char ensure_trie_link_offset_is_bounded[trie_link_offset+
sizeof(trie_link)<=
sizeof(*
this)];
1732 template<
class keytype_,
class type_,
class iteratortype_> trie_maptype(
const trie_maptype<keytype_, type_, trie_maptype_keyfunct<keytype_, type_>, iteratortype_> &o) : trie_value(o.trie_value), trie_keyvalue(o.trie_keyvalue) { }
1733 #ifdef HAVE_CPP0XRVALUEREFS
1734 template<
class keytype_,
class type_,
class iteratortype_> trie_maptype(trie_maptype<keytype_, type_, trie_maptype_keyfunct<keytype_, type_>, iteratortype_> &&o) : trie_value(
std::move(o.trie_value)), trie_keyvalue(
std::move(o.trie_keyvalue)) { }
1736 operator const type &()
const {
return trie_value; }
1744 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer,
class iteratortype,
int dir,
class mapvaluetype,
class constiteratortype>
class trie_iterator :
protected iteratortype
1746 trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *parent;
1748 typedef typename iteratortype::value_type::trie_value_type value_type;
1749 typedef typename iteratortype::difference_type difference_type;
1750 typedef typename iteratortype::pointer pointer;
1751 typedef typename iteratortype::reference reference;
1752 typedef typename iteratortype::iterator_category iterator_category;
1754 operator constiteratortype ()
const {
return constiteratortype(parent, static_cast<const iteratortype &>(*
this)); }
1756 trie_iterator() : parent(0) { }
1757 trie_iterator(
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *parent_,
const iteratortype &o) : iteratortype(o), parent(const_cast<trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *>(parent_)) { }
1758 trie_iterator(
const trie_iterator &o) : iteratortype(o), parent(o.parent) { }
1759 #ifdef HAVE_CPP0XRVALUEREFS
1760 trie_iterator(trie_iterator &&o) : iteratortype(
std::move(o)), parent(o.parent) { }
1762 trie_iterator &operator=(
const trie_iterator &o)
1764 return *
new(
this) trie_iterator(o);
1766 #ifdef HAVE_CPP0XRVALUEREFS
1767 trie_iterator &operator=(trie_iterator &&o)
1769 return *
new(
this) trie_iterator(std::move(o));
1772 trie_iterator &operator++()
1774 mapvaluetype *r=dir>0 ?
1775 trienext<trie_map_head<mapvaluetype>, mapvaluetype, mapvaluetype::trie_link_offset, intern::to_Ckeyfunct<typename mapvaluetype::trie_keyfunct_type> >(&parent->triehead, (mapvaluetype *)(&**
this)) :
1776 trieprev<trie_map_head<mapvaluetype>, mapvaluetype, mapvaluetype::trie_link_offset, intern::to_Ckeyfunct<typename mapvaluetype::trie_keyfunct_type> >(&parent->triehead, (mapvaluetype *)(&**
this));
1778 new(
this) iteratortype((iteratortype &) r->trie_iterator);
1780 *
this=parent->end();
1783 trie_iterator &operator++(
int) { trie_iterator tmp(*
this); operator++();
return tmp; }
1784 trie_iterator &operator--()
1786 mapvaluetype *r=dir<0 ?
1787 trienext<trie_map_head<mapvaluetype>, mapvaluetype, mapvaluetype::trie_link_offset, intern::to_Ckeyfunct<typename mapvaluetype::trie_keyfunct_type> >(&parent->triehead, (mapvaluetype *)(&**
this)) :
1788 trieprev<trie_map_head<mapvaluetype>, mapvaluetype, mapvaluetype::trie_link_offset, intern::to_Ckeyfunct<typename mapvaluetype::trie_keyfunct_type> >(&parent->triehead, (mapvaluetype *)(&**
this));
1790 new(
this) iteratortype((iteratortype &) r->trie_iterator);
1792 *
this=parent->end();
1795 trie_iterator &operator--(
int) { trie_iterator tmp(*
this); operator--();
return tmp; }
1796 bool operator==(
const trie_iterator &o)
const {
return static_cast<const iteratortype &
>(*this)==
static_cast<const iteratortype &
>(o); }
1797 bool operator!=(
const trie_iterator &o)
const {
return static_cast<const iteratortype &
>(*this)!=
static_cast<const iteratortype &
>(o); }
1798 const mapvaluetype &operator *()
const {
return (
const mapvaluetype &) iteratortype::operator *(); }
1799 mapvaluetype &operator *() {
return (mapvaluetype &) iteratortype::operator *(); }
1800 const mapvaluetype *operator ->()
const {
return (
const mapvaluetype *) iteratortype::operator->(); }
1801 mapvaluetype *operator ->() {
return (mapvaluetype *) iteratortype::operator->(); }
1806 template<
class key_type>
struct keystore_t {
size_t magic;
const key_type &key; keystore_t(
size_t magic_,
const key_type &key_) : magic(magic_), key(key_) { }
private: keystore_t &operator=(
const keystore_t &); };
1807 template<
class keytype,
class type,
class mapvaluetype,
class keyfunct>
struct findkeyfunct_t :
public std::unary_function<type, keytype>
1809 size_t operator()(
const mapvaluetype &v)
const
1811 keystore_t<keytype> *r=(keystore_t<keytype> *)(
void *)(&v);
1814 if(r->magic==*(
size_t *)
"TRIEFINDKEYSTORE")
1816 return keyfunct()(v);
1860 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
class trie_map :
protected stlcontainer,
protected nobblepolicy<trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> >
1862 typedef nobblepolicy<trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> > nobblepolicytype;
1863 typedef typename stlcontainer::value_type mapvaluetype;
1864 static const size_t trie_fieldoffset=mapvaluetype::trie_link_offset;
1865 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
1867 typedef typename stlcontainer::allocator_type allocator_type;
1868 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer, typename stlcontainer::const_iterator, 1, mapvaluetype> const_iterator;
1869 typedef typename stlcontainer::const_pointer const_pointer;
1870 typedef typename stlcontainer::const_reference const_reference;
1871 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer,
typename stlcontainer::const_reverse_iterator, -1, mapvaluetype> const_reverse_iterator;
1872 typedef typename stlcontainer::difference_type difference_type;
1873 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer, typename stlcontainer::iterator, 1, mapvaluetype, const_iterator> iterator;
1874 typedef keytype key_type;
1875 typedef type mapped_type;
1876 typedef typename stlcontainer::pointer pointer;
1877 typedef typename stlcontainer::reference reference;
1878 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer,
typename stlcontainer::reverse_iterator, -1, mapvaluetype, const_reverse_iterator> reverse_iterator;
1879 typedef typename stlcontainer::size_type size_type;
1880 typedef typename stlcontainer::value_type::trie_value_type value_type;
1882 trie_map_head<mapvaluetype> triehead;
1883 static typename mapvaluetype::trie_iterator_type &from_iterator(iterator &it)
1885 void *_it=(
void *) ⁢
1886 return *(
typename mapvaluetype::trie_iterator_type *)_it;
1889 void triehead_reindex()
1892 for(iterator it=begin(); it!=end(); ++it)
1894 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
1895 it->trie_iterator=it;
1898 const mapvaluetype *triehead_find(
const key_type &key)
const
1900 char buffer[
sizeof(mapvaluetype)];
1901 new(buffer) intern::keystore_t<key_type>(*(
size_t *)
"TRIEFINDKEYSTORE", key);
1902 return triefind<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<intern::findkeyfunct_t<keytype, type, mapvaluetype, keyfunct> > >(&triehead, (mapvaluetype *) buffer);
1904 const mapvaluetype *triehead_nfind(
const key_type &key)
const
1906 char buffer[
sizeof(mapvaluetype)];
1907 new(buffer) intern::keystore_t<key_type>(*(
size_t *)
"TRIEFINDKEYSTORE", key);
1908 return trieNfind<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<intern::findkeyfunct_t<keytype, type, mapvaluetype, keyfunct> > >(&triehead, (mapvaluetype *) buffer);
1910 const mapvaluetype *triehead_cfind(
const key_type &key,
int rounds)
const
1912 char buffer[
sizeof(mapvaluetype)];
1913 new(buffer) intern::keystore_t<key_type>(*(
size_t *)
"TRIEFINDKEYSTORE", key);
1914 return trieCfind<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<intern::findkeyfunct_t<keytype, type, mapvaluetype, keyfunct> > >(&triehead, (mapvaluetype *) buffer, rounds);
1916 iterator triehead_insert(
const value_type &val)
1918 iterator it=iterator(
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
1919 it->trie_iterator=from_iterator(it);
1920 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
1923 #ifdef HAVE_CPP0XRVALUEREFS
1924 iterator triehead_insert(value_type &&val)
1926 iterator it=iterator(
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
1927 it->trie_iterator=from_iterator(it);
1928 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
1932 iterator triehead_insert(
const keytype &key,
const value_type &val)
1934 iterator it=iterator(
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
1935 it->trie_iterator=from_iterator(it);
1936 it->trie_keyvalue=key;
1937 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
1940 #ifdef HAVE_CPP0XRVALUEREFS
1941 iterator triehead_insert(
const keytype &key, value_type &&val)
1943 iterator it=iterator(
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
1944 it->trie_iterator=from_iterator(it);
1945 it->trie_keyvalue=key;
1946 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
1951 iterator begin() {
return iterator(
this, stlcontainer::begin()); }
1952 const_iterator begin()
const {
return const_iterator(
this, stlcontainer::begin()); }
1953 using stlcontainer::clear;
1955 size_type count(
const key_type &key)
const
1958 const mapvaluetype *r=triehead_find(key);
1961 if(r->trie_link.prev) r=r->trie_link.trie_prev;
1962 for(; r; r=r->trie_link.trie_next) ret++;
1966 using stlcontainer::empty;
1967 iterator end() {
return iterator(
this, stlcontainer::end()); }
1968 const_iterator end()
const {
return const_iterator(
this, stlcontainer::end()); }
1972 iterator erase(iterator it)
1975 trieremove<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct>,
1978 nobblepolicytype::trie_nobblefunction<trie_map_head<mapvaluetype> >
1980 nobblepolicytype::trie_nobblefunction
1982 >(&triehead, &(*it));
1983 return iterator(
this, stlcontainer::erase((
typename stlcontainer::iterator &) it));
1986 iterator erase(iterator first, iterator last)
1988 iterator ret(last); ++ret;
1989 for(iterator it=first; it!=last; ++it)
1991 trieremove<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct>,
1993 nobblepolicytype::trie_nobblefunction<trie_map_head<mapvaluetype> >
1995 nobblepolicytype::trie_nobblefunction
1997 >(&triehead, &(*it));
1998 stlcontainer::erase((
typename stlcontainer::iterator &) it);
2003 iterator find(
const key_type &key) { const_iterator it=
static_cast<const trie_map *
>(
this)->find(key);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2005 const_iterator find(
const key_type &key)
const
2007 const mapvaluetype *r=triehead_find(key);
2008 return !r ? end() : const_iterator(this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2011 iterator nfind(
const key_type &key) { const_iterator it=
static_cast<const trie_map *
>(
this)->nfind(key);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2013 const_iterator nfind(
const key_type &key)
const
2015 const mapvaluetype *r=triehead_nfind(key);
2016 return !r ? end() : const_iterator(this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2019 iterator cfind(
const key_type &key,
int rounds=INT_MAX) { const_iterator it=
static_cast<const trie_map *
>(
this)->cfind(key, rounds);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2021 const_iterator cfind(
const key_type &key,
int rounds=INT_MAX)
const
2023 const mapvaluetype *r=triehead_cfind(key, rounds);
2024 return !r ? end() : const_iterator(this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2026 using stlcontainer::get_allocator;
2028 std::pair<iterator, bool> insert(
const value_type &val)
2030 mapvaluetype *r=
const_cast<mapvaluetype *
>(triehead_find(keyfunct()(val)));
2033 r->trie_value=std::move(val);
2034 return std::make_pair(iterator(
this, (
typename stlcontainer::iterator &) r->trie_iterator),
false);
2036 return std::make_pair(triehead_insert(std::move(val)),
true);
2039 iterator insert(iterator at,
const value_type &val)
2041 iterator it=stlcontainer::insert(at, val);
2042 it->trie_iterator=from_iterator(it);
2043 trieinsert<trie_map_head, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
2047 template<
class inputiterator>
void insert(inputiterator first, inputiterator last)
2049 iterator it=--end();
2050 stlcontainer::insert(first, last);
2051 for(; it!=end(); ++it)
2053 it->trie_iterator=from_iterator(it);
2054 trieinsert<trie_map_head, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
2060 using stlcontainer::max_size;
2061 reverse_iterator rbegin() {
return reverse_iterator(
this, stlcontainer::begin()); }
2062 const_reverse_iterator rbegin()
const {
return const_reverse_iterator(
this, stlcontainer::begin()); }
2063 reverse_iterator rend() {
return reverse_iterator(
this, stlcontainer::end()); }
2064 const_reverse_iterator rend()
const {
return const_reverse_iterator(
this, stlcontainer::end()); }
2065 using stlcontainer::size;
2066 using stlcontainer::swap;
2071 mapped_type &operator[](
const keytype &key)
2073 mapvaluetype *r=
const_cast<mapvaluetype *
>(triehead_find(key));
2076 it=iterator(
this, (
typename stlcontainer::iterator &) r->trie_iterator);
2079 it=triehead_insert(key, std::move(type()));
2081 return it->trie_value;
2084 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator!=(
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2085 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator<(const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2086 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator<=(const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2087 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator==(
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2088 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator>(
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2089 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator>=(
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_map<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2092 trie_map() : stlcontainer() {
NEDTRIE_INIT(&triehead); }
2093 explicit trie_map(
const allocator &a) : stlcontainer(a) {
NEDTRIE_INIT(&triehead); }
2094 template<
class okeytype,
class otype,
class oallocator> trie_map(
const trie_map<okeytype, otype, oallocator> &o) : stlcontainer(o) { triehead_reindex(); }
2095 template<
class okeytype,
class otype,
class oallocator> trie_map &operator=(
const trie_map<okeytype, otype, oallocator> &o) { *
static_cast<stlcontainer *
>(
this)=static_cast<const stlcontainer &>(o); triehead_reindex();
return *
this; }
2096 #ifdef HAVE_CPP0XRVALUEREFS
2097 template<
class okeytype,
class otype,
class oallocator> trie_map(trie_map<okeytype, otype, oallocator> &&o) : stlcontainer(
std::move(o))
2099 memcpy(&triehead, &o.triehead,
sizeof(triehead));
2101 template<
class okeytype,
class otype,
class oallocator> trie_map &operator=(trie_map<okeytype, otype, oallocator> &&o)
2103 *
static_cast<stlcontainer *
>(
this)=std::move(static_cast<stlcontainer &&>(o));
2104 memcpy(&triehead, &o.triehead,
sizeof(triehead));
2108 template<
class inputiterator> trie_map(inputiterator s, inputiterator e) : stlcontainer(s, e) { triehead_reindex(); }
2109 template<
class inputiterator> trie_map(inputiterator s, inputiterator e,
const allocator &a) : stlcontainer(s, e, a) { triehead_reindex(); }
2111 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator!=(
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2113 return static_cast<const stlcontainer &
>(a)!=static_cast<const stlcontainer &>(b);
2115 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator<(const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2117 return static_cast<const stlcontainer &
>(a)<static_cast<const stlcontainer &>(b);
2119 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator<=(const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2121 return static_cast<const stlcontainer &
>(a)<=static_cast<const stlcontainer &>(b);
2123 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator==(
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2125 return static_cast<const stlcontainer &
>(a)==static_cast<const stlcontainer &>(b);
2127 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator>(
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2129 return static_cast<const stlcontainer &
>(a)>static_cast<const stlcontainer &>(b);
2131 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator>=(
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2133 return static_cast<const stlcontainer &
>(a)>=static_cast<const stlcontainer &>(b);
2175 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
class trie_multimap :
protected stlcontainer,
protected nobblepolicy<trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> >
2177 typedef nobblepolicy<trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> > nobblepolicytype;
2178 typedef typename stlcontainer::value_type mapvaluetype;
2179 static const size_t trie_fieldoffset=mapvaluetype::trie_link_offset;
2180 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_,
class iteratortype_,
int dir,
class mapvaluetype,
class constiteratortype>
friend class trie_iterator;
2182 typedef typename stlcontainer::allocator_type allocator_type;
2183 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer, typename stlcontainer::const_iterator, 1, mapvaluetype> const_iterator;
2184 typedef typename stlcontainer::const_pointer const_pointer;
2185 typedef typename stlcontainer::const_reference const_reference;
2186 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer,
typename stlcontainer::const_reverse_iterator, -1, mapvaluetype> const_reverse_iterator;
2187 typedef typename stlcontainer::difference_type difference_type;
2188 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer, typename stlcontainer::iterator, 1, mapvaluetype, const_iterator> iterator;
2189 typedef keytype key_type;
2190 typedef type mapped_type;
2191 typedef typename stlcontainer::pointer pointer;
2192 typedef typename stlcontainer::reference reference;
2193 typedef trie_iterator<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer,
typename stlcontainer::reverse_iterator, -1, mapvaluetype, const_reverse_iterator> reverse_iterator;
2194 typedef typename stlcontainer::size_type size_type;
2195 typedef typename stlcontainer::value_type::trie_value_type value_type;
2197 trie_map_head<mapvaluetype> triehead;
2198 static typename mapvaluetype::trie_iterator_type &from_iterator(iterator &it)
2200 void *_it=(
void *) ⁢
2201 return *(
typename mapvaluetype::trie_iterator_type *)_it;
2204 void triehead_reindex()
2207 for(iterator it=begin(); it!=end(); ++it)
2209 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
2210 it->trie_iterator=it;
2213 const mapvaluetype *triehead_find(
const key_type &key)
const
2215 char buffer[
sizeof(mapvaluetype)];
2216 new(buffer) intern::keystore_t<key_type>(*(
size_t *)
"TRIEFINDKEYSTORE", key);
2217 return triefind<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<intern::findkeyfunct_t<keytype, type, mapvaluetype, keyfunct> > >(&triehead, (mapvaluetype *) buffer);
2219 iterator triehead_insert(
const value_type &val)
2221 iterator it=iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
2222 it->trie_iterator=from_iterator(it);
2223 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
2226 #ifdef HAVE_CPP0XRVALUEREFS
2227 iterator triehead_insert(value_type &&val)
2229 iterator it=iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
2230 it->trie_iterator=from_iterator(it);
2231 trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead,
const_cast<mapvaluetype *
>(&(*it)));
2236 iterator begin() {
return iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::begin()); }
2237 const_iterator begin()
const {
return const_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::begin()); }
2238 using stlcontainer::clear;
2240 size_type count(
const key_type &key)
const
2243 const mapvaluetype *r=triehead_find(key);
2246 if(r->trie_link.prev) r=r->trie_link.trie_prev;
2247 for(; r; r=r->trie_link.trie_next) ret++;
2251 using stlcontainer::empty;
2252 iterator end() {
return iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::end()); }
2253 const_iterator end()
const {
return const_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::end()); }
2257 iterator erase(iterator it)
2260 trieremove<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct>,
2263 nobblepolicytype::trie_nobblefunction<trie_map_head<mapvaluetype> >
2265 nobblepolicytype::trie_nobblefunction
2267 >(&triehead, &(*it));
2268 return iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::erase((
typename stlcontainer::iterator &) it));
2271 iterator erase(iterator first, iterator last)
2273 iterator ret(last); ++ret;
2274 for(iterator it=first; it!=last; ++it)
2276 trieremove<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct>,
2278 nobblepolicytype::trie_nobblefunction<trie_map_head<mapvaluetype> >
2280 nobblepolicytype::trie_nobblefunction
2282 >(&triehead, &(*it));
2283 stlcontainer::erase((
typename stlcontainer::iterator &) it);
2288 iterator find(
const key_type &key) { const_iterator it=
static_cast<const trie_multimap *
>(
this)->find(key);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2290 const_iterator find(
const key_type &key)
const
2292 const mapvaluetype *r=triehead_find(key);
2293 return !r ? end() : const_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *) this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2296 iterator nfind(
const key_type &key) { const_iterator it=
static_cast<const trie_multimap *
>(
this)->nfind(key);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2298 const_iterator nfind(
const key_type &key)
const
2300 const mapvaluetype *r=triehead_nfind(key);
2301 return !r ? end() : const_iterator(this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2304 iterator cfind(
const key_type &key,
int rounds=INT_MAX) { const_iterator it=
static_cast<const trie_multimap *
>(
this)->cfind(key, rounds);
void *_it=(
void *) ⁢
return *(iterator *)_it; }
2306 const_iterator cfind(
const key_type &key,
int rounds=INT_MAX)
const
2308 const mapvaluetype *r=triehead_cfind(key, rounds);
2309 return !r ? end() : const_iterator(this, (const typename stlcontainer::const_iterator &) r->trie_iterator);
2311 using stlcontainer::get_allocator;
2313 iterator insert(
const value_type &val)
2315 return triehead_insert(std::move(val));
2318 iterator insert(iterator at,
const value_type &val)
2320 iterator it=stlcontainer::insert(at, val);
2321 it->trie_iterator=from_iterator(it);
2322 trieinsert<trie_map_head, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
2326 template<
class inputiterator>
void insert(inputiterator first, inputiterator last)
2328 iterator it=--end();
2329 stlcontainer::insert(first, last);
2330 for(; it!=end(); ++it)
2332 it->trie_iterator=from_iterator(it);
2333 trieinsert<trie_map_head, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, &(*it));
2339 using stlcontainer::max_size;
2340 reverse_iterator rbegin() {
return reverse_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::begin()); }
2341 const_reverse_iterator rbegin()
const {
return const_reverse_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::begin()); }
2342 reverse_iterator rend() {
return reverse_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::end()); }
2343 const_reverse_iterator rend()
const {
return const_reverse_iterator((trie_map<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> *)
this, stlcontainer::end()); }
2344 using stlcontainer::size;
2345 using stlcontainer::swap;
2350 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator!=(
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2351 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator<(const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2352 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator<=(const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2353 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator==(
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2354 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator>(
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2355 template<
class keytype_,
class type_,
class keyfunct_,
class allocator_,
template<
class>
class nobblepolicy_,
class stlcontainer_>
friend bool operator>=(
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &a,
const trie_multimap<keytype_, type_, keyfunct_, allocator_, nobblepolicy_, stlcontainer_> &b);
2358 trie_multimap() : stlcontainer() {
NEDTRIE_INIT(&triehead); }
2359 explicit trie_multimap(
const allocator &a) : stlcontainer(a) {
NEDTRIE_INIT(&triehead); }
2360 template<
class okeytype,
class otype,
class oallocator> trie_multimap(
const trie_multimap<okeytype, otype, oallocator> &o) : stlcontainer(o) { triehead_reindex(); }
2361 template<
class okeytype,
class otype,
class oallocator> trie_multimap &operator=(
const trie_multimap<okeytype, otype, oallocator> &o) { *
static_cast<stlcontainer *
>(
this)=static_cast<const stlcontainer &>(o); triehead_reindex();
return *
this; }
2362 #ifdef HAVE_CPP0XRVALUEREFS
2363 template<
class okeytype,
class otype,
class oallocator> trie_multimap(trie_multimap<okeytype, otype, oallocator> &&o) : stlcontainer(
std::move(o))
2365 memcpy(&triehead, &o.triehead,
sizeof(triehead));
2367 template<
class okeytype,
class otype,
class oallocator> trie_multimap &operator=(trie_multimap<okeytype, otype, oallocator> &&o)
2369 *
static_cast<stlcontainer *
>(
this)=std::move(static_cast<stlcontainer &&>(o));
2370 memcpy(&triehead, &o.triehead,
sizeof(triehead));
2374 template<
class inputiterator> trie_multimap(inputiterator s, inputiterator e) : stlcontainer(s, e) { triehead_reindex(); }
2375 template<
class inputiterator> trie_multimap(inputiterator s, inputiterator e,
const allocator &a) : stlcontainer(s, e, a) { triehead_reindex(); }
2377 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator!=(
const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, allocator, keyfunct, nobblepolicy, stlcontainer> &b)
2379 return static_cast<const stlcontainer &
>(a)!=static_cast<const stlcontainer &>(b);
2381 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator<(const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, allocator, keyfunct, nobblepolicy, stlcontainer> &b)
2383 return static_cast<const stlcontainer &
>(a)<static_cast<const stlcontainer &>(b);
2385 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator<=(const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, allocator, keyfunct, nobblepolicy, stlcontainer> &b)
2387 return static_cast<const stlcontainer &
>(a)<=static_cast<const stlcontainer &>(b);
2389 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator==(
const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, allocator, keyfunct, nobblepolicy, stlcontainer> &b)
2391 return static_cast<const stlcontainer &
>(a)==static_cast<const stlcontainer &>(b);
2393 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator>(
const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, allocator, keyfunct, nobblepolicy, stlcontainer> &b)
2395 return static_cast<const stlcontainer &
>(a)>static_cast<const stlcontainer &>(b);
2397 template<
class keytype,
class type,
class keyfunct,
class allocator,
template<
class>
class nobblepolicy,
class stlcontainer>
bool operator>=(
const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &a,
const trie_multimap<keytype, type, keyfunct, allocator, nobblepolicy, stlcontainer> &b)
2399 return static_cast<const stlcontainer &
>(a)>=static_cast<const stlcontainer &>(b);
2407 #pragma warning(pop)
void triecheckvaliditybranch(trietype *head, type *node, unsigned bitidx, TrieValidityState &state)
Definition: nedtrie.h:1402
size_t n
Definition: nedtrie.h:302
int trienobblezeros(trietype *)
Definition: nedtrie.h:258
size_t largestkey
Definition: nedtrie.h:1398
size_t leafs
Definition: nedtrie.h:1398
#define INLINE
Defined to the inline keyword or equivalent if available.
Definition: nedtrie.h:67
Definition: nedtrie.h:302
type * triefind(const trietype *head, const type *r)
Definition: nedtrie.h:608
Definition: nedtrie.h:256
void triecheckvalidity(trietype *head)
Definition: nedtrie.h:1443
Definition: nedtrie.h:1396
type * trienext(const trietype *head, const type *r)
Definition: nedtrie.h:1142
void trieremove(trietype *head, type *r)
Definition: nedtrie.h:426
#define NEDTRIE_ENTRY(type)
Substitutes the type used to store the per-node trie information. Occupies 5*sizeof(size_t).
Definition: nedtrie.h:231
#define NEDTRIE_INDEXBINS
Defines the number of top level bit bins to use. The default based on size_t is usually fine...
Definition: nedtrie.h:217
size_t smallestkey
Definition: nedtrie.h:1398
size_t tops
Definition: nedtrie.h:1398
#define NEDTRIE_HEAD2(name, type)
Definition: nedtrie.h:221
type * trie_prev
Definition: nedtrie.h:297
int trienobbleones(trietype *)
Definition: nedtrie.h:262
Definition: nedtrie.h:303
struct nedtries::testtrielinksize::foo1::@0 link
#define DEBUGINLINE
Defined to be INLINE when NDEBUG is defined, NOINLINE when DEBUG is defined, unset otherwise...
Definition: nedtrie.h:102
type * trieprev(const trietype *head, const type *r)
Definition: nedtrie.h:1004
type * trieminmax(const trietype *head, const unsigned dir)
Definition: nedtrie.h:893
size_t count
Definition: nedtrie.h:1398
type * triebranchprev(const type *r, const TrieLink_t< type > **rlinkaddr)
Definition: nedtrie.h:961
Definition: nedtrie.h:294
void trieinsert(trietype *head, type *r)
Definition: nedtrie.h:320
size_t rights
Definition: nedtrie.h:1398
type * trieNfind(const trietype *head, const type *r)
Definition: nedtrie.h:1212
type * trieCfind(const trietype *head, const type *r, int rounds)
Definition: nedtrie.h:728
type * trie_child[2]
Definition: nedtrie.h:296
int trieexactfind(const trietype *head, const type *r)
Definition: nedtrie.h:683
struct nedtries::TrieValidityState_t TrieValidityState
#define NEDTRIEFIELDOFFSET2(type, field)
Definition: nedtrie.h:314
int trienobbleequally(trietype *head)
Definition: nedtrie.h:266
type * trie_next
Definition: nedtrie.h:297
type * trie_parent
Definition: nedtrie.h:295
#define RESTRICT
Defined to the restrict keyword or equivalent if available.
Definition: nedtrie.h:59
size_t lefts
Definition: nedtrie.h:1398
#define NEDTRIE_INIT(root)
Initialises a nedtrie for usage.
Definition: nedtrie.h:241
type * triebranchnext(const type *r, const TrieLink_t< type > **rlinkaddr)
Definition: nedtrie.h:1103
size_t n
Definition: nedtrie.h:303
TrieLink_t< foo2 > link
Definition: nedtrie.h:303