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 |
401 | |