williamr@2: // Boost.Assign library williamr@2: // williamr@2: // Copyright Thorsten Ottosen 2003-2004. Use, modification and williamr@2: // distribution is subject to the Boost Software License, Version williamr@2: // 1.0. (See accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // For more information, see http://www.boost.org/libs/assign/ williamr@2: // williamr@2: williamr@2: #ifndef BOOST_ASSIGN_LIST_INSERTER_HPP williamr@2: #define BOOST_ASSIGN_LIST_INSERTER_HPP williamr@2: williamr@2: #if defined(_MSC_VER) && (_MSC_VER >= 1020) williamr@2: # pragma once williamr@2: #endif williamr@2: williamr@2: #include williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: namespace assign_detail williamr@2: { williamr@2: template< class T > williamr@2: struct repeater williamr@2: { williamr@2: std::size_t sz; williamr@2: T val; williamr@2: williamr@2: repeater( std::size_t sz, T r ) : sz( sz ), val( r ) williamr@2: { } williamr@2: }; williamr@2: williamr@2: template< class Fun > williamr@2: struct fun_repeater williamr@2: { williamr@2: std::size_t sz; williamr@2: Fun val; williamr@2: williamr@2: fun_repeater( std::size_t sz, Fun r ) : sz( sz ), val( r ) williamr@2: { } williamr@2: }; williamr@2: williamr@2: template< class C > williamr@2: class call_push_back williamr@2: { williamr@2: C& c_; williamr@2: public: williamr@2: call_push_back( C& c ) : c_( c ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator()( T r ) williamr@2: { williamr@2: c_.push_back( r ); williamr@2: } williamr@2: }; williamr@2: williamr@2: template< class C > williamr@2: class call_push_front williamr@2: { williamr@2: C& c_; williamr@2: public: williamr@2: call_push_front( C& c ) : c_( c ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator()( T r ) williamr@2: { williamr@2: c_.push_front( r ); williamr@2: } williamr@2: }; williamr@2: williamr@2: template< class C > williamr@2: class call_push williamr@2: { williamr@2: C& c_; williamr@2: public: williamr@2: call_push( C& c ) : c_( c ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator()( T r ) williamr@2: { williamr@2: c_.push( r ); williamr@2: } williamr@2: }; williamr@2: williamr@2: template< class C > williamr@2: class call_insert williamr@2: { williamr@2: C& c_; williamr@2: public: williamr@2: call_insert( C& c ) : c_( c ) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator()( T r ) williamr@2: { williamr@2: c_.insert( r ); williamr@2: } williamr@2: }; williamr@2: williamr@2: template< class C > williamr@2: class call_add_edge williamr@2: { williamr@2: C& c_; williamr@2: public: williamr@2: call_add_edge( C& c ) : c_(c) williamr@2: { } williamr@2: williamr@2: template< class T > williamr@2: void operator()( T l, T r ) williamr@2: { williamr@2: add_edge( l, r, c_ ); williamr@2: } williamr@2: williamr@2: template< class T, class EP > williamr@2: void operator()( T l, T r, const EP& ep ) williamr@2: { williamr@2: add_edge( l, r, ep, c_ ); williamr@2: } williamr@2: williamr@2: }; williamr@2: williamr@2: struct forward_n_arguments {}; williamr@2: williamr@2: } // namespace 'assign_detail' williamr@2: williamr@2: namespace assign williamr@2: { williamr@2: williamr@2: template< class T > williamr@2: inline assign_detail::repeater williamr@2: repeat( std::size_t sz, T r ) williamr@2: { williamr@2: return assign_detail::repeater( sz, r ); williamr@2: } williamr@2: williamr@2: template< class Function > williamr@2: inline assign_detail::fun_repeater williamr@2: repeat_fun( std::size_t sz, Function r ) williamr@2: { williamr@2: return assign_detail::fun_repeater( sz, r ); williamr@2: } williamr@2: williamr@2: williamr@2: template< class Function, class Argument = assign_detail::forward_n_arguments > williamr@2: class list_inserter williamr@2: { williamr@2: struct single_arg_type {}; williamr@2: struct n_arg_type {}; williamr@2: williamr@2: typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same::value, williamr@2: n_arg_type, williamr@2: single_arg_type >::type arg_type; williamr@2: williamr@2: public: williamr@2: williamr@2: list_inserter( Function fun ) : insert_( fun ) williamr@2: {} williamr@2: williamr@2: template< class Function2, class Arg > williamr@2: list_inserter( const list_inserter& r ) williamr@2: : insert_( r.fun_private() ) williamr@2: {} williamr@2: williamr@2: list_inserter( const list_inserter& r ) : insert_( r.insert_ ) williamr@2: {} williamr@2: williamr@2: list_inserter& operator()() williamr@2: { williamr@2: insert_( Argument() ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: list_inserter& operator=( const T& r ) williamr@2: { williamr@2: insert_( r ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: list_inserter& operator=( assign_detail::repeater r ) williamr@2: { williamr@2: return operator,( r ); williamr@2: } williamr@2: williamr@2: template< class Nullary_function > williamr@2: list_inserter& operator=( const assign_detail::fun_repeater& r ) williamr@2: { williamr@2: //BOOST_STATIC_ASSERT( function_traits::arity == 0 ); williamr@2: //BOOST_STATIC_ASSERT( is_convertible< BOOST_DEDUCED_TYPENAME function_traits< williamr@2: // Nullary_function>::result_type >,T>::value ); williamr@2: williamr@2: return operator,( r ); williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: list_inserter& operator,( const T& r ) williamr@2: { williamr@2: insert_( r ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) williamr@2: template< class T > williamr@2: list_inserter& operator,( const assign_detail::repeater & r ) williamr@2: { williamr@2: return repeat( r.sz, r.val ); williamr@2: } williamr@2: #else williamr@2: template< class T > williamr@2: list_inserter& operator,( assign_detail::repeater r ) williamr@2: { williamr@2: return repeat( r.sz, r.val ); williamr@2: } williamr@2: #endif williamr@2: williamr@2: template< class Nullary_function > williamr@2: list_inserter& operator,( const assign_detail::fun_repeater& r ) williamr@2: { williamr@2: return repeat_fun( r.sz, r.val ); williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: list_inserter& repeat( std::size_t sz, T r ) williamr@2: { williamr@2: std::size_t i = 0; williamr@2: while( i++ != sz ) williamr@2: insert_( r ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template< class Nullary_function > williamr@2: list_inserter& repeat_fun( std::size_t sz, Nullary_function fun ) williamr@2: { williamr@2: std::size_t i = 0; williamr@2: while( i++ != sz ) williamr@2: insert_( fun() ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template< class SinglePassIterator > williamr@2: list_inserter& range( SinglePassIterator first, williamr@2: SinglePassIterator last ) williamr@2: { williamr@2: for( ; first != last; ++first ) williamr@2: insert_( *first ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: template< class SinglePassRange > williamr@2: list_inserter& range( const SinglePassRange& r ) williamr@2: { williamr@2: return range( boost::begin(r), boost::end(r) ); williamr@2: } williamr@2: williamr@2: template< class T > williamr@2: list_inserter& operator()( const T& t ) williamr@2: { williamr@2: insert_( t ); williamr@2: return *this; williamr@2: } williamr@2: williamr@2: #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value williamr@2: #define BOOST_ASSIGN_MAX_PARAMS 5 williamr@2: #endif williamr@2: #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) williamr@2: #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) williamr@2: #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) williamr@2: #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) williamr@2: williamr@2: #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) williamr@2: #define BOOST_PP_LOCAL_MACRO(n) \ williamr@2: template< class T, BOOST_ASSIGN_PARAMS1(n) > \ williamr@2: list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \ williamr@2: { \ williamr@2: BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \ williamr@2: return *this; \ williamr@2: } \ williamr@2: /**/ williamr@2: williamr@2: #include BOOST_PP_LOCAL_ITERATE() williamr@2: williamr@2: williamr@2: #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) williamr@2: #define BOOST_PP_LOCAL_MACRO(n) \ williamr@2: template< class T, BOOST_ASSIGN_PARAMS1(n) > \ williamr@2: void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \ williamr@2: { \ williamr@2: insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \ williamr@2: } \ williamr@2: /**/ williamr@2: williamr@2: #include BOOST_PP_LOCAL_ITERATE() williamr@2: williamr@2: #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) williamr@2: #define BOOST_PP_LOCAL_MACRO(n) \ williamr@2: template< class T, BOOST_ASSIGN_PARAMS1(n) > \ williamr@2: void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \ williamr@2: { \ williamr@2: insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \ williamr@2: } \ williamr@2: /**/ williamr@2: williamr@2: #include BOOST_PP_LOCAL_ITERATE() williamr@2: williamr@2: williamr@2: Function fun_private() const williamr@2: { williamr@2: return insert_; williamr@2: } williamr@2: williamr@2: private: williamr@2: williamr@2: list_inserter& operator=( const list_inserter& ); williamr@2: Function insert_; williamr@2: }; williamr@2: williamr@2: template< class Function > williamr@2: inline list_inserter< Function > williamr@2: make_list_inserter( Function fun ) williamr@2: { williamr@2: return list_inserter< Function >( fun ); williamr@2: } williamr@2: williamr@2: template< class Function, class Argument > williamr@2: inline list_inserter williamr@2: make_list_inserter( Function fun, Argument* ) williamr@2: { williamr@2: return list_inserter( fun ); williamr@2: } williamr@2: williamr@2: template< class C > williamr@2: inline list_inserter< assign_detail::call_push_back, williamr@2: BOOST_DEDUCED_TYPENAME C::value_type > williamr@2: push_back( C& c ) williamr@2: { williamr@2: static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; williamr@2: return make_list_inserter( assign_detail::call_push_back( c ), williamr@2: p ); williamr@2: } williamr@2: williamr@2: template< class C > williamr@2: inline list_inserter< assign_detail::call_push_front, williamr@2: BOOST_DEDUCED_TYPENAME C::value_type > williamr@2: push_front( C& c ) williamr@2: { williamr@2: static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; williamr@2: return make_list_inserter( assign_detail::call_push_front( c ), williamr@2: p ); williamr@2: } williamr@2: williamr@2: template< class C > williamr@2: inline list_inserter< assign_detail::call_insert, williamr@2: BOOST_DEDUCED_TYPENAME C::value_type > williamr@2: insert( C& c ) williamr@2: { williamr@2: static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; williamr@2: return make_list_inserter( assign_detail::call_insert( c ), williamr@2: p ); williamr@2: } williamr@2: williamr@2: template< class C > williamr@2: inline list_inserter< assign_detail::call_push, williamr@2: BOOST_DEDUCED_TYPENAME C::value_type > williamr@2: push( C& c ) williamr@2: { williamr@2: static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; williamr@2: return make_list_inserter( assign_detail::call_push( c ), williamr@2: p ); williamr@2: } williamr@2: williamr@2: template< class C > williamr@2: inline list_inserter< assign_detail::call_add_edge > williamr@2: add_edge( C& c ) williamr@2: { williamr@2: return make_list_inserter( assign_detail::call_add_edge( c ) ); williamr@2: } williamr@2: williamr@2: } // namespace 'assign' williamr@2: } // namespace 'boost' williamr@2: williamr@2: #undef BOOST_ASSIGN_PARAMS1 williamr@2: #undef BOOST_ASSIGN_PARAMS2 williamr@2: #undef BOOST_ASSIGN_PARAMS3 williamr@2: #undef BOOST_ASSIGN_MAX_PARAMETERS williamr@2: williamr@2: #endif