]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/modules/lseditor/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 ) const\ 
 173                 mCmpFunctorObj(x,y);\ 
 174                 return ( !mCmpFunctorObj(x,y) && !mCmpFunctorObj(y,x) );\ 
 177         inline int is_less( const key_type& x, const key_type& y ) const\ 
 179                 return mCmpFunctorObj(x,y);\ 
 182         static inline const actual_value_type& value( node_ref_type pNode )\ 
 184                 return pNode->_VALUE_NAME;\ 
 187         static inline const key_type& key( node_ref_type pNode )\ 
 189                 return pNode->_KEY_NAME;\ 
 192         inline node_ref_type AllocNode() \ 
 194                 if ( mpFreeListHead ) \ 
 196                         node_ref_type pFreeNode = mpFreeListHead;\ 
 197                         mpFreeListHead = mpFreeListHead->mpLeft;\ 
 203                         char* pHeapBlock = new char[sizeof(tree_node)];\ 
 205                         return (node_ref_type)pHeapBlock;\ 
 209         inline void DestroyFreeList()\ 
 211                 while ( mpFreeListHead )\ 
 213                         node_ref_type tmp = mpFreeListHead;\ 
 214                         mpFreeListHead = mpFreeListHead->mpLeft;\ 
 216                         delete [](char*)tmp;\ 
 220         inline void RecycleNode( node_ref_type pNode ) \ 
 222                 pNode->mpLeft = mpFreeListHead;\ 
 223                 mpFreeListHead = pNode;\ 
 226         inline node_ref_type do_insert(const value_type& x = value_type() )\ 
 228                 node_ref_type pNewNode = AllocNode();\ 
 230                 pNewNode->mpParent = \ 
 232                                 pNewNode->mpRight = 0;\ 
 234             node_ref_type pCurrent = mpRoot;\ 
 235                 node_ref_type pParent = 0;\ 
 239                         if ( mKeyIsUnique && are_equel( _X_KEY_NAME, key(pCurrent) ) )\ 
 241                                 RecycleNode(pNewNode);\ 
 247                         pCurrent = is_less( _X_KEY_NAME, key(pCurrent) ) \ 
 249                                 : pCurrent->mpRight;\ 
 252                 pNewNode->mpParent = pParent;\ 
 256                         if( is_less(_X_KEY_NAME, key(pParent) ) )\ 
 258                                 pParent->mpLeft = pNewNode;\ 
 260                                 pParent->mpRight = pNewNode;\ 
 264                 new ( &pNewNode->_KEY_NAME   ) key_type(_X_KEY_NAME);\ 
 265                 new ( &pNewNode->_VALUE_NAME ) actual_value_type(_X_VALUE_NAME);\ 
 267                 if ( prev(pNewNode) == 0 ) mpLeftMost = pNewNode;\ 
 268                 if ( next(pNewNode) == 0 ) mpRightMost = pNewNode;\ 
 273         friend class iterator;\ 
 278         class const_iterator;\ 
 283                 node_ref_type mpNode;\ 
 284                 friend class CONT_CLASS_NAME;\ 
 285                 friend class const_iterator;\ 
 286                 friend class const_reverse_iterator;\ 
 288                 inline iterator( node_ref_type pNode )\ 
 294                 inline iterator() {}\ 
 295                 inline int operator==( const iterator& rhs ) const { return (mpNode == rhs.mpNode); }\ 
 296                 inline int operator!=( const iterator& rhs ) const { return (mpNode != rhs.mpNode); }\ 
 298                 inline iterator( const iterator& other )\ 
 300                         mpNode = other.mpNode;\ 
 303                 inline const iterator& operator=( const iterator& other )\ 
 305                         mpNode = other.mpNode;\ 
 309                 inline const iterator& operator--() \ 
 311                         mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\ 
 315                 inline iterator operator--(int)\ 
 317                         iterator tmp = *this;\ 
 318                         mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\ 
 322                 inline const iterator& operator++() \ 
 324                         mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\ 
 328                 inline iterator operator++(int)\ 
 330                         iterator tmp = *this;\ 
 331                         mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\ 
 335                 inline reference operator*() const { return mpNode->mData; }\ 
 339         class const_iterator \ 
 342                 node_ref_type mpNode;\ 
 343                 friend class CONT_CLASS_NAME;\ 
 344                 friend class const_reverse_iterator;\ 
 346                 inline const_iterator( node_ref_type pNode )\ 
 352                 inline const_iterator() {}\ 
 354                 inline int operator==( const const_iterator& rhs ) const { return (mpNode == rhs.mpNode); }\ 
 355                 inline int operator!=( const const_iterator& rhs ) const { return (mpNode != rhs.mpNode); }\ 
 357                 inline const_iterator( const iterator& other )\ 
 359                         mpNode = other.mpNode;\ 
 362                 inline const_iterator( const const_iterator& other )\ 
 364                         mpNode = other.mpNode;\ 
 367                 inline const const_iterator& operator=( const const_iterator& other )\ 
 369                         mpNode = other.mpNode;\ 
 373                 inline const const_iterator& operator--() \ 
 375                         mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\ 
 379                 inline const_iterator operator--(int)\ 
 381                         const_iterator tmp = *this;\ 
 382                         mpNode = ASSOC_CONT_CLASS_NAME::prev(mpNode);\ 
 386                 inline const const_iterator& operator++() \ 
 388                         mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\ 
 392                 inline const_iterator operator++(int)\ 
 394                         const_iterator tmp = *this;\ 
 395                         mpNode = ASSOC_CONT_CLASS_NAME::next(mpNode);\ 
 399                 inline const_reference operator*() const { return mpNode->mData; }\ 
 404         inline ASSOC_CONT_CLASS_NAME( key_compare cmpFunctorObj = key_compare(),\ 
 405                                                                   int keyIsUnique = ARG_IS_UNIQUE )\ 
 406                         : mpFreeListHead( 0 ),\ 
 407                           mKeyIsUnique( keyIsUnique ),\ 
 408                           mCmpFunctorObj( cmpFunctorObj )\ 
 415         inline ~ASSOC_CONT_CLASS_NAME() \ 
 417                 erase( begin(), end() ); \ 
 422         inline iterator begin() { return mpLeftMost; }\ 
 423         inline iterator end()   { return 0; }\ 
 425         inline const_iterator begin() const { return mpLeftMost; }\ 
 426         inline const_iterator end()   const { return 0; }\ 
 428         inline iterator lower_bound( const key_type& x )\ 
 430                 node_ref_type pCurrent = mpRoot;\ 
 434                         node_ref_type pParent = pCurrent;\ 
 436                         if( are_equel( x, key(pCurrent) ) )\ 
 440                                 pCurrent = is_less( x, key(pCurrent) ) \ 
 442                                         : pCurrent->mpRight;\ 
 444                         if ( !pCurrent ) return (pParent);\ 
 450         inline const_iterator lower_bound( const key_type& x ) const\ 
 452                 { return const_iterator( lower_bound(x).mpNode ); }\ 
 454         inline iterator upper_bound( const key_type& x )\ 
 456                 node_ref_type pCurrent = mpRoot;\ 
 460                         node_ref_type pParent = pCurrent;\ 
 462                         if( are_equel( x, key(pCurrent) ) )\ 
 466                                 pCurrent = is_less( x, key(pCurrent) ) \ 
 468                                         : pCurrent->mpRight;\ 
 470                         if ( !pCurrent ) return next(pParent);\ 
 476         inline iterator find( const key_type& x ) const\ 
 478                 node_ref_type pCurrent = mpRoot;\ 
 482                         if( are_equel( x, key(pCurrent) ) )\ 
 486                                 pCurrent = is_less( x, key(pCurrent) ) \ 
 488                                         : pCurrent->mpRight;\ 
 494         inline actual_value_type& operator[]( const key_type x ) const\ 
 496                 { return find(x).mpNode->_VALUE_NAME; }\ 
 498         inline void erase(iterator first, iterator last)\ 
 500                 if ( first.mpNode == 0 ) return;\ 
 502                 while( first != last ) \ 
 504                         iterator next = first;\ 
 511         inline void erase(iterator position)\ 
 513                 if ( position.mpNode == 0 ) return;\ 
 515                 node_ref_type pZ = position.mpNode;\ 
 516                 node_ref_type pX, pY;\ 
 518                 if ( pZ == mpLeftMost ) mpLeftMost   = next(pZ);\ 
 519                 if ( pZ == mpRightMost ) mpRightMost = prev( pZ );\ 
 521         if ( !pZ->mpLeft || !pZ->mpRight )\ 
 539         if ( pX ) pX->mpParent = pY->mpParent;\ 
 543             if (pY == pY->mpParent->mpLeft )\ 
 545                 pY->mpParent->mpLeft = pX;\ 
 547                 pY->mpParent->mpRight = pX;\ 
 551                 node_ref_type toRemove = 0;\ 
 555             pY->mpLeft = pZ->mpLeft;\ 
 557             if (pY->mpLeft) pY->mpLeft->mpParent = pY;\ 
 559             pY->mpRight = pZ->mpRight;\ 
 563                                 pY->mpRight->mpParent = pY;\ 
 565             pY->mpParent = pZ->mpParent;\ 
 569                 if (pZ == pZ->mpParent->mpLeft)\ 
 571                     pZ->mpParent->mpLeft = pY;\ 
 573                     pZ->mpParent->mpRight = pY;\ 
 583                 RecycleNode( toRemove );\ 
 586         _INSERT_METHOD_DEFINITION\ 
 589 // do not undefine ___WXSTL_COMMA, where associated containers are defined! 
 590 // (it is used as workaround for constraints of C-Preprocessor's nested macros) 
 592 #define ___WXSTL_COMMA , 
 594 #define __DEFINE_MAP(ARG_IS_UNIQUE, KEY_TYPE, VAL_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\ 
 596 __WXSTLMAP_##KEY_TYPE##VAL_TYPE##ARG_IS_UNIQUE, \ 
 597 struct key_value_pair   { KEY_TYPE first ; \ 
 600                                                   key_value_pair( const KEY_TYPE& key ___WXSTL_COMMA const VAL_TYPE& value ) \ 
 601                                                         : first(key) ___WXSTL_COMMA second( value ) {} \ 
 605 mData.first, mData.second, x.first, x.second, \ 
 606 struct insert_result_iterator\ 
 611 inline insert_result_iterator insert( const value_type& x )\ 
 613         insert_result_iterator result;\ 
 615         result.first = do_insert(x);\ 
 616         result.second  = ( result.first == end() ) ? 0 : 1;\ 
 621 #define __DEFINE_SET(ARG_IS_UNIQUE, KEY_TYPE, FUNCTOR ) __DEFINE_ASOC_CLASS( ARG_IS_UNIQUE,\ 
 623 __WXSTLSET_##TYPE##ARG_IS_UNIQUE, \ 
 627 mData, mData, x, x, \ 
 628 struct insert_result_iterator\ 
 633 inline insert_result_iterator insert( const value_type& x )\ 
 635         insert_result_iterator result;\ 
 637         result.first = do_insert(x);\ 
 638         result.second  = ( result.first == end() ) ? 0 : 1;\ 
 643 // helper macros to create functor objects for associative containers of the given type 
 645 #define LESS_THEN_FUNCTOR(TYPE) struct \ 
 646 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x < y; } } 
 648 #define GREATER_THEN_FUNCTOR(TYPE) struct \ 
 649 { inline int operator()(const TYPE& x, const TYPE& y ) const { return x > y; } } 
 651 // functor argument should be created using the two above macros  
 652 // or passing own class with method "operator()(const TYPE&,cosnt TYPE&)" defined in it 
 654 #define WXSTL_MAP( KEY_TYPE, VALUE_TYPE, FUNCTOR )      __DEFINE_MAP( 1 ,KEY_TYPE, VALUE_TYPE, FUNCTOR) 
 655 #define WXSTL_MULTIMAP( KEY_TYPE, VALUE_TYPE, FUNCTOR ) __DEFINE_MAP( 0 ,KEY_TYPE, VALUE_TYPE, FUNCTOR) 
 656 #define WXSTL_SET( KEY_TYPE, FUNCTOR )                  __DEFINE_SET( 1 ,KEY_TYPE, FUNCTOR ) 
 657 #define WXSTL_MULTISET( KEY_TYPE, FUNCTOR )             __DEFINE_SET( 0 ,KEY_TYPE, FUNCTOR )