]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
92f5a8d4 | 25 | #include <boost/move/utility.hpp> |
7c673cae FG |
26 | #include <cstddef> |
27 | ||
92f5a8d4 TL |
28 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
29 | ||
7c673cae FG |
30 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> |
31 | #include <boost/preprocessor/repetition/enum_params.hpp> | |
32 | #include <boost/preprocessor/cat.hpp> | |
33 | #include <boost/preprocessor/iteration/local.hpp> | |
34 | #include <boost/preprocessor/arithmetic/inc.hpp> | |
35 | ||
92f5a8d4 TL |
36 | #endif |
37 | ||
7c673cae FG |
38 | namespace boost |
39 | { | |
40 | namespace assign_detail | |
41 | { | |
42 | template< class T > | |
43 | struct repeater | |
44 | { | |
45 | std::size_t sz; | |
46 | T val; | |
47 | ||
48 | repeater( std::size_t sz_, T r ) : sz( sz_ ), val( r ) | |
49 | { } | |
50 | }; | |
51 | ||
52 | template< class Fun > | |
53 | struct fun_repeater | |
54 | { | |
55 | std::size_t sz; | |
56 | Fun val; | |
57 | ||
58 | fun_repeater( std::size_t sz_, Fun r ) : sz( sz_ ), val( r ) | |
59 | { } | |
60 | }; | |
92f5a8d4 TL |
61 | |
62 | ||
63 | template< class T > | |
64 | struct is_repeater : boost::false_type {}; | |
65 | ||
66 | template< class T > | |
67 | struct is_repeater< boost::assign_detail::repeater<T> > : boost::true_type{}; | |
68 | ||
69 | template< class Fun > | |
70 | struct is_repeater< boost::assign_detail::fun_repeater<Fun> > : boost::true_type{}; | |
71 | ||
72 | ||
7c673cae FG |
73 | template< class C > |
74 | class call_push_back | |
75 | { | |
76 | C& c_; | |
77 | public: | |
78 | call_push_back( C& c ) : c_( c ) | |
79 | { } | |
80 | ||
92f5a8d4 | 81 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
7c673cae FG |
82 | template< class T > |
83 | void operator()( T r ) | |
84 | { | |
85 | c_.push_back( r ); | |
86 | } | |
92f5a8d4 TL |
87 | #else |
88 | template< class T > | |
89 | void operator()(T&& r) | |
90 | { | |
91 | c_.push_back(boost::forward<T>(r)); | |
92 | } | |
93 | #endif | |
7c673cae FG |
94 | }; |
95 | ||
96 | template< class C > | |
97 | class call_push_front | |
98 | { | |
99 | C& c_; | |
100 | public: | |
101 | call_push_front( C& c ) : c_( c ) | |
102 | { } | |
92f5a8d4 TL |
103 | |
104 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
7c673cae FG |
105 | template< class T > |
106 | void operator()( T r ) | |
107 | { | |
108 | c_.push_front( r ); | |
109 | } | |
92f5a8d4 TL |
110 | #else |
111 | template< class T > | |
112 | void operator()(T&& r) | |
113 | { | |
114 | c_.push_front(boost::forward<T>(r)); | |
115 | } | |
116 | #endif | |
7c673cae FG |
117 | }; |
118 | ||
119 | template< class C > | |
120 | class call_push | |
121 | { | |
122 | C& c_; | |
123 | public: | |
124 | call_push( C& c ) : c_( c ) | |
125 | { } | |
126 | ||
92f5a8d4 | 127 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
7c673cae FG |
128 | template< class T > |
129 | void operator()( T r ) | |
130 | { | |
131 | c_.push( r ); | |
132 | } | |
92f5a8d4 TL |
133 | #else |
134 | template< class T > | |
135 | void operator()(T&& r) | |
136 | { | |
137 | c_.push(boost::forward<T>(r)); | |
138 | } | |
139 | #endif | |
7c673cae FG |
140 | }; |
141 | ||
142 | template< class C > | |
143 | class call_insert | |
144 | { | |
145 | C& c_; | |
146 | public: | |
147 | call_insert( C& c ) : c_( c ) | |
148 | { } | |
92f5a8d4 TL |
149 | |
150 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
7c673cae FG |
151 | template< class T > |
152 | void operator()( T r ) | |
153 | { | |
154 | c_.insert( r ); | |
155 | } | |
92f5a8d4 TL |
156 | #else |
157 | template< class T > | |
158 | void operator()(T&& r) | |
159 | { | |
160 | c_.insert(boost::forward<T>(r)); | |
161 | } | |
162 | #endif | |
7c673cae FG |
163 | }; |
164 | ||
165 | template< class C > | |
166 | class call_add_edge | |
167 | { | |
168 | C& c_; | |
169 | public: | |
170 | call_add_edge( C& c ) : c_(c) | |
171 | { } | |
172 | ||
173 | template< class T > | |
174 | void operator()( T l, T r ) | |
175 | { | |
176 | add_edge( l, r, c_ ); | |
177 | } | |
178 | ||
179 | template< class T, class EP > | |
180 | void operator()( T l, T r, const EP& ep ) | |
181 | { | |
182 | add_edge( l, r, ep, c_ ); | |
183 | } | |
184 | ||
185 | }; | |
186 | ||
187 | struct forward_n_arguments {}; | |
188 | ||
189 | } // namespace 'assign_detail' | |
190 | ||
191 | namespace assign | |
192 | { | |
193 | ||
194 | template< class T > | |
195 | inline assign_detail::repeater<T> | |
196 | repeat( std::size_t sz, T r ) | |
197 | { | |
198 | return assign_detail::repeater<T>( sz, r ); | |
199 | } | |
200 | ||
201 | template< class Function > | |
202 | inline assign_detail::fun_repeater<Function> | |
203 | repeat_fun( std::size_t sz, Function r ) | |
204 | { | |
205 | return assign_detail::fun_repeater<Function>( sz, r ); | |
206 | } | |
207 | ||
208 | ||
209 | template< class Function, class Argument = assign_detail::forward_n_arguments > | |
210 | class list_inserter | |
211 | { | |
92f5a8d4 TL |
212 | struct single_arg_type {}; |
213 | struct n_arg_type {}; | |
214 | struct repeater_arg_type {}; | |
7c673cae FG |
215 | |
216 | typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same<Argument,assign_detail::forward_n_arguments>::value, | |
217 | n_arg_type, | |
218 | single_arg_type >::type arg_type; | |
219 | ||
220 | public: | |
221 | ||
222 | list_inserter( Function fun ) : insert_( fun ) | |
223 | {} | |
224 | ||
225 | template< class Function2, class Arg > | |
226 | list_inserter( const list_inserter<Function2,Arg>& r ) | |
227 | : insert_( r.fun_private() ) | |
228 | {} | |
229 | ||
230 | list_inserter( const list_inserter& r ) : insert_( r.insert_ ) | |
231 | {} | |
232 | ||
233 | list_inserter& operator()() | |
234 | { | |
235 | insert_( Argument() ); | |
236 | return *this; | |
237 | } | |
92f5a8d4 TL |
238 | |
239 | #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
7c673cae FG |
240 | template< class T > |
241 | list_inserter& operator=( const T& r ) | |
242 | { | |
243 | insert_( r ); | |
244 | return *this; | |
245 | } | |
92f5a8d4 | 246 | |
7c673cae FG |
247 | template< class T > |
248 | list_inserter& operator=( assign_detail::repeater<T> r ) | |
249 | { | |
250 | return operator,( r ); | |
251 | } | |
252 | ||
253 | template< class Nullary_function > | |
254 | list_inserter& operator=( const assign_detail::fun_repeater<Nullary_function>& r ) | |
255 | { | |
256 | return operator,( r ); | |
257 | } | |
258 | ||
259 | template< class T > | |
260 | list_inserter& operator,( const T& r ) | |
261 | { | |
262 | insert_( r ); | |
263 | return *this; | |
264 | } | |
265 | ||
266 | #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) | |
267 | template< class T > | |
268 | list_inserter& operator,( const assign_detail::repeater<T> & r ) | |
269 | { | |
270 | return repeat( r.sz, r.val ); | |
271 | } | |
272 | #else | |
273 | template< class T > | |
274 | list_inserter& operator,( assign_detail::repeater<T> r ) | |
275 | { | |
276 | return repeat( r.sz, r.val ); | |
277 | } | |
278 | #endif | |
279 | ||
280 | template< class Nullary_function > | |
281 | list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r ) | |
282 | { | |
283 | return repeat_fun( r.sz, r.val ); | |
284 | } | |
92f5a8d4 TL |
285 | #else |
286 | // BOOST_NO_CXX11_RVALUE_REFERENCES | |
287 | template< class T > | |
288 | list_inserter& operator=(T&& r) | |
289 | { | |
290 | return operator,(boost::forward<T>(r)); | |
291 | } | |
292 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
293 | template< class T > | |
294 | list_inserter& operator,(T&& r) | |
295 | { | |
296 | typedef BOOST_DEDUCED_TYPENAME mpl::if_c< assign_detail::is_repeater< T >::value, | |
297 | repeater_arg_type, | |
298 | arg_type >::type tag; | |
299 | ||
300 | insert(boost::forward<T>(r), tag()); | |
301 | return *this; | |
302 | } | |
303 | #else | |
304 | // we add the tag as the first argument when using variadic templates | |
305 | template< class T > | |
306 | list_inserter& operator,(T&& r) | |
307 | { | |
308 | typedef BOOST_DEDUCED_TYPENAME mpl::if_c< assign_detail::is_repeater< T >::value, | |
309 | repeater_arg_type, | |
310 | arg_type >::type tag; | |
311 | ||
312 | insert(tag(), boost::forward<T>(r)); | |
313 | return *this; | |
314 | } | |
315 | #endif | |
316 | #endif | |
7c673cae FG |
317 | |
318 | template< class T > | |
319 | list_inserter& repeat( std::size_t sz, T r ) | |
320 | { | |
321 | std::size_t i = 0; | |
322 | while( i++ != sz ) | |
323 | insert_( r ); | |
324 | return *this; | |
325 | } | |
326 | ||
327 | template< class Nullary_function > | |
328 | list_inserter& repeat_fun( std::size_t sz, Nullary_function fun ) | |
329 | { | |
330 | std::size_t i = 0; | |
331 | while( i++ != sz ) | |
332 | insert_( fun() ); | |
333 | return *this; | |
334 | } | |
335 | ||
336 | template< class SinglePassIterator > | |
337 | list_inserter& range( SinglePassIterator first, | |
338 | SinglePassIterator last ) | |
339 | { | |
340 | for( ; first != last; ++first ) | |
341 | insert_( *first ); | |
342 | return *this; | |
343 | } | |
344 | ||
345 | template< class SinglePassRange > | |
346 | list_inserter& range( const SinglePassRange& r ) | |
347 | { | |
348 | return range( boost::begin(r), boost::end(r) ); | |
349 | } | |
350 | ||
92f5a8d4 | 351 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
7c673cae FG |
352 | template< class T > |
353 | list_inserter& operator()( const T& t ) | |
354 | { | |
355 | insert_( t ); | |
356 | return *this; | |
357 | } | |
358 | ||
359 | #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value | |
360 | #define BOOST_ASSIGN_MAX_PARAMS 5 | |
361 | #endif | |
362 | #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) | |
363 | #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T) | |
364 | #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t) | |
365 | #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t) | |
366 | ||
367 | #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) | |
368 | #define BOOST_PP_LOCAL_MACRO(n) \ | |
369 | template< class T, BOOST_ASSIGN_PARAMS1(n) > \ | |
370 | list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \ | |
371 | { \ | |
372 | BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \ | |
373 | return *this; \ | |
374 | } \ | |
375 | /**/ | |
376 | ||
377 | #include BOOST_PP_LOCAL_ITERATE() | |
378 | ||
379 | ||
380 | #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) | |
381 | #define BOOST_PP_LOCAL_MACRO(n) \ | |
382 | template< class T, BOOST_ASSIGN_PARAMS1(n) > \ | |
383 | void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \ | |
384 | { \ | |
385 | insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \ | |
386 | } \ | |
387 | /**/ | |
388 | ||
389 | #include BOOST_PP_LOCAL_ITERATE() | |
390 | ||
391 | #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS) | |
392 | #define BOOST_PP_LOCAL_MACRO(n) \ | |
393 | template< class T, BOOST_ASSIGN_PARAMS1(n) > \ | |
394 | void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \ | |
395 | { \ | |
396 | insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \ | |
397 | } \ | |
398 | /**/ | |
399 | ||
400 | #include BOOST_PP_LOCAL_ITERATE() | |
401 | ||
92f5a8d4 TL |
402 | #else |
403 | template< class... Ts > | |
404 | list_inserter& operator()(Ts&&... ts) | |
405 | { | |
406 | insert(arg_type(), boost::forward<Ts>(ts)...); | |
407 | return *this; | |
408 | } | |
409 | ||
410 | template< class T > | |
411 | void insert(single_arg_type, T&& t) | |
412 | { | |
413 | // Special implementation for single argument overload to prevent accidental casts (type-cast using functional notation) | |
414 | insert_(boost::forward<T>(t)); | |
415 | } | |
416 | ||
417 | template< class T1, class T2, class... Ts > | |
418 | void insert(single_arg_type, T1&& t1, T2&& t2, Ts&&... ts) | |
419 | { | |
420 | insert_(Argument(boost::forward<T1>(t1), boost::forward<T2>(t2), boost::forward<Ts>(ts)...)); | |
421 | } | |
422 | ||
423 | template< class... Ts > | |
424 | void insert(n_arg_type, Ts&&... ts) | |
425 | { | |
426 | insert_(boost::forward<Ts>(ts)...); | |
427 | } | |
428 | ||
429 | #endif | |
430 | ||
431 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
432 | ||
433 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) | |
434 | ||
435 | template< class T > | |
436 | void insert( T&& r, arg_type) | |
437 | { | |
438 | insert_( boost::forward<T>(r) ); | |
439 | } | |
440 | ||
441 | template< class T > | |
442 | void insert(assign_detail::repeater<T> r, repeater_arg_type) | |
443 | { | |
444 | repeat(r.sz, r.val); | |
445 | } | |
446 | ||
447 | template< class Nullary_function > | |
448 | void insert(const assign_detail::fun_repeater<Nullary_function>& r, repeater_arg_type) | |
449 | { | |
450 | repeat_fun(r.sz, r.val); | |
451 | } | |
452 | #else | |
453 | template< class T > | |
454 | void insert(repeater_arg_type, assign_detail::repeater<T> r) | |
455 | { | |
456 | repeat(r.sz, r.val); | |
457 | } | |
458 | ||
459 | template< class Nullary_function > | |
460 | void insert(repeater_arg_type, const assign_detail::fun_repeater<Nullary_function>& r) | |
461 | { | |
462 | repeat_fun(r.sz, r.val); | |
463 | } | |
464 | #endif | |
465 | #endif | |
466 | ||
467 | ||
7c673cae FG |
468 | Function fun_private() const |
469 | { | |
470 | return insert_; | |
471 | } | |
472 | ||
473 | private: | |
474 | ||
475 | list_inserter& operator=( const list_inserter& ); | |
476 | Function insert_; | |
477 | }; | |
478 | ||
479 | template< class Function > | |
480 | inline list_inserter< Function > | |
481 | make_list_inserter( Function fun ) | |
482 | { | |
483 | return list_inserter< Function >( fun ); | |
484 | } | |
485 | ||
486 | template< class Function, class Argument > | |
487 | inline list_inserter<Function,Argument> | |
488 | make_list_inserter( Function fun, Argument* ) | |
489 | { | |
490 | return list_inserter<Function,Argument>( fun ); | |
491 | } | |
492 | ||
493 | template< class C > | |
494 | inline list_inserter< assign_detail::call_push_back<C>, | |
495 | BOOST_DEDUCED_TYPENAME C::value_type > | |
496 | push_back( C& c ) | |
497 | { | |
498 | static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; | |
499 | return make_list_inserter( assign_detail::call_push_back<C>( c ), | |
500 | p ); | |
501 | } | |
502 | ||
503 | template< class C > | |
504 | inline list_inserter< assign_detail::call_push_front<C>, | |
505 | BOOST_DEDUCED_TYPENAME C::value_type > | |
506 | push_front( C& c ) | |
507 | { | |
508 | static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; | |
509 | return make_list_inserter( assign_detail::call_push_front<C>( c ), | |
510 | p ); | |
511 | } | |
512 | ||
513 | template< class C > | |
514 | inline list_inserter< assign_detail::call_insert<C>, | |
515 | BOOST_DEDUCED_TYPENAME C::value_type > | |
516 | insert( C& c ) | |
517 | { | |
518 | static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; | |
519 | return make_list_inserter( assign_detail::call_insert<C>( c ), | |
520 | p ); | |
521 | } | |
522 | ||
523 | template< class C > | |
524 | inline list_inserter< assign_detail::call_push<C>, | |
525 | BOOST_DEDUCED_TYPENAME C::value_type > | |
526 | push( C& c ) | |
527 | { | |
528 | static BOOST_DEDUCED_TYPENAME C::value_type* p = 0; | |
529 | return make_list_inserter( assign_detail::call_push<C>( c ), | |
530 | p ); | |
531 | } | |
532 | ||
533 | template< class C > | |
534 | inline list_inserter< assign_detail::call_add_edge<C> > | |
535 | add_edge( C& c ) | |
536 | { | |
537 | return make_list_inserter( assign_detail::call_add_edge<C>( c ) ); | |
538 | } | |
539 | ||
540 | } // namespace 'assign' | |
541 | } // namespace 'boost' | |
542 | ||
92f5a8d4 TL |
543 | #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES) |
544 | ||
7c673cae FG |
545 | #undef BOOST_ASSIGN_PARAMS1 |
546 | #undef BOOST_ASSIGN_PARAMS2 | |
547 | #undef BOOST_ASSIGN_PARAMS3 | |
548 | #undef BOOST_ASSIGN_MAX_PARAMETERS | |
549 | ||
550 | #endif | |
92f5a8d4 TL |
551 | |
552 | #endif |