Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[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             Array ar;
161             const std::size_t sz = ar.size();
162             if( sz < static_cast<const DerivedTAssign*>(this)->size() )
163                 throw assign::assignment_exception( "array initialized with too many elements" );
164             std::size_t n = 0; 
165             BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator 
166                 i   = static_cast<const DerivedTAssign*>(this)->begin(), 
167                 end = static_cast<const DerivedTAssign*>(this)->end();
168             for( ; i != end; ++i, ++n )
169                 ar[n] = *i;
170             for( ; n < sz; ++n )
171                 ar[n] = value_type();
172             return ar; 
173         }
174
175         template< class Adapter >
176         Adapter convert_to_adapter( const Adapter* = 0 ) const
177         {
178             Adapter a;
179             BOOST_DEDUCED_TYPENAME DerivedTAssign::iterator 
180                 i = static_cast<const DerivedTAssign*>(this)->begin(), 
181                 end = static_cast<const DerivedTAssign*>(this)->end();
182             for( ; i != end; ++i )
183                 a.push( *i );
184             return a;
185         }
186
187     private:
188         struct adapter_converter;
189         friend struct adapter_converter;
190
191         struct adapter_converter
192         {
193             const converter& gl;
194             adapter_converter( const converter& this_ ) : gl( this_ )
195             {}
196
197             adapter_converter( const adapter_converter& r ) 
198             : gl( r.gl )
199             { }
200
201             template< class Adapter >
202             operator Adapter() const
203             {
204                 return gl.convert_to_adapter<Adapter>();
205             }
206         };
207
208     public: 
209         template< class Container >
210         Container to_container( Container& c ) const
211         {
212             return convert( &c, default_type_tag() ); 
213         }
214
215         adapter_converter to_adapter() const
216         {
217             return adapter_converter( *this );
218         }
219
220         template< class Adapter >
221         Adapter to_adapter( Adapter& a ) const
222         {
223             return this->convert_to_adapter( &a ); 
224         }
225
226         template< class Array >
227         Array to_array( Array& a ) const
228         {
229             return convert( &a, array_type_tag() );
230         }
231     };
232     
233     /////////////////////////////////////////////////////////////////////////
234     // Part 1: flexible, but inefficient interface
235     /////////////////////////////////////////////////////////////////////////    
236
237     template< class T > 
238     class generic_list : 
239         public converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type > >
240     {
241         typedef converter< generic_list< BOOST_DEDUCED_TYPENAME assign_decay<T>::type > >
242                                                              base_type;
243         typedef BOOST_DEDUCED_TYPENAME assign_decay<T>::type Ty;
244         typedef std::deque<Ty>  impl_type;
245         mutable impl_type       values_;
246         
247     public:
248         typedef BOOST_DEDUCED_TYPENAME impl_type::iterator         iterator;
249         typedef BOOST_DEDUCED_TYPENAME impl_type::const_iterator   const_iterator;
250         typedef BOOST_DEDUCED_TYPENAME impl_type::value_type       value_type;
251         typedef BOOST_DEDUCED_TYPENAME impl_type::size_type        size_type;
252         typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type  difference_type;
253         
254     public:
255         iterator begin() const       { return values_.begin(); }
256         iterator end() const         { return values_.end(); }
257         bool empty() const           { return values_.empty(); }
258         size_type size() const       { return values_.size(); }
259         
260     private:
261         void push_back( value_type r ) { values_.push_back( r ); }
262         
263     public:
264         generic_list& operator()()
265         {
266             this->push_back( Ty() );
267             return *this;
268         }
269         
270         generic_list& operator()( const Ty& u )
271         {
272             this->push_back( u );
273             return *this;
274         }
275         
276        
277 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
278 #define BOOST_ASSIGN_MAX_PARAMS 5
279 #endif        
280 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1) 
281 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
282 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
283 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
284 #define BOOST_ASSIGN_PARAMS4(n) BOOST_PP_ENUM_PARAMS(n, U)
285 #define BOOST_ASSIGN_PARAMS2_NO_REF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, u)
286
287 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
288 #define BOOST_PP_LOCAL_MACRO(n) \
289     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
290     generic_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
291     { \
292         this->push_back( Ty(u, BOOST_ASSIGN_PARAMS3(n))); \
293         return *this; \
294     } \
295     /**/
296         
297 #include BOOST_PP_LOCAL_ITERATE()
298
299         
300         template< class U >
301         generic_list& repeat( std::size_t sz, U u )
302         {
303             std::size_t i = 0;
304             while( i++ != sz )
305                 this->push_back( u );
306             return *this;
307         }
308         
309         template< class Nullary_function >
310         generic_list& repeat_fun( std::size_t sz, Nullary_function fun )
311         {
312             std::size_t i = 0;
313             while( i++ != sz )
314                 this->push_back( fun() );
315             return *this;
316         }
317
318         template< class SinglePassIterator >
319         generic_list& range( SinglePassIterator first, 
320                              SinglePassIterator last )
321         {
322             for( ; first != last; ++first )
323                 this->push_back( *first );
324             return *this;
325         }
326         
327         template< class SinglePassRange >
328         generic_list& range( const SinglePassRange& r )
329         {
330             return range( boost::begin(r), boost::end(r) );
331         }
332
333         template< class Container >
334         operator Container() const
335         {
336             return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
337         }
338     };
339
340     /////////////////////////////////////////////////////////////////////////
341     // Part 2: efficient, but inconvenient interface
342     /////////////////////////////////////////////////////////////////////////
343
344     template< class T >
345     struct assign_reference
346     {
347         assign_reference()
348         { /* intentionally empty */ }
349
350         assign_reference( T& r ) : ref_(&r)
351         { }
352
353         void operator=( T& r )
354         {
355             ref_ = &r;
356         }
357
358         operator T&() const
359         {
360             return *ref_;
361         }
362
363         void swap( assign_reference& r )
364         {
365             std::swap( *ref_, *r.ref_ );
366         }
367
368         T& get_ref() const
369         {
370             return *ref_;
371         }
372         
373     private:
374         T* ref_;
375
376     };
377
378     template< class T >
379     inline bool operator<( const assign_reference<T>& l, 
380                            const assign_reference<T>& r )
381     {
382         return l.get_ref() < r.get_ref();
383     }
384
385     template< class T >
386     inline bool operator>( const assign_reference<T>& l,
387                            const assign_reference<T>& r )
388     {
389         return l.get_ref() > r.get_ref();
390     }
391
392     template< class T >
393     inline void swap( assign_reference<T>& l, 
394                       assign_reference<T>& r )
395     {
396         l.swap( r );
397     }
398
399
400     
401     template< class T, int N >
402     struct static_generic_list : 
403         public converter< static_generic_list<T,N> >
404     {
405     private:
406         typedef converter< static_generic_list<T,N> >  base_class;
407         typedef T                                      internal_value_type;
408
409     public:
410         typedef assign_reference<internal_value_type> value_type;
411         typedef value_type*                           iterator;
412         typedef const value_type*                     const_iterator;
413         typedef std::size_t                           size_type;
414         typedef std::ptrdiff_t                        difference_type;
415
416     
417         static_generic_list( T& r ) :
418             current_(1)
419         {
420             refs_[0] = r;
421         }
422
423         static_generic_list& operator()( T& r )
424         {
425             insert( r );
426             return *this;
427         }
428
429         iterator begin() const 
430         {
431             return &refs_[0];
432         }
433
434         iterator end() const
435         {
436             return &refs_[current_];
437         }
438
439         size_type size() const
440         {
441             return static_cast<size_type>( current_ ); 
442         }
443
444         bool empty() const
445         {
446             return false;
447         }
448
449         template< class ForwardIterator >
450         static_generic_list& range( ForwardIterator first, 
451                                     ForwardIterator last )
452         {
453             for( ; first != last; ++first )
454                 this->insert( *first );
455             return *this;
456         }
457
458         template< class ForwardRange >
459         static_generic_list& range( const ForwardRange& r )
460         {
461             return range( boost::begin(r), boost::end(r) );
462         }
463
464         template< class Container >
465         operator Container() const
466         {
467             return this-> BOOST_NESTED_TEMPLATE convert_to_container<Container>();
468         }
469
470     private:
471         void insert( T& r )
472         {
473             refs_[current_] = r;
474             ++current_;
475         }
476         
477         static_generic_list();
478         
479         mutable assign_reference<internal_value_type> refs_[N];
480         int current_;
481     };
482
483 } // namespace 'assign_detail'
484
485 namespace assign
486 {
487     template< class T >
488     inline assign_detail::generic_list<T>
489     list_of()
490     {
491         return assign_detail::generic_list<T>(T());
492     }
493     
494     template< class T >
495     inline assign_detail::generic_list<T> 
496     list_of( const T& t )
497     {
498         return assign_detail::generic_list<T>()( t );
499     }
500
501     template< int N, class T >
502     inline assign_detail::static_generic_list< BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
503     ref_list_of( T& t )
504     {
505         return assign_detail::static_generic_list<BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
506     }
507     
508     template< int N, class T >
509     inline assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>
510     cref_list_of( const T& t )
511     {
512         return assign_detail::static_generic_list<const BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type,N>( t );
513     }
514
515 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
516 #define BOOST_PP_LOCAL_MACRO(n) \
517     template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
518     inline assign_detail::generic_list<T> \
519     list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
520     { \
521         return assign_detail::generic_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
522     } \
523     /**/
524     
525 #include BOOST_PP_LOCAL_ITERATE()
526
527 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
528 #define BOOST_PP_LOCAL_MACRO(n) \
529     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
530     inline assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> > \
531     tuple_list_of(U u, BOOST_ASSIGN_PARAMS2_NO_REF(n) ) \
532     { \
533         return assign_detail::generic_list< tuple<U, BOOST_ASSIGN_PARAMS4(n)> >()( tuple<U,BOOST_ASSIGN_PARAMS4(n)>( u, BOOST_ASSIGN_PARAMS3(n) )); \
534     } \
535     /**/
536     
537 #include BOOST_PP_LOCAL_ITERATE()
538
539
540     template< class Key, class T >
541     inline assign_detail::generic_list< std::pair
542         < 
543             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type, 
544             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type
545         > >
546     map_list_of( const Key& k, const T& t )
547     {
548         typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<Key>::type k_type;
549         typedef BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<T>::type   t_type;
550         return assign_detail::generic_list< std::pair<k_type,t_type> >()( k, t );
551     }
552
553     template< class F, class S >
554     inline assign_detail::generic_list< std::pair
555         < 
556             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<F>::type, 
557             BOOST_DEDUCED_TYPENAME assign_detail::assign_decay<S>::type
558         > >
559     pair_list_of( const F& f, const S& s )
560     {
561         return map_list_of( f, s );
562     }
563
564
565 } // namespace 'assign'
566 } // namespace 'boost'
567
568
569 #undef BOOST_ASSIGN_PARAMS1
570 #undef BOOST_ASSIGN_PARAMS2
571 #undef BOOST_ASSIGN_PARAMS3
572 #undef BOOST_ASSIGN_PARAMS4
573 #undef BOOST_ASSIGN_PARAMS2_NO_REF
574 #undef BOOST_ASSIGN_MAX_PARAMETERS
575
576 #endif