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 #include <boost/move/utility.hpp>
30 
31 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
32 
33 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
34 #include <boost/preprocessor/repetition/enum_params.hpp>
35 #include <boost/preprocessor/iteration/local.hpp>
36 
37 #endif
38 
39 namespace boost
40 {
41 
42 namespace assign_detail
43 {
44     /////////////////////////////////////////////////////////////////////////
45     // Part 1: flexible and efficient interface
46     /////////////////////////////////////////////////////////////////////////
47 
48     template< class T >
49     class generic_ptr_list :
50         public converter< generic_ptr_list<T>,
51                           BOOST_DEDUCED_TYPENAME boost::ptr_vector<T>::iterator >
52     {
53     protected:
54         typedef boost::ptr_vector<T>       impl_type;
55 #if defined(BOOST_NO_AUTO_PTR)
56         typedef std::unique_ptr<impl_type> release_type;
57 #else
58         typedef std::auto_ptr<impl_type>   release_type;
59 #endif
60         mutable impl_type                  values_;
61 
62     public:
63         typedef BOOST_DEDUCED_TYPENAME impl_type::iterator         iterator;
64         typedef iterator                                           const_iterator;
65         typedef BOOST_DEDUCED_TYPENAME impl_type::value_type       value_type;
66         typedef BOOST_DEDUCED_TYPENAME impl_type::size_type        size_type;
67         typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type  difference_type;
68     public:
generic_ptr_list()69         generic_ptr_list() : values_( 32u )
70         { }
71 
generic_ptr_list(release_type r)72         generic_ptr_list( release_type r ) : values_(r)
73         { }
74 
release()75         release_type release()
76         {
77             return values_.release();
78         }
79 
80     public:
begin() const81         iterator begin() const       { return values_.begin(); }
end() const82         iterator end() const         { return values_.end(); }
empty() const83         bool empty() const           { return values_.empty(); }
size() const84         size_type size() const       { return values_.size(); }
85 
86     public:
87 
operator impl_type() const88         operator impl_type() const
89         {
90             return values_;
91         }
92 
93         template< template<class,class,class> class Seq, class U,
94                   class CA, class A >
operator Seq<U,CA,A>() const95         operator Seq<U,CA,A>() const
96         {
97             Seq<U,CA,A> result;
98             result.transfer( result.end(), values_ );
99             BOOST_ASSERT( empty() );
100             return result;
101         }
102 
103         template< class PtrContainer >
104 #if defined(BOOST_NO_AUTO_PTR)
105         std::unique_ptr<PtrContainer>
106 #else
107         std::auto_ptr<PtrContainer>
108 #endif
convert(const PtrContainer * c) const109 		convert( const PtrContainer* c ) const
110         {
111 #if defined(BOOST_NO_AUTO_PTR)
112             std::unique_ptr<PtrContainer> res( new PtrContainer() );
113 #else
114             std::auto_ptr<PtrContainer> res( new PtrContainer() );
115 #endif
116             while( !empty() )
117                 res->insert( res->end(),
118                              values_.pop_back().release() );
119             return res;
120         }
121 
122         template< class PtrContainer >
123 #if defined(BOOST_NO_AUTO_PTR)
124         std::unique_ptr<PtrContainer>
125 #else
126         std::auto_ptr<PtrContainer>
127 #endif
to_container(const PtrContainer & c) const128         to_container( const PtrContainer& c ) const
129         {
130             return convert( &c );
131         }
132 
133     protected:
push_back(T * r)134         void push_back( T* r ) { values_.push_back( r ); }
135 
136     public:
137 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
138 
operator ()()139         generic_ptr_list& operator()()
140         {
141             this->push_back( new T() );
142             return *this;
143         }
144 
145         template< class U >
operator ()(const U & u)146         generic_ptr_list& operator()( const U& u )
147         {
148             this->push_back( new T(u) );
149             return *this;
150         }
151 
152 
153 #ifndef BOOST_ASSIGN_MAX_PARAMS // use user's value
154 #define BOOST_ASSIGN_MAX_PARAMS 5
155 #endif
156 #define BOOST_ASSIGN_MAX_PARAMETERS (BOOST_ASSIGN_MAX_PARAMS - 1)
157 #define BOOST_ASSIGN_PARAMS1(n) BOOST_PP_ENUM_PARAMS(n, class U)
158 #define BOOST_ASSIGN_PARAMS2(n) BOOST_PP_ENUM_BINARY_PARAMS(n, U, const& u)
159 #define BOOST_ASSIGN_PARAMS3(n) BOOST_PP_ENUM_PARAMS(n, u)
160 
161 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
162 #define BOOST_PP_LOCAL_MACRO(n) \
163     template< class U, BOOST_ASSIGN_PARAMS1(n) > \
164     generic_ptr_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
165     { \
166         this->push_back( new T(u, BOOST_ASSIGN_PARAMS3(n))); \
167         return *this; \
168     } \
169     /**/
170 
171 #include BOOST_PP_LOCAL_ITERATE()
172 
173 #else
174         template< class... Us >
175         generic_ptr_list& operator()(Us&&... us)
176         {
177             this->push_back(new T(boost::forward<Us>(us)...));
178             return *this;
179         }
180 #endif
181 
182 
183 
184     }; // class 'generic_ptr_list'
185 
186 } // namespace 'assign_detail'
187 
188 namespace assign
189 {
190 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
191 
192     template< class T >
193     inline assign_detail::generic_ptr_list<T>
ptr_list_of()194     ptr_list_of()
195     {
196         assign_detail::generic_ptr_list<T> gpl;
197         gpl();
198         return gpl;
199     }
200 
201     template< class T, class U >
202     inline assign_detail::generic_ptr_list<T>
ptr_list_of(const U & t)203     ptr_list_of( const U& t )
204     {
205         assign_detail::generic_ptr_list<T> gpl;
206         gpl( t );
207         return gpl;
208     }
209 
210 
211 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
212 #define BOOST_PP_LOCAL_MACRO(n) \
213     template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
214     inline assign_detail::generic_ptr_list<T> \
215     ptr_list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
216     { \
217         return assign_detail::generic_ptr_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
218     } \
219     /**/
220 
221 #include BOOST_PP_LOCAL_ITERATE()
222 
223 #else
224     template< class T, class... Us >
225     inline assign_detail::generic_ptr_list<T>
226     ptr_list_of(Us&&... us)
227     {
228         assign_detail::generic_ptr_list<T> gpl;
229         gpl(boost::forward<Us>(us)...);
230         return gpl;
231     }
232 
233 #endif
234 
235 } // namespace 'assign'
236 } // namespace 'boost'
237 
238 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
239 
240 #undef BOOST_ASSIGN_PARAMS1
241 #undef BOOST_ASSIGN_PARAMS2
242 #undef BOOST_ASSIGN_PARAMS3
243 #undef BOOST_ASSIGN_MAX_PARAMETERS
244 
245 #endif
246 
247 #endif
248