Add new boost dependencies
[dyninst.git] / external / boost / assign / list_of.hpp
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) && (_MSC_VER >= 1020)
16 # pragma once
17 #endif
18
19 #include <boost/assign/assignment_exception.hpp>
20 #include <boost/range/begin.hpp>
21 #include <boost/range/end.hpp>
22 #include <boost/config.hpp>
23 #include <boost/tuple/tuple.hpp>
24 #include <boost/type_traits/remove_const.hpp>
25 #include <boost/type_traits/remove_reference.hpp>
26 #include <boost/type_traits/is_reference.hpp>
27 #include <boost/static_assert.hpp>
28 #include <boost/type_traits/detail/yes_no_type.hpp>
29 #include <boost/type_traits/decay.hpp>
30 #include <boost/type_traits/is_array.hpp>
31 #include <boost/mpl/if.hpp>
32 #include <deque>
33 #include <cstddef>
34 #include <utility>
35
36 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
37 #include <boost/preprocessor/repetition/enum_params.hpp>
38 #include <boost/preprocessor/iteration/local.hpp>
39
40 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
41 // BCB requires full type definition for is_array<> to work correctly.
42 #include <boost/array.hpp>
43 #endif
44
45 namespace boost
46 {
47
48 // this here is necessary to avoid compiler error in <boost/array.hpp>
49 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
50     template< class T, std::size_t sz >
51     class array;
52 #endif    
53     
54 namespace assign_detail
55 {
56     /////////////////////////////////////////////////////////////////////////
57     // Part 0: common conversion code
58     /////////////////////////////////////////////////////////////////////////
59
60     template< class T >
61     struct assign_decay
62     {
63         //
64         // Add constness to array parameters
65         // to support string literals properly
66         //
67         typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
68             ::boost::is_array<T>,
69             ::boost::decay<const T>,
70             ::boost::decay<T> >::type type;
71     };
72     
73     template< class T, std::size_t sz >
74     type_traits::yes_type assign_is_array( const array<T,sz>* );
75     type_traits::no_type assign_is_array( ... );
76     template< class T, class U >
77     type_traits::yes_type assign_is_pair( const std::pair<T,U>* );
78     type_traits::no_type assign_is_pair( ... ); 
79
80
81     
82     struct array_type_tag
83     {
84     #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
85     private:
86       char dummy_;  // BCB would by default use 8 bytes
87     #endif
88     };
89     struct adapter_type_tag
90     {
91     #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
92     private:
93       char dummy_;  // BCB would by default use 8 bytes
94     #endif
95     };
96     struct pair_type_tag
97     {
98     #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
99     private:
100       char dummy_;  // BCB would by default use 8 bytes
101     #endif
102     };
103     struct default_type_tag
104     {
105     #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
106     private:
107       char dummy_;  // BCB would by default use 8 bytes
108     #endif
109     };
110
111
112     
113     template< class DerivedTAssign >
114     class converter
115     {
116     public:
117
118         template< class Container >
119         Container convert_to_container() const
120         {
121             static Container* c = 0;
122             BOOST_STATIC_CONSTANT( bool, is_array_flag = sizeof( assign_detail::assign_is_array( c ) ) 
123                                    == sizeof( type_traits::yes_type ) );
124
125             typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_array_flag,
126                                                       array_type_tag,
127                                              default_type_tag >::type tag_type;
128
129             return convert<Container>( c, tag_type() );
130         }
131         
132     private:
133         
134         template< class Container >
135         Container convert( const Container*, default_type_tag ) const
136         {
137
138 #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
139 // old Dinkumware doesn't support iterator type as template
140             Container result;
141             BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator 
142                 it  = static_cast<const DerivedTAssign*>(this)->begin(), 
143                 end = static_cast<const DerivedTAssign*>(this)->end();
144             while( it != end )
145             {
146                 result.insert( result.end(), *it );
147                 ++it;
148             }
149             return result;
150 #else
151             return Container( static_cast<const DerivedTAssign*>(this)->begin(),
152                               static_cast<const DerivedTAssign*>(this)->end() );
153 #endif
154         }
155
156         template< class Array >
157         Array convert( const Array*, array_type_tag ) const
158         {
159             typedef BOOST_DEDUCED_TYPENAME Array::value_type value_type;
160
161 #if BOOST_WORKAROUND(BOOST_INTEL, <= 910 ) || BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580 )
162             BOOST_DEDUCED_TYPENAME remove_const<Array>::type ar;
163 #else
164             Array ar;
165 #endif            
166             const std::size_t sz = ar.size();
167             if( sz < static_cast<const DerivedTAssign*>(this)->size() )
168                 throw assign::assignment_exception( "array initialized with too many elements" );
169             std::size_t n = 0; 
170             BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator 
171                 i   = static_cast<const DerivedTAssign*>(this)->begin(), 
172                 end = static_cast<const DerivedTAssign*>(this)->end();
173             for( ; i != end; ++i, ++n )
174                 ar[n] = *i;
175             for( ; n < sz; ++n )
176                 ar[n] = value_type();
177             return ar; 
178         }
179
180         template< class Adapter >
181         Adapter convert_to_adapter( const Adapter* = 0 ) const
182         {
183             Adapter a;
184             BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator 
185                 i = static_cast<const DerivedTAssign*>(this)->begin(), 
186                 end = static_cast<const DerivedTAssign*>(this)->end();
187             for( ; i != end; ++i )
188                 a.push( *i );
189             return a;
190         }
191
192     private:
193         struct adapter_converter;
194         friend struct adapter_converter;
195
196         struct adapter_converter
197         {
198             const converter& gl;
199             adapter_converter( const converter& this_ ) : gl( this_ )
200             {}
201
202             adapter_converter( const adapter_converter& r ) 
203             : gl( r.gl )
204             { }
205
206             template< class Adapter >
207             operator Adapter() const
208             {
209                 return gl.convert_to_adapter<Adapter>();
210             }
211         };
212
213     public: 
214         template< class Container >
215         Container to_container( Container& c ) const
216         {
217             return convert( &c, default_type_tag() ); 
218         }
219
220         adapter_converter to_adapter() const
221         {
222             return adapter_converter( *this );
223         }
224
225         template< class Adapter >
226         Adapter to_adapter( Adapter& a ) const
227         {
228             return this->convert_to_adapter( &a ); 
229         }
230
231         template< class Array >
232         Array to_array( Array& a ) const
233         {
234             return convert( &a, array_type_tag() );
235         }
236     };
237     
238     /////////////////////////////////////////////////////////////////////////
239     // Part 1: flexible, but inefficient interface
240     /////////////////////////////////////////////////////////////////////////    
241
242     template< class T > 
243     class generic_list : 
244         public converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type > >
245     {
246         typedef converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type > >
247                                                              base_type;
248         typedef BOOST_DEDUCED_TYPENAME assign_decay<T>::type Ty;
249         typedef std::deque<Ty>  impl_type;
250         mutable impl_type       values_;
251         
252     public:
253         typedef BOOST_DEDUCED_TYPENAME impl_type::iterator         iterator;
254         typedef BOOST_DEDUCED_TYPENAME impl_type::const_iterator   const_iterator;
255         typedef BOOST_DEDUCED_TYPENAME impl_type::value_type       value_type;
256         typedef BOOST_DEDUCED_TYPENAME impl_type::size_type        size_type;
257         typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type  difference_type;
258         
259     public:
260         iterator begin() const       { return values_.begin(); }
261         iterator end() const         { return values_.end(); }
262         bool empty() const           { return values_.empty(); }
263         size_type size() const       { return values_.size(); }
264         
265     private:
266         void push_back( value_type r ) { values_.push_back( r ); }
267         
268     public:
269         generic_list& operator,( const Ty& u )
270         {
271             this->push_back( u ); 
272             return *this;
273         }
274
275         generic_list& operator()()
276         {
277             this->push_back( Ty() );
278             return *this;
279         }
280
281         generic_list& operator()( const Ty& u )
282         {
283             this->push_back( u );
284             return *this;
285         }
286         
287        
288 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
289 #define BOOST_ASSIGN_MAX_PARAMS 5
290 #endif        
291 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) 
292 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
293 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
294 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
295 #define BOOST_ASSIGN_PARAMS4(n) BOOST_PP_ENUM_PARAMS(n, U)
296 #define BOOST_ASSIGN_PARAMS2_NO_REF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, u)
297
298 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
299 #define BOOST_PP_LOCAL_MACRO(n) \
300     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
301     generic_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
302     { \
303         this->push_back( Ty(u, BOOST_ASSIGN_PARAMS3(n))); \
304         return *this; \
305     } \
306     /**/
307         
308 #include BOOST_PP_LOCAL_ITERATE()
309
310         
311         template< class U >
312         generic_list& repeat( std::size_t sz, U u )
313         {
314             std::size_t i = 0;
315             while( i++ != sz )
316                 this->push_back( u );
317             return *this;
318         }
319         
320         template< class Nullary_function >
321         generic_list& repeat_fun( std::size_t sz, Nullary_function fun )
322         {
323             std::size_t i = 0;
324             while( i++ != sz )
325                 this->push_back( fun() );
326             return *this;
327         }
328
329         template< class SinglePassIterator >
330         generic_list& range( SinglePassIterator first, 
331                              SinglePassIterator last )
332         {
333             for( ; first != last; ++first )
334                 this->push_back( *first );
335             return *this;
336         }
337         
338         template< class SinglePassRange >
339         generic_list& range( const SinglePassRange& r )
340         {
341             return range( boost::begin(r), boost::end(r) );
342         }
343
344         template< class Container >
345         operator Container() const
346         {
347             return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
348         }
349     };
350
351     /////////////////////////////////////////////////////////////////////////
352     // Part 2: efficient, but inconvenient interface
353     /////////////////////////////////////////////////////////////////////////
354
355     template< class T >
356     struct assign_reference
357     {
358         assign_reference()
359         { /* intentionally empty */ }
360
361         assign_reference( T& r ) : ref_(&r)
362         { }
363
364         void operator=( T& r )
365         {
366             ref_ = &r;
367         }
368
369         operator T&() const
370         {
371             return *ref_;
372         }
373
374         void swap( assign_reference& r )
375         {
376             std::swap( *ref_, *r.ref_ );
377         }
378
379         T& get_ref() const
380         {
381             return *ref_;
382         }
383         
384     private:
385         T* ref_;
386
387     };
388
389     template< class T >
390     inline bool operator<( const assign_reference<T>& l, 
391                            const assign_reference<T>& r )
392     {
393         return l.get_ref() < r.get_ref();
394     }
395
396     template< class T >
397     inline bool operator>( const assign_reference<T>& l,
398                            const assign_reference<T>& r )
399     {
400         return l.get_ref() > r.get_ref();
401     }
402
403     template< class T >
404     inline void swap( assign_reference<T>& l, 
405                       assign_reference<T>& r )
406     {
407         l.swap( r );
408     }
409
410
411     
412     template< class T, int N >
413     struct static_generic_list : 
414         public converter< static_generic_list<T,N> >
415     {
416     private:
417         typedef converter< static_generic_list<T,N> >  base_class;
418         typedef T                                      internal_value_type;
419
420     public:
421         typedef assign_reference<internal_value_type> value_type;
422         typedef value_type*                           iterator;
423         typedef const value_type*                     const_iterator;
424         typedef std::size_t                           size_type;
425         typedef std::ptrdiff_t                        difference_type;
426
427     
428         static_generic_list( T& r ) :
429             current_(1)
430         {
431             refs_[0] = r;
432         }
433
434         static_generic_list& operator()( T& r )
435         {
436             insert( r );
437             return *this;
438         }
439
440         iterator begin() const 
441         {
442             return &refs_[0];
443         }
444
445         iterator end() const
446         {
447             return &refs_[current_];
448         }
449
450         size_type size() const
451         {
452             return static_cast<size_type>( current_ ); 
453         }
454
455         bool empty() const
456         {
457             return false;
458         }
459
460         template< class ForwardIterator >
461         static_generic_list& range( ForwardIterator first, 
462                                     ForwardIterator last )
463         {
464             for( ; first != last; ++first )
465                 this->insert( *first );
466             return *this;
467         }
468
469         template< class ForwardRange >
470         static_generic_list& range( ForwardRange& r )
471         {
472             return range( boost::begin(r), boost::end(r) );
473         }
474
475         template< class ForwardRange >
476         static_generic_list& range( const ForwardRange& r )
477         {
478             return range( boost::begin(r), boost::end(r) );
479         }
480
481         template< class Container >
482         operator Container() const
483         {
484             return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
485         }
486
487     private:
488         void insert( T& r )
489         {
490             refs_[current_] = r;
491             ++current_;
492         }
493         
494         static_generic_list();
495         
496         mutable assign_reference<internal_value_type> refs_[N];
497         int current_;
498     };
499
500 } // namespace 'assign_detail'
501
502 namespace assign
503 {
504     template< class T >
505     inline assign_detail::generic_list<T>
506     list_of()
507     {
508         return assign_detail::generic_list<T>()( T() );
509     }
510     
511     template< class T >
512     inline assign_detail::generic_list<T> 
513     list_of( const T& t )
514     {
515         return assign_detail::generic_list<T>()( t );
516     }
517
518     template< int N, class T >
519     inline assign_detail::static_generic_list< BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
520     ref_list_of( T& t )
521     {
522         return assign_detail::static_generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
523     }
524     
525     template< int N, class T >
526     inline assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
527     cref_list_of( const T& t )
528     {
529         return assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
530     }
531
532 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
533 #define BOOST_PP_LOCAL_MACRO(n) \
534     template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
535     inline assign_detail::generic_list<T> \
536     list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
537     { \
538         return assign_detail::generic_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
539     } \
540     /**/
541     
542 #include BOOST_PP_LOCAL_ITERATE()
543
544 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
545 #define BOOST_PP_LOCAL_MACRO(n) \
546     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
547     inline assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> > \
548     tuple_list_of(U u, BOOST_ASSIGN_PARAMS2_NO_REF(n) ) \
549     { \
550         return assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> >()( tuple<U,BOOST_ASSIGN_PARAMS4(n)>( u, BOOST_ASSIGN_PARAMS3(n) )); \
551     } \
552     /**/
553     
554 #include BOOST_PP_LOCAL_ITERATE()
555
556
557     template< class Key, class T >
558     inline assign_detail::generic_list< std::pair
559         < 
560             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type, 
561             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type
562         > >
563     map_list_of( const Key& k, const T& t )
564     {
565         typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type k_type;
566         typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type   t_type;
567         return assign_detail::generic_list< std::pair<k_type,t_type> >()( k, t );
568     }
569
570     template< class F, class S >
571     inline assign_detail::generic_list< std::pair
572         < 
573             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<F>::type, 
574             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<S>::type
575         > >
576     pair_list_of( const F& f, const S& s )
577     {
578         return map_list_of( f, s );
579     }
580
581
582 } // namespace 'assign'
583 } // namespace 'boost'
584
585
586 #undef BOOST_ASSIGN_PARAMS1
587 #undef BOOST_ASSIGN_PARAMS2
588 #undef BOOST_ASSIGN_PARAMS3
589 #undef BOOST_ASSIGN_PARAMS4
590 #undef BOOST_ASSIGN_PARAMS2_NO_REF
591 #undef BOOST_ASSIGN_MAX_PARAMETERS
592
593 #endif