Update of /cvsroot/cpptool/rfta/include/xtl In directory sc8-pr-cvs1:/tmp/cvs-serv29686/include/xtl Added Files: EnumAdaptor.h Enumerator.h EnumeratorImpl.h Int2Type.h NullEnumerator.h StlEnumerator.h StlMapEnumerator.h Type.h Log Message: * added Enumerator concept. Allow enumeration of STL container while hiding implementation. --- NEW FILE: EnumAdaptor.h --- #ifndef XTL_ENUMADAPTOR_H_INCLUDED #define XTL_ENUMADAPTOR_H_INCLUDED #include <boost/config.hpp> namespace Xtl { template<typename EnumeratedType> struct EnumAdaptor { typedef EnumeratedType EnumeratedType; }; template<typename EnumeratedType> struct IdendityEnumAdpator : public EnumAdaptor<EnumeratedType> { EnumeratedType operator()( const EnumeratedType &source ) const { return source; } }; template<typename EnumeratedType> struct ConstructEnumAdaptor : public EnumAdaptor<EnumeratedType> { template<typename SourceType> EnumeratedType operator()( const SourceType &source ) const { return EnumeratedType( source ); } }; template<typename EnumeratedType> struct FirstEnumAdaptor : public EnumAdaptor<EnumeratedType> { template<typename SourceType> EnumeratedType operator()( const SourceType &source ) const { return EnumeratedType( source.first ); } }; template<typename EnumeratedType> struct SecondEnumAdaptor : public EnumAdaptor<EnumeratedType> { template<typename SourceType> EnumeratedType operator()( const SourceType &source ) const { return EnumeratedType( source.second ); } }; template<typename EnumeratedType> struct DerefEnumAdaptor : public EnumAdaptor<EnumeratedType> { template<typename SourceType> EnumeratedType operator()( const SourceType &source ) const { return EnumeratedType( *source ); } }; template<typename Functor> struct TransformEnumAdaptor : public EnumAdaptor<BOOST_DEDUCED_TYPENAME Functor::result_type> { TransformEnumAdaptor() { } TransformEnumAdaptor( Functor functor ) : functor_( functor ) { } template<typename SourceType> EnumeratedType operator()( const SourceType &source ) const { return functor_( source ); } Functor functor_; }; template<typename OutterAdaptor ,typename InnerFunctor> struct ComposeAdaptor : public EnumAdaptor<BOOST_DEDUCED_TYPENAME OutterAdaptor::EnumeratedType> { ComposeAdaptor() { } ComposeAdaptor( OutterAdaptor outter, InnerFunctor inner ) : outter_( outter ) , inner_( inner ) { } template<typename SourceType> EnumeratedType operator()( const SourceType &x ) const { return outter_( inner_( x ) ); } OutterAdaptor outter_; InnerFunctor inner_; }; } // namespace Xtl #endif // XTL_ENUMADAPTOR_H_INCLUDED --- NEW FILE: Enumerator.h --- #ifndef XTL_ENUMERATOR_H_INCLUDED #define XTL_ENUMERATOR_H_INCLUDED #include <xtl/NullEnumerator.h> namespace Xtl { template<typename EnumeratedType> class Enumerator { public: typedef boost::intrusive_ptr< EnumeratorImpl<EnumeratedType> > ImplPtr; Enumerator() : impl_( new NullEnumeratorImpl<EnumeratedType>() ) { } Enumerator( const ImplPtr &impl ) : impl_( impl ) { } EnumeratedType getNext() { return impl_->getNext(); } bool hasNext() const { return impl_->hasNext(); } Enumerator clone() const { return Enumerator( impl_->clone() ); } private: ImplPtr impl_; }; } // namespace Xtl #endif // XTL_ENUMERATOR_H_INCLUDED --- NEW FILE: EnumeratorImpl.h --- #ifndef XTL_ENUMERATORIMPL_H_INCLUDED #define XTL_ENUMERATORIMPL_H_INCLUDED #include <boost/intrusive_ptr.hpp> #include <xtl/IntrusiveCount.h> #include <stdexcept> namespace Xtl { class EnumeratorError : public std::out_of_range { public: EnumeratorError() : std::out_of_range( "Enumerator::getNext() called with no next item" ) { } ~EnumeratorError() throw() { } }; template<typename EnumeratedType> class EnumeratorImpl : public IntrusiveCount { public: typedef boost::intrusive_ptr<EnumeratorImpl> Ptr; virtual EnumeratedType getNext() =0; virtual bool hasNext() const =0; virtual Ptr clone() const =0; }; } // namespace Xtl #endif // XTL_ENUMERATORIMPL_H_INCLUDED --- NEW FILE: Int2Type.h --- #ifndef XTL_INT2TYPE_H_INCLUDED #define XTL_INT2TYPE_H_INCLUDED // Based on Andrei Alexandrescu article in C++ user journal. namespace Xtl { template <int v> struct Int2Type { enum { value = v }; }; } // namespace Xtl #endif // XTL_INT2TYPE_H_INCLUDED --- NEW FILE: NullEnumerator.h --- #ifndef XTL_NULLENUMERATOR_H_INCLUDED #define XTL_NULLENUMERATOR_H_INCLUDED #include <xtl/EnumeratorImpl.h> namespace Xtl { template<typename EnumeratedType> class NullEnumeratorImpl : public EnumeratorImpl<EnumeratedType> { public: // overridden from EnumeratorImpl EnumeratedType getNext() { throw EnumeratorError(); } bool hasNext() const { return false; } Ptr clone() const { return Ptr( const_cast<NullEnumeratorImpl *>(this) ); // no state, don't need cloning } }; } // namespace Xtl #endif // XTL_NULLENUMERATOR_H_INCLUDED --- NEW FILE: StlEnumerator.h --- #ifndef XTL_STLENUMERATOR_H_INCLUDED #define XTL_STLENUMERATOR_H_INCLUDED #include <xtl/Enumerator.h> #include <xtl/EnumAdaptor.h> #include <xtl/Int2Type.h> #include <xtl/Type.h> #include <boost/type_traits.hpp> #include <functional> namespace Xtl { template<typename StlForwardIteratorType ,typename EnumeratedType ,typename Adaptor=IdendityEnumAdpator<EnumeratedType> > class StlEnumeratorImpl : public EnumeratorImpl<EnumeratedType> { public: typedef StlEnumeratorImpl<StlForwardIteratorType,EnumeratedType,Adaptor> ThisType; enum { isIdentityAdaptor = ::boost::is_convertible<IdendityEnumAdpator<EnumeratedType> ,Adaptor>::value }; StlEnumeratorImpl( StlForwardIteratorType first, StlForwardIteratorType last ) : current_( first ) , last_( last ) { } StlEnumeratorImpl( StlForwardIteratorType first, StlForwardIteratorType last, Adaptor adaptor ) : current_( first ) , last_( last ) , adaptor_( adaptor ) { } public: // overridden from EnumeratorImpl EnumeratedType getNext() { if ( current_ == last_ ) throw EnumeratorError(); return doGetNext( Int2Type<isIdentityAdaptor>() ); } bool hasNext() const { return current_ != last_; } Ptr clone() const { return Ptr( new ThisType( current_, last_ ) ); } private: inline EnumeratedType doGetNext( Int2Type<true> ) { return *current_++; } inline EnumeratedType doGetNext( Int2Type<false> ) { return adaptor_( *current_++ ); } private: StlForwardIteratorType current_; StlForwardIteratorType last_; Adaptor adaptor_; }; template<typename StlIteratorType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlAdapt( StlIteratorType first, StlIteratorType last, Adaptor adaptor ) { typedef BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType EnumeratedType; return Enumerator<EnumeratedType>( new StlEnumeratorImpl<StlIteratorType ,EnumeratedType ,Adaptor>( first, last, adaptor ) ); } template<typename StlContainerType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlAdapt( const StlContainerType &sequence, Adaptor adaptor ) { return enumStlAdapt( sequence.begin(), sequence.end(), adaptor ); } template<typename StlContainerType ,typename EnumeratedType> Enumerator<EnumeratedType> enumStl( const StlContainerType &sequence, Type<EnumeratedType> ) { return Enumerator<EnumeratedType>( new StlEnumeratorImpl<BOOST_DEDUCED_TYPENAME StlContainerType::const_iterator ,EnumeratedType ,ConstructEnumAdaptor<EnumeratedType> >( sequence.begin(), sequence.end() ) ); } template<typename StlContainerType> Enumerator<BOOST_DEDUCED_TYPENAME StlContainerType::value_type> enumStl( const StlContainerType &sequence ) { return enumStlAdapt( sequence, IdendityEnumAdpator<BOOST_DEDUCED_TYPENAME StlContainerType::value_type>() ); } template<typename StlIteratorType ,typename EnumeratedType> Enumerator<EnumeratedType> enumStl( StlIteratorType first, StlIteratorType last, Type<EnumeratedType> ) { return Enumerator<EnumeratedType>( new StlEnumeratorImpl<StlIteratorType ,EnumeratedType ,ConstructEnumAdaptor<EnumeratedType> >( first, last ) ); } #if defined( BOOST_MSVC_STD_ITERATOR ) // VC6, std::vector::iterator is a pointer => type is not extractable ! /// \warning : first and last iterator must be of exactly the same type. Unexpected behavior otherwise. /// no compile-time way to force that constraint. It is highly recommended to compile on a conforming STL( vc7). template<typename Category ,typename EnumeratedType ,typename Distance ,typename IteratorType> Enumerator<EnumeratedType> enumStl( const std::iterator<Category, EnumeratedType, Distance> &first, const IteratorType &last ) { return enumStlAdapt( static_cast<const IteratorType &>(first), last, IdendityEnumAdpator<EnumeratedType>() ); } // Overload to handle std::vector::iterator, which is a pointer. template<typename EnumeratedType> Enumerator<EnumeratedType> enumStl( const EnumeratedType *first, const EnumeratedType *last ) { return enumStlAdapt( first, last, IdendityEnumAdpator<EnumeratedType>() ); } #else // std::iterator_traits is available for all container (including std::vector) template<typename StlIteratorType> Enumerator<BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type> enumStl( StlIteratorType first, StlIteratorType last ) { typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type EnumeratedType; return enumStlAdapt( first, last, IdendityEnumAdpator<EnumeratedType>() ); } #endif template<typename StlMapType> Enumerator<BOOST_DEDUCED_TYPENAME StlMapType::key_type> enumStlMapKeys( const StlMapType &map ) { typedef BOOST_DEDUCED_TYPENAME StlMapType::key_type EnumeratedType; return enumStlAdapt( map, FirstEnumAdaptor<EnumeratedType>() ); } template<typename StlMapType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlMapKeysAdapt( const StlMapType &map, Adaptor adaptor ) { return enumStlAdapt( map, ComposeAdaptor<Adaptor,FirstEnumAdaptor>() ); } template<typename StlMapType ,typename EnumeratedType> Enumerator<BOOST_DEDUCED_TYPENAME StlMapType::key_type> enumStlMapKeys( const StlMapType &map, Type<EnumeratedType>() ) { return enumStlMapKeysAdapt( map, ConstructEnumAdaptor<EnumeratedType>() ); } template<typename StlIteratorType> Enumerator<BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type> enumStlMapKeys( StlIteratorType first, StlIteratorType last ) { typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type EnumeratedType; return enumStlAdapt( first, last, FirstEnumAdaptor<EnumeratedType>() ); } template<typename StlIteratorType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlMapKeys( StlIteratorType first, StlIteratorType last, Adaptor adaptor ) { return enumStlAdapt( first, last, ComposeAdaptor<Adaptor,FirstEnumAdaptor>() ); } template<typename StlIteratorType ,typename EnumeratedType> Enumerator<EnumeratedType> enumStlMapKeys( StlIteratorType first, StlIteratorType last, Type<EnumeratedType> ) { return enumStlMapKeysAdapt( first, last, ConstructEnumAdaptor<EnumeratedType>() ); } template<typename StlMapType> Enumerator<BOOST_DEDUCED_TYPENAME StlMapType::referent_type> enumStlMapValues( const StlMapType &map ) { typedef BOOST_DEDUCED_TYPENAME StlMapType::referent_type EnumeratedType; return enumStlAdapt( map, SecondEnumAdaptor<EnumeratedType>() ); } template<typename StlMapType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlMapValuesAdapt( const StlMapType &map, Adaptor adaptor ) { typedef BOOST_DEDUCED_TYPENAME StlMapType::referent_type EnumeratedType; return enumStlAdapt( map, ComposeAdaptor<Adaptor,SecondEnumAdaptor>() ); } template<typename StlIteratorType> Enumerator<BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type> enumStlMapValues( StlIteratorType first, StlIteratorType last ) { typedef BOOST_DEDUCED_TYPENAME std::iterator_traits<StlIteratorType>::value_type EnumeratedType; return enumStlAdapt( first, last, SecondEnumAdaptor<EnumeratedType>() ); } template<typename StlIteratorType ,typename Adaptor> Enumerator<BOOST_DEDUCED_TYPENAME Adaptor::EnumeratedType> enumStlMapValuesAdapt( StlIteratorType first, StlIteratorType last, Adaptor adaptor ) { return enumStlAdapt( first, last, ComposeAdaptor<Adaptor,SecondEnumAdaptor>() ); } template<typename StlIteratorType ,typename EnumeratedType> Enumerator<EnumeratedType> enumStlMapValues( StlIteratorType first, StlIteratorType last, Type<EnumeratedType> ) { return enumStlMapValuesAdapt( first, last, ConstructEnumAdaptor<EnumeratedType>() ); } } // namespace Xtl #endif // XTL_STLENUMERATOR_H_INCLUDED --- NEW FILE: StlMapEnumerator.h --- #ifndef XTL_STLMAPENUMERATOR_H_INCLUDED #define XTL_STLMAPENUMERATOR_H_INCLUDED #include <xtl/Enumerator.h> #include <xtl/type.h> namespace Xtl { template<typename StlForwardIteratorType ,typename EnumeratedType> class StlEnumeratorImpl : public EnumeratorImpl<EnumeratedType> { public: typedef StlEnumeratorImpl<StlForwardIteratorType,EnumeratedType> ThisType; StlEnumeratorImpl( StlForwardIteratorType first, StlForwardIteratorType last ) : current_( first ) , last_( last ) { } public: // overridden from EnumeratorImpl EnumeratedType getNext() { if ( current_ == last_ ) throw EnumeratorError(); return *current_++; } bool hasNext() const { return current_ != last_; } Ptr clone() const { return Ptr( new ThisType( current_, last_ ) ); } private: StlForwardIteratorType current_; StlForwardIteratorType last_; }; template<typename StlContainerType ,typename EnumeratedType> Enumerator<EnumeratedType> enumStl( const StlContainerType &sequence, Type<EnumeratedType> ) { return Enumerator<EnumeratedType>( new StlEnumeratorImpl<BOOST_DEDUCED_TYPENAME StlContainerType::const_iterator ,EnumeratedType>( sequence.begin(), sequence.end() ) ); } template<typename StlContainerType> Enumerator<BOOST_DEDUCED_TYPENAME StlContainerType::value_type> enumStl( const StlContainerType &sequence ) { return enumStl( sequence, Type<BOOST_DEDUCED_TYPENAME StlContainerType::value_type>() ); } template<typename MapType ,typename EnumeratedType> Enumerator<EnumeratedType> enumMapKeys( const MapType &map, Type<EnumeratedType>() ) { return Enumerator<EnumeratedType>( new StlMapEnumerator<EnumeratedType ,MapType::const_iterator ,MapEnumerateKeysPolicy>( map.begin(), map.end() ) ); } } // namespace Xtl #endif // XTL_STLMAPENUMERATOR_H_INCLUDED --- NEW FILE: Type.h --- #ifndef XTL_TYPE_H_INCLUDED #define XTL_TYPE_H_INCLUDED namespace Xtl { /** A simple type wrapper. * * Common technic to pass a type as a parameter. */ template<typename WrappedType> struct Type { typedef WrappedType OriginalType; }; } // namespace Xtl #endif // XTL_TYPE_H_INCLUDED |