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
12#ifndef BOOST_ASSIGN_LIST_OF_HPP
13#define BOOST_ASSIGN_LIST_OF_HPP
14
15#if defined(_MSC_VER)
16# pragma once
17#endif
18
19#include <boost/assign/assignment_exception.hpp>
20#include <boost/range/iterator_range.hpp>
21#include <boost/config.hpp>
22#include <boost/tuple/tuple.hpp>
23#include <boost/type_traits/remove_const.hpp>
24#include <boost/type_traits/remove_reference.hpp>
25#include <boost/type_traits/is_reference.hpp>
26#include <boost/static_assert.hpp>
27#include <boost/throw_exception.hpp>
28#include <boost/type_traits/conditional.hpp>
29#include <boost/type_traits/detail/yes_no_type.hpp>
30#include <boost/type_traits/decay.hpp>
31#include <boost/type_traits/is_array.hpp>
32#include <boost/utility/enable_if.hpp>
33#include <boost/utility/declval.hpp>
34#include <boost/move/utility.hpp>
35#include <deque>
36#include <cstddef>
37#include <utility>
38#ifndef BOOST_NO_CXX11_HDR_ARRAY
39#include <array>
40#endif
41#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
42#include <initializer_list>
43#endif
44
45// some gcc < 4.7 do not support all of the variadic features required for boost::assign
46#if !(defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || BOOST_WORKAROUND(BOOST_GCC, < 40700) \
47 || defined(BOOST_NO_CXX11_RVALUE_REFERENCES))
48# define BOOST_ASSIGN_USE_VARIADIC_TEMPLATES
49#endif
50
51#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
52
53#include <boost/preprocessor/repetition/enum_binary_params.hpp>
54#include <boost/preprocessor/repetition/enum_params.hpp>
55#include <boost/preprocessor/iteration/local.hpp>
56
57#endif
58
59#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
60// BCB requires full type definition for is_array<> to work correctly.
61#include <boost/array.hpp>
62#endif
63
64namespace boost
65{
66
67// this here is necessary to avoid compiler error in <boost/array.hpp>
68#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
69 template< class T, std::size_t sz >
70 class array;
71#endif
72
73namespace assign_detail
74{
75 /////////////////////////////////////////////////////////////////////////
76 // Part 0: common conversion code
77 /////////////////////////////////////////////////////////////////////////
78
79 template< class T >
80 struct assign_decay
81 {
82 //
83 // Add constness to array parameters
84 // to support string literals properly
85 //
86 typedef BOOST_DEDUCED_TYPENAME ::boost::conditional<
87 ::boost::is_array<T>::value,
88 ::boost::decay<const T>,
89 ::boost::decay<T> >::type::type type;
90 };
91
92 template< class T, std::size_t sz >
93 type_traits::yes_type assign_is_array( const array<T,sz>* );
94#ifndef BOOST_NO_CXX11_HDR_ARRAY
95 template< class T, std::size_t sz >
96 type_traits::yes_type assign_is_array( const std::array<T, sz>* );
97#endif
98 type_traits::no_type assign_is_array( ... );
99 template< class T, class U >
100 type_traits::yes_type assign_is_pair( const std::pair<T,U>* );
101 type_traits::no_type assign_is_pair( ... );
102
103
104
105 struct array_type_tag
106 {
107 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
108 private:
109 char dummy_; // BCB would by default use 8 bytes
110 #endif
111 };
112 struct adapter_type_tag
113 {
114 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
115 private:
116 char dummy_; // BCB would by default use 8 bytes
117 #endif
118 };
119 struct pair_type_tag
120 {
121 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
122 private:
123 char dummy_; // BCB would by default use 8 bytes
124 #endif
125 };
126 struct default_type_tag
127 {
128 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
129 private:
130 char dummy_; // BCB would by default use 8 bytes
131 #endif
132 };
133
134#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
135 template< class C >
136 struct is_initializer_list : boost::false_type {};
137
138 template< class E >
139 struct is_initializer_list< std::initializer_list<E> > : boost::true_type {};
140#endif
141
142 template< class DerivedTAssign, class Iterator >
143 class converter
144 {
145 public: // Range operations
146 typedef Iterator iterator;
147 typedef Iterator const_iterator;
148
149 iterator begin() const
150 {
151 return static_cast<const DerivedTAssign*>(this)->begin();
152 }
153
154 iterator end() const
155 {
156 return static_cast<const DerivedTAssign*>(this)->end();
157 }
158
159 public:
160
161 template< class Container >
162 Container convert_to_container() const
163 {
164 static Container* c = 0;
165 BOOST_STATIC_CONSTANT( bool, is_array_flag = sizeof( assign_detail::assign_is_array( c ) )
166 == sizeof( type_traits::yes_type ) );
167
168 typedef BOOST_DEDUCED_TYPENAME ::boost::conditional< is_array_flag,
169 array_type_tag,
170 default_type_tag >::type tag_type;
171
172 return convert<Container>( c, tag_type() );
173 }
174
175 private:
176
177 template< class Container >
178 Container convert( const Container*, default_type_tag ) const
179 {
180
181#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
182// old Dinkumware doesn't support iterator type as template
183 Container result;
184 iterator it = begin(),
185 e = end();
186 while( it != e )
187 {
188 result.insert( result.end(), *it );
189 ++it;
190 }
191 return result;
192#else
193 return Container( begin(), end() );
194#endif
195 }
196
197 template< class Array >
198 Array convert( const Array*, array_type_tag ) const
199 {
200 typedef BOOST_DEDUCED_TYPENAME Array::value_type value_type;
201
202#if BOOST_WORKAROUND(BOOST_INTEL, <= 910 ) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5100 )
203 BOOST_DEDUCED_TYPENAME remove_const<Array>::type ar;
204#else
205 Array ar;
206#endif
207 const std::size_t sz = ar.size();
208 if( sz < static_cast<const DerivedTAssign*>(this)->size() )
209 BOOST_THROW_EXCEPTION( assign::assignment_exception( "array initialized with too many elements" ) );
210 std::size_t n = 0;
211 iterator i = begin(),
212 e = end();
213 for( ; i != e; ++i, ++n )
214 ar[n] = *i;
215 for( ; n < sz; ++n )
216 ar[n] = value_type();
217 return ar;
218 }
219
220 template< class Adapter >
221 Adapter convert_to_adapter( const Adapter* = 0 ) const
222 {
223 Adapter a;
224 iterator i = begin(),
225 e = end();
226 for( ; i != e; ++i )
227 a.push( *i );
228 return a;
229 }
230
231 private:
232 struct adapter_converter;
233 friend struct adapter_converter;
234
235 struct adapter_converter
236 {
237 const converter& gl;
238 adapter_converter( const converter& this_ ) : gl( this_ )
239 {}
240
241 adapter_converter( const adapter_converter& r )
242 : gl( r.gl )
243 { }
244
245 template< class Adapter >
246 operator Adapter() const
247 {
248 return gl.convert_to_adapter<Adapter>();
249 }
250 };
251
252 public:
253 template< class Container >
254 Container to_container( Container& c ) const
255 {
256 return convert( &c, default_type_tag() );
257 }
258
259 adapter_converter to_adapter() const
260 {
261 return adapter_converter( *this );
262 }
263
264 template< class Adapter >
265 Adapter to_adapter( Adapter& a ) const
266 {
267 return this->convert_to_adapter( &a );
268 }
269
270 template< class Array >
271 Array to_array( Array& a ) const
272 {
273 return convert( &a, array_type_tag() );
274 }
275 };
276
277 template< class T, class I, class Range >
278 inline bool operator==( const converter<T,I>& l, const Range& r )
279 {
280 return ::boost::iterator_range_detail::equal( l, r );
281 }
282
283 template< class T, class I, class Range >
284 inline bool operator==( const Range& l, const converter<T,I>& r )
285 {
286 return r == l;
287 }
288
289 template< class T, class I, class Range >
290 inline bool operator!=( const converter<T,I>& l, const Range& r )
291 {
292 return !( l == r );
293 }
294
295 template< class T, class I, class Range >
296 inline bool operator!=( const Range& l, const converter<T,I>& r )
297 {
298 return !( l == r );
299 }
300
301 template< class T, class I, class Range >
302 inline bool operator<( const converter<T,I>& l, const Range& r )
303 {
304 return ::boost::iterator_range_detail::less_than( l, r );
305 }
306
307 template< class T, class I, class Range >
308 inline bool operator<( const Range& l, const converter<T,I>& r )
309 {
310 return ::boost::iterator_range_detail::less_than( l, r );
311 }
312
313 template< class T, class I, class Range >
314 inline bool operator>( const converter<T,I>& l, const Range& r )
315 {
316 return r < l;
317 }
318
319 template< class T, class I, class Range >
320 inline bool operator>( const Range& l, const converter<T,I>& r )
321 {
322 return r < l;
323 }
324
325 template< class T, class I, class Range >
326 inline bool operator<=( const converter<T,I>& l, const Range& r )
327 {
328 return !( l > r );
329 }
330
331 template< class T, class I, class Range >
332 inline bool operator<=( const Range& l, const converter<T,I>& r )
333 {
334 return !( l > r );
335 }
336
337 template< class T, class I, class Range >
338 inline bool operator>=( const converter<T,I>& l, const Range& r )
339 {
340 return !( l < r );
341 }
342
343 template< class T, class I, class Range >
344 inline bool operator>=( const Range& l, const converter<T,I>& r )
345 {
346 return !( l < r );
347 }
348
349 template< class T, class I, class Elem, class Traits >
350 inline std::basic_ostream<Elem,Traits>&
351 operator<<( std::basic_ostream<Elem, Traits>& Os,
352 const converter<T,I>& r )
353 {
354 return Os << ::boost::make_iterator_range( r.begin(), r.end() );
355 }
356
357 /////////////////////////////////////////////////////////////////////////
358 // Part 1: flexible, but inefficient interface
359 /////////////////////////////////////////////////////////////////////////
360
361 template< class T >
362 class generic_list :
363 public converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type >,
364 BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME
365 assign_decay<T>::type>::iterator >
366 {
367 typedef BOOST_DEDUCED_TYPENAME assign_decay<T>::type Ty;
368 typedef std::deque<Ty> impl_type;
369 mutable impl_type values_;
370
371 public:
372 typedef BOOST_DEDUCED_TYPENAME impl_type::iterator iterator;
373 typedef iterator const_iterator;
374 typedef BOOST_DEDUCED_TYPENAME impl_type::value_type value_type;
375 typedef BOOST_DEDUCED_TYPENAME impl_type::size_type size_type;
376 typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type difference_type;
377
378 public:
379 iterator begin() const { return values_.begin(); }
380 iterator end() const { return values_.end(); }
381 bool empty() const { return values_.empty(); }
382 size_type size() const { return values_.size(); }
383
384 private:
385#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
386 void push_back( value_type r ) { values_.push_back( r ); }
387#else
388 void push_back( const value_type& r ) { values_.push_back( r ); }
389 void push_back( value_type&& r ) { values_.push_back( boost::move( r ) ); }
390#endif
391 public:
392 generic_list& operator,( const Ty& u )
393 {
394 this->push_back( u );
395 return *this;
396 }
397
398#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
399
400 generic_list& operator,( Ty&& u )
401 {
402 this->push_back( boost::move(u) );
403 return *this;
404 }
405#endif
406 generic_list& operator()( const Ty& u )
407 {
408 this->push_back( u );
409 return *this;
410 }
411
412#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
413
414 generic_list& operator()(Ty&& u)
415 {
416 this->push_back( boost::move(u) );
417 return *this;
418 }
419#endif
420
421 generic_list& operator()()
422 {
423 this->push_back( Ty() );
424 return *this;
425 }
426
427#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
428
429#ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
430#define BOOST_ASSIGN_MAX_PARAMS 5
431#endif
432#define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
433#define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
434#define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
435#define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
436#define BOOST_ASSIGN_PARAMS4(n) BOOST_PP_ENUM_PARAMS(n, U)
437#define BOOST_ASSIGN_PARAMS2_NO_REF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, u)
438
439#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
440#define BOOST_PP_LOCAL_MACRO(n) \
441 template< class U, BOOST_ASSIGN_PARAMS1(n) > \
442 generic_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
443 { \
444 this->push_back( Ty(u, BOOST_ASSIGN_PARAMS3(n))); \
445 return *this; \
446 } \
447 /**/
448
449#include BOOST_PP_LOCAL_ITERATE()
450
451#else
452 template< class U0, class U1, class... Us >
453 generic_list& operator()(U0&& u0, U1&& u1, Us&&... us)
454 {
455 this->push_back(Ty(boost::forward<U0>(u0), boost::forward<U1>(u1), boost::forward<Us>(us)...));
456 return *this;
457 }
458#endif
459
460 template< class U >
461 generic_list& repeat( std::size_t sz, U u )
462 {
463 std::size_t i = 0;
464 while( i++ != sz )
465 this->push_back( u );
466 return *this;
467 }
468
469 template< class Nullary_function >
470 generic_list& repeat_fun( std::size_t sz, Nullary_function fun )
471 {
472 std::size_t i = 0;
473 while( i++ != sz )
474 this->push_back( fun() );
475 return *this;
476 }
477
478 template< class SinglePassIterator >
479 generic_list& range( SinglePassIterator first,
480 SinglePassIterator last )
481 {
482 for( ; first != last; ++first )
483 this->push_back( *first );
484 return *this;
485 }
486
487 template< class SinglePassRange >
488 generic_list& range( const SinglePassRange& r )
489 {
490 return range( boost::begin(r), boost::end(r) );
491 }
492#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
493 template< class Container,
494 class = decltype(Container(
495 boost::declval<BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME assign_decay<T>::type>::iterator>(),
496 boost::declval<BOOST_DEDUCED_TYPENAME std::deque<BOOST_DEDUCED_TYPENAME assign_decay<T>::type>::iterator>()
497 ))
498 >
499 operator Container() const
500 {
501 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
502 }
503
504 template< class Container,
505 class = typename boost::enable_if< boost::is_same< boost::type_traits::yes_type, decltype(assign_is_array((Container*)0))> >::type,
506 class = void
507 >
508 operator Container() const
509 {
510 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
511 }
512#elif !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
513 template< class Container
514# if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
515 , class = typename boost::disable_if< is_initializer_list<Container> >::type
516# endif
517 , class = typename Container::iterator
518 >
519 operator Container() const
520 {
521 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
522 }
523#else
524 template< class Container >
525 operator Container() const
526 {
527 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
528 }
529#endif
530 };
531
532 /////////////////////////////////////////////////////////////////////////
533 // Part 2: efficient, but inconvenient interface
534 /////////////////////////////////////////////////////////////////////////
535
536 template< class T >
537 struct assign_reference
538 {
539 assign_reference() : ref_(0)
540 { /* intentionally empty */ }
541
542 assign_reference( T& r ) : ref_(&r)
543 { }
544
545 void operator=( T& r )
546 {
547 ref_ = &r;
548 }
549
550 operator T&() const
551 {
552 return *ref_;
553 }
554
555 void swap( assign_reference& r )
556 {
557 std::swap( *ref_, *r.ref_ );
558 }
559
560 T& get_ref() const
561 {
562 return *ref_;
563 }
564
565 private:
566 T* ref_;
567
568 };
569
570 template< class T >
571 inline bool operator<( const assign_reference<T>& l,
572 const assign_reference<T>& r )
573 {
574 return l.get_ref() < r.get_ref();
575 }
576
577 template< class T >
578 inline bool operator>( const assign_reference<T>& l,
579 const assign_reference<T>& r )
580 {
581 return l.get_ref() > r.get_ref();
582 }
583
584 template< class T >
585 inline void swap( assign_reference<T>& l,
586 assign_reference<T>& r )
587 {
588 l.swap( r );
589 }
590
591
592
593 template< class T, int N >
594 struct static_generic_list :
595 public converter< static_generic_list<T,N>, assign_reference<T>* >
596 {
597 private:
598 typedef T internal_value_type;
599
600 public:
601 typedef assign_reference<internal_value_type> value_type;
602 typedef value_type* iterator;
603 typedef value_type* const_iterator;
604 typedef std::size_t size_type;
605 typedef std::ptrdiff_t difference_type;
606
607
608 static_generic_list( T& r ) :
609 current_(1)
610 {
611 refs_[0] = r;
612 }
613
614 static_generic_list& operator()( T& r )
615 {
616 insert( r );
617 return *this;
618 }
619
620 iterator begin() const
621 {
622 return &refs_[0];
623 }
624
625 iterator end() const
626 {
627 return &refs_[current_];
628 }
629
630 size_type size() const
631 {
632 return static_cast<size_type>( current_ );
633 }
634
635 bool empty() const
636 {
637 return false;
638 }
639
640 template< class ForwardIterator >
641 static_generic_list& range( ForwardIterator first,
642 ForwardIterator last )
643 {
644 for( ; first != last; ++first )
645 this->insert( *first );
646 return *this;
647 }
648
649 template< class ForwardRange >
650 static_generic_list& range( ForwardRange& r )
651 {
652 return range( boost::begin(r), boost::end(r) );
653 }
654
655 template< class ForwardRange >
656 static_generic_list& range( const ForwardRange& r )
657 {
658 return range( boost::begin(r), boost::end(r) );
659 }
660
661#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
662 template< class Container,
663 class = decltype(Container(boost::declval<assign_reference<T>*>(), boost::declval<assign_reference<T>*>()))
664 >
665 operator Container() const
666 {
667 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
668 }
669
670 template< class Container,
671 class = typename boost::enable_if< boost::is_same< boost::type_traits::yes_type, decltype(assign_is_array((Container*)0))> >::type,
672 class = void
673 >
674 operator Container() const
675 {
676 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
677 }
678#elif !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
679 template< class Container
680# if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
681 , class = typename boost::disable_if< is_initializer_list<Container> >::type
682# endif
683 , class = typename Container::iterator
684 >
685 operator Container() const
686 {
687 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
688 }
689#else
690 template< class Container >
691 operator Container() const
692 {
693 return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
694 }
695#endif
696
697 private:
698 void insert( T& r )
699 {
700 refs_[current_] = r;
701 ++current_;
702 }
703
704 static_generic_list();
705
706 mutable assign_reference<internal_value_type> refs_[N];
707 int current_;
708 };
709
710} // namespace 'assign_detail'
711
712namespace assign
713{
714 template< class T >
715 inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
716 list_of()
717 {
718 assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
719 gl();
720 return gl;
721 }
722
723#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
724
725 template< class T >
726 inline assign_detail::generic_list<T>
727 list_of( const T& t )
728 {
729 return assign_detail::generic_list<T>()( t );
730 }
731
732#else
733
734 template< class T >
735 inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
736 list_of(T&& t)
737 {
738 assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
739 gl(boost::forward<T>(t));
740 return gl;
741 }
742
743#endif
744
745 template< int N, class T >
746 inline assign_detail::static_generic_list< BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
747 ref_list_of( T& t )
748 {
749 return assign_detail::static_generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
750 }
751
752 template< int N, class T >
753 inline assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
754 cref_list_of( const T& t )
755 {
756 return assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
757 }
758
759#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
760
761#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
762#define BOOST_PP_LOCAL_MACRO(n) \
763 template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
764 inline assign_detail::generic_list<T> \
765 list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
766 { \
767 return assign_detail::generic_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
768 } \
769 /**/
770
771#include BOOST_PP_LOCAL_ITERATE()
772
773#define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
774#define BOOST_PP_LOCAL_MACRO(n) \
775 template< class U, BOOST_ASSIGN_PARAMS1(n) > \
776 inline assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> > \
777 tuple_list_of(U u, BOOST_ASSIGN_PARAMS2_NO_REF(n) ) \
778 { \
779 return assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> >()( tuple<U,BOOST_ASSIGN_PARAMS4(n)>( u, BOOST_ASSIGN_PARAMS3(n) )); \
780 } \
781 /**/
782
783#include BOOST_PP_LOCAL_ITERATE()
784
785#else
786 template< class T, class U, class... Us >
787 inline assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type>
788 list_of(U&& u, Us&&... us)
789 {
790 assign_detail::generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type> gl;
791 gl(boost::forward<U>(u), boost::forward<Us>(us)...);
792 return gl;
793 }
794
795
796 template< class U, class... Us >
797 inline assign_detail::generic_list< tuple<U, Us...> >
798 tuple_list_of(U u, Us... us)
799 {
800 assign_detail::generic_list< tuple<U, Us...> > gl;
801 gl(tuple<U, Us...>(u, us...));
802 return gl;
803 }
804#endif
805
806 template< class Key, class T >
807 inline assign_detail::generic_list< std::pair
808 <
809 BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type,
810 BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type
811 > >
812 map_list_of( const Key& k, const T& t )
813 {
814 typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type k_type;
815 typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type t_type;
816 return assign_detail::generic_list< std::pair<k_type,t_type> >()( k, t );
817 }
818
819 template< class F, class S >
820 inline assign_detail::generic_list< std::pair
821 <
822 BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<F>::type,
823 BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<S>::type
824 > >
825 pair_list_of( const F& f, const S& s )
826 {
827 return map_list_of( f, s );
828 }
829
830
831} // namespace 'assign'
832} // namespace 'boost'
833
834
835#if !defined(BOOST_ASSIGN_USE_VARIADIC_TEMPLATES)
836
837#undef BOOST_ASSIGN_PARAMS1
838#undef BOOST_ASSIGN_PARAMS2
839#undef BOOST_ASSIGN_PARAMS3
840#undef BOOST_ASSIGN_PARAMS4
841#undef BOOST_ASSIGN_PARAMS2_NO_REF
842#undef BOOST_ASSIGN_MAX_PARAMETERS
843
844#endif
845
846
847#endif
848

source code of boost/libs/assign/include/boost/assign/list_of.hpp