CppUnit project page CppUnit home page

enumerator.h

Go to the documentation of this file.
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 *> // broken stl vector iterator
00027    {
00028       typedef ValueType value_type;
00029    };
00030 # endif
00031 
00032 } // namespace CppTL
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 } // namespace Impl
00063 
00064 } // namespace Enum
00065 
00066 // Class StopEnumerationError
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 /* Enumerator concept:
00110  bool is_open() const;
00111  T current() const;
00112  class_type advance();
00113 
00114  // derived functions:
00115  bool hasNext() const;
00116  T next();
00117  T operator *() const;
00118  class_type &operator ++();
00119  class_type operator++(int);
00120  */
00121 
00122 
00133 #if 0
00134 /*
00135 // removed strangely recurring template and using macro instead. Stressed compiler too much
00136 template<class DerivedType
00137         ,class EnumValueType>
00138 class EnumerationSugar : public TypeEnumeratorBase<EnumValueType>
00139 {
00140 public:
00141    typedef EnumValueType value_type;
00142 
00143    bool hasNext() const
00144    {
00145       return derived().is_open();
00146    }
00147 
00148    value_type next()
00149    {
00150       value_type value = derived().current();
00151       derived().advance();
00152       return value;
00153    }
00154 
00155    value_type operator *() const
00156    {
00157       return derived().current();
00158    }
00159 
00160    DerivedType &operator ++()
00161    {
00162       return derived().advance();
00163    }
00164 
00165    DerivedType operator ++( int )
00166    {
00167       DerivedType old = derived();
00168       derived().advance();
00169       return old;
00170    }
00171 
00172 private:
00173    DerivedType &derived()
00174    {
00175       return *static_cast<DerivedType *>(this);
00176    }
00177 
00178    const DerivedType &derived() const
00179    {
00180       return *static_cast<const DerivedType *>(this);
00181    }
00182 };
00183 */
00184 #endif
00185 
00186 // Enumerator Sugar.
00187 // Enumerattor class should defines:
00188 // typedef ... value_type;
00189 // typedef ... self_type; // class type
00190 // bool is_open() const;
00191 // value_type current() const;
00192 // self_type &advance();
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:  // overridden from ProxyEnumeratorBase
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 // Notes: on broken STL implementation which use value_type * as vector iterator,
00871 // you need to pass explictly ValueType => range<int>( vectorInt.begin(), vectorInt.end() );
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    > // Notes: deducing second template param cause ICE on VC++ 7.1
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    > // Notes: deducing second template param cause ICE on VC++ 7.1
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 // AnyEnumerator helpers...
01060 // //////////////////////////////////////////////////////////////////
01061 // //////////////////////////////////////////////////////////////////
01062 
01063 
01064 // Notes: on broken STL implementation which use value_type * as vector iterator,
01065 // you need to pass explictly ValueType => range<int>( vectorInt.begin(), vectorInt.end() );
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 } // namespace Enum
01217 } // namespace CppTL
01218 
01219 
01220 #endif // CPPUTTOOLS_ENUMERATOR_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers