]>
git.saurik.com Git - wxWidgets.git/blob - utils/HelpGen/include/wxstlac.h
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Contrib. demo
4 // Author: Aleksandras Gluchovas
8 // Copyright: (c) Aleskandars Gluchovas
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
16 #include <sys/types.h>
22 // the below macro used internally (see actual interface after this macro)
27 // ASSOC_CONT_CLASS_NAME
31 // ARG_ACTUAL_VALUE_TYPE
39 // _INSERT_METHOD_DEFINITION
41 #define __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE, \
43 ASSOC_CONT_CLASS_NAME, \
46 ARG_ACTUAL_VALUE_TYPE, \
51 _INSERT_METHOD_DEFINITION \
53 ASSOC_CONT_CLASS_NAME\
58 typedef ARG_VALUE_TYPE value_type;\
59 typedef ARG_KEY_TYPE key_type;\
60 typedef ARG_ACTUAL_VALUE_TYPE actual_value_type;\
62 typedef value_type* pointer;\
63 typedef value_type& reference;\
65 typedef const value_type& const_reference;\
67 typedef FUNCTOR key_compare;\
68 typedef key_compare Compare;\
81 typedef tree_node* node_ref_type;\
83 node_ref_type mpRoot;\
84 node_ref_type mpLeftMost;\
85 node_ref_type mpRightMost;\
87 node_ref_type mpFreeListHead;\
90 key_compare mCmpFunctorObj;\
94 static inline node_ref_type next( node_ref_type pNode )\
96 if ( pNode->mpRight ) \
98 pNode = pNode->mpRight;\
100 while ( pNode->mpLeft ) pNode = pNode->mpLeft;\
105 if ( pNode->mpParent )\
107 if ( pNode == pNode->mpParent->mpLeft )\
109 return pNode->mpParent;\
111 pNode = pNode->mpParent;\
113 node_ref_type prevNode = pNode;\
114 pNode = pNode->mpParent;\
118 if ( pNode->mpRight &&\
119 pNode->mpRight != prevNode\
123 pNode= pNode->mpParent;\
132 static inline node_ref_type prev( node_ref_type pNode )\
134 if ( pNode->mpLeft ) \
136 pNode = pNode->mpLeft;\
138 while ( pNode->mpRight ) pNode = pNode->mpRight;\
143 if ( pNode->mpParent )\
145 if ( pNode == pNode->mpParent->mpRight )\
146 return pNode->mpParent;\
148 pNode = pNode->mpParent;\
150 node_ref_type prevNode = pNode;\
151 pNode = pNode->mpParent;\
155 if ( pNode->mpLeft &&\
156 pNode->mpLeft != prevNode\
160 pNode= pNode->mpParent;\
171 inline int are_equel( const key_type& x, const key_type& y )\
173 return ( !mCmpFunctorObj(x,y) && !mCmpFunctorObj(y,x) );\
176 inline int is_less( const key_type& x, const key_type& y )\
178 return mCmpFunctorObj(x,y);\
181 static inline const actual_value_type& value( node_ref_type pNode )\
183 return pNode->_VALUE_NAME;\
186 static inline const key_type& key( node_ref_type pNode )\
188 return pNode->_KEY_NAME;\
191 inline node_ref_type AllocNode() \
193 if ( mpFreeListHead ) \
195 node_ref_type pFreeNode = mpFreeListHead;\
196 mpFreeListHead = mpFreeListHead->mpLeft;\
202 char* pHeapBlock = new char[sizeof(tree_node)];\
204 return (node_ref_type)pHeapBlock;\
208 inline void DestroyFreeList()\
210 while ( mpFreeListHead )\
212 node_ref_type tmp = mpFreeListHead;\
213 mpFreeListHead = mpFreeListHead->mpLeft;\
215 delete [](char*)tmp;\
219 inline void RecycleNode( node_ref_type pNode ) \
221 pNode->mpLeft = mpFreeListHead;\
222 mpFreeListHead = pNode;\
225 inline node_ref_type do_insert(const value_type& x = value_type() )\
227 node_ref_type pNewNode = AllocNode();\
229 pNewNode->mpParent = \
231 pNewNode->mpRight = 0;\
233 node_ref_type pCurrent = mpRoot;\
234 node_ref_type pParent = 0;\
238 if ( mKeyIsUnique && are_equel( _X_KEY_NAME, value(pCurrent) ) )\
240 RecycleNode(pNewNode);\
246 pCurrent = is_less( _X_KEY_NAME, value(pCurrent) ) \
248 : pCurrent->mpRight;\
251 pNewNode->mpParent = pParent;\
255 if( is_less(_X_KEY_NAME, value(pParent) ) )\
257 pParent->mpLeft = pNewNode;\
259 pParent->mpRight = pNewNode;\
263 new ( &pNewNode->_KEY_NAME ) key_type(_X_KEY_NAME);\
264 new ( &pNewNode->_VALUE_NAME ) actual_value_type(_X_VALUE_NAME);\
266 if ( prev(pNewNode) == 0 ) mpLeftMost = pNewNode;\
267 if ( next(pNewNode) == 0 ) mpRightMost = pNewNode;\
272 friend class iterator;\
277 class const_iterator;\
282 node_ref_type mpNode;\
283 friend class CONT_CLASS_NAME;\
284 friend class const_iterator;\
285 friend class const_reverse_iterator;\
287 inline iterator( node_ref_type pNode )\
293 inline iterator() {}\
294 inline int operator==( const iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
295 inline int operator!=( const iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
297 inline iterator( const iterator& other )\
299 mpNode = other.mpNode;\
302 inline const iterator& operator=( const iterator& other )\
304 mpNode = other.mpNode;\
308 inline const iterator& operator--() \
310 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
314 inline iterator operator--(int)\
316 iterator tmp = *this;\
317 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
321 inline const iterator& operator++() \
323 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
327 inline iterator operator++(int)\
329 iterator tmp = *this;\
330 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
334 inline reference operator*() const { return mpNode->mData; }\
338 class const_iterator \
341 node_ref_type mpNode;\
342 friend class CONT_CLASS_NAME;\
343 friend class const_reverse_iterator;\
345 inline const_iterator( node_ref_type pNode )\
351 inline const_iterator() {}\
353 inline int operator==( const const_iterator& rhs ) const { return (mpNode == rhs.mpNode); }\
354 inline int operator!=( const const_iterator& rhs ) const { return (mpNode != rhs.mpNode); }\
356 inline const_iterator( const iterator& other )\
358 mpNode = other.mpNode;\
361 inline const_iterator( const const_iterator& other )\
363 mpNode = other.mpNode;\
366 inline const const_iterator& operator=( const const_iterator& other )\
368 mpNode = other.mpNode;\
372 inline const const_iterator& operator--() \
374 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
378 inline const_iterator operator--(int)\
380 const_iterator tmp = *this;\
381 mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\
385 inline const const_iterator& operator++() \
387 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
391 inline const_iterator operator++(int)\
393 const_iterator tmp = *this;\
394 mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\
398 inline const_reference operator*() const { return mpNode->mData; }\
403 inline ASSOC_CONT_CLASS_NAME( key_compare cmpFunctorObj = key_compare(),\
404 int keyIsUnique = ARG_IS_UNIQUE )\
405 : mpFreeListHead( 0 ),\
406 mKeyIsUnique( keyIsUnique ),\
407 mCmpFunctorObj( cmpFunctorObj )\
414 inline ~ASSOC_CONT_CLASS_NAME() \
416 erase( begin(), end() ); \
421 inline iterator begin() { return mpLeftMost; }\
422 inline iterator end() { return 0; }\
424 inline const_iterator begin() const { return mpLeftMost; }\
425 inline const_iterator end() const { return 0; }\
427 inline iterator lower_bound( const key_type& x )\
429 node_ref_type pCurrent = mpRoot;\
433 node_ref_type pParent = pCurrent;\
435 if( are_equel( x, key(pCurrent) ) )\
439 pCurrent = is_less( x, key(pCurrent) ) \
441 : pCurrent->mpRight;\
443 if ( !pCurrent ) return (pParent);\
449 inline const_iterator lower_bound( const key_type& x ) const\
451 { return const_iterator( lower_bound(x).mpNode ); }\
453 inline iterator upper_bound( const key_type& x )\
455 node_ref_type pCurrent = mpRoot;\
459 node_ref_type pParent = pCurrent;\
461 if( are_equel( x, key(pCurrent) ) )\
465 pCurrent = is_less( x, key(pCurrent) ) \
467 : pCurrent->mpRight;\
469 if ( !pCurrent ) return next(pParent);\
475 inline const_iterator upper_bound( const key_type& x ) const\
477 { return const_iterator( upper_bound(x).mpNode ); }\
479 inline iterator find( const key_type& x )\
481 node_ref_type pCurrent = mpRoot;\
485 if( are_equel( x, key(pCurrent) ) )\
489 pCurrent = is_less( x, key(pCurrent) ) \
491 : pCurrent->mpRight;\
497 inline const_iterator find( const key_type& x ) const\
499 { return const_iterator( find(x).mpNode ); }\
501 inline void erase(iterator first, iterator last)\
503 if ( first.mpNode == 0 ) return;\
505 while( first != last ) \
507 iterator next = first;\
514 inline void erase(iterator position)\
516 if ( position.mpNode == 0 ) return;\
518 node_ref_type pZ = position.mpNode;\
519 node_ref_type pX, pY;\
521 if ( pZ == mpLeftMost ) mpLeftMost = next(pZ);\
522 if ( pZ == mpRightMost ) mpRightMost = prev( pZ );\
524 if ( !pZ->mpLeft || !pZ->mpRight )\
542 if ( pX ) pX->mpParent = pY->mpParent;\
546 if (pY == pY->mpParent->mpLeft )\
548 pY->mpParent->mpLeft = pX;\
550 pY->mpParent->mpRight = pX;\
554 node_ref_type toRemove = 0;\
558 pY->mpLeft = pZ->mpLeft;\
560 if (pY->mpLeft) pY->mpLeft->mpParent = pY;\
562 pY->mpRight = pZ->mpRight;\
566 pY->mpRight->mpParent = pY;\
568 pY->mpParent = pZ->mpParent;\
572 if (pZ == pZ->mpParent->mpLeft)\
574 pZ->mpParent->mpLeft = pY;\
576 pZ->mpParent->mpRight = pY;\
585 value(toRemove).~actual_value_type();\
586 key(toRemove).~actual_value_type();\
588 RecycleNode( toRemove );\
591 _INSERT_METHOD_DEFINITION\
594 // do not undefine ___WXSTL_COMMA, where associated containers are defined!
595 // (it is used as workaround for constraints of C-Preprocessor's nested macros)
597 #define ___WXSTL_COMMA ,
599 #define __DEFINE_MAP(ARG_IS_UNIQUE, KEY_TYPE, VAL_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
601 __WXSTLMAP_##KEY_TYPE##VAL_TYPE##ARG_IS_UNIQUE, \
602 struct key_value_pair { KEY_TYPE first ; \
605 key_value_pair( const KEY_TYPE& key ___WXSTL_COMMA const VAL_TYPE& value ) \
606 : first(key) ___WXSTL_COMMA second( value ) {} \
610 mData.first, mData.second, x.first, x.second, \
611 struct insert_result_iterator\
616 inline insert_result_iterator insert( const value_type& x )\
618 insert_result_iterator result;\
620 result.first = do_insert(x);\
621 result.second = ( result.first == end() ) ? 0 : 1;\
626 #define __DEFINE_SET(ARG_IS_UNIQUE, KEY_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\
628 __WXSTLSET_##TYPE##ARG_IS_UNIQUE, \
632 mData, mData, x, x, \
633 struct insert_result_iterator\
638 inline insert_result_iterator insert( const value_type& x )\
640 insert_result_iterator result;\
642 result.first = do_insert(x);\
643 result.second = ( result.first == end() ) ? 0 : 1;\
648 // helper macros to create functor objects for associative containers of the given type
650 #define LESS_THEN_FUNCTOR(TYPE) struct \
651 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x < y; } }
653 #define GREATER_THEN_FUNCTOR(TYPE) struct \
654 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x > y; } }
656 // functor argument should be created using the two above macros
657 // or passing own class with method "operator()(const TYPE&,cosnt TYPE&)" defined in it
659 #define WXSTL_MAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 1 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
660 #define WXSTL_MULTIMAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 0 ,KEY_TYPE, VALUE_TYPE, FUNCTOR)
661 #define WXSTL_SET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 1 ,KEY_TYPE, FUNCTOR )
662 #define WXSTL_MULTISET( KEY_TYPE, FUNCTOR ) __DEFINE_SET( 0 ,KEY_TYPE, FUNCTOR )