1/* Boost.Flyweight basic test template.
2 *
3 * Copyright 2006-2023 Joaquin M Lopez Munoz.
4 * Distributed under the Boost Software License, Version 1.0.
5 * (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/libs/flyweight for library home page.
9 */
10
11#ifndef BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
12#define BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
13
14#if defined(_MSC_VER)
15#pragma once
16#endif
17
18#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
19#include <boost/detail/lightweight_test.hpp>
20#include <boost/flyweight/key_value.hpp>
21#include <boost/mpl/apply.hpp>
22#include <boost/utility/value_init.hpp>
23#include <string>
24#include <sstream>
25#include "heavy_objects.hpp"
26
27#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
28#include <utility>
29#endif
30
31#if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
32#include <boost/functional/hash.hpp>
33
34#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
35#include <functional>
36#endif
37#endif
38
39#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
40
41template<typename Flyweight,typename ForwardIterator>
42void test_basic_template(
43 ForwardIterator first,ForwardIterator last
44 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
45{
46 typedef typename Flyweight::value_type value_type;
47
48 ForwardIterator it;
49
50 for(it=first;it!=last;++it){
51 /* construct/copy/destroy */
52
53 Flyweight f1(*it);
54 Flyweight f2;
55 Flyweight c1(f1);
56 const Flyweight c2(static_cast<const Flyweight&>(f2));
57 value_type v1(*it);
58 boost::value_initialized<value_type> v2;
59 BOOST_TEST(f1.get_key()==*it);
60 BOOST_TEST((f1==f2)==(f1.get()==v2.data()));
61 BOOST_TEST(f1==c1);
62 BOOST_TEST(f2==c2);
63
64#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
65 Flyweight cr1(std::move(c1));
66 Flyweight cr2(std::move(c2));
67 BOOST_TEST(f1==cr1);
68 BOOST_TEST(f2==cr2);
69#endif
70
71#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
72 /* testcase for https://svn.boost.org/trac/boost/ticket/10439 */
73
74 Flyweight f3={};
75 BOOST_TEST(f3==f2);
76#endif
77
78 f1=((void)0,f1); /* self assignment warning */
79 BOOST_TEST(f1==f1);
80
81 c1=f2;
82 BOOST_TEST(c1==f2);
83
84 c1=f1;
85 BOOST_TEST(c1==f1);
86
87 /* convertibility to underlying type */
88
89 BOOST_TEST(f1.get()==v1);
90 BOOST_TEST(*f1==v1);
91
92 /* identity of reference */
93
94 BOOST_TEST(&f1.get()==&c1.get());
95 BOOST_TEST(&(*f1)==&c1.get());
96 BOOST_TEST(f1.operator->()==&c1.get());
97
98 /* modifiers */
99
100 f1.swap(f1);
101 BOOST_TEST(f1==c1);
102
103 f1.swap(f2);
104 BOOST_TEST(f1==c2);
105 BOOST_TEST(f2==c1);
106
107 boost::flyweights::swap(f1,f2);
108 BOOST_TEST(f1==c1);
109 BOOST_TEST(f2==c2);
110
111 /* specialized algorithms */
112
113 std::ostringstream oss1;
114 oss1<<f1;
115 std::ostringstream oss2;
116 oss2<<f1.get();
117 BOOST_TEST(oss1.str()==oss2.str());
118
119#if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
120
121 /* hash support */
122
123 BOOST_TEST(boost::hash<Flyweight>()(f1)==boost::hash<Flyweight>()(c1));
124 BOOST_TEST(boost::hash<Flyweight>()(f1)==
125 boost::hash<const value_type*>()(&f1.get()));
126
127#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
128 BOOST_TEST(std::hash<Flyweight>()(f1)==std::hash<Flyweight>()(c1));
129 BOOST_TEST(std::hash<Flyweight>()(f1)==
130 std::hash<const value_type*>()(&f1.get()));
131#endif
132#endif
133 }
134}
135
136template<typename Flyweight,typename ForwardIterator>
137void test_basic_with_assign_template(
138 ForwardIterator first,ForwardIterator last
139 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
140{
141 typedef typename Flyweight::value_type value_type;
142
143 ForwardIterator it;
144
145 test_basic_template<Flyweight>(first,last);
146
147 for(it=first;it!=last;++it){
148 /* value construction */
149
150 value_type v(*it);
151 Flyweight f1(v);
152 Flyweight f2(f1.get());
153 BOOST_TEST(f1.get()==v);
154 BOOST_TEST(f2.get()==v);
155 BOOST_TEST(f1==f2);
156
157#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
158 value_type v1(v);
159 const value_type v2(v);
160 Flyweight fr1(std::move(v1));
161 Flyweight fr2(std::move(v2));
162 BOOST_TEST(fr1==v);
163 BOOST_TEST(fr2==v);
164#endif
165
166 /* value assignment */
167
168 Flyweight f3,f4;
169 f3=v;
170 f4=f1.get();
171 BOOST_TEST(f2.get()==v);
172 BOOST_TEST(f3.get()==v);
173 BOOST_TEST(f2==f3);
174
175#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
176 Flyweight fr3;
177 fr3=value_type(*it);
178 BOOST_TEST(fr3.get()==value_type(*it));
179#endif
180
181 /* specialized algorithms */
182
183 std::ostringstream oss1;
184 oss1<<f1;
185 std::istringstream iss1(oss1.str());
186 Flyweight f5;
187 iss1>>f5;
188 BOOST_TEST(f5==f1);
189 }
190}
191
192template<
193 typename Flyweight1,typename Flyweight2,
194 typename ForwardIterator1,typename ForwardIterator2
195>
196void test_basic_comparison_template(
197 ForwardIterator1 first1,ForwardIterator1 last1,
198 ForwardIterator2 first2
199 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight1)
200 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight2))
201{
202 typedef typename Flyweight1::value_type value_type1;
203 typedef typename Flyweight2::value_type value_type2;
204
205 for(;first1!=last1;++first1,++first2){
206 value_type1 v1=value_type1(*first1);
207 value_type2 v2=value_type2(*first2);
208 Flyweight1 f1(v1);
209 Flyweight2 f2(v2);
210
211 BOOST_TEST((f1==f2)==(f1.get()==v2));
212 BOOST_TEST((f1< f2)==(f1.get()< v2));
213 BOOST_TEST((f1!=f2)==(f1.get()!=v2));
214 BOOST_TEST((f1> f2)==(f1.get()> v2));
215 BOOST_TEST((f1>=f2)==(f1.get()>=v2));
216 BOOST_TEST((f1<=f2)==(f1.get()<=v2));
217
218#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
219 BOOST_TEST((f1==v2)==(f1.get()==v2));
220 BOOST_TEST((f1< v2)==(f1.get()< v2));
221 BOOST_TEST((f1!=v2)==(f1.get()!=v2));
222 BOOST_TEST((f1> v2)==(f1.get()> v2));
223 BOOST_TEST((f1>=v2)==(f1.get()>=v2));
224 BOOST_TEST((f1<=v2)==(f1.get()<=v2));
225
226 BOOST_TEST((v1==f2)==(f1.get()==v2));
227 BOOST_TEST((v1< f2)==(f1.get()< v2));
228 BOOST_TEST((v1!=f2)==(f1.get()!=v2));
229 BOOST_TEST((v1> f2)==(f1.get()> v2));
230 BOOST_TEST((v1>=f2)==(f1.get()>=v2));
231 BOOST_TEST((v1<=f2)==(f1.get()<=v2));
232#endif
233
234 }
235}
236
237template<typename FlyweightSpecifier>
238void test_basic_template(BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier))
239{
240 typedef typename boost::mpl::apply1<
241 FlyweightSpecifier,int
242 >::type int_flyweight;
243
244 typedef typename boost::mpl::apply1<
245 FlyweightSpecifier,std::string
246 >::type string_flyweight;
247
248 typedef typename boost::mpl::apply1<
249 FlyweightSpecifier,char
250 >::type char_flyweight;
251
252 typedef typename boost::mpl::apply1<
253 FlyweightSpecifier,
254 boost::flyweights::key_value<std::string,texture,from_texture_to_string>
255 >::type texture_flyweight;
256
257 typedef typename boost::mpl::apply1<
258 FlyweightSpecifier,
259 boost::flyweights::key_value<int,factorization>
260 >::type factorization_flyweight;
261
262 int ints[]={0,1,1,0,1,2,3,4,3,4,0,0};
263 test_basic_with_assign_template<int_flyweight>(
264 &ints[0],&ints[0]+LENGTHOF(ints));
265
266 const char* words[]={"hello","boost","flyweight","boost","bye","c++","c++"};
267 test_basic_with_assign_template<string_flyweight>(
268 &words[0],&words[0]+LENGTHOF(words));
269
270 const char* textures[]={"wood","grass","sand","granite","terracotta"};
271 test_basic_with_assign_template<texture_flyweight>(
272 &textures[0],&textures[0]+LENGTHOF(textures));
273
274 int factorizations[]={1098,102387,90846,2223978};
275 test_basic_template<factorization_flyweight>(
276 &factorizations[0],&factorizations[0]+LENGTHOF(factorizations));
277
278 char chars[]={0,2,4,5,1,1,1,3,4,1,1,0};
279 test_basic_comparison_template<int_flyweight,char_flyweight>(
280 &ints[0],&ints[0]+LENGTHOF(ints),&chars[0]);
281
282 test_basic_comparison_template<string_flyweight,string_flyweight>(
283 &words[0],&words[0]+LENGTHOF(words)-1,&words[1]);
284
285 test_basic_comparison_template<texture_flyweight,texture_flyweight>(
286 &textures[0],&textures[0]+LENGTHOF(textures)-1,&textures[1]);
287
288#if !defined(BOOST_NO_EXCEPTIONS)
289 typedef typename boost::mpl::apply1<
290 FlyweightSpecifier,
291 boost::flyweights::key_value<int,throwing_value,from_throwing_value_to_int>
292 >::type throwing_flyweight;
293
294 try{
295 throwing_flyweight fw(0);
296 }catch(const throwing_value_exception&){}
297 try{
298 throwing_flyweight fw=throwing_flyweight(throwing_value());
299 (void)fw;
300 }catch(const throwing_value_exception&){}
301#endif
302
303}
304
305#undef LENGTHOF
306
307#endif
308

source code of boost/libs/flyweight/test/test_basic_template.hpp