]>
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 #if !defined(__WXMAC__) || defined(__DARWIN__)
21 # include <sys/types.h>
27 // the below macro used internally (see actual interface after this macro)
32 // ASSOC_CONT_CLASS_NAME
36 // ARG_ACTUAL_VALUE_TYPE
44 // _INSERT_METHOD_DEFINITION
46 #define __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE, \
48 ASSOC_CONT_CLASS_NAME, \
51 ARG_ACTUAL_VALUE_TYPE, \
56 _INSERT_METHOD_DEFINITION \
58 ASSOC_CONT_CLASS_NAME\
63 typedef ARG_VALUE_TYPE value_type;\
64 typedef ARG_KEY_TYPE key_type;\
65 typedef ARG_ACTUAL_VALUE_TYPE actual_value_type;\
67 typedef value_type* pointer;\
68 typedef value_type& reference;\
70 typedef const value_type& const_reference;\
72 typedef FUNCTOR key_compare;\
73 typedef key_compare Compare;\
86 typedef tree_node* node_ref_type;\
88 node_ref_type mpRoot;\
89 node_ref_type mpLeftMost;\
90 node_ref_type mpRightMost;\
92 node_ref_type mpFreeListHead;\
95 key_compare mCmpFunctorObj;\
99 static inline node_ref_type next( node_ref_type pNode )\
101 if ( pNode->mpRight ) \
103 pNode = pNode->mpRight;\
105 while ( pNode->mpLeft ) pNode = pNode->mpLeft;\
110 if ( pNode->mpParent )\
112 if ( pNode == pNode->mpParent->mpLeft )\
114 return pNode->mpParent;\
116 pNode = pNode->mpParent;\
118 node_ref_type prevNode = pNode;\
119 pNode = pNode->mpParent;\
123 if ( pNode->mpRight &&\
124 pNode->mpRight != prevNode\
128 pNode= pNode->mpParent;\
137 static inline node_ref_type prev( node_ref_type pNode )\
139 if ( pNode->mpLeft ) \
141 pNode = pNode->mpLeft;\
143 while ( pNode->mpRight ) pNode = pNode->mpRight;\
148 if ( pNode->mpParent )\
150 if ( pNode == pNode->mpParent->mpRight )\
151 return pNode->mpParent;\
153 pNode = pNode->mpParent;\
155 node_ref_type prevNode = pNode;\
156 pNode = pNode->mpParent;\
160 if ( pNode->mpLeft &&\
161 pNode->mpLeft != prevNode\
165 pNode= pNode->mpParent;\
176 inline int are_equel( const key_type& x, const key_type& y )\
178 return ( !mCmpFunctorObj(x,y) && !mCmpFunctorObj(y,x) );\
181 inline int is_less( const key_type& x, const key_type& y )\
183 return mCmpFunctorObj(x,y);\
186 static inline const actual_value_type& value( node_ref_type pNode )\
188 return pNode->_VALUE_NAME;\
191 static inline const key_type& key( node_ref_type pNode )\
193 return pNode->_KEY_NAME;\
196 inline node_ref_type AllocNode() \
198 if ( mpFreeListHead ) \
200 node_ref_type pFreeNode = mpFreeListHead;\
201 mpFreeListHead = mpFreeListHead->mpLeft;\
207 char* pHeapBlock = new char[sizeof(tree_node)];\
209 return (node_ref_type)pHeapBlock;\
213 inline void DestroyFreeList()\
215 while ( mpFreeListHead )\
217 node_ref_type tmp = mpFreeListHead;\
218 mpFreeListHead = mpFreeListHead->mpLeft;\
220 delete [](char*)tmp;\
224 inline void RecycleNode( node_ref_type pNode ) \
226 pNode->mpLeft = mpFreeListHead;\
227 mpFreeListHead = pNode;\
230 inline node_ref_type do_insert(const value_type& x = value_type() )\
232 node_ref_type pNewNode = AllocNode();\
234 pNewNode->mpParent = \
236 pNewNode->mpRight = 0;\
238 node_ref_type pCurrent = mpRoot;\
239 node_ref_type pParent = 0;\
243 if ( mKeyIsUnique && are_equel( _X_KEY_NAME, value(pCurrent) ) )\
245 RecycleNode(pNewNode);\
251 pCurrent = is_less( _X_KEY_NAME, value(pCurrent) ) \
253 : pCurrent->mpRight;\
256 pNewNode->mpParent = pParent;\
260 if( is_less(_X_KEY_NAME, value(pParent) ) )\
262 pParent->mpLeft = pNewNode;\
264 pParent->mpRight = pNewNode;\
268 new ( &pNewNode->_KEY_NAME ) key_type(_X_KEY_NAME);\
269 new ( &pNewNode->_VALUE_NAME ) actual_value_type(_X_VALUE_NAME);\
271 if ( prev(pNewNode) == 0 ) mpLeftMost = pNewNode;\
272 if ( next(pNewNode) == 0 ) mpRightMost = pNewNode;\
277 friend class iterator;\
282 class const_iterator;\
287 node_ref_type mpNode;\
288 friend class CONT_CLASS_NAME;\
289 friend class const_iterator;\
290 friend class const_reverse_iterator;\
292 inline iterator( node_ref_type pNode )\
298 inline iterator() {}\
299 inline int operator==( const iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
300 inline int operator!=( const iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
302 inline iterator( const iterator& other )\
304 mpNode = other.mpNode;\
307 inline const iterator& operator=( const iterator& other )\
309 mpNode = other.mpNode;\
313 inline const iterator& operator--() \
315 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
319 inline iterator operator--(int)\
321 iterator tmp = *this;\
322 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
326 inline const iterator& operator++() \
328 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
332 inline iterator operator++(int)\
334 iterator tmp = *this;\
335 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
339 inline reference operator*() const { return mpNode->mData; }\
343 class const_iterator \
346 node_ref_type mpNode;\
347 friend class CONT_CLASS_NAME;\
348 friend class const_reverse_iterator;\
350 inline const_iterator( node_ref_type pNode )\
356 inline const_iterator() {}\
358 inline int operator==( const const_iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
359 inline int operator!=( const const_iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
361 inline const_iterator( const iterator& other )\
363 mpNode = other.mpNode;\
366 inline const_iterator( const const_iterator& other )\
368 mpNode = other.mpNode;\
371 inline const const_iterator& operator=( const const_iterator& other )\
373 mpNode = other.mpNode;\
377 inline const const_iterator& operator--() \
379 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
383 inline const_iterator operator--(int)\
385 const_iterator tmp = *this;\
386 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
390 inline const const_iterator& operator++() \
392 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
396 inline const_iterator operator++(int)\
398 const_iterator tmp = *this;\
399 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
403 inline const_reference operator*() const { return mpNode->mData; }\
408 inline ASSOC_CONT_CLASS_NAME( key_compare cmpFunctorObj = key_compare(),\
409 int keyIsUnique = ARG_IS_UNIQUE )\
410 : mpFreeListHead( 0 ),\
411 mKeyIsUnique( keyIsUnique ),\
412 mCmpFunctorObj( cmpFunctorObj )\
419 inline ~ASSOC_CONT_CLASS_NAME() \
421 erase( begin(), end() ); \
426 inline iterator begin() { return mpLeftMost; }\
427 inline iterator end() { return 0; }\
429 inline const_iterator begin() const { return mpLeftMost; }\
430 inline const_iterator end() const { return 0; }\
432 inline iterator lower_bound( const key_type& x )\
434 node_ref_type pCurrent = mpRoot;\
438 node_ref_type pParent = pCurrent;\
440 if( are_equel( x, key(pCurrent) ) )\
444 pCurrent = is_less( x, key(pCurrent) ) \
446 : pCurrent->mpRight;\
448 if ( !pCurrent ) return (pParent);\
454 inline const_iterator lower_bound( const key_type& x ) const\
456 { return const_iterator( lower_bound(x).mpNode ); }\
458 inline iterator upper_bound( const key_type& x )\
460 node_ref_type pCurrent = mpRoot;\
464 node_ref_type pParent = pCurrent;\
466 if( are_equel( x, key(pCurrent) ) )\
470 pCurrent = is_less( x, key(pCurrent) ) \
472 : pCurrent->mpRight;\
474 if ( !pCurrent ) return next(pParent);\
480 inline const_iterator upper_bound( const key_type& x ) const\
482 { return const_iterator( upper_bound(x).mpNode ); }\
484 inline iterator find( const key_type& x )\
486 node_ref_type pCurrent = mpRoot;\
490 if( are_equel( x, key(pCurrent) ) )\
494 pCurrent = is_less( x, key(pCurrent) ) \
496 : pCurrent->mpRight;\
502 inline const_iterator find( const key_type& x ) const\
504 { return const_iterator( find(x).mpNode ); }\
506 inline void erase(iterator first, iterator last)\
508 if ( first.mpNode == 0 ) return;\
510 while( first != last ) \
512 iterator next = first;\
519 inline void erase(iterator position)\
521 if ( position.mpNode == 0 ) return;\
523 node_ref_type pZ = position.mpNode;\
524 node_ref_type pX, pY;\
526 if ( pZ == mpLeftMost ) mpLeftMost = next(pZ);\
527 if ( pZ == mpRightMost ) mpRightMost = prev( pZ );\
529 if ( !pZ->mpLeft || !pZ->mpRight )\
547 if ( pX ) pX->mpParent = pY->mpParent;\
551 if (pY == pY->mpParent->mpLeft )\
553 pY->mpParent->mpLeft = pX;\
555 pY->mpParent->mpRight = pX;\
559 node_ref_type toRemove = 0;\
563 pY->mpLeft = pZ->mpLeft;\
565 if (pY->mpLeft) pY->mpLeft->mpParent = pY;\
567 pY->mpRight = pZ->mpRight;\
571 pY->mpRight->mpParent = pY;\
573 pY->mpParent = pZ->mpParent;\
577 if (pZ == pZ->mpParent->mpLeft)\
579 pZ->mpParent->mpLeft = pY;\
581 pZ->mpParent->mpRight = pY;\
590 value(toRemove).~actual_value_type();\
591 key(toRemove).~actual_value_type();\
593 RecycleNode( toRemove );\
596 _INSERT_METHOD_DEFINITION\
599 // do not undefine ___WXSTL_COMMA, where associated containers are defined!
600 // (it is used as workaround for constraints of C-Preprocessor's nested macros)
602 #define ___WXSTL_COMMA ,
604 #define __DEFINE_MAP(ARG_IS_UNIQUE, KEY_TYPE, VAL_TYPE, FUNCTOR ) \
605 __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
607 __WXSTLMAP_##KEY_TYPE##VAL_TYPE##ARG_IS_UNIQUE, \
608 struct key_value_pair { KEY_TYPE first ; \
611 key_value_pair( const KEY_TYPE& key ___WXSTL_COMMA const VAL_TYPE& value ) \
612 : first(key) ___WXSTL_COMMA second( value ) {} \
616 mData.first, mData.second, x.first, x.second, \
617 struct insert_result_iterator\
622 inline insert_result_iterator insert( const value_type& x )\
624 insert_result_iterator result;\
626 result.first = do_insert(x);\
627 result.second = ( result.first == end() ) ? 0 : 1;\
632 #define __DEFINE_SET(ARG_IS_UNIQUE, KEY_TYPE, FUNCTOR ) \
633 __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
635 __WXSTLSET_##TYPE##ARG_IS_UNIQUE, \
639 mData, mData, x, x, \
640 struct insert_result_iterator\
645 inline insert_result_iterator insert( const value_type& x )\
647 insert_result_iterator result;\
649 result.first = do_insert(x);\
650 result.second = ( result.first == end() ) ? 0 : 1;\
655 // helper macros to create functor objects for associative containers of the given type
657 #define LESS_THEN_FUNCTOR(TYPE) struct \
658 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x < y; } }
660 #define GREATER_THEN_FUNCTOR(TYPE) struct \
661 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x > y; } }
663 // functor argument should be created using the two above macros
664 // or passing own class with method "operator()(const TYPE&,cosnt TYPE&)" defined in it
666 #define WXSTL_MAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 1 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
667 #define WXSTL_MULTIMAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 0 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
668 #define WXSTL_SET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 1 ,KEY_TYPE, FUNCTOR )
669 #define WXSTL_MULTISET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 0 ,KEY_TYPE, FUNCTOR )