]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* Boost.Flyweight basic test template. |
2 | * | |
92f5a8d4 | 3 | * Copyright 2006-2019 Joaquin M Lopez Munoz. |
7c673cae FG |
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 | ||
41 | template<typename Flyweight,typename ForwardIterator> | |
42 | void 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 | ||
92f5a8d4 | 78 | f1=((void)0,f1); /* self assignment warning */ |
7c673cae FG |
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 | ||
91 | /* identity of reference */ | |
92 | ||
93 | BOOST_TEST(&f1.get()==&c1.get()); | |
94 | ||
95 | /* modifiers */ | |
96 | ||
97 | f1.swap(f1); | |
98 | BOOST_TEST(f1==c1); | |
99 | ||
100 | f1.swap(f2); | |
101 | BOOST_TEST(f1==c2); | |
102 | BOOST_TEST(f2==c1); | |
103 | ||
104 | boost::flyweights::swap(f1,f2); | |
105 | BOOST_TEST(f1==c1); | |
106 | BOOST_TEST(f2==c2); | |
107 | ||
108 | /* specialized algorithms */ | |
109 | ||
110 | std::ostringstream oss1; | |
111 | oss1<<f1; | |
112 | std::ostringstream oss2; | |
113 | oss2<<f1.get(); | |
114 | BOOST_TEST(oss1.str()==oss2.str()); | |
115 | ||
116 | #if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT) | |
117 | ||
118 | /* hash support */ | |
119 | ||
120 | BOOST_TEST(boost::hash<Flyweight>()(f1)==boost::hash<Flyweight>()(c1)); | |
121 | BOOST_TEST(boost::hash<Flyweight>()(f1)== | |
122 | boost::hash<const value_type*>()(&f1.get())); | |
123 | ||
124 | #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) | |
125 | BOOST_TEST(std::hash<Flyweight>()(f1)==std::hash<Flyweight>()(c1)); | |
126 | BOOST_TEST(std::hash<Flyweight>()(f1)== | |
127 | std::hash<const value_type*>()(&f1.get())); | |
128 | #endif | |
129 | #endif | |
130 | } | |
131 | } | |
132 | ||
133 | template<typename Flyweight,typename ForwardIterator> | |
134 | void test_basic_with_assign_template( | |
135 | ForwardIterator first,ForwardIterator last | |
136 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight)) | |
137 | { | |
138 | typedef typename Flyweight::value_type value_type; | |
139 | ||
140 | ForwardIterator it; | |
141 | ||
142 | test_basic_template<Flyweight>(first,last); | |
143 | ||
144 | for(it=first;it!=last;++it){ | |
145 | /* value construction */ | |
146 | ||
147 | value_type v(*it); | |
148 | Flyweight f1(v); | |
149 | Flyweight f2(f1.get()); | |
150 | BOOST_TEST(f1.get()==v); | |
151 | BOOST_TEST(f2.get()==v); | |
152 | BOOST_TEST(f1==f2); | |
153 | ||
154 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
155 | value_type v1(v); | |
156 | const value_type v2(v); | |
157 | Flyweight fr1(std::move(v1)); | |
158 | Flyweight fr2(std::move(v2)); | |
159 | BOOST_TEST(fr1==v); | |
160 | BOOST_TEST(fr2==v); | |
161 | #endif | |
162 | ||
163 | /* value assignment */ | |
164 | ||
165 | Flyweight f3,f4; | |
166 | f3=v; | |
167 | f4=f1.get(); | |
168 | BOOST_TEST(f2.get()==v); | |
169 | BOOST_TEST(f3.get()==v); | |
170 | BOOST_TEST(f2==f3); | |
171 | ||
172 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
173 | Flyweight fr3; | |
174 | fr3=value_type(*it); | |
175 | BOOST_TEST(fr3.get()==value_type(*it)); | |
176 | #endif | |
177 | ||
178 | /* specialized algorithms */ | |
179 | ||
180 | std::ostringstream oss1; | |
181 | oss1<<f1; | |
182 | std::istringstream iss1(oss1.str()); | |
183 | Flyweight f5; | |
184 | iss1>>f5; | |
185 | BOOST_TEST(f5==f1); | |
186 | } | |
187 | } | |
188 | ||
189 | template< | |
190 | typename Flyweight1,typename Flyweight2, | |
191 | typename ForwardIterator1,typename ForwardIterator2 | |
192 | > | |
193 | void test_basic_comparison_template( | |
194 | ForwardIterator1 first1,ForwardIterator1 last1, | |
195 | ForwardIterator2 first2 | |
196 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight1) | |
197 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight2)) | |
198 | { | |
199 | typedef typename Flyweight1::value_type value_type1; | |
200 | typedef typename Flyweight2::value_type value_type2; | |
201 | ||
202 | for(;first1!=last1;++first1,++first2){ | |
203 | value_type1 v1=value_type1(*first1); | |
204 | value_type2 v2=value_type2(*first2); | |
205 | Flyweight1 f1(v1); | |
206 | Flyweight2 f2(v2); | |
207 | ||
208 | BOOST_TEST((f1==f2)==(f1.get()==v2)); | |
209 | BOOST_TEST((f1< f2)==(f1.get()< v2)); | |
210 | BOOST_TEST((f1!=f2)==(f1.get()!=v2)); | |
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 | ||
215 | #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) | |
216 | BOOST_TEST((f1==v2)==(f1.get()==v2)); | |
217 | BOOST_TEST((f1< v2)==(f1.get()< v2)); | |
218 | BOOST_TEST((f1!=v2)==(f1.get()!=v2)); | |
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 | ||
223 | BOOST_TEST((v1==f2)==(f1.get()==v2)); | |
224 | BOOST_TEST((v1< f2)==(f1.get()< v2)); | |
225 | BOOST_TEST((v1!=f2)==(f1.get()!=v2)); | |
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 | #endif | |
230 | ||
231 | } | |
232 | } | |
233 | ||
234 | template<typename FlyweightSpecifier> | |
235 | void test_basic_template(BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier)) | |
236 | { | |
237 | typedef typename boost::mpl::apply1< | |
238 | FlyweightSpecifier,int | |
239 | >::type int_flyweight; | |
240 | ||
241 | typedef typename boost::mpl::apply1< | |
242 | FlyweightSpecifier,std::string | |
243 | >::type string_flyweight; | |
244 | ||
245 | typedef typename boost::mpl::apply1< | |
246 | FlyweightSpecifier,char | |
247 | >::type char_flyweight; | |
248 | ||
249 | typedef typename boost::mpl::apply1< | |
250 | FlyweightSpecifier, | |
251 | boost::flyweights::key_value<std::string,texture,from_texture_to_string> | |
252 | >::type texture_flyweight; | |
253 | ||
254 | typedef typename boost::mpl::apply1< | |
255 | FlyweightSpecifier, | |
256 | boost::flyweights::key_value<int,factorization> | |
257 | >::type factorization_flyweight; | |
258 | ||
259 | int ints[]={0,1,1,0,1,2,3,4,3,4,0,0}; | |
260 | test_basic_with_assign_template<int_flyweight>( | |
261 | &ints[0],&ints[0]+LENGTHOF(ints)); | |
262 | ||
263 | const char* words[]={"hello","boost","flyweight","boost","bye","c++","c++"}; | |
264 | test_basic_with_assign_template<string_flyweight>( | |
265 | &words[0],&words[0]+LENGTHOF(words)); | |
266 | ||
267 | const char* textures[]={"wood","grass","sand","granite","terracotta"}; | |
268 | test_basic_with_assign_template<texture_flyweight>( | |
269 | &textures[0],&textures[0]+LENGTHOF(textures)); | |
270 | ||
271 | int factorizations[]={1098,102387,90846,2223978}; | |
272 | test_basic_template<factorization_flyweight>( | |
273 | &factorizations[0],&factorizations[0]+LENGTHOF(factorizations)); | |
274 | ||
275 | char chars[]={0,2,4,5,1,1,1,3,4,1,1,0}; | |
276 | test_basic_comparison_template<int_flyweight,char_flyweight>( | |
277 | &ints[0],&ints[0]+LENGTHOF(ints),&chars[0]); | |
278 | ||
279 | test_basic_comparison_template<string_flyweight,string_flyweight>( | |
280 | &words[0],&words[0]+LENGTHOF(words)-1,&words[1]); | |
281 | ||
282 | test_basic_comparison_template<texture_flyweight,texture_flyweight>( | |
283 | &textures[0],&textures[0]+LENGTHOF(textures)-1,&textures[1]); | |
284 | ||
285 | #if !defined(BOOST_NO_EXCEPTIONS) | |
286 | typedef typename boost::mpl::apply1< | |
287 | FlyweightSpecifier, | |
288 | boost::flyweights::key_value<int,throwing_value,from_throwing_value_to_int> | |
289 | >::type throwing_flyweight; | |
290 | ||
291 | try{ | |
292 | throwing_flyweight fw(0); | |
293 | }catch(const throwing_value_exception&){} | |
294 | try{ | |
295 | throwing_flyweight fw=throwing_flyweight(throwing_value()); | |
92f5a8d4 | 296 | (void)fw; |
7c673cae FG |
297 | }catch(const throwing_value_exception&){} |
298 | #endif | |
299 | ||
300 | } | |
301 | ||
302 | #undef LENGTHOF | |
303 | ||
304 | #endif |