Chris@16
|
1 // Boost.Assign library
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright Thorsten Ottosen 2003-2004. Use, modification and
|
Chris@16
|
4 // distribution is subject to the Boost Software License, Version
|
Chris@16
|
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 // For more information, see http://www.boost.org/libs/assign/
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_ASSIGN_LIST_INSERTER_HPP
|
Chris@16
|
12 #define BOOST_ASSIGN_LIST_INSERTER_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #if defined(_MSC_VER)
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/detail/workaround.hpp>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/mpl/if.hpp>
|
Chris@16
|
21 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
22 #include <boost/range/begin.hpp>
|
Chris@16
|
23 #include <boost/range/end.hpp>
|
Chris@16
|
24 #include <boost/config.hpp>
|
Chris@16
|
25 #include <cstddef>
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
28 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
29 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
30 #include <boost/preprocessor/iteration/local.hpp>
|
Chris@16
|
31 #include <boost/preprocessor/arithmetic/inc.hpp>
|
Chris@16
|
32
|
Chris@16
|
33 namespace boost
|
Chris@16
|
34 {
|
Chris@16
|
35 namespace assign_detail
|
Chris@16
|
36 {
|
Chris@16
|
37 template< class T >
|
Chris@16
|
38 struct repeater
|
Chris@16
|
39 {
|
Chris@16
|
40 std::size_t sz;
|
Chris@16
|
41 T val;
|
Chris@16
|
42
|
Chris@16
|
43 repeater( std::size_t sz_, T r ) : sz( sz_ ), val( r )
|
Chris@16
|
44 { }
|
Chris@16
|
45 };
|
Chris@16
|
46
|
Chris@16
|
47 template< class Fun >
|
Chris@16
|
48 struct fun_repeater
|
Chris@16
|
49 {
|
Chris@16
|
50 std::size_t sz;
|
Chris@16
|
51 Fun val;
|
Chris@16
|
52
|
Chris@16
|
53 fun_repeater( std::size_t sz_, Fun r ) : sz( sz_ ), val( r )
|
Chris@16
|
54 { }
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 template< class C >
|
Chris@16
|
58 class call_push_back
|
Chris@16
|
59 {
|
Chris@16
|
60 C& c_;
|
Chris@16
|
61 public:
|
Chris@16
|
62 call_push_back( C& c ) : c_( c )
|
Chris@16
|
63 { }
|
Chris@16
|
64
|
Chris@16
|
65 template< class T >
|
Chris@16
|
66 void operator()( T r )
|
Chris@16
|
67 {
|
Chris@16
|
68 c_.push_back( r );
|
Chris@16
|
69 }
|
Chris@16
|
70 };
|
Chris@16
|
71
|
Chris@16
|
72 template< class C >
|
Chris@16
|
73 class call_push_front
|
Chris@16
|
74 {
|
Chris@16
|
75 C& c_;
|
Chris@16
|
76 public:
|
Chris@16
|
77 call_push_front( C& c ) : c_( c )
|
Chris@16
|
78 { }
|
Chris@16
|
79
|
Chris@16
|
80 template< class T >
|
Chris@16
|
81 void operator()( T r )
|
Chris@16
|
82 {
|
Chris@16
|
83 c_.push_front( r );
|
Chris@16
|
84 }
|
Chris@16
|
85 };
|
Chris@16
|
86
|
Chris@16
|
87 template< class C >
|
Chris@16
|
88 class call_push
|
Chris@16
|
89 {
|
Chris@16
|
90 C& c_;
|
Chris@16
|
91 public:
|
Chris@16
|
92 call_push( C& c ) : c_( c )
|
Chris@16
|
93 { }
|
Chris@16
|
94
|
Chris@16
|
95 template< class T >
|
Chris@16
|
96 void operator()( T r )
|
Chris@16
|
97 {
|
Chris@16
|
98 c_.push( r );
|
Chris@16
|
99 }
|
Chris@16
|
100 };
|
Chris@16
|
101
|
Chris@16
|
102 template< class C >
|
Chris@16
|
103 class call_insert
|
Chris@16
|
104 {
|
Chris@16
|
105 C& c_;
|
Chris@16
|
106 public:
|
Chris@16
|
107 call_insert( C& c ) : c_( c )
|
Chris@16
|
108 { }
|
Chris@16
|
109
|
Chris@16
|
110 template< class T >
|
Chris@16
|
111 void operator()( T r )
|
Chris@16
|
112 {
|
Chris@16
|
113 c_.insert( r );
|
Chris@16
|
114 }
|
Chris@16
|
115 };
|
Chris@16
|
116
|
Chris@16
|
117 template< class C >
|
Chris@16
|
118 class call_add_edge
|
Chris@16
|
119 {
|
Chris@16
|
120 C& c_;
|
Chris@16
|
121 public:
|
Chris@16
|
122 call_add_edge( C& c ) : c_(c)
|
Chris@16
|
123 { }
|
Chris@16
|
124
|
Chris@16
|
125 template< class T >
|
Chris@16
|
126 void operator()( T l, T r )
|
Chris@16
|
127 {
|
Chris@16
|
128 add_edge( l, r, c_ );
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 template< class T, class EP >
|
Chris@16
|
132 void operator()( T l, T r, const EP& ep )
|
Chris@16
|
133 {
|
Chris@16
|
134 add_edge( l, r, ep, c_ );
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 };
|
Chris@16
|
138
|
Chris@16
|
139 struct forward_n_arguments {};
|
Chris@16
|
140
|
Chris@16
|
141 } // namespace 'assign_detail'
|
Chris@16
|
142
|
Chris@16
|
143 namespace assign
|
Chris@16
|
144 {
|
Chris@16
|
145
|
Chris@16
|
146 template< class T >
|
Chris@16
|
147 inline assign_detail::repeater<T>
|
Chris@16
|
148 repeat( std::size_t sz, T r )
|
Chris@16
|
149 {
|
Chris@16
|
150 return assign_detail::repeater<T>( sz, r );
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 template< class Function >
|
Chris@16
|
154 inline assign_detail::fun_repeater<Function>
|
Chris@16
|
155 repeat_fun( std::size_t sz, Function r )
|
Chris@16
|
156 {
|
Chris@16
|
157 return assign_detail::fun_repeater<Function>( sz, r );
|
Chris@16
|
158 }
|
Chris@16
|
159
|
Chris@16
|
160
|
Chris@16
|
161 template< class Function, class Argument = assign_detail::forward_n_arguments >
|
Chris@16
|
162 class list_inserter
|
Chris@16
|
163 {
|
Chris@16
|
164 struct single_arg_type {};
|
Chris@16
|
165 struct n_arg_type {};
|
Chris@16
|
166
|
Chris@16
|
167 typedef BOOST_DEDUCED_TYPENAME mpl::if_c< is_same<Argument,assign_detail::forward_n_arguments>::value,
|
Chris@16
|
168 n_arg_type,
|
Chris@16
|
169 single_arg_type >::type arg_type;
|
Chris@16
|
170
|
Chris@16
|
171 public:
|
Chris@16
|
172
|
Chris@16
|
173 list_inserter( Function fun ) : insert_( fun )
|
Chris@16
|
174 {}
|
Chris@16
|
175
|
Chris@16
|
176 template< class Function2, class Arg >
|
Chris@16
|
177 list_inserter( const list_inserter<Function2,Arg>& r )
|
Chris@16
|
178 : insert_( r.fun_private() )
|
Chris@16
|
179 {}
|
Chris@16
|
180
|
Chris@16
|
181 list_inserter( const list_inserter& r ) : insert_( r.insert_ )
|
Chris@16
|
182 {}
|
Chris@16
|
183
|
Chris@16
|
184 list_inserter& operator()()
|
Chris@16
|
185 {
|
Chris@16
|
186 insert_( Argument() );
|
Chris@16
|
187 return *this;
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 template< class T >
|
Chris@16
|
191 list_inserter& operator=( const T& r )
|
Chris@16
|
192 {
|
Chris@16
|
193 insert_( r );
|
Chris@16
|
194 return *this;
|
Chris@16
|
195 }
|
Chris@16
|
196
|
Chris@16
|
197 template< class T >
|
Chris@16
|
198 list_inserter& operator=( assign_detail::repeater<T> r )
|
Chris@16
|
199 {
|
Chris@16
|
200 return operator,( r );
|
Chris@16
|
201 }
|
Chris@16
|
202
|
Chris@16
|
203 template< class Nullary_function >
|
Chris@16
|
204 list_inserter& operator=( const assign_detail::fun_repeater<Nullary_function>& r )
|
Chris@16
|
205 {
|
Chris@16
|
206 return operator,( r );
|
Chris@16
|
207 }
|
Chris@16
|
208
|
Chris@16
|
209 template< class T >
|
Chris@16
|
210 list_inserter& operator,( const T& r )
|
Chris@16
|
211 {
|
Chris@16
|
212 insert_( r );
|
Chris@16
|
213 return *this;
|
Chris@16
|
214 }
|
Chris@16
|
215
|
Chris@16
|
216 #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
|
Chris@16
|
217 template< class T >
|
Chris@16
|
218 list_inserter& operator,( const assign_detail::repeater<T> & r )
|
Chris@16
|
219 {
|
Chris@16
|
220 return repeat( r.sz, r.val );
|
Chris@16
|
221 }
|
Chris@16
|
222 #else
|
Chris@16
|
223 template< class T >
|
Chris@16
|
224 list_inserter& operator,( assign_detail::repeater<T> r )
|
Chris@16
|
225 {
|
Chris@16
|
226 return repeat( r.sz, r.val );
|
Chris@16
|
227 }
|
Chris@16
|
228 #endif
|
Chris@16
|
229
|
Chris@16
|
230 template< class Nullary_function >
|
Chris@16
|
231 list_inserter& operator,( const assign_detail::fun_repeater<Nullary_function>& r )
|
Chris@16
|
232 {
|
Chris@16
|
233 return repeat_fun( r.sz, r.val );
|
Chris@16
|
234 }
|
Chris@16
|
235
|
Chris@16
|
236 template< class T >
|
Chris@16
|
237 list_inserter& repeat( std::size_t sz, T r )
|
Chris@16
|
238 {
|
Chris@16
|
239 std::size_t i = 0;
|
Chris@16
|
240 while( i++ != sz )
|
Chris@16
|
241 insert_( r );
|
Chris@16
|
242 return *this;
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 template< class Nullary_function >
|
Chris@16
|
246 list_inserter& repeat_fun( std::size_t sz, Nullary_function fun )
|
Chris@16
|
247 {
|
Chris@16
|
248 std::size_t i = 0;
|
Chris@16
|
249 while( i++ != sz )
|
Chris@16
|
250 insert_( fun() );
|
Chris@16
|
251 return *this;
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 template< class SinglePassIterator >
|
Chris@16
|
255 list_inserter& range( SinglePassIterator first,
|
Chris@16
|
256 SinglePassIterator last )
|
Chris@16
|
257 {
|
Chris@16
|
258 for( ; first != last; ++first )
|
Chris@16
|
259 insert_( *first );
|
Chris@16
|
260 return *this;
|
Chris@16
|
261 }
|
Chris@16
|
262
|
Chris@16
|
263 template< class SinglePassRange >
|
Chris@16
|
264 list_inserter& range( const SinglePassRange& r )
|
Chris@16
|
265 {
|
Chris@16
|
266 return range( boost::begin(r), boost::end(r) );
|
Chris@16
|
267 }
|
Chris@16
|
268
|
Chris@16
|
269 template< class T >
|
Chris@16
|
270 list_inserter& operator()( const T& t )
|
Chris@16
|
271 {
|
Chris@16
|
272 insert_( t );
|
Chris@16
|
273 return *this;
|
Chris@16
|
274 }
|
Chris@16
|
275
|
Chris@16
|
276 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
|
Chris@16
|
277 #define BOOST_ASSIGN_MAX_PARAMS 5
|
Chris@16
|
278 #endif
|
Chris@16
|
279 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
|
Chris@16
|
280 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class T)
|
Chris@16
|
281 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& t)
|
Chris@16
|
282 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, t)
|
Chris@16
|
283
|
Chris@16
|
284 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
|
Chris@16
|
285 #define BOOST_PP_LOCAL_MACRO(n) \
|
Chris@16
|
286 template< class T, BOOST_ASSIGN_PARAMS1(n) > \
|
Chris@16
|
287 list_inserter& operator()(T t, BOOST_ASSIGN_PARAMS2(n) ) \
|
Chris@16
|
288 { \
|
Chris@16
|
289 BOOST_PP_CAT(insert, BOOST_PP_INC(n))(t, BOOST_ASSIGN_PARAMS3(n), arg_type()); \
|
Chris@16
|
290 return *this; \
|
Chris@16
|
291 } \
|
Chris@16
|
292 /**/
|
Chris@16
|
293
|
Chris@16
|
294 #include BOOST_PP_LOCAL_ITERATE()
|
Chris@16
|
295
|
Chris@16
|
296
|
Chris@16
|
297 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
|
Chris@16
|
298 #define BOOST_PP_LOCAL_MACRO(n) \
|
Chris@16
|
299 template< class T, BOOST_ASSIGN_PARAMS1(n) > \
|
Chris@16
|
300 void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), single_arg_type) \
|
Chris@16
|
301 { \
|
Chris@16
|
302 insert_( Argument(t, BOOST_ASSIGN_PARAMS3(n) )); \
|
Chris@16
|
303 } \
|
Chris@16
|
304 /**/
|
Chris@16
|
305
|
Chris@16
|
306 #include BOOST_PP_LOCAL_ITERATE()
|
Chris@16
|
307
|
Chris@16
|
308 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
|
Chris@16
|
309 #define BOOST_PP_LOCAL_MACRO(n) \
|
Chris@16
|
310 template< class T, BOOST_ASSIGN_PARAMS1(n) > \
|
Chris@16
|
311 void BOOST_PP_CAT(insert, BOOST_PP_INC(n))(T const& t, BOOST_ASSIGN_PARAMS2(n), n_arg_type) \
|
Chris@16
|
312 { \
|
Chris@16
|
313 insert_(t, BOOST_ASSIGN_PARAMS3(n) ); \
|
Chris@16
|
314 } \
|
Chris@16
|
315 /**/
|
Chris@16
|
316
|
Chris@16
|
317 #include BOOST_PP_LOCAL_ITERATE()
|
Chris@16
|
318
|
Chris@16
|
319
|
Chris@16
|
320 Function fun_private() const
|
Chris@16
|
321 {
|
Chris@16
|
322 return insert_;
|
Chris@16
|
323 }
|
Chris@16
|
324
|
Chris@16
|
325 private:
|
Chris@16
|
326
|
Chris@16
|
327 list_inserter& operator=( const list_inserter& );
|
Chris@16
|
328 Function insert_;
|
Chris@16
|
329 };
|
Chris@16
|
330
|
Chris@16
|
331 template< class Function >
|
Chris@16
|
332 inline list_inserter< Function >
|
Chris@16
|
333 make_list_inserter( Function fun )
|
Chris@16
|
334 {
|
Chris@16
|
335 return list_inserter< Function >( fun );
|
Chris@16
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 template< class Function, class Argument >
|
Chris@16
|
339 inline list_inserter<Function,Argument>
|
Chris@16
|
340 make_list_inserter( Function fun, Argument* )
|
Chris@16
|
341 {
|
Chris@16
|
342 return list_inserter<Function,Argument>( fun );
|
Chris@16
|
343 }
|
Chris@16
|
344
|
Chris@16
|
345 template< class C >
|
Chris@16
|
346 inline list_inserter< assign_detail::call_push_back<C>,
|
Chris@16
|
347 BOOST_DEDUCED_TYPENAME C::value_type >
|
Chris@16
|
348 push_back( C& c )
|
Chris@16
|
349 {
|
Chris@16
|
350 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
|
Chris@16
|
351 return make_list_inserter( assign_detail::call_push_back<C>( c ),
|
Chris@16
|
352 p );
|
Chris@16
|
353 }
|
Chris@16
|
354
|
Chris@16
|
355 template< class C >
|
Chris@16
|
356 inline list_inserter< assign_detail::call_push_front<C>,
|
Chris@16
|
357 BOOST_DEDUCED_TYPENAME C::value_type >
|
Chris@16
|
358 push_front( C& c )
|
Chris@16
|
359 {
|
Chris@16
|
360 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
|
Chris@16
|
361 return make_list_inserter( assign_detail::call_push_front<C>( c ),
|
Chris@16
|
362 p );
|
Chris@16
|
363 }
|
Chris@16
|
364
|
Chris@16
|
365 template< class C >
|
Chris@16
|
366 inline list_inserter< assign_detail::call_insert<C>,
|
Chris@16
|
367 BOOST_DEDUCED_TYPENAME C::value_type >
|
Chris@16
|
368 insert( C& c )
|
Chris@16
|
369 {
|
Chris@16
|
370 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
|
Chris@16
|
371 return make_list_inserter( assign_detail::call_insert<C>( c ),
|
Chris@16
|
372 p );
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 template< class C >
|
Chris@16
|
376 inline list_inserter< assign_detail::call_push<C>,
|
Chris@16
|
377 BOOST_DEDUCED_TYPENAME C::value_type >
|
Chris@16
|
378 push( C& c )
|
Chris@16
|
379 {
|
Chris@16
|
380 static BOOST_DEDUCED_TYPENAME C::value_type* p = 0;
|
Chris@16
|
381 return make_list_inserter( assign_detail::call_push<C>( c ),
|
Chris@16
|
382 p );
|
Chris@16
|
383 }
|
Chris@16
|
384
|
Chris@16
|
385 template< class C >
|
Chris@16
|
386 inline list_inserter< assign_detail::call_add_edge<C> >
|
Chris@16
|
387 add_edge( C& c )
|
Chris@16
|
388 {
|
Chris@16
|
389 return make_list_inserter( assign_detail::call_add_edge<C>( c ) );
|
Chris@16
|
390 }
|
Chris@16
|
391
|
Chris@16
|
392 } // namespace 'assign'
|
Chris@16
|
393 } // namespace 'boost'
|
Chris@16
|
394
|
Chris@16
|
395 #undef BOOST_ASSIGN_PARAMS1
|
Chris@16
|
396 #undef BOOST_ASSIGN_PARAMS2
|
Chris@16
|
397 #undef BOOST_ASSIGN_PARAMS3
|
Chris@16
|
398 #undef BOOST_ASSIGN_MAX_PARAMETERS
|
Chris@16
|
399
|
Chris@16
|
400 #endif
|