Imported Upstream version 1.57.0
[platform/upstream/boost.git] / 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)
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             return operator,( r );
207         }
208         
209         template< class T >
210         list_inserter& operator,( const T& r )
211         {
212             insert_( r  );
213             return *this;
214         }
215
216 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
217         template< class T >
218         list_inserter& operator,( const assign_detail::repeater<T> & r )
219         {
220             return repeat( r.sz, r.val ); 
221         }
222 #else
223         template< class T >
224         list_inserter& operator,( assign_detail::repeater<T> r )
225         {
226             return repeat( r.sz, r.val ); 
227         }
228 #endif
229         
230         template< class Nullary_function >
231         list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r )
232         {
233             return repeat_fun( r.sz, r.val ); 
234         }
235
236         template< class T >
237         list_inserter& repeat( std::size_t sz, T r )
238         {
239             std::size_t i = 0;
240             while( i++ != sz )
241                 insert_( r );
242             return *this;
243         }
244         
245         template< class Nullary_function >
246         list_inserter& repeat_fun( std::size_t sz, Nullary_function fun )
247         {
248             std::size_t i = 0;
249             while( i++ != sz )
250                 insert_( fun() );
251             return *this;
252         }
253
254         template< class SinglePassIterator >
255         list_inserter& range( SinglePassIterator first, 
256                               SinglePassIterator last )
257         {
258             for( ; first != last; ++first )
259                 insert_( *first );
260             return *this;
261         }
262         
263         template< class SinglePassRange >
264         list_inserter& range( const SinglePassRange& r )
265         {
266             return range( boost::begin(r), boost::end(r) );
267         }
268         
269         template< class T >
270         list_inserter& operator()( const T& t )
271         {
272             insert_( t );
273             return *this;
274         }
275
276 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
277 #define BOOST_ASSIGN_MAX_PARAMS 5        
278 #endif
279 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
280 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T)
281 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t)
282 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t)
283         
284 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
285 #define BOOST_PP_LOCAL_MACRO(n) \
286     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
287     list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \
288         { \
289             BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \
290             return *this; \
291         } \
292         /**/
293
294 #include BOOST_PP_LOCAL_ITERATE()
295         
296
297 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
298 #define BOOST_PP_LOCAL_MACRO(n) \
299     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
300     void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \
301     { \
302         insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \
303     } \
304     /**/
305         
306 #include BOOST_PP_LOCAL_ITERATE()
307
308 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
309 #define BOOST_PP_LOCAL_MACRO(n) \
310     template< class T, BOOST_ASSIGN_PARAMS1(n) > \
311     void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \
312     { \
313         insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \
314     } \
315     /**/
316         
317 #include BOOST_PP_LOCAL_ITERATE()
318
319         
320         Function fun_private() const
321         {
322             return insert_;
323         }
324
325     private:
326         
327         list_inserter& operator=( const list_inserter& );
328         Function insert_;
329     };
330     
331     template< class Function >
332     inline list_inserter< Function >
333     make_list_inserter( Function fun )
334     {
335         return list_inserter< Function >( fun );
336     }
337     
338     template< class Function, class Argument >
339     inline list_inserter<Function,Argument>
340     make_list_inserter( Function fun, Argument* )
341     {
342         return list_inserter<Function,Argument>( fun );
343     }
344
345     template< class C >
346     inline list_inserter< assign_detail::call_push_back<C>, 
347                           BOOST_DEDUCED_TYPENAME C::value_type >
348     push_back( C& c )
349     {
350         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
351         return make_list_inserter( assign_detail::call_push_back<C>( c ), 
352                                    p );
353     }
354     
355     template< class C >
356     inline list_inserter< assign_detail::call_push_front<C>,
357                           BOOST_DEDUCED_TYPENAME C::value_type >
358     push_front( C& c )
359     {
360         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
361         return make_list_inserter( assign_detail::call_push_front<C>( c ),
362                                    p );
363     }
364
365     template< class C >
366     inline list_inserter< assign_detail::call_insert<C>, 
367                           BOOST_DEDUCED_TYPENAME C::value_type >
368     insert( C& c )
369     {
370         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
371         return make_list_inserter( assign_detail::call_insert<C>( c ),
372                                    p );
373     }
374
375     template< class C >
376     inline list_inserter< assign_detail::call_push<C>, 
377                           BOOST_DEDUCED_TYPENAME C::value_type >
378     push( C& c )
379     {
380         static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
381         return make_list_inserter( assign_detail::call_push<C>( c ),
382                                    p );
383     }
384
385     template< class C >
386     inline list_inserter< assign_detail::call_add_edge<C> >
387     add_edge( C& c )   
388     {
389         return make_list_inserter( assign_detail::call_add_edge<C>( c ) );
390     }
391     
392 } // namespace 'assign'
393 } // namespace 'boost'
394
395 #undef BOOST_ASSIGN_PARAMS1
396 #undef BOOST_ASSIGN_PARAMS2
397 #undef BOOST_ASSIGN_PARAMS3
398 #undef BOOST_ASSIGN_MAX_PARAMETERS
399
400 #endif