]>
git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/src/wxstlac.h
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
20 #include <sys/types.h>
25 // the below macro used internally (see actual interface after this macro)
30 // ASSOC_CONT_CLASS_NAME
34 // ARG_ACTUAL_VALUE_TYPE
42 // _INSERT_METHOD_DEFINITION
44 #define __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE, \
46 ASSOC_CONT_CLASS_NAME, \
49 ARG_ACTUAL_VALUE_TYPE, \
54 _INSERT_METHOD_DEFINITION \
56 ASSOC_CONT_CLASS_NAME\
61 typedef ARG_VALUE_TYPE value_type;\
62 typedef ARG_KEY_TYPE key_type;\
63 typedef ARG_ACTUAL_VALUE_TYPE actual_value_type;\
65 typedef value_type* pointer;\
66 typedef value_type& reference;\
68 typedef const value_type& const_reference;\
70 typedef FUNCTOR key_compare;\
71 typedef key_compare Compare;\
84 typedef tree_node* node_ref_type;\
86 node_ref_type mpRoot;\
87 node_ref_type mpLeftMost;\
88 node_ref_type mpRightMost;\
90 node_ref_type mpFreeListHead;\
93 key_compare mCmpFunctorObj;\
97 static inline node_ref_type next( node_ref_type pNode )\
99 if ( pNode->mpRight ) \
101 pNode = pNode->mpRight;\
103 while ( pNode->mpLeft ) pNode = pNode->mpLeft;\
108 if ( pNode->mpParent )\
110 if ( pNode == pNode->mpParent->mpLeft )\
112 return pNode->mpParent;\
114 pNode = pNode->mpParent;\
116 node_ref_type prevNode = pNode;\
117 pNode = pNode->mpParent;\
121 if ( pNode->mpRight &&\
122 pNode->mpRight != prevNode\
126 pNode= pNode->mpParent;\
135 static inline node_ref_type prev( node_ref_type pNode )\
137 if ( pNode->mpLeft ) \
139 pNode = pNode->mpLeft;\
141 while ( pNode->mpRight ) pNode = pNode->mpRight;\
146 if ( pNode->mpParent )\
148 if ( pNode == pNode->mpParent->mpRight )\
149 return pNode->mpParent;\
151 pNode = pNode->mpParent;\
153 node_ref_type prevNode = pNode;\
154 pNode = pNode->mpParent;\
158 if ( pNode->mpLeft &&\
159 pNode->mpLeft != prevNode\
163 pNode= pNode->mpParent;\
174 inline int are_equel( const key_type& x, const key_type& y )\
176 return ( !mCmpFunctorObj(x,y) && !mCmpFunctorObj(y,x) );\
179 inline int is_less( const key_type& x, const key_type& y )\
181 return mCmpFunctorObj(x,y);\
184 static inline const actual_value_type& value( node_ref_type pNode )\
186 return pNode->_VALUE_NAME;\
189 static inline const key_type& key( node_ref_type pNode )\
191 return pNode->_KEY_NAME;\
194 inline node_ref_type AllocNode() \
196 if ( mpFreeListHead ) \
198 node_ref_type pFreeNode = mpFreeListHead;\
199 mpFreeListHead = mpFreeListHead->mpLeft;\
205 char* pHeapBlock = new char[sizeof(tree_node)];\
207 return (node_ref_type)pHeapBlock;\
211 inline void DestroyFreeList()\
213 while ( mpFreeListHead )\
215 node_ref_type tmp = mpFreeListHead;\
216 mpFreeListHead = mpFreeListHead->mpLeft;\
218 delete [](char*)tmp;\
222 inline void RecycleNode( node_ref_type pNode ) \
224 pNode->mpLeft = mpFreeListHead;\
225 mpFreeListHead = pNode;\
228 inline node_ref_type do_insert(const value_type& x = value_type() )\
230 node_ref_type pNewNode = AllocNode();\
232 pNewNode->mpParent = \
234 pNewNode->mpRight = 0;\
236 node_ref_type pCurrent = mpRoot;\
237 node_ref_type pParent = 0;\
241 if ( mKeyIsUnique && are_equel( _X_KEY_NAME, value(pCurrent) ) )\
243 RecycleNode(pNewNode);\
249 pCurrent = is_less( _X_KEY_NAME, value(pCurrent) ) \
251 : pCurrent->mpRight;\
254 pNewNode->mpParent = pParent;\
258 if( is_less(_X_KEY_NAME, value(pParent) ) )\
260 pParent->mpLeft = pNewNode;\
262 pParent->mpRight = pNewNode;\
266 new ( &pNewNode->_KEY_NAME ) key_type(_X_KEY_NAME);\
267 new ( &pNewNode->_VALUE_NAME ) actual_value_type(_X_VALUE_NAME);\
269 if ( prev(pNewNode) == 0 ) mpLeftMost = pNewNode;\
270 if ( next(pNewNode) == 0 ) mpRightMost = pNewNode;\
275 friend class iterator;\
280 class const_iterator;\
285 node_ref_type mpNode;\
286 friend class CONT_CLASS_NAME;\
287 friend class const_iterator;\
288 friend class const_reverse_iterator;\
290 inline iterator( node_ref_type pNode )\
296 inline iterator() {}\
297 inline int operator==( const iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
298 inline int operator!=( const iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
300 inline iterator( const iterator& other )\
302 mpNode = other.mpNode;\
305 inline const iterator& operator=( const iterator& other )\
307 mpNode = other.mpNode;\
311 inline const iterator& operator--() \
313 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
317 inline iterator operator--(int)\
319 iterator tmp = *this;\
320 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
324 inline const iterator& operator++() \
326 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
330 inline iterator operator++(int)\
332 iterator tmp = *this;\
333 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
337 inline reference operator*() const { return mpNode->mData; }\
341 class const_iterator \
344 node_ref_type mpNode;\
345 friend class CONT_CLASS_NAME;\
346 friend class const_reverse_iterator;\
348 inline const_iterator( node_ref_type pNode )\
354 inline const_iterator() {}\
356 inline int operator==( const const_iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
357 inline int operator!=( const const_iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
359 inline const_iterator( const iterator& other )\
361 mpNode = other.mpNode;\
364 inline const_iterator( const const_iterator& other )\
366 mpNode = other.mpNode;\
369 inline const const_iterator& operator=( const const_iterator& other )\
371 mpNode = other.mpNode;\
375 inline const const_iterator& operator--() \
377 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
381 inline const_iterator operator--(int)\
383 const_iterator tmp = *this;\
384 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
388 inline const const_iterator& operator++() \
390 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
394 inline const_iterator operator++(int)\
396 const_iterator tmp = *this;\
397 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
401 inline const_reference operator*() const { return mpNode->mData; }\
406 inline ASSOC_CONT_CLASS_NAME( key_compare cmpFunctorObj = key_compare(),\
407 int keyIsUnique = ARG_IS_UNIQUE )\
408 : mpFreeListHead( 0 ),\
409 mKeyIsUnique( keyIsUnique ),\
410 mCmpFunctorObj( cmpFunctorObj )\
417 inline ~ASSOC_CONT_CLASS_NAME() \
419 erase( begin(), end() ); \
424 inline iterator begin() { return mpLeftMost; }\
425 inline iterator end() { return 0; }\
427 inline const_iterator begin() const { return mpLeftMost; }\
428 inline const_iterator end() const { return 0; }\
430 inline iterator lower_bound( const key_type& x )\
432 node_ref_type pCurrent = mpRoot;\
436 node_ref_type pParent = pCurrent;\
438 if( are_equel( x, key(pCurrent) ) )\
442 pCurrent = is_less( x, key(pCurrent) ) \
444 : pCurrent->mpRight;\
446 if ( !pCurrent ) return (pParent);\
452 inline const_iterator lower_bound( const key_type& x ) const\
454 { return const_iterator( lower_bound(x).mpNode ); }\
456 inline iterator upper_bound( const key_type& x )\
458 node_ref_type pCurrent = mpRoot;\
462 node_ref_type pParent = pCurrent;\
464 if( are_equel( x, key(pCurrent) ) )\
468 pCurrent = is_less( x, key(pCurrent) ) \
470 : pCurrent->mpRight;\
472 if ( !pCurrent ) return next(pParent);\
478 inline const_iterator upper_bound( const key_type& x ) const\
480 { return const_iterator( upper_bound(x).mpNode ); }\
482 inline iterator find( const key_type& x )\
484 node_ref_type pCurrent = mpRoot;\
488 if( are_equel( x, key(pCurrent) ) )\
492 pCurrent = is_less( x, key(pCurrent) ) \
494 : pCurrent->mpRight;\
500 inline const_iterator find( const key_type& x ) const\
502 { return const_iterator( find(x).mpNode ); }\
504 inline void erase(iterator first, iterator last)\
506 if ( first.mpNode == 0 ) return;\
508 while( first != last ) \
510 iterator next = first;\
517 inline void erase(iterator position)\
519 if ( position.mpNode == 0 ) return;\
521 node_ref_type pZ = position.mpNode;\
522 node_ref_type pX, pY;\
524 if ( pZ == mpLeftMost ) mpLeftMost = next(pZ);\
525 if ( pZ == mpRightMost ) mpRightMost = prev( pZ );\
527 if ( !pZ->mpLeft || !pZ->mpRight )\
545 if ( pX ) pX->mpParent = pY->mpParent;\
549 if (pY == pY->mpParent->mpLeft )\
551 pY->mpParent->mpLeft = pX;\
553 pY->mpParent->mpRight = pX;\
557 node_ref_type toRemove = 0;\
561 pY->mpLeft = pZ->mpLeft;\
563 if (pY->mpLeft) pY->mpLeft->mpParent = pY;\
565 pY->mpRight = pZ->mpRight;\
569 pY->mpRight->mpParent = pY;\
571 pY->mpParent = pZ->mpParent;\
575 if (pZ == pZ->mpParent->mpLeft)\
577 pZ->mpParent->mpLeft = pY;\
579 pZ->mpParent->mpRight = pY;\
588 value(toRemove).~actual_value_type();\
589 key(toRemove).~actual_value_type();\
591 RecycleNode( toRemove );\
594 _INSERT_METHOD_DEFINITION\
597 // do not undefine ___WXSTL_COMMA, where associated containers are defined!
598 // (it is used as workaround for constraints of C-Preprocessor's nested macros)
600 #define ___WXSTL_COMMA ,
602 #define __DEFINE_MAP(ARG_IS_UNIQUE, KEY_TYPE, VAL_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
604 __WXSTLMAP_##KEY_TYPE##VAL_TYPE##ARG_IS_UNIQUE, \
605 struct key_value_pair { KEY_TYPE first ; \
608 key_value_pair( const KEY_TYPE& key ___WXSTL_COMMA const VAL_TYPE& value ) \
609 : first(key) ___WXSTL_COMMA second( value ) {} \
613 mData.first, mData.second, x.first, x.second, \
614 struct insert_result_iterator\
619 inline insert_result_iterator insert( const value_type& x )\
621 insert_result_iterator result;\
623 result.first = do_insert(x);\
624 result.second = ( result.first == end() ) ? 0 : 1;\
629 #define __DEFINE_SET(ARG_IS_UNIQUE, KEY_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
631 __WXSTLSET_##TYPE##ARG_IS_UNIQUE, \
635 mData, mData, x, x, \
636 struct insert_result_iterator\
641 inline insert_result_iterator insert( const value_type& x )\
643 insert_result_iterator result;\
645 result.first = do_insert(x);\
646 result.second = ( result.first == end() ) ? 0 : 1;\
651 // helper macros to create functor objects for associative containers of the given type
653 #define LESS_THEN_FUNCTOR(TYPE) struct \
654 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x < y; } }
656 #define GREATER_THEN_FUNCTOR(TYPE) struct \
657 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x > y; } }
659 // functor argument should be created using the two above macros
660 // or passing own class with method "operator()(const TYPE&,cosnt TYPE&)" defined in it
662 #define WXSTL_MAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 1 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
663 #define WXSTL_MULTIMAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 0 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
664 #define WXSTL_SET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 1 ,KEY_TYPE, FUNCTOR )
665 #define WXSTL_MULTISET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 0 ,KEY_TYPE, FUNCTOR )