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
33namespace boost
34{
35namespace 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
143namespace 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
401

source code of boost/boost/assign/list_inserter.hpp