text: // 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
  