Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / assign / list_inserter.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 #ifndef BOOST_ASSIGN_LIST_INSERTER_HPP
12 #define BOOST_ASSIGN_LIST_INSERTER_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
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
43         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         
53         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:
62         call_push_back( C& c ) : c_( c )
63         { }
64         
65         template< class T >
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:
77         call_push_front( C& c ) : c_( c )
78         { }
79         
80         template< class T >
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:
92         call_push( C& c ) : c_( c )
93         { }
94     
95         template< class T >
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:
107         call_insert( C& c ) : c_( c )
108         { }
109     
110         template< class T >
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:
122         call_add_edge( C& c ) : c_(c)
123         { }
124
125         template< class T >
126         void operator()( T l, T r )
127         {
128             add_edge( l, r, c_ );
129         }
130
131         template< class T, class 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>
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>
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         
173         list_inserter( Function fun ) : insert_( fun )
174         {}
175         
176         template< class Function2, class Arg >
177         list_inserter( const list_inserter<Function2,Arg>& r ) 
178         : insert_( r.fun_private() ) 
179         {}
180
181         list_inserter( const list_inserter& r ) : insert_( r.insert_ )
182         {}
183
184         list_inserter& operator()()
185         {
186             insert_( Argument() );
187             return *this;
188         }
189         
190         template< class T >
191         list_inserter& operator=( const T& r )
192         {
193             insert_( r );
194             return *this;
195         }
196         
197         template< class T >
198         list_inserter& operator=( assign_detail::repeater<T> r )
199         {
200             return operator,( r );
201         }
202         
203         template< class Nullary_function >
204         list_inserter& operator=( const assign_detail::fun_repeater<Nullary_function>& r )
205         {
206             //BOOST_STATIC_ASSERT( function_traits<Nullary_function>::arity == 0 );
207             //BOOST_STATIC_ASSERT( is_convertible< BOOST_DEDUCED_TYPENAME function_traits<
208             //                      Nullary_function>::result_type >,T>::value );
209
210             return operator,( r );
211         }
212         
213         template< class T >
214         list_inserter& operator,( const T& r )
215         {
216             insert_( r  );
217             return *this;
218         }
219
220 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
221         template< class T >
222         list_inserter& operator,( const assign_detail::repeater<T> & r )
223         {
224             return repeat( r.sz, r.val ); 
225         }
226 #else
227         template< class T >
228         list_inserter& operator,( assign_detail::repeater<T> r )
229         {
230             return repeat( r.sz, r.val ); 
231         }
232 #endif
233         
234         template< class Nullary_function >
235         list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r )
236         {
237             return repeat_fun( r.sz, r.val ); 
238         }
239
240         template< class T >
241         list_inserter& repeat( std::size_t sz, T r )
242         {
243             std::size_t i = 0;
244             while( i++ != sz )
245                 insert_( r );
246             return *this;
247         }
248         
249         template< class Nullary_function >
250         list_inserter& repeat_fun( std::size_t sz, Nullary_function fun )
251         {
252             std::size_t i = 0;
253             while( i++ != sz )
254                 insert_( fun() );
255             return *this;
256         }
257
258         template< class SinglePassIterator >
259         list_inserter& range( SinglePassIterator first, 
260                               SinglePassIterator last )
261         {
262             for( ; first != last; ++first )
263                 insert_( *first );
264             return *this;
265         }
266         
267         template< class SinglePassRange >
268         list_inserter& range( const SinglePassRange& r )
269         {
270             return range( boost::begin(r), boost::end(r) );
271         }
272         
273         template< class T >
274         list_inserter& operator()( const T& t )
275         {
276             insert_( t );
277             return *this;
278         }
279
280 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
281 #define BOOST_ASSIGN_MAX_PARAMS 5        
282 #endif
283 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
284 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T)
285 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t)
286 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t)
287         
288 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
289 #define BOOST_PP_LOCAL_MACRO(n) \
290     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
291     list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \
292         { \
293             BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \
294             return *this; \
295         } \
296         /**/
297
298 #include BOOST_PP_LOCAL_ITERATE()
299         
300
301 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
302 #define BOOST_PP_LOCAL_MACRO(n) \
303     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
304     void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \
305     { \
306         insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \
307     } \
308     /**/
309         
310 #include BOOST_PP_LOCAL_ITERATE()
311
312 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
313 #define BOOST_PP_LOCAL_MACRO(n) \
314     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
315     void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \
316     { \
317         insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \
318     } \
319     /**/
320         
321 #include BOOST_PP_LOCAL_ITERATE()
322
323         
324         Function fun_private() const
325         {
326             return insert_;
327         }
328
329     private:
330         
331         list_inserter& operator=( const list_inserter& );
332         Function insert_;
333     };
334     
335     template< class Function >
336     inline list_inserter< Function >
337     make_list_inserter( Function fun )
338     {
339         return list_inserter< Function >( fun );
340     }
341     
342     template< class Function, class Argument >
343     inline list_inserter<Function,Argument>
344     make_list_inserter( Function fun, Argument* )
345     {
346         return list_inserter<Function,Argument>( fun );
347     }
348
349     template< class C >
350     inline list_inserter< assign_detail::call_push_back<C>, 
351                           BOOST_DEDUCED_TYPENAME C::value_type >
352     push_back( C& c )
353     {
354         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
355         return make_list_inserter( assign_detail::call_push_back<C>( c ), 
356                                    p );
357     }
358     
359     template< class C >
360     inline list_inserter< assign_detail::call_push_front<C>,
361                           BOOST_DEDUCED_TYPENAME C::value_type >
362     push_front( C& c )
363     {
364         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
365         return make_list_inserter( assign_detail::call_push_front<C>( c ),
366                                    p );
367     }
368
369     template< class C >
370     inline list_inserter< assign_detail::call_insert<C>, 
371                           BOOST_DEDUCED_TYPENAME C::value_type >
372     insert( C& c )
373     {
374         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
375         return make_list_inserter( assign_detail::call_insert<C>( c ),
376                                    p );
377     }
378
379     template< class C >
380     inline list_inserter< assign_detail::call_push<C>, 
381                           BOOST_DEDUCED_TYPENAME C::value_type >
382     push( C& c )
383     {
384         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
385         return make_list_inserter( assign_detail::call_push<C>( c ),
386                                    p );
387     }
388
389     template< class C >
390     inline list_inserter< assign_detail::call_add_edge<C> >
391     add_edge( C& c )   
392     {
393         return make_list_inserter( assign_detail::call_add_edge<C>( c ) );
394     }
395     
396 } // namespace 'assign'
397 } // namespace 'boost'
398
399 #undef BOOST_ASSIGN_PARAMS1
400 #undef BOOST_ASSIGN_PARAMS2
401 #undef BOOST_ASSIGN_PARAMS3
402 #undef BOOST_ASSIGN_MAX_PARAMETERS
403
404 #endif