allocator_argument_tester.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
  11. #define BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP
  12. #include <boost/container/uses_allocator.hpp>
  13. #include <boost/container/detail/mpl.hpp>
  14. #include <boost/move/core.hpp>
  15. template<class T, unsigned int Id, bool HasTrueTypes = false>
  16. class propagation_test_allocator
  17. {
  18. BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator)
  19. public:
  20. template<class U>
  21. struct rebind
  22. {
  23. typedef propagation_test_allocator<U, Id, HasTrueTypes> other;
  24. };
  25. typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_copy_assignment;
  26. typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_move_assignment;
  27. typedef boost::container::dtl::bool_<HasTrueTypes> propagate_on_container_swap;
  28. typedef boost::container::dtl::bool_<HasTrueTypes> is_always_equal;
  29. typedef T value_type;
  30. propagation_test_allocator()
  31. : m_move_contructed(false), m_move_assigned(false)
  32. {}
  33. propagation_test_allocator(const propagation_test_allocator&)
  34. : m_move_contructed(false), m_move_assigned(false)
  35. {}
  36. propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) )
  37. : m_move_contructed(true), m_move_assigned(false)
  38. {}
  39. template<class U>
  40. propagation_test_allocator(BOOST_RV_REF_BEG propagation_test_allocator<U, Id, HasTrueTypes> BOOST_RV_REF_END)
  41. : m_move_contructed(true), m_move_assigned(false)
  42. {}
  43. template<class U>
  44. propagation_test_allocator(const propagation_test_allocator<U, Id, HasTrueTypes> &)
  45. {}
  46. propagation_test_allocator & operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator))
  47. {
  48. return *this;
  49. }
  50. propagation_test_allocator & operator=(BOOST_RV_REF(propagation_test_allocator))
  51. {
  52. m_move_assigned = true;
  53. return *this;
  54. }
  55. std::size_t max_size() const
  56. { return std::size_t(-1); }
  57. T* allocate(std::size_t n)
  58. { return (T*)::new char[n*sizeof(T)]; }
  59. void deallocate(T*p, std::size_t)
  60. { delete []static_cast<char*>(static_cast<void*>(p)); }
  61. bool m_move_contructed;
  62. bool m_move_assigned;
  63. };
  64. template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
  65. bool operator==( const propagation_test_allocator<T1, Id, HasTrueTypes>&
  66. , const propagation_test_allocator<T2, Id, HasTrueTypes>&)
  67. { return true; }
  68. template <class T1, class T2, unsigned int Id, bool HasTrueTypes>
  69. bool operator!=( const propagation_test_allocator<T1, Id, HasTrueTypes>&
  70. , const propagation_test_allocator<T2, Id, HasTrueTypes>&)
  71. { return false; }
  72. //This enum lists the construction options
  73. //for an allocator-aware type
  74. enum ConstructionTypeEnum
  75. {
  76. ConstructiblePrefix,
  77. ConstructibleSuffix,
  78. NotUsesAllocator
  79. };
  80. //This base class provices types for
  81. //the derived class to implement each construction
  82. //type. If a construction type does not apply
  83. //the typedef is set to an internal nat
  84. //so that the class is not constructible from
  85. //the user arguments.
  86. template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
  87. struct uses_allocator_base;
  88. template<unsigned int AllocatorTag>
  89. struct uses_allocator_base<ConstructibleSuffix, AllocatorTag>
  90. {
  91. typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
  92. typedef allocator_type allocator_constructor_type;
  93. struct nat{};
  94. typedef nat allocator_arg_type;
  95. };
  96. template<unsigned int AllocatorTag>
  97. struct uses_allocator_base<ConstructiblePrefix, AllocatorTag>
  98. {
  99. typedef propagation_test_allocator<int, AllocatorTag> allocator_type;
  100. typedef allocator_type allocator_constructor_type;
  101. typedef boost::container::allocator_arg_t allocator_arg_type;
  102. };
  103. template<unsigned int AllocatorTag>
  104. struct uses_allocator_base<NotUsesAllocator, AllocatorTag>
  105. {
  106. struct nat{};
  107. typedef nat allocator_constructor_type;
  108. typedef nat allocator_arg_type;
  109. };
  110. template<ConstructionTypeEnum ConstructionType, unsigned int AllocatorTag>
  111. struct allocator_argument_tester
  112. : uses_allocator_base<ConstructionType, AllocatorTag>
  113. {
  114. private:
  115. BOOST_COPYABLE_AND_MOVABLE(allocator_argument_tester)
  116. public:
  117. typedef uses_allocator_base<ConstructionType, AllocatorTag> base_type;
  118. //0 user argument constructors
  119. allocator_argument_tester()
  120. : construction_type(NotUsesAllocator), value(0)
  121. {}
  122. explicit allocator_argument_tester
  123. (typename base_type::allocator_constructor_type)
  124. : construction_type(ConstructibleSuffix), value(0)
  125. {}
  126. explicit allocator_argument_tester
  127. (typename base_type::allocator_arg_type, typename base_type::allocator_constructor_type)
  128. : construction_type(ConstructiblePrefix), value(0)
  129. {}
  130. //1 user argument constructors
  131. explicit allocator_argument_tester(int i)
  132. : construction_type(NotUsesAllocator), value(i)
  133. {}
  134. allocator_argument_tester
  135. (int i, typename base_type::allocator_constructor_type)
  136. : construction_type(ConstructibleSuffix), value(i)
  137. {}
  138. allocator_argument_tester
  139. ( typename base_type::allocator_arg_type
  140. , typename base_type::allocator_constructor_type
  141. , int i)
  142. : construction_type(ConstructiblePrefix), value(i)
  143. {}
  144. //Copy constructors
  145. allocator_argument_tester(const allocator_argument_tester &other)
  146. : construction_type(NotUsesAllocator), value(other.value)
  147. {}
  148. allocator_argument_tester( const allocator_argument_tester &other
  149. , typename base_type::allocator_constructor_type)
  150. : construction_type(ConstructibleSuffix), value(other.value)
  151. {}
  152. allocator_argument_tester( typename base_type::allocator_arg_type
  153. , typename base_type::allocator_constructor_type
  154. , const allocator_argument_tester &other)
  155. : construction_type(ConstructiblePrefix), value(other.value)
  156. {}
  157. //Move constructors
  158. allocator_argument_tester(BOOST_RV_REF(allocator_argument_tester) other)
  159. : construction_type(NotUsesAllocator), value(other.value)
  160. { other.value = 0; other.construction_type = NotUsesAllocator; }
  161. allocator_argument_tester( BOOST_RV_REF(allocator_argument_tester) other
  162. , typename base_type::allocator_constructor_type)
  163. : construction_type(ConstructibleSuffix), value(other.value)
  164. { other.value = 0; other.construction_type = ConstructibleSuffix; }
  165. allocator_argument_tester( typename base_type::allocator_arg_type
  166. , typename base_type::allocator_constructor_type
  167. , BOOST_RV_REF(allocator_argument_tester) other)
  168. : construction_type(ConstructiblePrefix), value(other.value)
  169. { other.value = 0; other.construction_type = ConstructiblePrefix; }
  170. ConstructionTypeEnum construction_type;
  171. int value;
  172. };
  173. namespace boost {
  174. namespace container {
  175. template<unsigned int AllocatorTag>
  176. struct constructible_with_allocator_prefix
  177. < ::allocator_argument_tester<ConstructiblePrefix, AllocatorTag> >
  178. {
  179. static const bool value = true;
  180. };
  181. template<unsigned int AllocatorTag>
  182. struct constructible_with_allocator_suffix
  183. < ::allocator_argument_tester<ConstructibleSuffix, AllocatorTag> >
  184. {
  185. static const bool value = true;
  186. };
  187. } //namespace container {
  188. } //namespace boost {
  189. #endif //BOOST_CONTAINER_TEST_ALLOCATOR_ARGUMENT_TESTER_HPP