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 
13 #include "boost/config.hpp"
14 
15 #ifdef BOOST_MSVC
16 #pragma warning(disable:4244) // conversion from 'const int' to 'const short'
17 #endif
18 
19 #include "boost/core/lightweight_test.hpp"
20 #include "boost/variant.hpp"
21 
22 #include "jobs.h"
23 
24 #include <iostream>
25 #include <algorithm>
26 #include <string>
27 #include <map>
28 
29 #include "boost/detail/workaround.hpp"
30 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
31 #   include "boost/mpl/bool.hpp"
32 #   include "boost/type_traits/is_same.hpp"
33 #endif
34 
35 
36 using namespace boost;
37 using namespace std;
38 
39 
40 struct jas
41 {
42    jas(int n = 364);
43    jas(const jas& other);
44 
45    ~jas();
46    jas& operator=(const jas& other);
47 
48    void swap(jas& other);
49 
50    int n_;
51 
52    int sn_;
53    static int s_inst_id_;
54 };
55 
56 struct Tracker
57 {
58    typedef map<const jas*,int> table_type;
59    typedef table_type::iterator iterator_type;
60 
61    static table_type s_this_to_sn_;
62 
insertTracker63    static void insert(const jas& j)
64    {
65       s_this_to_sn_[&j] = j.sn_;
66       cout << "jas( " << j.sn_ << ") Registered" << endl;
67    }
68 
removeTracker69    static void remove(const jas& j)
70    {
71       iterator_type iter = s_this_to_sn_.find(&j);
72       BOOST_TEST(iter != s_this_to_sn_.end());
73       BOOST_TEST( ((*iter).second) == j.sn_);
74 
75       int sn = (*iter).second;
76       if(sn != j.sn_)
77       {
78          cout << "Mismatch: this = " << (*iter).first << ", sn_ = " << sn
79             << ", other: this = " << &j << ", j.sn_ = " << j.sn_ << endl;
80       }
81 
82       BOOST_TEST(sn == j.sn_);
83 
84 
85 
86 
87 
88       s_this_to_sn_.erase(&j);
89       cout << "jas( " << j.sn_ << ") Removed" << endl;
90    }
91 
checkTracker92    static void check()
93    {
94       BOOST_TEST(s_this_to_sn_.empty());
95    }
96 };
97 
98 Tracker::table_type Tracker::s_this_to_sn_;
99 
100 
101 
jas(int n)102 jas::jas(int n) : n_(n)
103 {
104    sn_ = s_inst_id_;
105    s_inst_id_ += 1;
106 
107    Tracker::insert(*this);
108 }
109 
jas(const jas & other)110 jas::jas(const jas& other) : n_(other.n_)
111 {
112    sn_ = s_inst_id_;
113    s_inst_id_ += 1;
114 
115    Tracker::insert(*this);
116 }
117 
~jas()118 jas::~jas()
119 {
120    Tracker::remove(*this);
121 }
122 
operator =(const jas & other)123 jas& jas::operator=(const jas& other)
124 {
125    jas temp(other);
126    swap(temp);
127 
128    return *this;
129 }
130 
swap(jas & other)131 void jas::swap(jas& other)
132 {
133    Tracker::remove(*this);
134    Tracker::remove(other);
135 
136    std::swap(n_, other.n_);
137    std::swap(sn_, other.sn_);
138 
139    Tracker::insert(*this);
140    Tracker::insert(other);
141 }
142 
143 int jas::s_inst_id_ = 0;
144 
145 
operator ==(const jas & a,const jas & b)146 bool operator==(const jas& a, const jas& b)
147 {
148    return a.n_ == b.n_;
149 }
150 
operator <<(ostream & out,const jas & a)151 ostream& operator<<(ostream& out, const jas& a)
152 {
153    cout << "jas::n_ = " << a.n_;
154    return out;
155 }
156 
157 
158 template<typename ValueType>
159 struct compare_helper : boost::static_visitor<bool>
160 {
compare_helpercompare_helper161    compare_helper(ValueType& expected) : expected_(expected) { }
162 
163 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
164 
operator ()compare_helper165    bool operator()(const ValueType& value)
166    {
167       return value == expected_;
168    }
169 
170    template <typename T>
operator ()compare_helper171    bool operator()(const T& )
172    {
173       return false;
174    }
175 
176 #else // MSVC6
177 
178 private:
179 
compare_implcompare_helper180    bool compare_impl(const ValueType& value, boost::mpl::true_)
181    {
182       return value == expected_;
183    }
184 
185    template <typename T>
compare_implcompare_helper186    bool compare_impl(const T&, boost::mpl::false_)
187    {
188       return false;
189    }
190 
191 public:
192 
193    template <typename T>
operator ()compare_helper194    bool operator()(const T& value)
195    {
196       typedef typename boost::is_same<T, ValueType>::type
197           T_is_ValueType;
198 
199       return compare_impl(value, T_is_ValueType());
200    }
201 
202 #endif // MSVC6 workaround
203 
204    ValueType& expected_;
205 
206 private:
207    compare_helper& operator=(const compare_helper&);
208 
209 };
210 
211 template<typename VariantType, typename ExpectedType>
var_compare(const VariantType & v,ExpectedType expected)212 void var_compare(const VariantType& v, ExpectedType expected)
213 {
214    compare_helper<ExpectedType> ch(expected);
215 
216    bool checks = boost::apply_visitor(ch, v);
217    BOOST_TEST(checks);
218 }
219 
220 
run()221 void run()
222 {
223    boost::variant<string, short> v0;
224 
225    var_compare(v0, string(""));
226 
227    v0 = 8;
228    var_compare(v0, static_cast<short>(8));
229 
230    v0 = "penny lane";
231    var_compare(v0, string("penny lane"));
232 
233    boost::variant<jas, string, int> v1, v2 = jas(195);
234    var_compare(v1, jas(364));
235 
236    v1 = jas(500);
237    v1.swap(v2);
238 
239    var_compare(v1, jas(195));
240    var_compare(v2, jas(500));
241 
242 
243    boost::variant<string, int> v3;
244    var_compare(v3, string(""));
245 }
246 
247 
main()248 int main()
249 {
250    run();
251    Tracker::check();
252 
253    return boost::report_errors();
254 }
255 
256