00001 #ifndef CPPUTTOOLS_ENUMERATOR_H_INCLUDED
00002 # define CPPUTTOOLS_ENUMERATOR_H_INCLUDED
00003
00004 # include <cpptl/typetraits.h>
00005 # include <stdexcept>
00006
00007
00008 #define CPPTL_ENUMERATOR_CHECK_CURRENT \
00009 CPPTL_ASSERT_MESSAGE( is_open(), \
00010 "Attempt to access current element on closed enumerator." )
00011
00012 #define CPPTL_ENUMERATOR_CHECK_ADVANCE \
00013 CPPTL_ASSERT_MESSAGE( is_open(), \
00014 "Attempt to advance enumerator past its end." )
00015
00016 namespace CppTL {
00017
00018 template<class IteratorType>
00019 struct STLIteratorTraits
00020 {
00021 typedef CPPTL_TYPENAME IteratorType::value_type value_type;
00022 };
00023
00024 # ifndef CPPTL_NO_TEMPLATE_PARTIAL_SPECIALIZATION
00025 template<class ValueType>
00026 struct STLIteratorTraits<ValueType *>
00027 {
00028 typedef ValueType value_type;
00029 };
00030 # endif
00031
00032 }
00033
00034
00035 namespace CppTL { namespace Enum {
00036
00038 namespace Impl
00039 {
00040 template<class Fn1, class Fn2, class ValueType>
00041 struct ComposeFn
00042 {
00043 typedef CPPTL_TYPENAME Fn1::result_type result_type;
00044
00045 ComposeFn( Fn1 fn1= Fn1(), Fn2 fn2= Fn2() )
00046 : fn1_( fn1 )
00047 , fn2_( fn2 )
00048 {
00049 }
00050
00051 CPPTL_TYPENAME Fn1::result_type operator()( const ValueType &value ) const
00052 {
00053 return fn1_( fn2_( value ) );
00054 }
00055
00056 private:
00057 Fn1 fn1_;
00058 Fn2 fn2_;
00059 };
00060
00061 }
00063
00064 }
00065
00066
00067
00068
00069 class StopEnumerationError : public std::out_of_range
00070 {
00071 public:
00072 StopEnumerationError()
00073 : std::out_of_range( "Enumerator::next() called with no next item." )
00074 {
00075 }
00076
00077 ~StopEnumerationError() throw()
00078 {
00079 }
00080 };
00081
00082
00083 class EnumeratorBase
00084 {
00085 public:
00086 static void stopEnumeration()
00087 {
00088 throw StopEnumerationError();
00089 }
00090 };
00091
00092 template<class EnumeratorType>
00093 void assertEnumeratorHasNext( const EnumeratorType &enumerator )
00094 {
00095 # ifndef NDEBUG
00096 if ( !enumerator.hasNext() )
00097 enumerator.stopEnumeration();
00098 # endif
00099 }
00100
00101 template<class EnumValueType>
00102 class TypeEnumeratorBase : public EnumeratorBase
00103 {
00104 public:
00105 typedef EnumValueType value_type;
00106 };
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00133 #if 0
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 #endif
00185
00186
00187
00188
00189
00190
00191
00192
00193 # define CPPTL_IMPL_ENUMERATOR \
00194 bool hasNext() const \
00195 { \
00196 return is_open(); \
00197 } \
00198 \
00199 value_type next() \
00200 { \
00201 value_type value = current(); \
00202 advance(); \
00203 return value; \
00204 } \
00205 \
00206 value_type operator *() const \
00207 { \
00208 return current(); \
00209 } \
00210 \
00211 self_type &operator ++() \
00212 { \
00213 return advance(); \
00214 } \
00215 \
00216 self_type operator ++( int ) \
00217 { \
00218 self_type old = *this; \
00219 advance(); \
00220 return old; \
00221 }
00222
00223
00224
00225 template<class ValueType>
00226 class EmptyEnumerator
00227 {
00228 public:
00229 typedef ValueType value_type;
00230 typedef EmptyEnumerator<ValueType> self_type;
00231
00232 CPPTL_IMPL_ENUMERATOR
00233
00234 bool is_open() const
00235 {
00236 return false;
00237 }
00238
00239 value_type current() const
00240 {
00241 CPPTL_ENUMERATOR_CHECK_CURRENT;
00242 throw StopEnumerationError();
00243 }
00244
00245 EmptyEnumerator &advance()
00246 {
00247 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00248 return *this;
00249 }
00250 };
00251
00252
00253
00254 template< class ForwardItType
00255 , class ForwardItValueType =
00256 CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME STLIteratorTraits<ForwardItType>::value_type>::type
00257 >
00258 class ForwardItEnumeratorBase
00259 {
00260 public:
00261 ForwardItEnumeratorBase()
00262 : current_()
00263 , end_()
00264 {
00265 }
00266
00267 ForwardItEnumeratorBase( const ForwardItType &begin,
00268 const ForwardItType &end )
00269 : current_( begin )
00270 , end_( end )
00271 {
00272 }
00273
00274 protected:
00275 ForwardItType current_;
00276 ForwardItType end_;
00277 };
00278
00279
00280 template< class ForwardItType
00281 , class ForwardItValueType =
00282 CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME STLIteratorTraits<ForwardItType>::value_type>::type
00283 >
00284 class ForwardItEnumerator
00285 : public ForwardItEnumeratorBase< ForwardItType
00286 , ForwardItValueType >
00287 {
00288 public:
00289 typedef ForwardItValueType value_type;
00290 typedef ForwardItEnumerator<ForwardItType,ForwardItValueType> self_type;
00291 typedef ForwardItEnumeratorBase< ForwardItType
00292 , ForwardItValueType > Super;
00293 CPPTL_IMPL_ENUMERATOR
00294
00295 ForwardItEnumerator()
00296 {
00297 }
00298
00299 ForwardItEnumerator( const ForwardItType &begin,
00300 const ForwardItType &end )
00301 : Super( begin, end )
00302 {
00303 }
00304
00305 bool is_open() const
00306 {
00307 return Super::current_ != Super::end_;
00308 }
00309
00310 value_type current() const
00311 {
00312 CPPTL_ENUMERATOR_CHECK_CURRENT;
00313 return *Super::current_;
00314 }
00315
00316 ForwardItEnumerator &advance()
00317 {
00318 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00319 ++(Super::current_);
00320 return *this;
00321 }
00322 };
00323
00324
00325 template< class ForwardItType
00326 , class TransformFn >
00327 class TransformForwardItEnumerator
00328 : public ForwardItEnumeratorBase< ForwardItType
00329 , CPPTL_TYPENAME TransformFn::result_type >
00330 {
00331 public:
00332 typedef CPPTL_TYPENAME TransformFn::result_type value_type;
00333 typedef TransformForwardItEnumerator<ForwardItType,TransformFn> self_type;
00334 typedef ForwardItEnumeratorBase< ForwardItType
00335 , CPPTL_TYPENAME TransformFn::result_type > Super;
00336
00337 CPPTL_IMPL_ENUMERATOR
00338
00339 TransformForwardItEnumerator()
00340 {
00341 }
00342
00343 TransformForwardItEnumerator( const ForwardItType &begin,
00344 const ForwardItType &end )
00345 : Super( begin, end )
00346 {
00347 }
00348
00349 TransformForwardItEnumerator( const ForwardItType &begin,
00350 const ForwardItType &end,
00351 TransformFn transform )
00352 : Super( begin, end )
00353 , transform_( transform )
00354 {
00355 }
00356
00357 bool is_open() const
00358 {
00359 return Super::current_ != Super::end_;
00360 }
00361
00362 value_type current() const
00363 {
00364 CPPTL_ENUMERATOR_CHECK_CURRENT;
00365 return transform_( *Super::current_ );
00366 }
00367
00368 TransformForwardItEnumerator &advance()
00369 {
00370 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00371 ++(Super::current_);
00372 return *this;
00373 }
00374
00375 protected:
00376 TransformFn transform_;
00377 };
00378
00379
00380
00381 template< class STLContainerType
00382 , class ValueType = CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME STLContainerType::value_type>::type >
00383 class ContainerEnumerator :
00384 public ForwardItEnumerator< CPPTL_TYPENAME STLContainerType::const_iterator
00385 , ValueType>
00386 {
00387 public:
00388 typedef ValueType value_type;
00389 typedef ContainerEnumerator<STLContainerType,ValueType> self_type;
00390 typedef ForwardItEnumerator< CPPTL_TYPENAME STLContainerType::const_iterator
00391 , ValueType> Super;
00392 typedef CPPTL_TYPENAME STLContainerType::const_iterator ContainerConstIterator;
00393
00394 ContainerEnumerator()
00395 {
00396 }
00397
00398 ContainerEnumerator( const STLContainerType &sequence )
00399 : Super( sequence.begin(), sequence.end() )
00400 {
00401 }
00402
00403 ContainerEnumerator( ContainerConstIterator begin, ContainerConstIterator end )
00404 : Super( begin, end )
00405 {
00406 }
00407
00408 ContainerEnumerator( const Super &other )
00409 : Super( other )
00410 {
00411 }
00412
00413 ContainerEnumerator &advance()
00414 {
00415 Super::advance();
00416 return *this;
00417 }
00418
00419 ContainerEnumerator &operator ++()
00420 {
00421 Super::operator ++();
00422 return *this;
00423 }
00424
00425 ContainerEnumerator<STLContainerType,ValueType> operator ++( int )
00426 {
00427 return ContainerEnumerator<STLContainerType,ValueType>( Super::operator ++( 1 ) );
00428 }
00429 };
00430
00431
00432 template<class Adaptor
00433 ,class AdaptedEnumeratorType >
00434 class TransformEnumerator
00435 {
00436 public:
00437 typedef CPPTL_TYPENAME Adaptor::result_type value_type;
00438 typedef TransformEnumerator<Adaptor,AdaptedEnumeratorType> self_type;
00439
00440 CPPTL_IMPL_ENUMERATOR
00441
00442 TransformEnumerator()
00443 {
00444 }
00445
00446 TransformEnumerator( const AdaptedEnumeratorType &other )
00447 : enumerator_( other )
00448 {
00449 }
00450
00451 TransformEnumerator( const AdaptedEnumeratorType &other,
00452 Adaptor adaptor )
00453 : enumerator_( other )
00454 , adaptor_( adaptor )
00455 {
00456 }
00457
00458 bool is_open() const
00459 {
00460 return enumerator_.is_open();
00461 }
00462
00463 value_type current() const
00464 {
00465 return adaptor_( enumerator_.current() );
00466 }
00467
00468 TransformEnumerator &advance()
00469 {
00470 enumerator_.advance();
00471 return *this;
00472 }
00473
00474 protected:
00475 AdaptedEnumeratorType enumerator_;
00476 Adaptor adaptor_;
00477 };
00478
00479
00480 template< class MapIteratorType
00481 , class ValueType =
00482 CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME MapIteratorType::value_type::first_type>::type >
00483 class MapKeysEnumerator : public ForwardItEnumeratorBase< MapIteratorType, ValueType >
00484 {
00485 public:
00486 typedef ValueType value_type;
00487 typedef MapKeysEnumerator<MapIteratorType,ValueType> self_type;
00488 typedef ForwardItEnumeratorBase< MapIteratorType, ValueType > Super;
00489
00490 CPPTL_IMPL_ENUMERATOR
00491
00492 MapKeysEnumerator()
00493 {
00494 }
00495
00496 MapKeysEnumerator( MapIteratorType begin, MapIteratorType end )
00497 : Super( begin, end )
00498 {
00499 }
00500
00501 MapKeysEnumerator( const Super &other )
00502 : Super( other )
00503 {
00504 }
00505
00506 MapKeysEnumerator &operator =( const Super &other )
00507 {
00508 Super::operator =( other );
00509 return *this;
00510 }
00511
00512 bool is_open() const
00513 {
00514 return Super::current_ != Super::end_;
00515 }
00516
00517 value_type current() const
00518 {
00519 CPPTL_ENUMERATOR_CHECK_CURRENT;
00520 return Super::current_->first;
00521 }
00522
00523 MapKeysEnumerator &advance()
00524 {
00525 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00526 ++(Super::current_);
00527 return *this;
00528 }
00529 };
00530
00531
00532 template< class MapIteratorType
00533 , class ValueType =
00534 CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME MapIteratorType::value_type::second_type>::type >
00535 class MapValuesEnumerator : public ForwardItEnumeratorBase< MapIteratorType, ValueType >
00536 {
00537 public:
00538 typedef ValueType value_type;
00539 typedef MapValuesEnumerator<MapIteratorType,ValueType> self_type;
00540 typedef ForwardItEnumeratorBase< MapIteratorType, ValueType > Super;
00541
00542 CPPTL_IMPL_ENUMERATOR
00543
00544 MapValuesEnumerator()
00545 {
00546 }
00547
00548 MapValuesEnumerator( MapIteratorType begin, MapIteratorType end )
00549 : Super( begin, end )
00550 {
00551 }
00552
00553 MapValuesEnumerator( const Super &other )
00554 : Super( other )
00555 {
00556 }
00557
00558 MapValuesEnumerator &operator =( const Super &other )
00559 {
00560 Super::operator =( other );
00561 return *this;
00562 }
00563
00564 bool is_open() const
00565 {
00566 return Super::current_ != Super::end_;
00567 }
00568
00569 value_type current() const
00570 {
00571 CPPTL_ENUMERATOR_CHECK_CURRENT;
00572 return Super::current_->second;
00573 }
00574
00575 MapValuesEnumerator &advance()
00576 {
00577 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00578 ++(Super::current_);
00579 return *this;
00580 }
00581 };
00582
00583
00584 template<class FilteredEnumerator
00585 ,class FilterPredicate>
00586 class FilterEnumerator
00587 {
00588 public:
00589 typedef CPPTL_TYPENAME FilteredEnumerator::value_type value_type;
00590 typedef FilterEnumerator<FilteredEnumerator,FilterPredicate> self_type;
00591
00592 CPPTL_IMPL_ENUMERATOR
00593
00594 FilterEnumerator()
00595 {
00596 }
00597
00598 FilterEnumerator( const FilteredEnumerator &enumerator,
00599 FilterPredicate filter = FilterPredicate() )
00600 : enumerator_( enumerator )
00601 , filter_( filter )
00602 {
00603 while ( enumerator_.is_open() && !filter_( enumerator_.current() ) )
00604 enumerator_.advance();
00605 }
00606
00607 bool is_open() const
00608 {
00609 return enumerator_.is_open();
00610 }
00611
00612 value_type current() const
00613 {
00614 CPPTL_ENUMERATOR_CHECK_CURRENT;
00615 return enumerator_.current();
00616 }
00617
00618 FilterEnumerator &advance()
00619 {
00620 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00621 enumerator_.advance();
00622 while ( enumerator_.is_open() && !filter_( enumerator_.current() ) )
00623 enumerator_.advance();
00624 return *this;
00625 }
00626
00627 private:
00628 FilteredEnumerator enumerator_;
00629 FilterPredicate filter_;
00630 };
00631
00632
00633 template<class EnumeratorType>
00634 class SliceEnumerator
00635 {
00636 public:
00637 typedef CPPTL_TYPENAME EnumeratorType::value_type value_type;
00638 typedef SliceEnumerator<EnumeratorType> self_type;
00639
00640 CPPTL_IMPL_ENUMERATOR
00641
00642 typedef unsigned int size_t;
00643
00644 SliceEnumerator()
00645 : length_(0)
00646 {
00647 }
00648
00649 SliceEnumerator( const EnumeratorType &enumerator,
00650 size_t begin,
00651 size_t end )
00652 : length_( end >= begin ? end-begin : 0 )
00653 , enumerator_( enumerator )
00654 {
00655 if ( length_ > 0 )
00656 while ( begin-- > 0 && enumerator_.is_open() )
00657 enumerator_.advance();
00658 }
00659
00660 bool is_open() const
00661 {
00662 return length_ > 0 && enumerator_.is_open();
00663 }
00664
00665 value_type current() const
00666 {
00667 CPPTL_ENUMERATOR_CHECK_CURRENT;
00668 return enumerator_.current();
00669 }
00670
00671 SliceEnumerator &advance()
00672 {
00673 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00674 enumerator_.advance();
00675 --length_;
00676 return *this;
00677 }
00678
00679 private:
00680 EnumeratorType enumerator_;
00681 size_t length_;
00682 };
00683
00684
00685 template<class ValueType>
00686 class AnyEnumeratorBase
00687 {
00688 public:
00689 typedef ValueType value_type;
00690
00691 virtual ~AnyEnumeratorBase()
00692 {
00693 }
00694
00695 virtual bool is_open() const = 0;
00696
00697 virtual ValueType current() const = 0;
00698
00699 virtual void advance() = 0;
00700
00701 virtual AnyEnumeratorBase *clone() const = 0;
00702 };
00703
00704
00705 template< class EnumeratorType
00706 , class ValueType = CPPTL_TYPENAME EnumeratorType::value_type >
00707 class AnyEnumeratorImpl : public AnyEnumeratorBase<ValueType>
00708 {
00709 public:
00710 typedef AnyEnumeratorImpl<EnumeratorType,ValueType> ClassType;
00711 typedef AnyEnumeratorBase<ValueType> Super;
00712
00713 AnyEnumeratorImpl()
00714 {
00715 }
00716
00717 AnyEnumeratorImpl( const EnumeratorType &enumerator )
00718 : enumerator_( enumerator )
00719 {
00720 }
00721
00722 public:
00723 bool is_open() const
00724 {
00725 return enumerator_.is_open();
00726 }
00727
00728 ValueType current() const
00729 {
00730 return enumerator_.current();
00731 }
00732
00733 void advance()
00734 {
00735 enumerator_.advance();
00736 }
00737
00738 Super *clone() const
00739 {
00740 return new ClassType( enumerator_ );
00741 }
00742
00743 protected:
00744 EnumeratorType enumerator_;
00745 };
00746
00747
00748
00749 template<class ValueType>
00750 class AnyEnumerator
00751 {
00752 public:
00753 typedef ValueType value_type;
00754 typedef AnyEnumerator<ValueType> self_type;
00755 typedef AnyEnumeratorBase<ValueType> *Ptr;
00756
00757 CPPTL_IMPL_ENUMERATOR
00758
00759 AnyEnumerator()
00760 : enumerator_( new AnyEnumeratorImpl< EmptyEnumerator<ValueType> >() )
00761 {
00762 }
00763
00764 explicit AnyEnumerator( Ptr enumerator )
00765 : enumerator_( enumerator )
00766 {
00767 }
00768
00769 AnyEnumerator( const AnyEnumerator &other )
00770 : enumerator_( other.enumerator_->clone() )
00771 {
00772 }
00773
00774 AnyEnumerator &operator =( const AnyEnumerator &other )
00775 {
00776 AnyEnumerator temp( *this );
00777 swap( temp );
00778 return *this;
00779 }
00780
00781 ~AnyEnumerator()
00782 {
00783 delete enumerator_;
00784 }
00785
00786 void swap( AnyEnumerator &other )
00787 {
00788 Ptr temp = enumerator_;
00789 enumerator_ = other.enumerator_;
00790 other.enumerator_ = temp;
00791 }
00792
00793 bool is_open() const
00794 {
00795 return enumerator_->is_open();
00796 }
00797
00798 ValueType current() const
00799 {
00800 return enumerator_->current();
00801 }
00802
00803 void advance()
00804 {
00805 enumerator_->advance();
00806 }
00807
00808 protected:
00809 Ptr enumerator_;
00810 };
00811
00812
00813 template<class ThinEnumeratorType
00814 ,class ValueType = CPPTL_TYPENAME ThinEnumeratorType::value_type >
00815 class SugarEnumerator
00816 {
00817 public:
00818 typedef ValueType value_type;
00819 typedef SugarEnumerator<ThinEnumeratorType> self_type;
00820
00821 CPPTL_IMPL_ENUMERATOR
00822
00823 SugarEnumerator()
00824 {
00825 }
00826
00827 SugarEnumerator( const ThinEnumeratorType &enumerator )
00828 : enumerator_( enumerator )
00829 {
00830 }
00831
00832 bool is_open() const
00833 {
00834 return enumerator_.is_open();
00835 }
00836
00837 value_type current() const
00838 {
00839 CPPTL_ENUMERATOR_CHECK_CURRENT;
00840 return enumerator_.current();
00841 }
00842
00843 self_type &advance()
00844 {
00845 CPPTL_ENUMERATOR_CHECK_ADVANCE;
00846 enumerator_.advance();
00847 return *this;
00848 }
00849
00850 private:
00851 ThinEnumeratorType enumerator_;
00852 };
00853
00854
00855 template<class ValueType>
00856 class AddressOfAdaptor
00857 {
00858 public:
00859 typedef ValueType *value_type;
00860
00861 value_type operator()( const ValueType &value ) const
00862 {
00863 return &value;
00864 }
00865 };
00866
00867
00868 namespace Enum {
00869
00870
00871
00872 template<class ForwardItType >
00873 ForwardItEnumerator<ForwardItType>
00874 range( ForwardItType begin, ForwardItType end )
00875 {
00876 typedef ForwardItEnumerator<ForwardItType> EnumType;
00877 return EnumType( begin, end );
00878 }
00879 template<class ForwardItType
00880 ,class ValueType>
00881 ForwardItEnumerator<ForwardItType,CPPTL_TYPENAME ValueType::type>
00882 range( ForwardItType begin, ForwardItType end, ValueType )
00883 {
00884 typedef ForwardItEnumerator<ForwardItType,CPPTL_TYPENAME ValueType::type> EnumType;
00885 return EnumType( begin, end );
00886 }
00887
00888
00889 template<class ForwardItType
00890 ,class Adaptor >
00891 TransformForwardItEnumerator<ForwardItType,Adaptor>
00892 rangeTransform( ForwardItType begin, ForwardItType end, Adaptor adaptor )
00893 {
00894 typedef TransformForwardItEnumerator<ForwardItType,Adaptor> EnumType;
00895 return EnumType( begin, end, adaptor );
00896 }
00897
00898
00899 template<class ContainerType>
00900 ContainerEnumerator<ContainerType>
00901 container( const ContainerType &enumeratedContainer )
00902 {
00903 typedef ContainerEnumerator<ContainerType> EnumType;
00904 return EnumType( enumeratedContainer );
00905 }
00906
00907
00908 template<class ContainerType
00909 ,class ValueType>
00910 ContainerEnumerator<ContainerType,CPPTL_TYPENAME ValueType::type>
00911 container( const ContainerType &enumeratedContainer, ValueType )
00912 {
00913 typedef ContainerEnumerator<ContainerType,CPPTL_TYPENAME ValueType::type> EnumType;
00914 return EnumType( enumeratedContainer );
00915 }
00916
00917 template<class ForwardItType>
00918 MapKeysEnumerator<ForwardItType>
00919 keysRange( ForwardItType begin, ForwardItType end )
00920 {
00921 typedef MapKeysEnumerator<ForwardItType> EnumType;
00922 return EnumType( begin, end );
00923 }
00924
00925 template<class ForwardItType
00926 ,class ValueType>
00927 MapKeysEnumerator<ForwardItType,CPPTL_TYPENAME ValueType::type>
00928 keysRange( ForwardItType begin, ForwardItType end, ValueType )
00929 {
00930 typedef MapKeysEnumerator<ForwardItType,CPPTL_TYPENAME ValueType::type> EnumType;
00931 return EnumType( begin, end );
00932 }
00933
00934 template<class ContainerType>
00935 MapKeysEnumerator<
00936 CPPTL_TYPENAME ContainerType::const_iterator
00937 , CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME ContainerType::value_type::first_type>::type
00938 >
00939 keys( const ContainerType &container )
00940 {
00941 return keysRange( container.begin(), container.end() );
00942 }
00943
00944 template<class ContainerType
00945 ,class ValueType>
00946 MapKeysEnumerator< CPPTL_TYPENAME ContainerType::const_iterator
00947 , CPPTL_TYPENAME ValueType::type >
00948 keys( const ContainerType &container, ValueType )
00949 {
00950 return keysRange( container.begin(), container.end(), ValueType() );
00951 }
00952
00953 template<class ContainerType>
00954 MapValuesEnumerator<
00955 CPPTL_TYPENAME ContainerType::const_iterator
00956 , CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME ContainerType::value_type::second_type>::type
00957 >
00958 values( const ContainerType &container )
00959 {
00960 typedef MapValuesEnumerator<CPPTL_TYPENAME ContainerType::const_iterator> EnumType;
00961 return EnumType( container.begin(), container.end() );
00962 }
00963
00964 template<class ContainerType
00965 ,class ValueType>
00966 MapValuesEnumerator< CPPTL_TYPENAME ContainerType::const_iterator
00967 , CPPTL_TYPENAME ValueType::type >
00968 values( const ContainerType &container, ValueType )
00969 {
00970 typedef MapValuesEnumerator< CPPTL_TYPENAME ContainerType::const_iterator
00971 , CPPTL_TYPENAME ValueType::type > EnumType;
00972 return EnumType( container.begin(), container.end() );
00973 }
00974
00975 template<class ForwardItType>
00976 MapValuesEnumerator<ForwardItType>
00977 valuesRange( ForwardItType begin, ForwardItType end )
00978 {
00979 typedef MapValuesEnumerator<ForwardItType> EnumType;
00980 return EnumType( begin, end );
00981 }
00982
00983 template<class ForwardItType
00984 ,class ValueType>
00985 MapValuesEnumerator< ForwardItType, CPPTL_TYPENAME ValueType::type >
00986 valuesRange( ForwardItType begin, ForwardItType end, ValueType )
00987 {
00988 typedef MapValuesEnumerator< ForwardItType, CPPTL_TYPENAME ValueType::type > EnumType;
00989 return EnumType( begin, end );
00990 }
00991
00992
00993 template<class EnumeratorType>
00994 AnyEnumerator<CPPTL_TYPENAME EnumeratorType::value_type>
00995 any( const EnumeratorType &enumerator )
00996 {
00997 typedef AnyEnumerator<CPPTL_TYPENAME EnumeratorType::value_type> EnumType;
00998 return EnumType( new AnyEnumeratorImpl<EnumeratorType>( enumerator ) );
00999 }
01000
01001
01002 template<class EnumeratorType
01003 ,class Adaptor>
01004 TransformEnumerator<Adaptor, EnumeratorType>
01005 transform( const EnumeratorType &enumerator, Adaptor adaptor )
01006 {
01007 typedef TransformEnumerator<Adaptor, EnumeratorType> EnumType;
01008 return EnumType( enumerator, adaptor );
01009 }
01010
01011
01012 template<class EnumeratorType>
01013 TransformEnumerator< AddressOfAdaptor<CPPTL_TYPENAME EnumeratorType::value_type>,
01014 EnumeratorType >
01015 addressOfTransform( const EnumeratorType &enumerator )
01016 {
01017 typedef AddressOfAdaptor<CPPTL_TYPENAME EnumeratorType::value_type> Adaptor;
01018 typedef TransformEnumerator< Adaptor, EnumeratorType > EnumType;
01019 Adaptor adaptor;
01020 return EnumType( enumerator, adaptor );
01021 }
01022
01023
01024 template<class EnumeratorType
01025 ,class Predicate>
01026 FilterEnumerator<EnumeratorType,Predicate>
01027 filter( const EnumeratorType &enumerator, Predicate predicate )
01028 {
01029 typedef FilterEnumerator<EnumeratorType,Predicate> EnumType;
01030 return EnumType( enumerator, predicate );
01031 }
01032
01033
01034 template<class EnumeratorType>
01035 SliceEnumerator<EnumeratorType>
01036 slice( const EnumeratorType &enumerator,
01037 unsigned int beginIndex,
01038 unsigned int endIndex = -1 )
01039 {
01040 typedef SliceEnumerator<EnumeratorType> EnumType;
01041 return EnumType( enumerator, beginIndex, endIndex );
01042 }
01043
01044
01047 template<class ThinEnumeratorType>
01048 SugarEnumerator<ThinEnumeratorType>
01049 sugar( const ThinEnumeratorType &e )
01050 {
01051 typedef SugarEnumerator<ThinEnumeratorType> EnumType;
01052 return EnumType( e );
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 template<class ForwardItType>
01067 AnyEnumerator<CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME ForwardItType::value_type>::type>
01068 anyRange( ForwardItType begin, ForwardItType end )
01069 {
01070 return any( range( begin, end ) );
01071 }
01072
01073
01074 template<class ForwardItType
01075 ,class ValueType>
01076 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01077 anyRange( ForwardItType begin, ForwardItType end, ValueType type )
01078 {
01079 return any( range( begin, end, type ) );
01080 }
01081
01082
01083 template<class ForwardItType
01084 ,class Adaptor >
01085 AnyEnumerator<CPPTL_TYPENAME Adaptor::result_type>
01086 anyRangeTransform( ForwardItType begin, ForwardItType end, Adaptor adaptor )
01087 {
01088 return any( rangeTransform( begin, end, adaptor ) );
01089 }
01090
01091 template<class ContainerType>
01092 AnyEnumerator<CPPTL_TYPENAME RemoveConst<CPPTL_TYPENAME ContainerType::value_type>::type>
01093 anyContainer( const ContainerType &enumeratedContainer )
01094 {
01095 return any( container( enumeratedContainer ) );
01096 }
01097
01098 template<class ContainerType
01099 ,class ValueType>
01100 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01101 anyContainer( const ContainerType &enumeratedContainer, ValueType type )
01102 {
01103 return any( container( enumeratedContainer, type ) );
01104 }
01105
01106 template<class ForwardItType>
01107 AnyEnumerator<CPPTL_TYPENAME RemoveConst<
01108 CPPTL_TYPENAME ForwardItType::value_type::first_type>::type>
01109 anyKeysRange( ForwardItType begin, ForwardItType end )
01110 {
01111 return any( keysRange( begin, end ) );
01112 }
01113
01114 template<class ForwardItType
01115 ,class ValueType>
01116 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01117 anyKeysRange( ForwardItType begin, ForwardItType end, ValueType type )
01118 {
01119 return any( keysRange( begin, end, type ) );
01120 }
01121
01122 template<class ContainerType
01123 ,class ValueType>
01124 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01125 anyKeys( const ContainerType &container, ValueType type )
01126 {
01127 return any( keys( container, type ) );
01128 }
01129
01130 template<class ContainerType>
01131 AnyEnumerator<CPPTL_TYPENAME RemoveConst<
01132 CPPTL_TYPENAME ContainerType::value_type::first_type>::type>
01133 anyKeys( const ContainerType &container )
01134 {
01135 return any( keys( container ) );
01136 }
01137
01138 template<class ForwardItType>
01139 AnyEnumerator<CPPTL_TYPENAME RemoveConst<
01140 CPPTL_TYPENAME ForwardItType::value_type::second_type>::type>
01141 anyValuesRange( ForwardItType begin, ForwardItType end )
01142 {
01143 return any( valuesRange( begin, end ) );
01144 }
01145
01146 template<class ForwardItType
01147 ,class ValueType>
01148 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01149 anyValuesRange( ForwardItType begin, ForwardItType end, ValueType type )
01150 {
01151 return any( valuesRange( begin, end, type ) );
01152 }
01153
01154 template<class ContainerType>
01155 AnyEnumerator<CPPTL_TYPENAME RemoveConst<
01156 CPPTL_TYPENAME ContainerType::value_type::second_type>::type>
01157 anyValues( const ContainerType &container )
01158 {
01159 return any( values( container ) );
01160 }
01161
01162 template<class ContainerType
01163 ,class ValueType>
01164 AnyEnumerator<CPPTL_TYPENAME ValueType::type>
01165 anyValues( const ContainerType &container, ValueType type )
01166 {
01167 return any( values( container, type ) );
01168 }
01169
01170
01171 template<class EnumeratorType
01172 ,class Adaptor>
01173 AnyEnumerator<CPPTL_TYPENAME Adaptor::result_type>
01174 anyTransform( const EnumeratorType &enumerator, Adaptor adaptor )
01175 {
01176 return any( transform( enumerator, adaptor ) );
01177 }
01178
01179
01180 template<class EnumeratorType>
01181 AnyEnumerator<CPPTL_TYPENAME EnumeratorType::value_type *>
01182 anyAddressOfTransform( const EnumeratorType &enumerator )
01183 {
01184 return any( addressOfTransform( enumerator ) );
01185 }
01186
01187
01188 template<class EnumeratorType
01189 ,class Predicate>
01190 AnyEnumerator<CPPTL_TYPENAME EnumeratorType::value_type>
01191 anyFilter( const EnumeratorType &enumerator, Predicate predicate )
01192 {
01193 return any( filter( enumerator, predicate ) );
01194 }
01195
01196
01197 template<class EnumeratorType>
01198 AnyEnumerator<CPPTL_TYPENAME EnumeratorType::value_type>
01199 anySlice( const EnumeratorType &enumerator,
01200 unsigned int beginIndex,
01201 unsigned int endIndex = -1 )
01202 {
01203 return any( slice( enumerator, beginIndex, endIndex ) );
01204 }
01205
01206
01207 template<class ThinEnumeratorType>
01208 AnyEnumerator<CPPTL_TYPENAME ThinEnumeratorType::value_type>
01209 anySugar( const ThinEnumeratorType &e )
01210 {
01211 return any( sugar( e ) );
01212 }
01213
01214
01215
01216 }
01217 }
01218
01219
01220 #endif // CPPUTTOOLS_ENUMERATOR_H_INCLUDED