1 /* Boost.Flyweight basic test template.
3 * Copyright 2006-2019 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)
8 * See http://www.boost.org/libs/flyweight for library home page.
11 #ifndef BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
12 #define BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
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>
25 #include "heavy_objects.hpp"
27 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
31 #if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
32 #include <boost/functional/hash.hpp>
34 #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
39 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
41 template<typename Flyweight,typename ForwardIterator>
42 void test_basic_template(
43 ForwardIterator first,ForwardIterator last
44 BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
46 typedef typename Flyweight::value_type value_type;
50 for(it=first;it!=last;++it){
51 /* construct/copy/destroy */
56 const Flyweight c2(static_cast<const Flyweight&>(f2));
58 boost::value_initialized<value_type> v2;
59 BOOST_TEST(f1.get_key()==*it);
60 BOOST_TEST((f1==f2)==(f1.get()==v2.data()));
64 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
65 Flyweight cr1(std::move(c1));
66 Flyweight cr2(std::move(c2));
71 #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
72 /* testcase for https://svn.boost.org/trac/boost/ticket/10439 */
78 f1=((void)0,f1); /* self assignment warning */
87 /* convertibility to underlying type */
89 BOOST_TEST(f1.get()==v1);
91 /* identity of reference */
93 BOOST_TEST(&f1.get()==&c1.get());
104 boost::flyweights::swap(f1,f2);
108 /* specialized algorithms */
110 std::ostringstream oss1;
112 std::ostringstream oss2;
114 BOOST_TEST(oss1.str()==oss2.str());
116 #if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
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()));
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()));
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))
138 typedef typename Flyweight::value_type value_type;
142 test_basic_template<Flyweight>(first,last);
144 for(it=first;it!=last;++it){
145 /* value construction */
149 Flyweight f2(f1.get());
150 BOOST_TEST(f1.get()==v);
151 BOOST_TEST(f2.get()==v);
154 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
156 const value_type v2(v);
157 Flyweight fr1(std::move(v1));
158 Flyweight fr2(std::move(v2));
163 /* value assignment */
168 BOOST_TEST(f2.get()==v);
169 BOOST_TEST(f3.get()==v);
172 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
175 BOOST_TEST(fr3.get()==value_type(*it));
178 /* specialized algorithms */
180 std::ostringstream oss1;
182 std::istringstream iss1(oss1.str());
190 typename Flyweight1,typename Flyweight2,
191 typename ForwardIterator1,typename ForwardIterator2
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))
199 typedef typename Flyweight1::value_type value_type1;
200 typedef typename Flyweight2::value_type value_type2;
202 for(;first1!=last1;++first1,++first2){
203 value_type1 v1=value_type1(*first1);
204 value_type2 v2=value_type2(*first2);
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));
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));
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));
234 template<typename FlyweightSpecifier>
235 void test_basic_template(BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier))
237 typedef typename boost::mpl::apply1<
238 FlyweightSpecifier,int
239 >::type int_flyweight;
241 typedef typename boost::mpl::apply1<
242 FlyweightSpecifier,std::string
243 >::type string_flyweight;
245 typedef typename boost::mpl::apply1<
246 FlyweightSpecifier,char
247 >::type char_flyweight;
249 typedef typename boost::mpl::apply1<
251 boost::flyweights::key_value<std::string,texture,from_texture_to_string>
252 >::type texture_flyweight;
254 typedef typename boost::mpl::apply1<
256 boost::flyweights::key_value<int,factorization>
257 >::type factorization_flyweight;
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));
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));
267 const char* textures[]={"wood","grass","sand","granite","terracotta"};
268 test_basic_with_assign_template<texture_flyweight>(
269 &textures[0],&textures[0]+LENGTHOF(textures));
271 int factorizations[]={1098,102387,90846,2223978};
272 test_basic_template<factorization_flyweight>(
273 &factorizations[0],&factorizations[0]+LENGTHOF(factorizations));
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]);
279 test_basic_comparison_template<string_flyweight,string_flyweight>(
280 &words[0],&words[0]+LENGTHOF(words)-1,&words[1]);
282 test_basic_comparison_template<texture_flyweight,texture_flyweight>(
283 &textures[0],&textures[0]+LENGTHOF(textures)-1,&textures[1]);
285 #if !defined(BOOST_NO_EXCEPTIONS)
286 typedef typename boost::mpl::apply1<
288 boost::flyweights::key_value<int,throwing_value,from_throwing_value_to_int>
289 >::type throwing_flyweight;
292 throwing_flyweight fw(0);
293 }catch(const throwing_value_exception&){}
295 throwing_flyweight fw=throwing_flyweight(throwing_value());
297 }catch(const throwing_value_exception&){}