00001 // 00002 // The Austria library is copyright (c) Gianni Mariani 2004. 00003 // 00004 // Grant Of License. Grants to LICENSEE the non-exclusive right to use the Austria 00005 // library subject to the terms of the LGPL. 00006 // 00007 // A copy of the license is available in this directory or one may be found at this URL: 00008 // http://www.gnu.org/copyleft/lesser.txt 00009 // 00015 #ifndef x_at_list_h_x 00016 #define x_at_list_h_x 1 00017 00018 #include "at_exports.h" 00019 #include "at_unionptr.h" 00020 00021 // Austria namespace 00022 namespace at 00023 { 00024 00051 // ======== List_Positions ========================================= 00060 enum List_Positions 00061 { 00065 xE_Element = 0, 00066 00070 xE_End = 1, 00071 00075 xE_Beginning = 2 00076 }; 00077 00078 00079 // ======== List_EmptyMutex ========================================= 00087 class AUSTRIA_EXPORT List_EmptyMutex 00088 { 00089 public: 00090 00091 inline void Lock() {} 00092 inline void UnLock() {} 00093 00094 // ======== t_Lock ================================================ 00101 class t_Lock 00102 { 00103 public: 00104 00105 t_Lock( List_EmptyMutex & io_mutex ) 00106 { 00107 } 00108 00109 ~t_Lock() 00110 { 00111 } 00112 00113 private: 00114 00115 // must not allow the copy or assignment so make 00116 // these methods private. 00117 t_Lock( const t_Lock & ); 00118 t_Lock & operator=( const t_Lock & ); 00119 }; 00120 }; 00121 00122 00123 // ======== List_Mutex ============================================= 00129 template < 00130 typename w_lock_base 00131 > 00132 class List_Mutex 00133 : public w_lock_base 00134 { 00135 public: 00136 00137 // ======== t_Lock ================================================ 00144 class t_Lock 00145 { 00146 public: 00147 00148 List_EmptyMutex * m_lock; 00149 00150 t_Lock( List_EmptyMutex & io_mutex ) 00151 : m_lock( & io_mutex ) 00152 { 00153 m_lock->Lock(); 00154 } 00155 00156 ~t_Lock() 00157 { 00158 m_lock->UnLock(); 00159 } 00160 00161 private: 00162 00163 // must not allow the copy or assignment so make 00164 // these methods private. 00165 t_Lock( const t_Lock & ); 00166 t_Lock & operator=( const t_Lock & ); 00167 }; 00168 00169 }; 00170 00171 00172 // ======== ListNothing_Basic ===================================== 00178 class AUSTRIA_EXPORT ListNothing_Basic 00179 { 00180 public: 00181 00182 }; 00183 00184 00185 // ======== List_Error_Traits ====================================== 00191 class List_Error_Traits 00192 { 00193 public: 00194 00195 static inline void IteratorUndefined() 00196 { 00197 AT_Assert( false ); 00198 } 00199 00200 }; 00201 00202 00203 // ======== Iterator =============================================== 00209 template < 00210 typename w_base_class 00211 > 00212 class Iterator 00213 { 00214 public: 00215 typedef typename w_base_class::txC_List_Traits xC_List_Traits; 00216 typedef typename w_base_class::txC_List_Entry xC_List_Entry; 00217 typedef typename w_base_class::txC_List_Head xC_List_Head; 00218 typedef typename w_base_class::txW_PayloadType xW_PayloadType; 00219 typedef UnionPtrType<List_Positions, xC_List_Entry *, xC_List_Head * > 00220 xC_PointerType; 00221 00222 public: 00223 00224 xC_PointerType m_pointer; 00225 00226 // 00227 // empty constructor 00228 Iterator() 00229 { 00230 } 00231 00232 inline static xC_PointerType xF_EndIterator( xC_List_Head * l_head ) 00233 { 00234 xC_PointerType l_next_ptr; 00235 00236 l_next_ptr = l_head; 00237 00238 return l_next_ptr; 00239 } 00240 00241 xC_PointerType xF_Iterate( 00242 typename xC_List_Entry::txC_Entry_MemberPtr w_elem_pos, 00243 typename xC_List_Entry::txC_Entry_MemberPtr w_elem_neg, 00244 typename xC_List_Head::txC_Head_MemberPtr w_head_pos, 00245 typename xC_List_Head::txC_Head_MemberPtr w_head_neg, 00246 List_Positions w_posi_pos, 00247 List_Positions w_posi_neg 00248 ) 00249 { 00250 // 00251 // create places to put data 00252 // 00253 List_Positions l_type; 00254 xC_List_Entry * l_entry; 00255 xC_List_Head * l_head; 00256 00257 // 00258 // go read the data 00259 // 00260 l_type = m_pointer.Get( l_entry, l_head ); 00261 00262 xC_List_Entry * l_next_entry; 00263 // 00264 // if this is an element, we can iterate 00265 if ( l_type == xE_Element ) 00266 { 00267 l_next_entry = l_entry->*w_elem_pos; 00268 00269 // 00270 // We have reached the end of the list. 00271 if ( l_next_entry == 0 ) 00272 { 00273 return xF_EndIterator( l_entry->m_head ); 00274 } 00275 00276 } 00277 else 00278 { 00279 // OK - we're already at the end of the list 00280 // if we're asked to interate in the correct 00281 // direction (back into the list) then do so. 00282 // Otherwise we assert. 00283 00284 AT_Assert( l_type != w_posi_pos ); 00285 00286 l_next_entry = l_head->*w_head_pos; 00287 00288 // 00289 // We have reached the end of the list. 00290 if ( l_next_entry == 0 ) 00291 { 00292 return xF_EndIterator( l_head ); 00293 } 00294 00295 } 00296 00297 xC_PointerType l_next_ptr = l_next_entry; 00298 00299 // 00300 // return the pointer to the next object 00301 return l_next_ptr; 00302 00303 } 00304 00305 // 00306 // Determiine if the iterator it at the end. 00307 // 00308 00309 inline bool is_end() 00310 { 00311 00312 List_Positions l_type; 00313 xC_List_Entry * l_entry; 00314 xC_List_Head * l_head; 00315 00316 // 00317 // go read the data 00318 // 00319 l_type = m_pointer.Get( l_entry, l_head ); 00320 00321 // 00322 // if this is an element, we can iterate 00323 return l_type != xE_Element; 00324 00325 } 00326 00327 // 00328 // Determiine if the iterator is linked 00329 // 00330 00331 inline bool is_linked() 00332 { 00333 00334 xC_List_Entry * l_entry = Dereference(); 00335 00336 return l_entry->m_head != 0; 00337 } 00338 00339 inline Iterator & operator -- () 00340 { 00341 m_pointer = xF_Iterate( &xC_List_Entry::m_back, &xC_List_Entry::m_forw, &xC_List_Head::m_begin, &xC_List_Head::m_end, xE_End, xE_Beginning ); 00342 00343 return * this; 00344 } 00345 00346 inline Iterator operator -- ( int ) 00347 { 00348 Iterator l_tmp = * this; 00349 00350 m_pointer = xF_Iterate( &xC_List_Entry::m_back, &xC_List_Entry::m_forw, &xC_List_Head::m_begin, &xC_List_Head::m_end, xE_End, xE_Beginning ); 00351 00352 return l_tmp; 00353 } 00354 00355 inline Iterator & operator ++ () 00356 { 00357 m_pointer = xF_Iterate( &xC_List_Entry::m_forw, &xC_List_Entry::m_back, &xC_List_Head::m_end, &xC_List_Head::m_begin, xE_Beginning, xE_End ); 00358 00359 return * this; 00360 } 00361 00362 inline Iterator operator ++ ( int ) 00363 { 00364 Iterator l_tmp = * this; 00365 00366 m_pointer = xF_Iterate( &xC_List_Entry::m_forw, &xC_List_Entry::m_back, &xC_List_Head::m_end, &xC_List_Head::m_begin, xE_Beginning, xE_End ); 00367 00368 return l_tmp; 00369 } 00370 00371 inline xC_List_Entry * Dereference() 00372 { 00373 // 00374 // 00375 if ( xC_List_Traits::DoDereferenceCheck ) 00376 { 00377 // 00378 // create places to put data 00379 // 00380 List_Positions l_type; 00381 xC_List_Entry * l_entry; 00382 xC_List_Head * l_head; 00383 00384 // 00385 // go read the data 00386 // 00387 l_type = m_pointer.Get( l_entry, l_head ); 00388 00389 AT_Assert( l_type == xE_Element ); 00390 00391 return l_entry; 00392 } 00393 else 00394 { 00395 // this just pulls the value directly out of the pointer 00396 // this only works with the first value. 00397 return m_pointer.m_value.m_value_0; 00398 } 00399 } 00400 00401 inline xW_PayloadType & operator * () 00402 { 00403 return * static_cast<xW_PayloadType *>( Dereference() ); 00404 } 00405 00406 inline xW_PayloadType * operator -> () 00407 { 00408 return static_cast<xW_PayloadType *>( Dereference() ); 00409 } 00410 00411 inline Iterator operator + ( Int32 i_val ) const 00412 { 00413 Iterator l_rval = * this; 00414 00415 while ( i_val -- ) 00416 { 00417 l_rval->operator ++ (); 00418 } 00419 00420 return l_rval; 00421 } 00422 00423 inline Iterator operator - ( Int32 i_val ) const 00424 { 00425 Iterator l_rval = * this; 00426 00427 while ( i_val -- ) 00428 { 00429 l_rval->operator -- (); 00430 } 00431 00432 return l_rval; 00433 } 00434 00435 template< typename w_base_rhs > inline bool operator == ( Iterator<w_base_rhs> & i_rhs ) 00436 { 00437 return m_pointer == i_rhs.m_pointer; 00438 } 00439 00440 template< typename w_base_rhs > Iterator & operator = ( Iterator<w_base_rhs> i_rhs ) 00441 { 00442 m_pointer = i_rhs.m_pointer; 00443 00444 return * this; 00445 } 00446 00447 template< typename w_base_rhs > Iterator( Iterator<w_base_rhs> i_rhs ) 00448 : m_pointer( i_rhs.m_pointer ) 00449 { 00450 } 00451 00452 inline void unlink() 00453 { 00454 xC_List_Entry * l_entry = Dereference(); 00455 00456 l_entry->xF_Unlink(); 00457 } 00458 }; 00459 00460 00461 // ======== ListAccessorDeclare =================================== 00468 template< 00469 typename w_entry_class_name, 00470 typename w_base_class = ListNothing_Basic, 00471 typename w_error_traits = List_Error_Traits 00472 > 00473 class ListAccessorDeclare 00474 : public w_base_class 00475 { 00476 public: 00477 00478 virtual bool GetIterator( Iterator<w_entry_class_name> & o_iterator ) 00479 { 00480 w_error_traits::IteratorUndefined(); 00481 return false; 00482 } 00483 00484 }; 00485 00486 00487 // ======== ListElementBase ======================================== 00493 template< 00494 typename w_payload_class, 00495 typename w_default_mutex_type = List_EmptyMutex 00496 > 00497 class ListElementBase 00498 { 00499 public: 00500 00501 typedef w_default_mutex_type xW_DefaultMutexType; 00502 typedef w_payload_class xW_PayloadType; 00503 00504 virtual ~ListElementBase() 00505 { 00506 } 00507 00508 }; 00509 00510 00511 // ======== List_Traits ============================================ 00518 template <typename w_payload_type, typename w_accessor_traits> 00519 class List_Traits 00520 { 00521 public: 00522 00523 enum { 00524 00529 DoDereferenceCheck = 1 00530 }; 00531 00532 00533 // ======== ContainerDestructionNotification =============================== 00547 template < 00548 typename w_list_types 00549 > 00550 static inline bool ContainerDestructionNotification( 00551 typename w_list_types::xC_List_Entry * i_entry 00552 ) 00553 { 00554 i_entry->xF_RemoveSelf(); 00555 00556 return true; 00557 } // end ContainerDestructionNotification 00558 00559 00560 }; 00561 00562 00563 00564 // ======== List_Types ============================================= 00571 template < 00572 typename w_foward_class, 00573 typename w_base_class, 00574 typename w_accessor_traits, 00575 typename w_payload_type = typename w_base_class::xW_PayloadType, 00576 typename w_mutex_type = typename w_payload_type::xW_DefaultMutexType 00577 > 00578 class List_Types 00579 { 00580 public: 00581 00582 class xC_List_Head; 00583 typedef List_Types xC_List_Types; 00584 00585 00586 // ======== xC_List_Entry ========================================= 00593 class xC_List_Entry 00594 : public w_base_class 00595 { 00596 public: 00597 00598 typedef xC_List_Entry txC_List_Entry; 00599 typedef xC_List_Head txC_List_Head; 00600 typedef w_payload_type txW_PayloadType; 00601 typedef w_mutex_type txC_MutexType; 00602 typedef w_accessor_traits txC_List_Traits; 00603 typedef w_foward_class txW_Forward_Class; 00604 00605 typedef xC_List_Head list; 00606 00607 typedef xC_List_Entry * xC_List_Entry::* txC_Entry_MemberPtr; 00608 00609 inline bool xF_InList() 00610 { 00611 return m_head != 0; 00612 } 00613 00614 00615 // ======== xC_List_Entry ===================================== 00621 xC_List_Entry( const xC_List_Entry & i_other ) 00622 : m_head( 0 ) 00623 { 00624 } // end xC_List_Entry 00625 00626 // ======== operator = ( const xC_List_Entry & ) ============== 00632 xC_List_Entry & operator = ( const xC_List_Entry & i_other ) 00633 { 00634 return * this; 00635 } 00636 00637 00638 // ======== xF_Inserter ======================================= 00646 void xF_Inserter( 00647 xC_List_Entry * xC_List_Entry::* w_elem_pos, 00648 xC_List_Entry * xC_List_Entry::* w_elem_neg, 00649 xC_List_Entry * xC_List_Head::* w_head_pos, 00650 xC_List_Entry * xC_List_Head::* w_head_neg, 00651 xC_List_Entry * i_entry 00652 ) 00653 { 00654 00655 if ( i_entry->xF_InList() ) 00656 { 00657 i_entry->xF_RemoveSelf(); 00658 } 00659 00660 xC_List_Head * l_head = m_head; 00661 00662 AT_Assert( l_head != 0 ); 00663 00664 // this portion has to be performed in a lock 00665 { 00666 typename txC_MutexType::t_Lock l_lock( l_head->m_mutex ); 00667 00668 // 00669 // Use the same head 00670 // 00671 i_entry->m_head = l_head; 00672 00673 // increment count 00674 l_head->m_count ++; 00675 00676 // get what we're pointing to in our direction 00677 // 00678 xC_List_Entry * l_tmp = this->*w_elem_pos; 00679 00680 // we now point to the new object 00681 this->*w_elem_pos = i_entry; 00682 00683 // the new entry can now insert itself 00684 i_entry->*w_elem_neg = this; 00685 i_entry->*w_elem_pos = l_tmp; 00686 00687 // Now, if we were at the end of the list 00688 // we need to fix the head 00689 if ( l_tmp == 0 ) 00690 { 00691 l_head->*w_head_pos = i_entry; 00692 } 00693 else 00694 { 00695 l_tmp->*w_elem_neg = i_entry; 00696 } 00697 00698 } 00699 00700 } // end xF_Inserter 00701 00702 inline void xF_InsertBack( xC_List_Entry * i_entry ) 00703 { 00704 xF_Inserter(&xC_List_Entry::m_forw,&xC_List_Entry::m_back,&xC_List_Head::m_end,&xC_List_Head::m_begin, i_entry ); 00705 } 00706 00707 inline void xF_InsertForw( xC_List_Entry * i_entry ) 00708 { 00709 xF_Inserter(&xC_List_Entry::m_back,&xC_List_Entry::m_forw,&xC_List_Head::m_begin,&xC_List_Head::m_end, i_entry ); 00710 } 00711 00712 inline void xF_RemoveSelf() 00713 { 00714 // this portion has to be performed in a lock 00715 { 00716 typename txC_MutexType::t_Lock l_lock( m_head->m_mutex ); 00717 00718 00719 xC_List_Entry * l_back = m_back; 00720 xC_List_Entry * l_forw = m_forw; 00721 xC_List_Head * l_head = m_head; 00722 00723 // 00724 // remove it 00725 m_head = 0; 00726 l_head->m_count --; 00727 00728 if ( l_back == 0 ) 00729 { 00730 l_head->m_begin = l_forw; 00731 } 00732 else 00733 { 00734 l_back->m_forw = l_forw; 00735 } 00736 00737 if ( l_forw == 0 ) 00738 { 00739 l_head->m_end = l_back; 00740 } 00741 else 00742 { 00743 l_forw->m_back = l_back; 00744 } 00745 00746 } 00747 } 00748 00749 00750 // ======== xF_Unlink ========================================= 00761 inline bool xF_Unlink() 00762 { 00763 if ( xF_InList() ) 00764 { 00765 xF_RemoveSelf(); 00766 return true; 00767 } 00768 00769 return false; 00770 00771 } // end xF_Unlink 00772 00773 00774 ~xC_List_Entry() 00775 { 00776 xF_Unlink(); 00777 } 00778 00779 xC_List_Entry() 00780 : m_head( 0 ) 00781 { 00782 } 00783 00784 // 00785 // these three pointers point to the list entries. 00786 // 00787 00788 xC_List_Entry * m_back; 00789 xC_List_Entry * m_forw; 00790 xC_List_Head * m_head; 00791 00792 }; 00793 00794 00795 // ======== xC_List_Head ========================================== 00802 class xC_List_Head 00803 { 00804 public: 00805 00806 typedef xC_List_Entry txC_List_Entry; 00807 typedef w_mutex_type xW_MutexType; 00808 typedef xC_List_Entry * xC_List_Head::* txC_Head_MemberPtr; 00809 00810 // ======== iterator ========================================== 00817 typedef Iterator<xC_List_Entry> iterator; 00818 00819 void xF_Pusher( 00820 xC_List_Entry * xC_List_Entry::* w_elem_pos, 00821 xC_List_Entry * xC_List_Entry::* w_elem_neg, 00822 xC_List_Entry * xC_List_Head::* w_head_pos, 00823 xC_List_Entry * xC_List_Head::* w_head_neg, 00824 xC_List_Entry * i_entry 00825 ) 00826 { 00827 00828 if ( i_entry->xF_InList() ) 00829 { 00830 i_entry->xF_RemoveSelf(); 00831 } 00832 00833 { 00834 typename xW_MutexType::t_Lock l_lock( m_mutex ); 00835 00836 xC_List_Entry * l_pos = this->*w_head_pos; 00837 00838 // 00839 // if either pointer is nil, it indicates that the 00840 // list is empty - this being the first, we add it... 00841 if ( l_pos == 0 ) 00842 { 00843 00844 AT_Assert( m_count == 0 ); 00845 00846 i_entry->m_head = this; 00847 i_entry->m_back = 0; 00848 i_entry->m_forw = 0; 00849 00850 this->m_begin = i_entry; 00851 this->m_end = i_entry; 00852 this->m_count = 1; 00853 00854 } 00855 else 00856 { 00857 // 00858 // use the inserter to insert now. 00859 l_pos->xF_Inserter( w_elem_pos, w_elem_neg, w_head_pos, w_head_neg, i_entry ); 00860 } 00861 00862 } 00863 00864 } 00865 00866 inline void push_back( typename xC_List_Entry::txW_Forward_Class & i_entry ) 00867 { 00868 xF_Pusher( 00869 &xC_List_Entry::m_forw,&xC_List_Entry::m_back,&xC_List_Head::m_end,&xC_List_Head::m_begin, 00870 static_cast< xC_List_Entry * >( & i_entry ) 00871 ); 00872 } 00873 00874 inline void push_front( typename xC_List_Entry::txW_Forward_Class & i_entry ) 00875 { 00876 xF_Pusher( 00877 &xC_List_Entry::m_back,&xC_List_Entry::m_forw,&xC_List_Head::m_begin,&xC_List_Head::m_end, 00878 static_cast< xC_List_Entry * >( & i_entry ) 00879 ); 00880 } 00881 00882 inline void push_back( iterator i_entry ) 00883 { 00884 xF_Pusher( 00885 &xC_List_Entry::m_forw,&xC_List_Entry::m_back,&xC_List_Head::m_end,&xC_List_Head::m_begin, 00886 i_entry.Dereference() 00887 ); 00888 } 00889 00890 inline void push_front( iterator i_entry ) 00891 { 00892 xF_Pusher( 00893 &xC_List_Entry::m_back,&xC_List_Entry::m_forw,&xC_List_Head::m_begin,&xC_List_Head::m_end, 00894 i_entry.Dereference() 00895 ); 00896 } 00897 00898 inline iterator begin() 00899 { 00900 iterator l_iter; 00901 00902 xC_List_Entry * l_begin = m_begin; 00903 00904 if ( l_begin == 0 ) 00905 { 00906 l_iter.m_pointer = iterator::xF_EndIterator( this ); 00907 } 00908 else 00909 { 00910 l_iter.m_pointer = l_begin; 00911 } 00912 00913 return l_iter; 00914 } 00915 00916 inline iterator end() 00917 { 00918 iterator l_iter; 00919 00920 l_iter.m_pointer = iterator::xF_EndIterator( this ); 00921 00922 return l_iter; 00923 } 00924 00925 inline Uint32 size() 00926 { 00927 return m_count; 00928 } 00929 00930 xC_List_Head() 00931 : m_begin( 0 ), 00932 m_end( 0 ), 00933 m_count( 0 ) 00934 { 00935 } 00936 00937 00938 ~xC_List_Head() 00939 { 00940 // this is where we keep on asking each entry to 00941 // delete/remove themselves - it may do whatever 00942 // it likes just as long as it unlinks itself. 00943 00944 for ( xC_List_Entry * l_entry = m_begin; l_entry != 0; l_entry = m_begin ) 00945 { 00946 // 00947 // this is where we call a user provided method to perform 00948 // the action. 00949 // 00950 00951 // List_Traits<w_payload_type,ListNothing_Basic> 00952 w_accessor_traits::template ContainerDestructionNotification< xC_List_Types >( l_entry ); 00953 // l_entry->xF_RemoveSelf(); 00954 00955 } 00956 00957 } 00958 00959 // 00960 // member data for the list head 00961 // 00962 00963 xC_List_Entry * m_begin; 00964 xC_List_Entry * m_end; 00965 Uint32 m_count; 00966 xW_MutexType m_mutex; 00967 00968 }; 00969 00970 }; 00971 00972 00973 00974 // ======== List1 ================================================== 00982 template < 00983 typename w_app_class, 00984 typename w_default_mutex_type = List_EmptyMutex 00985 > 00986 class List1 00987 { 00988 public: 00989 00990 typedef w_app_class xW_App_Class; 00991 00992 // 00993 // Forward declare some critical classes 00994 // 00995 class xC_Parent; 00996 typedef typename xW_App_Class::template Payload< xC_Parent > Payload; 00997 class xC_ListEntry_1; 00998 typedef xC_ListEntry_1 Apogee; 00999 01000 // 01001 // create a few typedefs for making things visible 01002 typedef typename xW_App_Class::Error_Traits xC_Error_Traits; 01003 typedef typename xW_App_Class::template Entry_1_Traits<Payload> xC_Entry_1_Traits; 01004 01005 class xC_Parent 01006 { 01007 public: 01008 01009 typedef w_default_mutex_type xW_DefaultMutexType; 01010 typedef Payload xW_PayloadType; 01011 typedef List1<w_app_class,w_default_mutex_type> xW_Wapper; 01012 01013 virtual ~xC_Parent() {} 01014 01015 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) = 0; 01016 01017 }; 01018 01019 class xC_ListEntry_1 01020 : public List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Entry 01021 { 01022 public: 01023 01024 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) 01025 { 01026 o_iterator.m_pointer = this; 01027 return true; 01028 } 01029 01030 }; 01031 01032 typedef typename List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Head list_1; 01033 01034 }; 01035 01036 // ======== List2 ================================================== 01044 template < 01045 typename w_app_class, 01046 typename w_default_mutex_type = List_EmptyMutex 01047 > 01048 class List2 01049 { 01050 public: 01051 01052 typedef w_app_class xW_App_Class; 01053 01054 // 01055 // Forward declare some critical classes 01056 // 01057 class xC_Parent; 01058 typedef typename xW_App_Class::template Payload< xC_Parent > Payload; 01059 class xC_ListEntry_1; 01060 class xC_ListEntry_2; 01061 class Apogee; 01062 01063 // 01064 // create a few typedefs for making things visible 01065 typedef typename xW_App_Class::Error_Traits xC_Error_Traits; 01066 typedef typename xW_App_Class::template Entry_1_Traits<Payload> xC_Entry_1_Traits; 01067 typedef typename xW_App_Class::template Entry_2_Traits<Payload> xC_Entry_2_Traits; 01068 01069 class xC_Parent 01070 { 01071 public: 01072 01073 typedef w_default_mutex_type xW_DefaultMutexType; 01074 typedef Payload xW_PayloadType; 01075 typedef List2<w_app_class,w_default_mutex_type> xW_Wapper; 01076 01077 virtual ~xC_Parent() {} 01078 01079 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) = 0; 01080 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) = 0; 01081 01082 }; 01083 01084 class xC_ListEntry_1 01085 : public List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Entry 01086 { 01087 public: 01088 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01089 }; 01090 01091 class xC_ListEntry_2 01092 : public List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Entry 01093 { 01094 public: 01095 01096 }; 01097 01098 class Apogee 01099 : public xC_ListEntry_2 01100 { 01101 public: 01102 01103 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) 01104 { 01105 o_iterator.m_pointer = static_cast< xC_ListEntry_1 * >( this ); 01106 return true; 01107 } 01108 01109 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) 01110 { 01111 o_iterator.m_pointer = static_cast< xC_ListEntry_2 * >( this ); 01112 return true; 01113 } 01114 }; 01115 01116 typedef typename List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Head list_1; 01117 typedef typename List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Head list_2; 01118 01119 template < 01120 typename w_list_type 01121 > 01122 static typename w_list_type::iterator GetIterator( xC_Parent & i_base ) 01123 { 01124 typedef typename w_list_type::txC_List_Entry::txW_Forward_Class t_entry_base; 01125 Iterator< t_entry_base > l_iterator; 01126 01127 i_base.GetIterator( l_iterator ); 01128 01129 return l_iterator; 01130 } 01131 01132 template < 01133 typename w_list_type 01134 > 01135 static typename w_list_type::iterator GetIterator( const w_list_type & i_list, xC_Parent & i_base ) 01136 { 01137 return GetIterator<w_list_type>( i_base ); 01138 } 01139 }; 01140 01141 // ======== List3 ================================================== 01149 template < 01150 typename w_app_class, 01151 typename w_default_mutex_type = List_EmptyMutex 01152 > 01153 class List3 01154 { 01155 public: 01156 01157 typedef w_app_class xW_App_Class; 01158 01159 // 01160 // Forward declare some critical classes 01161 // 01162 class xC_Parent; 01163 typedef typename xW_App_Class::template Payload< xC_Parent > Payload; 01164 class xC_ListEntry_1; 01165 class xC_ListEntry_2; 01166 class xC_ListEntry_3; 01167 class Apogee; 01168 01169 // 01170 // create a few typedefs for making things visible 01171 typedef typename xW_App_Class::Error_Traits xC_Error_Traits; 01172 typedef typename xW_App_Class::template Entry_1_Traits<Payload> xC_Entry_1_Traits; 01173 typedef typename xW_App_Class::template Entry_2_Traits<Payload> xC_Entry_2_Traits; 01174 typedef typename xW_App_Class::template Entry_3_Traits<Payload> xC_Entry_3_Traits; 01175 01176 class xC_Parent 01177 { 01178 public: 01179 01180 typedef w_default_mutex_type xW_DefaultMutexType; 01181 typedef Payload xW_PayloadType; 01182 typedef List3<w_app_class,w_default_mutex_type> xW_Wapper; 01183 01184 virtual ~xC_Parent() {} 01185 01186 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) = 0; 01187 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) = 0; 01188 virtual bool GetIterator( Iterator<xC_ListEntry_3> & o_iterator ) = 0; 01189 01190 }; 01191 01192 class xC_ListEntry_1 01193 : public List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Entry 01194 { 01195 public: 01196 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01197 }; 01198 01199 class xC_ListEntry_2 01200 : public List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Entry 01201 { 01202 public: 01203 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01204 }; 01205 01206 class xC_ListEntry_3 01207 : public List_Types< xC_ListEntry_3, xC_ListEntry_2, xC_Entry_3_Traits >::xC_List_Entry 01208 { 01209 public: 01210 01211 }; 01212 01213 class Apogee 01214 : public xC_ListEntry_3 01215 { 01216 public: 01217 01218 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) 01219 { 01220 o_iterator.m_pointer = static_cast< xC_ListEntry_1 * >( this ); 01221 return true; 01222 } 01223 01224 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) 01225 { 01226 o_iterator.m_pointer = static_cast< xC_ListEntry_2 * >( this ); 01227 return true; 01228 } 01229 01230 virtual bool GetIterator( Iterator<xC_ListEntry_3> & o_iterator ) 01231 { 01232 o_iterator.m_pointer = static_cast< xC_ListEntry_3 * >( this ); 01233 return true; 01234 } 01235 }; 01236 01237 typedef typename List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Head list_1; 01238 typedef typename List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Head list_2; 01239 typedef typename List_Types< xC_ListEntry_3, xC_ListEntry_2, xC_Entry_3_Traits >::xC_List_Head list_3; 01240 01241 template < 01242 typename w_list_type 01243 > 01244 static typename w_list_type::iterator GetIterator( xC_Parent & i_base ) 01245 { 01246 typedef typename w_list_type::txC_List_Entry::txW_Forward_Class t_entry_base; 01247 Iterator< t_entry_base > l_iterator; 01248 01249 i_base.GetIterator( l_iterator ); 01250 01251 return l_iterator; 01252 } 01253 01254 template < 01255 typename w_list_type 01256 > 01257 static typename w_list_type::iterator GetIterator( const w_list_type & i_list, xC_Parent & i_base ) 01258 { 01259 return GetIterator<w_list_type>( i_base ); 01260 } 01261 }; 01262 01263 // ======== List4 ================================================== 01271 template < 01272 typename w_app_class, 01273 typename w_default_mutex_type = List_EmptyMutex 01274 > 01275 class List4 01276 { 01277 public: 01278 01279 typedef w_app_class xW_App_Class; 01280 01281 // 01282 // Forward declare some critical classes 01283 // 01284 class xC_Parent; 01285 typedef typename xW_App_Class::template Payload< xC_Parent > Payload; 01286 class xC_ListEntry_1; 01287 class xC_ListEntry_2; 01288 class xC_ListEntry_3; 01289 class xC_ListEntry_4; 01290 class Apogee; 01291 01292 // 01293 // create a few typedefs for making things visible 01294 typedef typename xW_App_Class::Error_Traits xC_Error_Traits; 01295 typedef typename xW_App_Class::template Entry_1_Traits<Payload> xC_Entry_1_Traits; 01296 typedef typename xW_App_Class::template Entry_2_Traits<Payload> xC_Entry_2_Traits; 01297 typedef typename xW_App_Class::template Entry_3_Traits<Payload> xC_Entry_3_Traits; 01298 typedef typename xW_App_Class::template Entry_4_Traits<Payload> xC_Entry_4_Traits; 01299 01300 class xC_Parent 01301 { 01302 public: 01303 01304 typedef w_default_mutex_type xW_DefaultMutexType; 01305 typedef Payload xW_PayloadType; 01306 typedef List4<w_app_class,w_default_mutex_type> xW_Wapper; 01307 01308 virtual ~xC_Parent() {} 01309 01310 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) = 0; 01311 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) = 0; 01312 virtual bool GetIterator( Iterator<xC_ListEntry_3> & o_iterator ) = 0; 01313 virtual bool GetIterator( Iterator<xC_ListEntry_4> & o_iterator ) = 0; 01314 01315 }; 01316 01317 class xC_ListEntry_1 01318 : public List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Entry 01319 { 01320 public: 01321 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01322 }; 01323 01324 class xC_ListEntry_2 01325 : public List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Entry 01326 { 01327 public: 01328 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01329 }; 01330 01331 class xC_ListEntry_3 01332 : public List_Types< xC_ListEntry_3, xC_ListEntry_2, xC_Entry_3_Traits >::xC_List_Entry 01333 { 01334 public: 01335 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01336 }; 01337 01338 class xC_ListEntry_4 01339 : public List_Types< xC_ListEntry_4, xC_ListEntry_3, xC_Entry_4_Traits >::xC_List_Entry 01340 { 01341 public: 01342 typedef Payload xW_PayloadType; //-- workaround VC++7.1 bug 01343 }; 01344 01345 class Apogee 01346 : public xC_ListEntry_4 01347 { 01348 public: 01349 01350 virtual bool GetIterator( Iterator<xC_ListEntry_1> & o_iterator ) 01351 { 01352 o_iterator.m_pointer = static_cast< xC_ListEntry_1 * >( this ); 01353 return true; 01354 } 01355 01356 virtual bool GetIterator( Iterator<xC_ListEntry_2> & o_iterator ) 01357 { 01358 o_iterator.m_pointer = static_cast< xC_ListEntry_2 * >( this ); 01359 return true; 01360 } 01361 01362 virtual bool GetIterator( Iterator<xC_ListEntry_3> & o_iterator ) 01363 { 01364 o_iterator.m_pointer = static_cast< xC_ListEntry_3 * >( this ); 01365 return true; 01366 } 01367 01368 virtual bool GetIterator( Iterator<xC_ListEntry_4> & o_iterator ) 01369 { 01370 o_iterator.m_pointer = static_cast< xC_ListEntry_4 * >( this ); 01371 return true; 01372 } 01373 }; 01374 01375 typedef typename List_Types< xC_ListEntry_1, Payload, xC_Entry_1_Traits >::xC_List_Head list_1; 01376 typedef typename List_Types< xC_ListEntry_2, xC_ListEntry_1, xC_Entry_2_Traits >::xC_List_Head list_2; 01377 typedef typename List_Types< xC_ListEntry_3, xC_ListEntry_2, xC_Entry_3_Traits >::xC_List_Head list_3; 01378 typedef typename List_Types< xC_ListEntry_4, xC_ListEntry_3, xC_Entry_4_Traits >::xC_List_Head list_4; 01379 01380 template < 01381 typename w_list_type 01382 > 01383 static typename w_list_type::iterator GetIterator( xC_Parent & i_base ) 01384 { 01385 typedef typename w_list_type::txC_List_Entry::txW_Forward_Class t_entry_base; 01386 Iterator< t_entry_base > l_iterator; 01387 01388 i_base.GetIterator( l_iterator ); 01389 01390 return l_iterator; 01391 } 01392 01393 template < 01394 typename w_list_type 01395 > 01396 static typename w_list_type::iterator GetIterator( const w_list_type & i_list, xC_Parent & i_base ) 01397 { 01398 return GetIterator<w_list_type>( i_base ); 01399 } 01400 }; 01401 01402 // ======== Default_List_Traits ==================================== 01408 class Default_List_Traits 01409 { 01410 public: 01411 01412 typedef List_Error_Traits Error_Traits; 01413 01414 template < 01415 typename w_container_wrapper 01416 > 01417 class Entry_1_Traits 01418 : public List_Traits< w_container_wrapper, ListNothing_Basic > 01419 { 01420 }; 01421 01422 template < 01423 typename w_container_wrapper 01424 > 01425 class Entry_2_Traits 01426 : public List_Traits< w_container_wrapper, ListNothing_Basic > 01427 { 01428 }; 01429 01430 template < 01431 typename w_container_wrapper 01432 > 01433 class Entry_3_Traits 01434 : public List_Traits< w_container_wrapper, ListNothing_Basic > 01435 { 01436 }; 01437 01438 template < 01439 typename w_container_wrapper 01440 > 01441 class Entry_4_Traits 01442 : public List_Traits< w_container_wrapper, ListNothing_Basic > 01443 { 01444 }; 01445 01446 }; 01447 01448 01449 // end FlexibleList 01454 }; // namespace 01455 #endif // x_at_list_h_x 01456 01457
Generated for Austria by
and
MakeXS at Sun Oct 24 17:35:34 PDT 2004