source: NonGTP/Boost/boost/assign/list_inserter.hpp @ 857

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