]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |