You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
400 lines
10 KiB
400 lines
10 KiB
// 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
|
|
|