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 11 #ifndef BOOST_ASSIGN_LIST_INSERTER_HPP 12 #define BOOST_ASSIGN_LIST_INSERTER_HPP 13 14 #if defined(_MSC_VER) 15 # pragma once 16 #endif 17 18 #include <boost/detail/workaround.hpp> 19 20 #include <boost/mpl/if.hpp> 21 #include <boost/type_traits/is_same.hpp> 22 #include <boost/range/begin.hpp> 23 #include <boost/range/end.hpp> 24 #include <boost/config.hpp> 25 #include <cstddef> 26 27 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 28 #include <boost/preprocessor/repetition/enum_params.hpp> 29 #include <boost/preprocessor/cat.hpp> 30 #include <boost/preprocessor/iteration/local.hpp> 31 #include <boost/preprocessor/arithmetic/inc.hpp> 32 33 namespace boost 34 { 35 namespace assign_detail 36 { 37 template< class T > 38 struct repeater 39 { 40 std::size_t sz; 41 T val; 42 repeaterboost::assign_detail::repeater43 repeater( std::size_t sz_, T r ) : sz( sz_ ), val( r ) 44 { } 45 }; 46 47 template< class Fun > 48 struct fun_repeater 49 { 50 std::size_t sz; 51 Fun val; 52 fun_repeaterboost::assign_detail::fun_repeater53 fun_repeater( std::size_t sz_, Fun r ) : sz( sz_ ), val( r ) 54 { } 55 }; 56 57 template< class C > 58 class call_push_back 59 { 60 C& c_; 61 public: call_push_back(C & c)62 call_push_back( C& c ) : c_( c ) 63 { } 64 65 template< class T > operator ()(T r)66 void operator()( T r ) 67 { 68 c_.push_back( r ); 69 } 70 }; 71 72 template< class C > 73 class call_push_front 74 { 75 C& c_; 76 public: call_push_front(C & c)77 call_push_front( C& c ) : c_( c ) 78 { } 79 80 template< class T > operator ()(T r)81 void operator()( T r ) 82 { 83 c_.push_front( r ); 84 } 85 }; 86 87 template< class C > 88 class call_push 89 { 90 C& c_; 91 public: call_push(C & c)92 call_push( C& c ) : c_( c ) 93 { } 94 95 template< class T > operator ()(T r)96 void operator()( T r ) 97 { 98 c_.push( r ); 99 } 100 }; 101 102 template< class C > 103 class call_insert 104 { 105 C& c_; 106 public: call_insert(C & c)107 call_insert( C& c ) : c_( c ) 108 { } 109 110 template< class T > operator ()(T r)111 void operator()( T r ) 112 { 113 c_.insert( r ); 114 } 115 }; 116 117 template< class C > 118 class call_add_edge 119 { 120 C& c_; 121 public: call_add_edge(C & c)122 call_add_edge( C& c ) : c_(c) 123 { } 124 125 template< class T > operator ()(T l,T r)126 void operator()( T l, T r ) 127 { 128 add_edge( l, r, c_ ); 129 } 130 131 template< class T, class EP > operator ()(T l,T r,const EP & ep)132 void operator()( T l, T r, const EP& ep ) 133 { 134 add_edge( l, r, ep, c_ ); 135 } 136 137 }; 138 139 struct forward_n_arguments {}; 140 141 } // namespace 'assign_detail' 142 143 namespace assign 144 { 145 146 template< class T > 147 inline assign_detail::repeater<T> repeat(std::size_t sz,T r)148 repeat( std::size_t sz, T r ) 149 { 150 return assign_detail::repeater<T>( sz, r ); 151 } 152 153 template< class Function > 154 inline assign_detail::fun_repeater<Function> repeat_fun(std::size_t sz,Function r)155 repeat_fun( std::size_t sz, Function r ) 156 { 157 return assign_detail::fun_repeater<Function>( sz, r ); 158 } 159 160 161 template< class Function, class Argument = assign_detail::forward_n_arguments > 162 class list_inserter 163 { 164 struct single_arg_type {}; 165 struct n_arg_type {}; 166 167 typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same<Argument,assign_detail::forward_n_arguments>::value, 168 n_arg_type, 169 single_arg_type >::type arg_type; 170 171 public: 172 list_inserter(Function fun)173 list_inserter( Function fun ) : insert_( fun ) 174 {} 175 176 template< class Function2, class Arg > list_inserter(const list_inserter<Function2,Arg> & r)177 list_inserter( const list_inserter<Function2,Arg>& r ) 178 : insert_( r.fun_private() ) 179 {} 180 list_inserter(const list_inserter & r)181 list_inserter( const list_inserter& r ) : insert_( r.insert_ ) 182 {} 183 operator ()()184 list_inserter& operator()() 185 { 186 insert_( Argument() ); 187 return *this; 188 } 189 190 template< class T > operator =(const T & r)191 list_inserter& operator=( const T& r ) 192 { 193 insert_( r ); 194 return *this; 195 } 196 197 template< class T > operator =(assign_detail::repeater<T> r)198 list_inserter& operator=( assign_detail::repeater<T> r ) 199 { 200 return operator,( r ); 201 } 202 203 template< class Nullary_function > operator =(const assign_detail::fun_repeater<Nullary_function> & r)204 list_inserter& operator=( const assign_detail::fun_repeater<Nullary_function>& r ) 205 { 206 return operator,( r ); 207 } 208 209 template< class T > operator ,(const T & r)210 list_inserter& operator,( const T& r ) 211 { 212 insert_( r ); 213 return *this; 214 } 215 216 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) 217 template< class T > operator ,(const assign_detail::repeater<T> & r)218 list_inserter& operator,( const assign_detail::repeater<T> & r ) 219 { 220 return repeat( r.sz, r.val ); 221 } 222 #else 223 template< class T > operator ,(assign_detail::repeater<T> r)224 list_inserter& operator,( assign_detail::repeater<T> r ) 225 { 226 return repeat( r.sz, r.val ); 227 } 228 #endif 229 230 template< class Nullary_function > operator ,(const assign_detail::fun_repeater<Nullary_function> & r)231 list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r ) 232 { 233 return repeat_fun( r.sz, r.val ); 234 } 235 236 template< class T > repeat(std::size_t sz,T r)237 list_inserter& repeat( std::size_t sz, T r ) 238 { 239 std::size_t i = 0; 240 while( i++ != sz ) 241 insert_( r ); 242 return *this; 243 } 244 245 template< class Nullary_function > repeat_fun(std::size_t sz,Nullary_function fun)246 list_inserter& repeat_fun( std::size_t sz, Nullary_function fun ) 247 { 248 std::size_t i = 0; 249 while( i++ != sz ) 250 insert_( fun() ); 251 return *this; 252 } 253 254 template< class SinglePassIterator > range(SinglePassIterator first,SinglePassIterator last)255 list_inserter& range( SinglePassIterator first, 256 SinglePassIterator last ) 257 { 258 for( ; first != last; ++first ) 259 insert_( *first ); 260 return *this; 261 } 262 263 template< class SinglePassRange > range(const SinglePassRange & r)264 list_inserter& range( const SinglePassRange& r ) 265 { 266 return range( boost::begin(r), boost::end(r) ); 267 } 268 269 template< class T > operator ()(const T & t)270 list_inserter& operator()( const T& t ) 271 { 272 insert_( t ); 273 return *this; 274 } 275 276 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value 277 #define BOOST_ASSIGN_MAX_PARAMS 5 278 #endif 279 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) 280 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) 281 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) 282 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) 283 284 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) 285 #define BOOST_PP_LOCAL_MACRO(n) \ 286 template< class T, BOOST_ASSIGN_PARAMS1(n) > \ 287 list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \ 288 { \ 289 BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \ 290 return *this; \ 291 } \ 292 /**/ 293 294 #include BOOST_PP_LOCAL_ITERATE() 295 296 297 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) 298 #define BOOST_PP_LOCAL_MACRO(n) \ 299 template< class T, BOOST_ASSIGN_PARAMS1(n) > \ 300 void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \ 301 { \ 302 insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \ 303 } \ 304 /**/ 305 306 #include BOOST_PP_LOCAL_ITERATE() 307 308 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) 309 #define BOOST_PP_LOCAL_MACRO(n) \ 310 template< class T, BOOST_ASSIGN_PARAMS1(n) > \ 311 void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \ 312 { \ 313 insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \ 314 } \ 315 /**/ 316 317 #include BOOST_PP_LOCAL_ITERATE() 318 319 fun_private() const320 Function fun_private() const 321 { 322 return insert_; 323 } 324 325 private: 326 327 list_inserter& operator=( const list_inserter& ); 328 Function insert_; 329 }; 330 331 template< class Function > 332 inline list_inserter< Function > make_list_inserter(Function fun)333 make_list_inserter( Function fun ) 334 { 335 return list_inserter< Function >( fun ); 336 } 337 338 template< class Function, class Argument > 339 inline list_inserter<Function,Argument> make_list_inserter(Function fun,Argument *)340 make_list_inserter( Function fun, Argument* ) 341 { 342 return list_inserter<Function,Argument>( fun ); 343 } 344 345 template< class C > 346 inline list_inserter< assign_detail::call_push_back<C>, 347 BOOST_DEDUCED_TYPENAME C::value_type > push_back(C & c)348 push_back( C& c ) 349 { 350 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; 351 return make_list_inserter( assign_detail::call_push_back<C>( c ), 352 p ); 353 } 354 355 template< class C > 356 inline list_inserter< assign_detail::call_push_front<C>, 357 BOOST_DEDUCED_TYPENAME C::value_type > push_front(C & c)358 push_front( C& c ) 359 { 360 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; 361 return make_list_inserter( assign_detail::call_push_front<C>( c ), 362 p ); 363 } 364 365 template< class C > 366 inline list_inserter< assign_detail::call_insert<C>, 367 BOOST_DEDUCED_TYPENAME C::value_type > insert(C & c)368 insert( C& c ) 369 { 370 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; 371 return make_list_inserter( assign_detail::call_insert<C>( c ), 372 p ); 373 } 374 375 template< class C > 376 inline list_inserter< assign_detail::call_push<C>, 377 BOOST_DEDUCED_TYPENAME C::value_type > push(C & c)378 push( C& c ) 379 { 380 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; 381 return make_list_inserter( assign_detail::call_push<C>( c ), 382 p ); 383 } 384 385 template< class C > 386 inline list_inserter< assign_detail::call_add_edge<C> > add_edge(C & c)387 add_edge( C& c ) 388 { 389 return make_list_inserter( assign_detail::call_add_edge<C>( c ) ); 390 } 391 392 } // namespace 'assign' 393 } // namespace 'boost' 394 395 #undef BOOST_ASSIGN_PARAMS1 396 #undef BOOST_ASSIGN_PARAMS2 397 #undef BOOST_ASSIGN_PARAMS3 398 #undef BOOST_ASSIGN_MAX_PARAMETERS 399 400 #endif 401