1 // Boost.Assign library
2 //
3 //  Copyright Thorsten Ottosen 2003-2005. 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 
12 #ifndef BOOST_ASSIGN_PTR_LIST_OF_HPP
13 #define BOOST_ASSIGN_PTR_LIST_OF_HPP
14 
15 #if defined(_MSC_VER)
16 # pragma once
17 #endif
18 
19 #include <boost/assign/list_of.hpp>
20 #include <boost/type_traits/remove_const.hpp>
21 #include <boost/type_traits/remove_reference.hpp>
22 #include <boost/type_traits/is_reference.hpp>
23 #include <boost/static_assert.hpp>
24 #include <boost/type_traits/detail/yes_no_type.hpp>
25 #include <boost/type_traits/decay.hpp>
26 #include <boost/type_traits/is_array.hpp>
27 #include <boost/mpl/if.hpp>
28 #include <boost/ptr_container/ptr_vector.hpp>
29 
30 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
31 #include <boost/preprocessor/repetition/enum_params.hpp>
32 #include <boost/preprocessor/iteration/local.hpp>
33 
34 namespace boost
35 {
36 
37 namespace assign_detail
38 {
39     /////////////////////////////////////////////////////////////////////////
40     // Part 1: flexible and efficient interface
41     /////////////////////////////////////////////////////////////////////////
42 
43     template< class T >
44     class generic_ptr_list :
45         public converter< generic_ptr_list<T>,
46                           BOOST_DEDUCED_TYPENAME boost::ptr_vector<T>::iterator >
47     {
48     protected:
49         typedef boost::ptr_vector<T>       impl_type;
50         typedef std::auto_ptr<impl_type>   release_type;
51         mutable impl_type                  values_;
52 
53     public:
54         typedef BOOST_DEDUCED_TYPENAME impl_type::iterator         iterator;
55         typedef iterator                                           const_iterator;
56         typedef BOOST_DEDUCED_TYPENAME impl_type::value_type       value_type;
57         typedef BOOST_DEDUCED_TYPENAME impl_type::size_type        size_type;
58         typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type  difference_type;
59     public:
generic_ptr_list()60         generic_ptr_list() : values_( 32u )
61         { }
62 
generic_ptr_list(release_type r)63         generic_ptr_list( release_type r ) : values_(r)
64         { }
65 
release()66         release_type release()
67         {
68             return values_.release();
69         }
70 
71     public:
begin() const72         iterator begin() const       { return values_.begin(); }
end() const73         iterator end() const         { return values_.end(); }
empty() const74         bool empty() const           { return values_.empty(); }
size() const75         size_type size() const       { return values_.size(); }
76 
77     public:
78 
operator impl_type() const79         operator impl_type() const
80         {
81             return values_;
82         }
83 
84         template< template<class,class,class> class Seq, class U,
85                   class CA, class A >
operator Seq<U,CA,A>() const86         operator Seq<U,CA,A>() const
87         {
88             Seq<U,CA,A> result;
89             result.transfer( result.end(), values_ );
90             BOOST_ASSERT( empty() );
91             return result;
92         }
93 
94         template< class PtrContainer >
convert(const PtrContainer * c) const95         std::auto_ptr<PtrContainer> convert( const PtrContainer* c ) const
96         {
97             std::auto_ptr<PtrContainer> res( new PtrContainer() );
98             while( !empty() )
99                 res->insert( res->end(),
100                              values_.pop_back().release() );
101             return res;
102         }
103 
104         template< class PtrContainer >
to_container(const PtrContainer & c) const105         std::auto_ptr<PtrContainer> to_container( const PtrContainer& c ) const
106         {
107             return convert( &c );
108         }
109 
110     protected:
push_back(T * r)111         void push_back( T* r ) { values_.push_back( r ); }
112 
113     public:
operator ()()114         generic_ptr_list& operator()()
115         {
116             this->push_back( new T() );
117             return *this;
118         }
119 
120         template< class U >
operator ()(const U & u)121         generic_ptr_list& operator()( const U& u )
122         {
123             this->push_back( new T(u) );
124             return *this;
125         }
126 
127 
128 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
129 #define BOOST_ASSIGN_MAX_PARAMS 5
130 #endif
131 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
132 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
133 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
134 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
135 
136 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
137 #define BOOST_PP_LOCAL_MACRO(n) \
138     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
139     generic_ptr_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
140     { \
141         this->push_back( new T(u, BOOST_ASSIGN_PARAMS3(n))); \
142         return *this; \
143     } \
144     /**/
145 
146 #include BOOST_PP_LOCAL_ITERATE()
147 
148     }; // class 'generic_ptr_list'
149 
150 } // namespace 'assign_detail'
151 
152 namespace assign
153 {
154     template< class T >
155     inline assign_detail::generic_ptr_list<T>
ptr_list_of()156     ptr_list_of()
157     {
158         return assign_detail::generic_ptr_list<T>()();
159     }
160 
161     template< class T, class U >
162     inline assign_detail::generic_ptr_list<T>
ptr_list_of(const U & t)163     ptr_list_of( const U& t )
164     {
165         return assign_detail::generic_ptr_list<T>()( t );
166     }
167 
168 
169 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
170 #define BOOST_PP_LOCAL_MACRO(n) \
171     template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
172     inline assign_detail::generic_ptr_list<T> \
173     ptr_list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
174     { \
175         return assign_detail::generic_ptr_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
176     } \
177     /**/
178 
179 #include BOOST_PP_LOCAL_ITERATE()
180 
181 
182 } // namespace 'assign'
183 } // namespace 'boost'
184 
185 
186 #undef BOOST_ASSIGN_PARAMS1
187 #undef BOOST_ASSIGN_PARAMS2
188 #undef BOOST_ASSIGN_PARAMS3
189 #undef BOOST_ASSIGN_MAX_PARAMETERS
190 
191 #endif
192