optional_test_common.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
  2. // Copyright (C) 2014, Andrzej Krzemienski.
  3. //
  4. // Use, modification, and distribution is subject to the Boost Software
  5. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // See http://www.boost.org/lib/optional for documentation.
  9. //
  10. // You are welcome to contact the author at:
  11. // fernando_cacciola@hotmail.com
  12. //
  13. #include <boost/core/ignore_unused.hpp>
  14. #ifdef ENABLE_TRACE
  15. #define TRACE(msg) std::cout << msg << std::endl ;
  16. #else
  17. #define TRACE(msg)
  18. #endif
  19. namespace boost {
  20. void assertion_failed (char const * expr, char const * func, char const * file, long )
  21. {
  22. using std::string ;
  23. string msg = string("Boost assertion failure for \"")
  24. + string(expr)
  25. + string("\" at file \"")
  26. + string(file)
  27. + string("\" function \"")
  28. + string(func)
  29. + string("\"") ;
  30. TRACE(msg);
  31. throw std::logic_error(msg);
  32. }
  33. }
  34. using boost::optional ;
  35. #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
  36. using boost::swap ;
  37. using boost::get ;
  38. using boost::get_pointer ;
  39. #endif
  40. // MSVC6.0 does not support comparisons of optional against a literal null pointer value (0)
  41. // via the safe_bool operator.
  42. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
  43. #define BOOST_OPTIONAL_NO_NULL_COMPARE
  44. #else
  45. #define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere
  46. #endif
  47. #define ARG(T) (static_cast< T const* >(0))
  48. //
  49. // Helper class used to verify the lifetime managment of the values held by optional
  50. //
  51. class X
  52. {
  53. public :
  54. X ( int av ) : v(av)
  55. {
  56. ++ count ;
  57. TRACE ( "X::X(" << av << "). this=" << this ) ;
  58. }
  59. X ( X const& rhs ) : v(rhs.v)
  60. {
  61. pending_copy = false ;
  62. TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
  63. if ( throw_on_copy )
  64. {
  65. TRACE ( "throwing exception in X's copy ctor" ) ;
  66. throw 0 ;
  67. }
  68. ++ count ;
  69. }
  70. ~X()
  71. {
  72. pending_dtor = false ;
  73. -- count ;
  74. TRACE ( "X::~X(). v=" << v << " this=" << this );
  75. }
  76. X& operator= ( X const& rhs )
  77. {
  78. pending_assign = false ;
  79. if ( throw_on_assign )
  80. {
  81. TRACE ( "throwing exception in X's assignment" ) ;
  82. v = -1 ;
  83. throw 0 ;
  84. }
  85. else
  86. {
  87. v = rhs.v ;
  88. TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
  89. }
  90. return *this ;
  91. }
  92. friend bool operator == ( X const& a, X const& b )
  93. { return a.v == b.v ; }
  94. friend bool operator != ( X const& a, X const& b )
  95. { return a.v != b.v ; }
  96. friend bool operator < ( X const& a, X const& b )
  97. { return a.v < b.v ; }
  98. int V() const { return v ; }
  99. int& V() { return v ; }
  100. static int count ;
  101. static bool pending_copy ;
  102. static bool pending_dtor ;
  103. static bool pending_assign ;
  104. static bool throw_on_copy ;
  105. static bool throw_on_assign ;
  106. private :
  107. int v ;
  108. private :
  109. X() ;
  110. } ;
  111. int X::count = 0 ;
  112. bool X::pending_copy = false ;
  113. bool X::pending_dtor = false ;
  114. bool X::pending_assign = false ;
  115. bool X::throw_on_copy = false ;
  116. bool X::throw_on_assign = false ;
  117. inline void set_pending_copy ( X const* ) { X::pending_copy = true ; }
  118. inline void set_pending_dtor ( X const* ) { X::pending_dtor = true ; }
  119. inline void set_pending_assign ( X const* ) { X::pending_assign = true ; }
  120. inline void set_throw_on_copy ( X const* ) { X::throw_on_copy = true ; }
  121. inline void set_throw_on_assign ( X const* ) { X::throw_on_assign = true ; }
  122. inline void reset_throw_on_copy ( X const* ) { X::throw_on_copy = false ; }
  123. inline void reset_throw_on_assign ( X const* ) { X::throw_on_assign = false ; }
  124. inline void check_is_pending_copy ( X const* ) { BOOST_TEST( X::pending_copy ) ; }
  125. inline void check_is_pending_dtor ( X const* ) { BOOST_TEST( X::pending_dtor ) ; }
  126. inline void check_is_pending_assign ( X const* ) { BOOST_TEST( X::pending_assign ) ; }
  127. inline void check_is_not_pending_copy ( X const* ) { BOOST_TEST( !X::pending_copy ) ; }
  128. inline void check_is_not_pending_dtor ( X const* ) { BOOST_TEST( !X::pending_dtor ) ; }
  129. inline void check_is_not_pending_assign( X const* ) { BOOST_TEST( !X::pending_assign ) ; }
  130. inline void check_instance_count ( int c, X const* ) { BOOST_TEST( X::count == c ) ; }
  131. inline int get_instance_count ( X const* ) { return X::count ; }
  132. inline void set_pending_copy (...) {}
  133. inline void set_pending_dtor (...) {}
  134. inline void set_pending_assign (...) {}
  135. inline void set_throw_on_copy (...) {}
  136. inline void set_throw_on_assign (...) {}
  137. inline void reset_throw_on_copy (...) {}
  138. inline void reset_throw_on_assign (...) {}
  139. inline void check_is_pending_copy (...) {}
  140. inline void check_is_pending_dtor (...) {}
  141. inline void check_is_pending_assign (...) {}
  142. inline void check_is_not_pending_copy (...) {}
  143. inline void check_is_not_pending_dtor (...) {}
  144. inline void check_is_not_pending_assign(...) {}
  145. inline void check_instance_count (...) {}
  146. inline int get_instance_count (...) { return 0 ; }
  147. template<class T>
  148. inline void check_uninitialized_const ( optional<T> const& opt )
  149. {
  150. #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
  151. BOOST_TEST( opt == 0 ) ;
  152. #endif
  153. BOOST_TEST( !opt ) ;
  154. BOOST_TEST( !get_pointer(opt) ) ;
  155. BOOST_TEST( !opt.get_ptr() ) ;
  156. BOOST_TEST( !opt.has_value() ) ;
  157. BOOST_TEST( !opt.is_initialized() ) ;
  158. BOOST_TEST( opt == boost::none ) ;
  159. }
  160. template<class T>
  161. inline void check_uninitialized ( optional<T>& opt )
  162. {
  163. #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
  164. BOOST_TEST( opt == 0 ) ;
  165. #endif
  166. BOOST_TEST( !opt ) ;
  167. BOOST_TEST( !get_pointer(opt) ) ;
  168. BOOST_TEST( !opt.get_ptr() ) ;
  169. BOOST_TEST( !opt.has_value() ) ;
  170. BOOST_TEST( !opt.is_initialized() ) ;
  171. BOOST_TEST( opt == boost::none ) ;
  172. check_uninitialized_const(opt);
  173. }
  174. template<class T>
  175. inline void check_initialized_const ( optional<T> const& opt )
  176. {
  177. BOOST_TEST( opt ) ;
  178. #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
  179. BOOST_TEST( opt != 0 ) ;
  180. #endif
  181. BOOST_TEST ( !!opt ) ;
  182. BOOST_TEST ( get_pointer(opt) ) ;
  183. BOOST_TEST ( opt.get_ptr() ) ;
  184. BOOST_TEST ( opt.has_value() ) ;
  185. BOOST_TEST ( opt.is_initialized() ) ;
  186. BOOST_TEST ( opt != boost::none ) ;
  187. }
  188. template<class T>
  189. inline void check_initialized ( optional<T>& opt )
  190. {
  191. BOOST_TEST( opt ) ;
  192. #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
  193. BOOST_TEST( opt != 0 ) ;
  194. #endif
  195. BOOST_TEST ( !!opt ) ;
  196. BOOST_TEST ( get_pointer(opt) ) ;
  197. BOOST_TEST ( opt.get_ptr() ) ;
  198. BOOST_TEST ( opt.has_value() ) ;
  199. BOOST_TEST ( opt.is_initialized() ) ;
  200. BOOST_TEST ( opt != boost::none ) ;
  201. check_initialized_const(opt);
  202. }
  203. template<class T>
  204. inline void check_value_const ( optional<T> const& opt, T const& v, T const& z )
  205. {
  206. BOOST_TEST( *opt == v ) ;
  207. BOOST_TEST( *opt != z ) ;
  208. BOOST_TEST( opt.get() == v ) ;
  209. BOOST_TEST( opt.get() != z ) ;
  210. BOOST_TEST( (*(opt.operator->()) == v) ) ;
  211. BOOST_TEST( *get_pointer(opt) == v ) ;
  212. }
  213. template<class T>
  214. inline void check_value ( optional<T>& opt, T const& v, T const& z )
  215. {
  216. #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0
  217. // For some reason, VC6.0 is creating a temporary while evaluating (*opt == v),
  218. // so we need to turn throw on copy off first.
  219. reset_throw_on_copy( ARG(T) ) ;
  220. #endif
  221. BOOST_TEST( *opt == v ) ;
  222. BOOST_TEST( *opt != z ) ;
  223. BOOST_TEST( opt.get() == v ) ;
  224. BOOST_TEST( opt.get() != z ) ;
  225. BOOST_TEST( (*(opt.operator->()) == v) ) ;
  226. BOOST_TEST( *get_pointer(opt) == v ) ;
  227. check_value_const(opt,v,z);
  228. }