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
|