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