unique_ptr_test_utils_beg.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Howard Hinnant 2009
  4. // (C) Copyright Ion Gaztanaga 2014-2014.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/move for documentation.
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. #ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
  14. #define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
  15. #include <boost/move/core.hpp>
  16. #include <boost/move/detail/unique_ptr_meta_utils.hpp>
  17. #include <boost/static_assert.hpp>
  18. //////////////////////////////////////////////
  19. //
  20. // The initial implementation of these tests
  21. // was written by Howard Hinnant.
  22. //
  23. // These test were later refactored grouping
  24. // and porting them to Boost.Move.
  25. //
  26. // Many thanks to Howard for releasing his C++03
  27. // unique_ptr implementation with such detailed
  28. // test cases.
  29. //
  30. //////////////////////////////////////////////
  31. //A deleter that can only default constructed
  32. template <class T>
  33. class def_constr_deleter
  34. {
  35. int state_;
  36. def_constr_deleter(const def_constr_deleter&);
  37. def_constr_deleter& operator=(const def_constr_deleter&);
  38. public:
  39. typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
  40. static const bool is_array = ::boost::move_upmu::is_array<T>::value;
  41. def_constr_deleter() : state_(5) {}
  42. explicit def_constr_deleter(int s) : state_(s) {}
  43. int state() const {return state_;}
  44. void set_state(int s) {state_ = s;}
  45. void operator()(element_type* p) const
  46. { is_array ? delete []p : delete p; }
  47. void operator()(element_type* p)
  48. { ++state_; is_array ? delete []p : delete p; }
  49. };
  50. //A deleter that can be copy constructed
  51. template <class T>
  52. class copy_constr_deleter
  53. {
  54. int state_;
  55. public:
  56. typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
  57. static const bool is_array = ::boost::move_upmu::is_array<T>::value;
  58. copy_constr_deleter() : state_(5) {}
  59. template<class U>
  60. copy_constr_deleter(const copy_constr_deleter<U>&
  61. , typename boost::move_upd::enable_def_del<U, T>::type* =0)
  62. { state_ = 5; }
  63. explicit copy_constr_deleter(int s) : state_(s) {}
  64. template <class U>
  65. typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
  66. operator=(const copy_constr_deleter<U> &d)
  67. {
  68. state_ = d.state();
  69. return *this;
  70. }
  71. int state() const {return state_;}
  72. void set_state(int s) {state_ = s;}
  73. void operator()(element_type* p) const
  74. { is_array ? delete []p : delete p; }
  75. void operator()(element_type* p)
  76. { ++state_; is_array ? delete []p : delete p; }
  77. };
  78. //A deleter that can be only move constructed
  79. template <class T>
  80. class move_constr_deleter
  81. {
  82. int state_;
  83. BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
  84. public:
  85. typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
  86. static const bool is_array = ::boost::move_upmu::is_array<T>::value;
  87. move_constr_deleter() : state_(5) {}
  88. move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
  89. : state_(r.state_)
  90. { r.state_ = 0; }
  91. explicit move_constr_deleter(int s) : state_(s) {}
  92. template <class U>
  93. move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
  94. , typename boost::move_upd::enable_def_del<U, T>::type* =0)
  95. : state_(d.state())
  96. { d.set_state(0); }
  97. move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
  98. {
  99. state_ = r.state_;
  100. r.state_ = 0;
  101. return *this;
  102. }
  103. template <class U>
  104. typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
  105. operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
  106. {
  107. state_ = d.state();
  108. d.set_state(0);
  109. return *this;
  110. }
  111. int state() const {return state_;}
  112. void set_state(int s) {state_ = s;}
  113. void operator()(element_type* p) const
  114. { is_array ? delete []p : delete p; }
  115. void operator()(element_type* p)
  116. { ++state_; is_array ? delete []p : delete p; }
  117. friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
  118. {return x.state_ == y.state_;}
  119. };
  120. //A base class containing state with a static instance counter
  121. struct A
  122. {
  123. int state_;
  124. static int count;
  125. A() : state_(999) {++count;}
  126. explicit A(int i) : state_(i) {++count;}
  127. A(const A& a) : state_(a.state_) {++count;}
  128. A& operator=(const A& a) { state_ = a.state_; return *this; }
  129. void set(int i) {state_ = i;}
  130. virtual ~A() {--count;}
  131. friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
  132. };
  133. int A::count = 0;
  134. //A class derived from A with a static instance counter
  135. struct B
  136. : public A
  137. {
  138. static int count;
  139. B() : A() {++count;}
  140. B(const B &b) : A(b) {++count;}
  141. virtual ~B() {--count;}
  142. };
  143. int B::count = 0;
  144. void reset_counters();
  145. BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
  146. //Incomplete Type function declarations
  147. struct I;
  148. void check(int i);
  149. I* get();
  150. I* get_array(int i);
  151. #include <boost/move/unique_ptr.hpp>
  152. template <class T, class D = ::boost::movelib::default_delete<T> >
  153. struct J
  154. {
  155. typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
  156. typedef typename unique_ptr_type::element_type element_type;
  157. boost::movelib::unique_ptr<T, D> a_;
  158. J() {}
  159. explicit J(element_type*a) : a_(a) {}
  160. ~J();
  161. element_type* get() const {return a_.get();}
  162. D& get_deleter() {return a_.get_deleter();}
  163. };
  164. #endif //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP