ptr_list_of.hpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #ifndef BOOST_ASSIGN_PTR_LIST_OF_HPP
  11. #define BOOST_ASSIGN_PTR_LIST_OF_HPP
  12. #if defined(_MSC_VER)
  13. # pragma once
  14. #endif
  15. #include <boost/assign/list_of.hpp>
  16. #include <boost/type_traits/remove_const.hpp>
  17. #include <boost/type_traits/remove_reference.hpp>
  18. #include <boost/type_traits/is_reference.hpp>
  19. #include <boost/static_assert.hpp>
  20. #include <boost/type_traits/detail/yes_no_type.hpp>
  21. #include <boost/type_traits/decay.hpp>
  22. #include <boost/type_traits/is_array.hpp>
  23. #include <boost/mpl/if.hpp>
  24. #include <boost/ptr_container/ptr_vector.hpp>
  25. #include <boost/move/utility.hpp>
  26. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  27. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  28. #include <boost/preprocessor/repetition/enum_params.hpp>
  29. #include <boost/preprocessor/iteration/local.hpp>
  30. #endif
  31. namespace boost
  32. {
  33. namespace assign_detail
  34. {
  35. /////////////////////////////////////////////////////////////////////////
  36. // Part 1: flexible and efficient interface
  37. /////////////////////////////////////////////////////////////////////////
  38. template< class T >
  39. class generic_ptr_list :
  40. public converter< generic_ptr_list<T>,
  41. BOOST_DEDUCED_TYPENAME boost::ptr_vector<T>::iterator >
  42. {
  43. protected:
  44. typedef boost::ptr_vector<T> impl_type;
  45. #if defined(BOOST_NO_AUTO_PTR)
  46. typedef std::unique_ptr<impl_type> release_type;
  47. #else
  48. typedef std::auto_ptr<impl_type> release_type;
  49. #endif
  50. mutable impl_type values_;
  51. public:
  52. typedef BOOST_DEDUCED_TYPENAME impl_type::iterator iterator;
  53. typedef iterator const_iterator;
  54. typedef BOOST_DEDUCED_TYPENAME impl_type::value_type value_type;
  55. typedef BOOST_DEDUCED_TYPENAME impl_type::size_type size_type;
  56. typedef BOOST_DEDUCED_TYPENAME impl_type::difference_type difference_type;
  57. public:
  58. generic_ptr_list() : values_( 32u )
  59. { }
  60. generic_ptr_list( release_type r ) : values_(r)
  61. { }
  62. release_type release()
  63. {
  64. return values_.release();
  65. }
  66. public:
  67. iterator begin() const { return values_.begin(); }
  68. iterator end() const { return values_.end(); }
  69. bool empty() const { return values_.empty(); }
  70. size_type size() const { return values_.size(); }
  71. public:
  72. operator impl_type() const
  73. {
  74. return values_;
  75. }
  76. template< template<class,class,class> class Seq, class U,
  77. class CA, class A >
  78. operator Seq<U,CA,A>() const
  79. {
  80. Seq<U,CA,A> result;
  81. result.transfer( result.end(), values_ );
  82. BOOST_ASSERT( empty() );
  83. return result;
  84. }
  85. template< class PtrContainer >
  86. #if defined(BOOST_NO_AUTO_PTR)
  87. std::unique_ptr<PtrContainer>
  88. #else
  89. std::auto_ptr<PtrContainer>
  90. #endif
  91. convert( const PtrContainer* c ) const
  92. {
  93. #if defined(BOOST_NO_AUTO_PTR)
  94. std::unique_ptr<PtrContainer> res( new PtrContainer() );
  95. #else
  96. std::auto_ptr<PtrContainer> res( new PtrContainer() );
  97. #endif
  98. while( !empty() )
  99. res->insert( res->end(),
  100. values_.pop_back().release() );
  101. return res;
  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
  109. to_container( const PtrContainer& c ) const
  110. {
  111. return convert( &c );
  112. }
  113. protected:
  114. void push_back( T* r ) { values_.push_back( r ); }
  115. public:
  116. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  117. generic_ptr_list& operator()()
  118. {
  119. this->push_back( new T() );
  120. return *this;
  121. }
  122. template< class U >
  123. generic_ptr_list& operator()( const U& u )
  124. {
  125. this->push_back( new T(u) );
  126. return *this;
  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. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
  136. #define BOOST_PP_LOCAL_MACRO(n) \
  137. template< class U, BOOST_ASSIGN_PARAMS1(n) > \
  138. generic_ptr_list& operator()(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
  139. { \
  140. this->push_back( new T(u, BOOST_ASSIGN_PARAMS3(n))); \
  141. return *this; \
  142. } \
  143. /**/
  144. #include BOOST_PP_LOCAL_ITERATE()
  145. #else
  146. template< class... Us >
  147. generic_ptr_list& operator()(Us&&... us)
  148. {
  149. this->push_back(new T(boost::forward<Us>(us)...));
  150. return *this;
  151. }
  152. #endif
  153. }; // class 'generic_ptr_list'
  154. } // namespace 'assign_detail'
  155. namespace assign
  156. {
  157. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  158. template< class T >
  159. inline assign_detail::generic_ptr_list<T>
  160. ptr_list_of()
  161. {
  162. assign_detail::generic_ptr_list<T> gpl;
  163. gpl();
  164. return gpl;
  165. }
  166. template< class T, class U >
  167. inline assign_detail::generic_ptr_list<T>
  168. ptr_list_of( const U& t )
  169. {
  170. assign_detail::generic_ptr_list<T> gpl;
  171. gpl( t );
  172. return gpl;
  173. }
  174. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_ASSIGN_MAX_PARAMETERS)
  175. #define BOOST_PP_LOCAL_MACRO(n) \
  176. template< class T, class U, BOOST_ASSIGN_PARAMS1(n) > \
  177. inline assign_detail::generic_ptr_list<T> \
  178. ptr_list_of(U const& u, BOOST_ASSIGN_PARAMS2(n) ) \
  179. { \
  180. return assign_detail::generic_ptr_list<T>()(u, BOOST_ASSIGN_PARAMS3(n)); \
  181. } \
  182. /**/
  183. #include BOOST_PP_LOCAL_ITERATE()
  184. #else
  185. template< class T, class... Us >
  186. inline assign_detail::generic_ptr_list<T>
  187. ptr_list_of(Us&&... us)
  188. {
  189. assign_detail::generic_ptr_list<T> gpl;
  190. gpl(boost::forward<Us>(us)...);
  191. return gpl;
  192. }
  193. #endif
  194. } // namespace 'assign'
  195. } // namespace 'boost'
  196. #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  197. #undef BOOST_ASSIGN_PARAMS1
  198. #undef BOOST_ASSIGN_PARAMS2
  199. #undef BOOST_ASSIGN_PARAMS3
  200. #undef BOOST_ASSIGN_MAX_PARAMETERS
  201. #endif
  202. #endif