test7.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //-----------------------------------------------------------------------------
  2. // boost-libs variant/test/test7.cpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003
  7. // Eric Friedman, Itay Maman
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #include "boost/config.hpp"
  13. #ifdef BOOST_MSVC
  14. #pragma warning(disable:4244) // conversion from 'const int' to 'const short'
  15. #endif
  16. #include "boost/core/lightweight_test.hpp"
  17. #include "boost/variant.hpp"
  18. #include "jobs.h"
  19. #include <iostream>
  20. #include <algorithm>
  21. #include <string>
  22. #include <map>
  23. #include "boost/detail/workaround.hpp"
  24. #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
  25. # include "boost/mpl/bool.hpp"
  26. # include "boost/type_traits/is_same.hpp"
  27. #endif
  28. using namespace boost;
  29. using namespace std;
  30. struct jas
  31. {
  32. jas(int n = 364);
  33. jas(const jas& other);
  34. ~jas();
  35. jas& operator=(const jas& other);
  36. void swap(jas& other);
  37. int n_;
  38. int sn_;
  39. static int s_inst_id_;
  40. };
  41. struct Tracker
  42. {
  43. typedef map<const jas*,int> table_type;
  44. typedef table_type::iterator iterator_type;
  45. static table_type s_this_to_sn_;
  46. static void insert(const jas& j)
  47. {
  48. s_this_to_sn_[&j] = j.sn_;
  49. cout << "jas( " << j.sn_ << ") Registered" << endl;
  50. }
  51. static void remove(const jas& j)
  52. {
  53. iterator_type iter = s_this_to_sn_.find(&j);
  54. BOOST_TEST(iter != s_this_to_sn_.end());
  55. BOOST_TEST( ((*iter).second) == j.sn_);
  56. int sn = (*iter).second;
  57. if(sn != j.sn_)
  58. {
  59. cout << "Mismatch: this = " << (*iter).first << ", sn_ = " << sn
  60. << ", other: this = " << &j << ", j.sn_ = " << j.sn_ << endl;
  61. }
  62. BOOST_TEST(sn == j.sn_);
  63. s_this_to_sn_.erase(&j);
  64. cout << "jas( " << j.sn_ << ") Removed" << endl;
  65. }
  66. static void check()
  67. {
  68. BOOST_TEST(s_this_to_sn_.empty());
  69. }
  70. };
  71. Tracker::table_type Tracker::s_this_to_sn_;
  72. jas::jas(int n) : n_(n)
  73. {
  74. sn_ = s_inst_id_;
  75. s_inst_id_ += 1;
  76. Tracker::insert(*this);
  77. }
  78. jas::jas(const jas& other) : n_(other.n_)
  79. {
  80. sn_ = s_inst_id_;
  81. s_inst_id_ += 1;
  82. Tracker::insert(*this);
  83. }
  84. jas::~jas()
  85. {
  86. Tracker::remove(*this);
  87. }
  88. jas& jas::operator=(const jas& other)
  89. {
  90. jas temp(other);
  91. swap(temp);
  92. return *this;
  93. }
  94. void jas::swap(jas& other)
  95. {
  96. Tracker::remove(*this);
  97. Tracker::remove(other);
  98. std::swap(n_, other.n_);
  99. std::swap(sn_, other.sn_);
  100. Tracker::insert(*this);
  101. Tracker::insert(other);
  102. }
  103. int jas::s_inst_id_ = 0;
  104. bool operator==(const jas& a, const jas& b)
  105. {
  106. return a.n_ == b.n_;
  107. }
  108. ostream& operator<<(ostream& out, const jas& a)
  109. {
  110. cout << "jas::n_ = " << a.n_;
  111. return out;
  112. }
  113. template<typename ValueType>
  114. struct compare_helper : boost::static_visitor<bool>
  115. {
  116. compare_helper(ValueType& expected) : expected_(expected) { }
  117. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
  118. bool operator()(const ValueType& value)
  119. {
  120. return value == expected_;
  121. }
  122. template <typename T>
  123. bool operator()(const T& )
  124. {
  125. return false;
  126. }
  127. #else // MSVC6
  128. private:
  129. bool compare_impl(const ValueType& value, boost::mpl::true_)
  130. {
  131. return value == expected_;
  132. }
  133. template <typename T>
  134. bool compare_impl(const T&, boost::mpl::false_)
  135. {
  136. return false;
  137. }
  138. public:
  139. template <typename T>
  140. bool operator()(const T& value)
  141. {
  142. typedef typename boost::is_same<T, ValueType>::type
  143. T_is_ValueType;
  144. return compare_impl(value, T_is_ValueType());
  145. }
  146. #endif // MSVC6 workaround
  147. ValueType& expected_;
  148. private:
  149. compare_helper& operator=(const compare_helper&);
  150. };
  151. template<typename VariantType, typename ExpectedType>
  152. void var_compare(const VariantType& v, ExpectedType expected)
  153. {
  154. compare_helper<ExpectedType> ch(expected);
  155. bool checks = boost::apply_visitor(ch, v);
  156. BOOST_TEST(checks);
  157. }
  158. void run()
  159. {
  160. boost::variant<string, short> v0;
  161. var_compare(v0, string(""));
  162. v0 = 8;
  163. var_compare(v0, static_cast<short>(8));
  164. v0 = "penny lane";
  165. var_compare(v0, string("penny lane"));
  166. boost::variant<jas, string, int> v1, v2 = jas(195);
  167. var_compare(v1, jas(364));
  168. v1 = jas(500);
  169. v1.swap(v2);
  170. var_compare(v1, jas(195));
  171. var_compare(v2, jas(500));
  172. boost::variant<string, int> v3;
  173. var_compare(v3, string(""));
  174. }
  175. int main()
  176. {
  177. run();
  178. Tracker::check();
  179. return boost::report_errors();
  180. }