1/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2// test_variant.cpp
3// test of non-intrusive serialization of variant types
4//
5// copyright (c) 2005
6// troy d. straszheim <troy@resophonic.com>
7// http://www.resophonic.com
8//
9// copyright (c) 2023
10// Robert Ramey <ramey@rrsd.com>
11// http://www.rrsd.com
12//
13// Use, modification and distribution is subject to the Boost Software
14// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16//
17// See http://www.boost.org for updates, documentation, and revision history.
18//
19// thanks to Robert Ramey and Peter Dimov.
20//
21
22#include <cstddef> // NULL
23#include <cstdio> // remove
24#include <fstream>
25
26#include <boost/config.hpp>
27#if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
28#include <boost/math/special_functions/next.hpp>
29#endif
30
31#if defined(BOOST_NO_STDC_NAMESPACE)
32namespace std {
33 using ::remove;
34}
35#endif
36
37#include <boost/type_traits/is_same.hpp>
38#include <boost/mpl/eval_if.hpp>
39#include <boost/mpl/identity.hpp>
40
41#if defined(_MSC_VER) && (_MSC_VER <= 1020)
42# pragma warning (disable : 4786) // too long name, harmless warning
43#endif
44
45#include "test_tools.hpp"
46
47#include <boost/archive/archive_exception.hpp>
48#include <boost/serialization/nvp.hpp>
49#include <boost/serialization/throw_exception.hpp>
50
51#include <boost/variant/static_visitor.hpp>
52
53namespace boost {
54 template<typename ResultType> class static_visitor;
55}
56
57#include "A.hpp"
58#include "A.ipp"
59
60class are_equal
61 : public boost::static_visitor<bool>
62{
63public:
64 typedef bool result_type;
65 // note extra rigamarole for compilers which don't support
66 // partial function template ordering - specifically msvc 6.x
67 struct same {
68 template<class T, class U>
69 static bool invoke(const T & t, const U & u){
70 return t == u;
71 }
72 };
73
74 struct not_same {
75 template<class T, class U>
76 static bool invoke(const T &, const U &){
77 return false;
78 }
79 };
80
81 template <class T, class U>
82 bool operator()( const T & t, const U & u) const
83 {
84 typedef typename boost::mpl::eval_if<boost::is_same<T, U>,
85 boost::mpl::identity<same>,
86 boost::mpl::identity<not_same>
87 >::type type;
88 return type::invoke(t, u);
89 }
90
91 template <class T, class U>
92 bool operator()(T * const & t, U * const & u) const
93 {
94 return this->operator()(*t, *u);
95 }
96
97 bool operator()( const float & lhs, const float & rhs ) const
98 {
99 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
100 return std::abs( x: boost::math::float_distance(a: lhs, b: rhs) ) < 2;
101 #else
102 return true;
103 #endif
104 }
105 bool operator()( const double & lhs, const double & rhs ) const
106 {
107 #if BOOST_CXX_VERSION > 199711L // only include floating point if C++ version >= C++11
108 return std::abs( x: boost::math::float_distance(a: lhs, b: rhs) ) < 2;
109 #else
110 return true;
111 #endif
112 }
113};
114
115template<class Variant>
116bool test_type(const Variant & v){
117 const char * testfile = boost::archive::tmpnam(NULL);
118 BOOST_REQUIRE(testfile != NULL);
119 {
120 test_ostream os(testfile, TEST_STREAM_FLAGS);
121 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
122 oa << boost::serialization::make_nvp("written", v);
123 }
124
125 Variant vx;
126 {
127 test_istream is(testfile, TEST_STREAM_FLAGS);
128 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
129 BOOST_TRY {
130 ia >> boost::serialization::make_nvp("written", vx);
131 BOOST_CHECK(visit(are_equal(), v, vx));
132 }
133 BOOST_CATCH(boost::archive::archive_exception const& e) {
134 return false;
135 }
136 BOOST_CATCH_END
137 }
138 std::remove(filename: testfile);
139 return true;
140}
141
142template<class Variant>
143void test(Variant & v)
144{
145 // uninitialized
146 test_type(v);
147 v = false;
148 test_type(v);
149 v = 1;
150 test_type(v);
151 v = (float) 2.3;
152 test_type(v);
153 v = (double) 6.4;
154 test_type(v);
155 v = A();
156 test_type(v);
157 v = std::string("we can't stop here, this is Bat Country");
158 test_type(v);
159}
160
161#include <boost/serialization/variant.hpp>
162
163int test_main( int /* argc */, char* /* argv */[] ){
164
165 // boost::variant - compatible with C++03
166 {
167 boost::variant<bool, int, float, double, A, std::string> v;
168 test(v);
169 const A a;
170 boost::variant<bool, int, float, double, const A *, std::string> v1 = & a;
171 test_type(v: v1);
172 }
173
174 // boost::variant2/variant requires C++ 11
175 #if BOOST_CXX_VERSION >= 201103L
176 {
177 boost::variant2::variant<bool, int, float, double, A, std::string> v;
178 test(v);
179 const A a;
180 boost::variant2::variant<bool, int, float, double, const A *, std::string> v1 = & a;
181 test_type(v: v1);
182 }
183 #endif
184
185 // std::variant reqires C++ 17 or more
186 #ifndef BOOST_NO_CXX17_HDR_VARIANT
187 {
188 std::variant<bool, int, float, double, A, std::string> v;
189 test(v);
190 const A a;
191 std::variant<bool, int, float, double, const A *, std::string> v1 = & a;
192 test_type(v: v1);
193 }
194 #endif
195
196 return EXIT_SUCCESS;
197}
198
199// EOF
200

source code of boost/libs/serialization/test/test_variant.cpp