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