1 | /* Boost.Flyweight test of flyweight forwarding and initializer_list ctors. |
2 | * |
3 | * Copyright 2006-2015 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 | #include "test_multictor.hpp" |
12 | |
13 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
14 | #include <boost/detail/lightweight_test.hpp> |
15 | #include <boost/detail/workaround.hpp> |
16 | #include <boost/flyweight.hpp> |
17 | #include <boost/functional/hash.hpp> |
18 | #include <boost/tuple/tuple.hpp> |
19 | #include <boost/tuple/tuple_comparison.hpp> |
20 | |
21 | using boost::flyweight; |
22 | |
23 | #if BOOST_WORKAROUND(BOOST_MSVC,<1300) |
24 | #define NONCONST const |
25 | #else |
26 | #define NONCONST |
27 | #endif |
28 | |
29 | struct multictor |
30 | { |
31 | typedef multictor type; |
32 | |
33 | multictor(): |
34 | t(0,0,0.0,"" ,false){} |
35 | multictor(NONCONST int& x0): |
36 | t(x0,0,0.0,"" ,false){} |
37 | multictor(int x0,NONCONST char& x1): |
38 | t(x0,x1,0.0,"" ,false){} |
39 | multictor(int x0,char x1,NONCONST double& x2): |
40 | t(x0,x1,x2,"" ,false){} |
41 | multictor(int x0,char x1,double x2,NONCONST std::string& x3): |
42 | t(x0,x1,x2,x3,false){} |
43 | multictor(int x0,char x1,double x2,const std::string& x3,NONCONST bool& x4): |
44 | t(x0,x1,x2,x3,x4){} |
45 | |
46 | friend bool operator==(const type& x,const type& y){return x.t==y.t;} |
47 | friend bool operator< (const type& x,const type& y){return x.t< y.t;} |
48 | friend bool operator!=(const type& x,const type& y){return x.t!=y.t;} |
49 | friend bool operator> (const type& x,const type& y){return x.t> y.t;} |
50 | friend bool operator>=(const type& x,const type& y){return x.t>=y.t;} |
51 | friend bool operator<=(const type& x,const type& y){return x.t<=y.t;} |
52 | |
53 | boost::tuples::tuple<int,char,double,std::string,bool> t; |
54 | }; |
55 | |
56 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
57 | namespace boost{ |
58 | #endif |
59 | |
60 | inline std::size_t hash_value(const multictor& x) |
61 | { |
62 | std::size_t res=0; |
63 | boost::hash_combine(seed&: res,v: boost::tuples::get<0>(c: x.t)); |
64 | boost::hash_combine(seed&: res,v: boost::tuples::get<1>(c: x.t)); |
65 | boost::hash_combine(seed&: res,v: boost::tuples::get<2>(c: x.t)); |
66 | boost::hash_combine(seed&: res,v: boost::tuples::get<3>(c: x.t)); |
67 | boost::hash_combine(seed&: res,v: boost::tuples::get<4>(c: x.t)); |
68 | return res; |
69 | } |
70 | |
71 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
72 | } /* namespace boost */ |
73 | #endif |
74 | |
75 | #if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) |
76 | |
77 | #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) |
78 | #define INIT0(_) {} |
79 | #define INIT1(a) {a} |
80 | #define INIT2(a,b) {a,b} |
81 | #define INIT_LIST1(a) {a} |
82 | #define INIT_LIST2(a,b) {a,b} |
83 | #else |
84 | #define INIT0(_) |
85 | #define INIT1(a) ((a)) |
86 | #define INIT2(a,b) ((a),(b)) |
87 | #define INIT_LIST1(a) ({a}) |
88 | #define INIT_LIST2(a,b) ({a,b}) |
89 | #endif |
90 | |
91 | struct initctor |
92 | { |
93 | struct arg{arg(int= 0){}}; |
94 | |
95 | initctor():res(-1){} |
96 | initctor(arg,arg):res(-2){} |
97 | initctor(int,unsigned int):res(-3){} |
98 | |
99 | initctor(std::initializer_list<int> list):res(0) |
100 | { |
101 | typedef const int* iterator; |
102 | for(iterator it=list.begin(),it_end=list.end();it!=it_end;++it){ |
103 | res+=*it; |
104 | } |
105 | } |
106 | |
107 | initctor(std::initializer_list<unsigned int> list):res(0) |
108 | { |
109 | typedef const unsigned int* iterator; |
110 | for(iterator it=list.begin(),it_end=list.end();it!=it_end;++it){ |
111 | res+=(int)(*it)*2; |
112 | } |
113 | } |
114 | |
115 | friend bool operator==(const initctor& x,const initctor& y) |
116 | { |
117 | return x.res==y.res; |
118 | } |
119 | |
120 | int res; |
121 | }; |
122 | |
123 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
124 | namespace boost{ |
125 | #endif |
126 | |
127 | inline std::size_t hash_value(const initctor& x) |
128 | { |
129 | return (std::size_t)(x.res); |
130 | } |
131 | |
132 | #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) |
133 | } /* namespace boost */ |
134 | #endif |
135 | |
136 | #endif |
137 | |
138 | void test_multictor() |
139 | { |
140 | flyweight<multictor> f; |
141 | multictor m; |
142 | BOOST_TEST(f==m); |
143 | |
144 | int x0=1; |
145 | flyweight<multictor> f0(x0); |
146 | multictor m0(x0); |
147 | BOOST_TEST(f0==m0); |
148 | |
149 | char x1='a'; |
150 | flyweight<multictor> f1(1,x1); |
151 | multictor m1(1,x1); |
152 | BOOST_TEST(f1==m1); |
153 | |
154 | double x2=3.1416; |
155 | flyweight<multictor> f2(1,'a',x2); |
156 | multictor m2(1,'a',x2); |
157 | BOOST_TEST(f2==m2); |
158 | |
159 | std::string x3("boost" ); |
160 | flyweight<multictor> f3(1,'a',3.1416,x3); |
161 | multictor m3(1,'a',3.1416,x3); |
162 | BOOST_TEST(f3==m3); |
163 | |
164 | bool x4=true; |
165 | flyweight<multictor> f4(1,'a',3.1416,"boost" ,x4); |
166 | multictor m4(1,'a',3.1416,"boost" ,x4); |
167 | BOOST_TEST(f4==m4); |
168 | |
169 | #if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) |
170 | flyweight<initctor> ff INIT0(~); |
171 | BOOST_TEST(ff.get().res==-1); |
172 | |
173 | ff=flyweight<initctor> INIT2(initctor::arg(),1); |
174 | BOOST_TEST(ff.get().res==-2); |
175 | |
176 | flyweight<initctor> ff0 INIT2(initctor::arg(),initctor::arg()); |
177 | BOOST_TEST(ff0.get().res==-2); |
178 | |
179 | ff0={1}; |
180 | BOOST_TEST(ff0.get().res==1); |
181 | |
182 | flyweight<initctor> ff1 INIT_LIST2(1,2); |
183 | BOOST_TEST(ff1.get().res==3); |
184 | |
185 | ff1={1u,2u,3u}; |
186 | BOOST_TEST(ff1.get().res==12); |
187 | |
188 | flyweight<initctor> ff2 INIT_LIST1(1u); |
189 | BOOST_TEST(ff2.get().res==2); |
190 | #endif |
191 | } |
192 | |