list_inserter.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. // Boost.Assign library
  2. //
  3. // Copyright Thorsten Ottosen 2003-2004. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/assign/
  9. //
  10. #ifndef BOOST_ASSIGN_LIST_INSERTER_HPP
  11. #define BOOST_ASSIGN_LIST_INSERTER_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  13. # pragma once
  14. #endif
  15. #include <boost/detail/workaround.hpp>
  16. #include <boost/mpl/if.hpp>
  17. #include <boost/type_traits/is_same.hpp>
  18. #include <boost/range/begin.hpp>
  19. #include <boost/range/end.hpp>
  20. #include <boost/config.hpp>
  21. #include <cstddef>
  22. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  23. #include <boost/preprocessor/repetition/enum_params.hpp>
  24. #include <boost/preprocessor/cat.hpp>
  25. #include <boost/preprocessor/iteration/local.hpp>
  26. #include <boost/preprocessor/arithmetic/inc.hpp>
  27. namespace boost
  28. {
  29. namespace assign_detail
  30. {
  31. template< class T >
  32. struct repeater
  33. {
  34. std::size_t sz;
  35. T val;
  36. repeater( std::size_t sz, T r ) : sz( sz ), val( r )
  37. { }
  38. };
  39. template< class Fun >
  40. struct fun_repeater
  41. {
  42. std::size_t sz;
  43. Fun val;
  44. fun_repeater( std::size_t sz, Fun r ) : sz( sz ), val( r )
  45. { }
  46. };
  47. template< class C >
  48. class call_push_back
  49. {
  50. C& c_;
  51. public:
  52. call_push_back( C& c ) : c_( c )
  53. { }
  54. template< class T >
  55. void operator()( T r )
  56. {
  57. c_.push_back( r );
  58. }
  59. };
  60. template< class C >
  61. class call_push_front
  62. {
  63. C& c_;
  64. public:
  65. call_push_front( C& c ) : c_( c )
  66. { }
  67. template< class T >
  68. void operator()( T r )
  69. {
  70. c_.push_front( r );
  71. }
  72. };
  73. template< class C >
  74. class call_push
  75. {
  76. C& c_;
  77. public:
  78. call_push( C& c ) : c_( c )
  79. { }
  80. template< class T >
  81. void operator()( T r )
  82. {
  83. c_.push( r );
  84. }
  85. };
  86. template< class C >
  87. class call_insert
  88. {
  89. C& c_;
  90. public:
  91. call_insert( C& c ) : c_( c )
  92. { }
  93. template< class T >
  94. void operator()( T r )
  95. {
  96. c_.insert( r );
  97. }
  98. };
  99. template< class C >
  100. class call_add_edge
  101. {
  102. C& c_;
  103. public:
  104. call_add_edge( C& c ) : c_(c)
  105. { }
  106. template< class T >
  107. void operator()( T l, T r )
  108. {
  109. add_edge( l, r, c_ );
  110. }
  111. template< class T, class EP >
  112. void operator()( T l, T r, const EP& ep )
  113. {
  114. add_edge( l, r, ep, c_ );
  115. }
  116. };
  117. struct forward_n_arguments {};
  118. } // namespace 'assign_detail'
  119. namespace assign
  120. {
  121. template< class T >
  122. inline assign_detail::repeater<T>
  123. repeat( std::size_t sz, T r )
  124. {
  125. return assign_detail::repeater<T>( sz, r );
  126. }
  127. template< class Function >
  128. inline assign_detail::fun_repeater<Function>
  129. repeat_fun( std::size_t sz, Function r )
  130. {
  131. return assign_detail::fun_repeater<Function>( sz, r );
  132. }
  133. template< class Function, class Argument = assign_detail::forward_n_arguments >
  134. class list_inserter
  135. {
  136. struct single_arg_type {};
  137. struct n_arg_type {};
  138. typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same<Argument,assign_detail::forward_n_arguments>::value,
  139. n_arg_type,
  140. single_arg_type >::type arg_type;
  141. public:
  142. list_inserter( Function fun ) : insert_( fun )
  143. {}
  144. template< class Function2, class Arg >
  145. list_inserter( const list_inserter<Function2,Arg>& r )
  146. : insert_( r.fun_private() )
  147. {}
  148. list_inserter( const list_inserter& r ) : insert_( r.insert_ )
  149. {}
  150. list_inserter& operator()()
  151. {
  152. insert_( Argument() );
  153. return *this;
  154. }
  155. template< class T >
  156. list_inserter& operator=( const T& r )
  157. {
  158. insert_( r );
  159. return *this;
  160. }
  161. template< class T >
  162. list_inserter& operator=( assign_detail::repeater<T> r )
  163. {
  164. return operator,( r );
  165. }
  166. template< class Nullary_function >
  167. list_inserter& operator=( const assign_detail::fun_repeater<Nullary_function>& r )
  168. {
  169. return operator,( r );
  170. }
  171. template< class T >
  172. list_inserter& operator,( const T& r )
  173. {
  174. insert_( r );
  175. return *this;
  176. }
  177. #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
  178. template< class T >
  179. list_inserter& operator,( const assign_detail::repeater<T> & r )
  180. {
  181. return repeat( r.sz, r.val );
  182. }
  183. #else
  184. template< class T >
  185. list_inserter& operator,( assign_detail::repeater<T> r )
  186. {
  187. return repeat( r.sz, r.val );
  188. }
  189. #endif
  190. template< class Nullary_function >
  191. list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r )
  192. {
  193. return repeat_fun( r.sz, r.val );
  194. }
  195. template< class T >
  196. list_inserter& repeat( std::size_t sz, T r )
  197. {
  198. std::size_t i = 0;
  199. while( i++ != sz )
  200. insert_( r );
  201. return *this;
  202. }
  203. template< class Nullary_function >
  204. list_inserter& repeat_fun( std::size_t sz, Nullary_function fun )
  205. {
  206. std::size_t i = 0;
  207. while( i++ != sz )
  208. insert_( fun() );
  209. return *this;
  210. }
  211. template< class SinglePassIterator >
  212. list_inserter& range( SinglePassIterator first,
  213. SinglePassIterator last )
  214. {
  215. for( ; first != last; ++first )
  216. insert_( *first );
  217. return *this;
  218. }
  219. template< class SinglePassRange >
  220. list_inserter& range( const SinglePassRange& r )
  221. {
  222. return range( boost::begin(r), boost::end(r) );
  223. }
  224. template< class T >
  225. list_inserter& operator()( const T& t )
  226. {
  227. insert_( t );
  228. return *this;
  229. }
  230. #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
  231. #define BOOST_ASSIGN_MAX_PARAMS 5
  232. #endif
  233. #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
  234. #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T)
  235. #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t)
  236. #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t)
  237. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
  238. #define BOOST_PP_LOCAL_MACRO(n) \
  239. template< class T, BOOST_ASSIGN_PARAMS1(n) > \
  240. list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \
  241. { \
  242. BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \
  243. return *this; \
  244. } \
  245. /**/
  246. #include BOOST_PP_LOCAL_ITERATE()
  247. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
  248. #define BOOST_PP_LOCAL_MACRO(n) \
  249. template< class T, BOOST_ASSIGN_PARAMS1(n) > \
  250. void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \
  251. { \
  252. insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \
  253. } \
  254. /**/
  255. #include BOOST_PP_LOCAL_ITERATE()
  256. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
  257. #define BOOST_PP_LOCAL_MACRO(n) \
  258. template< class T, BOOST_ASSIGN_PARAMS1(n) > \
  259. void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \
  260. { \
  261. insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \
  262. } \
  263. /**/
  264. #include BOOST_PP_LOCAL_ITERATE()
  265. Function fun_private() const
  266. {
  267. return insert_;
  268. }
  269. private:
  270. list_inserter& operator=( const list_inserter& );
  271. Function insert_;
  272. };
  273. template< class Function >
  274. inline list_inserter< Function >
  275. make_list_inserter( Function fun )
  276. {
  277. return list_inserter< Function >( fun );
  278. }
  279. template< class Function, class Argument >
  280. inline list_inserter<Function,Argument>
  281. make_list_inserter( Function fun, Argument* )
  282. {
  283. return list_inserter<Function,Argument>( fun );
  284. }
  285. template< class C >
  286. inline list_inserter< assign_detail::call_push_back<C>,
  287. BOOST_DEDUCED_TYPENAME C::value_type >
  288. push_back( C& c )
  289. {
  290. static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
  291. return make_list_inserter( assign_detail::call_push_back<C>( c ),
  292. p );
  293. }
  294. template< class C >
  295. inline list_inserter< assign_detail::call_push_front<C>,
  296. BOOST_DEDUCED_TYPENAME C::value_type >
  297. push_front( C& c )
  298. {
  299. static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
  300. return make_list_inserter( assign_detail::call_push_front<C>( c ),
  301. p );
  302. }
  303. template< class C >
  304. inline list_inserter< assign_detail::call_insert<C>,
  305. BOOST_DEDUCED_TYPENAME C::value_type >
  306. insert( C& c )
  307. {
  308. static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
  309. return make_list_inserter( assign_detail::call_insert<C>( c ),
  310. p );
  311. }
  312. template< class C >
  313. inline list_inserter< assign_detail::call_push<C>,
  314. BOOST_DEDUCED_TYPENAME C::value_type >
  315. push( C& c )
  316. {
  317. static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
  318. return make_list_inserter( assign_detail::call_push<C>( c ),
  319. p );
  320. }
  321. template< class C >
  322. inline list_inserter< assign_detail::call_add_edge<C> >
  323. add_edge( C& c )
  324. {
  325. return make_list_inserter( assign_detail::call_add_edge<C>( c ) );
  326. }
  327. } // namespace 'assign'
  328. } // namespace 'boost'
  329. #undef BOOST_ASSIGN_PARAMS1
  330. #undef BOOST_ASSIGN_PARAMS2
  331. #undef BOOST_ASSIGN_PARAMS3
  332. #undef BOOST_ASSIGN_MAX_PARAMETERS
  333. #endif