Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/flyweight/flyweight.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* Flyweight class. | |
2 * | |
3 * Copyright 2006-2009 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_FLYWEIGHT_HPP | |
12 #define BOOST_FLYWEIGHT_FLYWEIGHT_HPP | |
13 | |
14 #if defined(_MSC_VER)&&(_MSC_VER>=1200) | |
15 #pragma once | |
16 #endif | |
17 | |
18 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ | |
19 #include <algorithm> | |
20 #include <boost/detail/workaround.hpp> | |
21 #include <boost/flyweight/detail/default_value_policy.hpp> | |
22 #include <boost/flyweight/detail/flyweight_core.hpp> | |
23 #include <boost/flyweight/factory_tag.hpp> | |
24 #include <boost/flyweight/flyweight_fwd.hpp> | |
25 #include <boost/flyweight/locking_tag.hpp> | |
26 #include <boost/flyweight/simple_locking_fwd.hpp> | |
27 #include <boost/flyweight/static_holder_fwd.hpp> | |
28 #include <boost/flyweight/hashed_factory_fwd.hpp> | |
29 #include <boost/flyweight/holder_tag.hpp> | |
30 #include <boost/flyweight/refcounted_fwd.hpp> | |
31 #include <boost/flyweight/tag.hpp> | |
32 #include <boost/flyweight/tracking_tag.hpp> | |
33 #include <boost/mpl/assert.hpp> | |
34 #include <boost/mpl/if.hpp> | |
35 #include <boost/mpl/not.hpp> | |
36 #include <boost/mpl/or.hpp> | |
37 #include <boost/parameter/binding.hpp> | |
38 #include <boost/preprocessor/repetition/enum_params.hpp> | |
39 #include <boost/type_traits/is_same.hpp> | |
40 #include <boost/utility/swap.hpp> | |
41 | |
42 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) | |
43 #pragma warning(push) | |
44 #pragma warning(disable:4521) /* multiple copy ctors */ | |
45 #endif | |
46 | |
47 namespace boost{ | |
48 | |
49 namespace flyweights{ | |
50 | |
51 namespace detail{ | |
52 | |
53 /* Used for the detection of unmatched template args in a | |
54 * flyweight instantiation. | |
55 */ | |
56 | |
57 struct unmatched_arg; | |
58 | |
59 /* Boost.Parameter structures for use in flyweight. | |
60 * NB: these types are derived from instead of typedef'd to force their | |
61 * instantiation, which solves http://bugs.sun.com/view_bug.do?bug_id=6782987 | |
62 * as found out by Simon Atanasyan. | |
63 */ | |
64 | |
65 struct flyweight_signature: | |
66 parameter::parameters< | |
67 parameter::optional< | |
68 parameter::deduced<tag<> >, | |
69 detail::is_tag<boost::mpl::_> | |
70 >, | |
71 parameter::optional< | |
72 parameter::deduced<tracking<> >, | |
73 is_tracking<boost::mpl::_> | |
74 >, | |
75 parameter::optional< | |
76 parameter::deduced<factory<> >, | |
77 is_factory<boost::mpl::_> | |
78 >, | |
79 parameter::optional< | |
80 parameter::deduced<locking<> >, | |
81 is_locking<boost::mpl::_> | |
82 >, | |
83 parameter::optional< | |
84 parameter::deduced<holder<> >, | |
85 is_holder<boost::mpl::_> | |
86 > | |
87 > | |
88 {}; | |
89 | |
90 struct flyweight_unmatched_signature: | |
91 parameter::parameters< | |
92 parameter::optional< | |
93 parameter::deduced< | |
94 detail::unmatched_arg | |
95 >, | |
96 mpl::not_< | |
97 mpl::or_< | |
98 detail::is_tag<boost::mpl::_>, | |
99 is_tracking<boost::mpl::_>, | |
100 is_factory<boost::mpl::_>, | |
101 is_locking<boost::mpl::_>, | |
102 is_holder<boost::mpl::_> | |
103 > | |
104 > | |
105 > | |
106 > | |
107 {}; | |
108 | |
109 } /* namespace flyweights::detail */ | |
110 | |
111 template< | |
112 typename T, | |
113 typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 | |
114 > | |
115 class flyweight | |
116 { | |
117 private: | |
118 typedef typename mpl::if_< | |
119 detail::is_value<T>, | |
120 T, | |
121 detail::default_value_policy<T> | |
122 >::type value_policy; | |
123 typedef typename detail:: | |
124 flyweight_signature::bind< | |
125 Arg1,Arg2,Arg3,Arg4,Arg5 | |
126 >::type args; | |
127 typedef typename parameter::binding< | |
128 args,tag<>,mpl::na | |
129 >::type tag_type; | |
130 typedef typename parameter::binding< | |
131 args,tracking<>,refcounted | |
132 >::type tracking_policy; | |
133 typedef typename parameter::binding< | |
134 args,factory<>,hashed_factory<> | |
135 >::type factory_specifier; | |
136 typedef typename parameter::binding< | |
137 args,locking<>,simple_locking | |
138 >::type locking_policy; | |
139 typedef typename parameter::binding< | |
140 args,holder<>,static_holder | |
141 >::type holder_specifier; | |
142 | |
143 typedef typename detail:: | |
144 flyweight_unmatched_signature::bind< | |
145 Arg1,Arg2,Arg3,Arg4,Arg5 | |
146 >::type unmatched_args; | |
147 typedef typename parameter::binding< | |
148 unmatched_args,detail::unmatched_arg, | |
149 detail::unmatched_arg | |
150 >::type unmatched_arg_detected; | |
151 | |
152 /* You have passed a type in the specification of a flyweight type that | |
153 * could not be interpreted as a valid argument. | |
154 */ | |
155 BOOST_MPL_ASSERT_MSG( | |
156 (is_same<unmatched_arg_detected,detail::unmatched_arg>::value), | |
157 INVALID_ARGUMENT_TO_FLYWEIGHT, | |
158 (flyweight)); | |
159 | |
160 typedef detail::flyweight_core< | |
161 value_policy,tag_type,tracking_policy, | |
162 factory_specifier,locking_policy, | |
163 holder_specifier | |
164 > core; | |
165 typedef typename core::handle_type handle_type; | |
166 | |
167 public: | |
168 typedef typename value_policy::key_type key_type; | |
169 typedef typename value_policy::value_type value_type; | |
170 | |
171 /* static data initialization */ | |
172 | |
173 static bool init(){return core::init();} | |
174 | |
175 class initializer | |
176 { | |
177 public: | |
178 initializer():b(init()){} | |
179 private: | |
180 bool b; | |
181 }; | |
182 | |
183 /* construct/copy/destroy */ | |
184 | |
185 flyweight():h(core::insert(key_type())){} | |
186 flyweight(const flyweight& x):h(x.h){} | |
187 flyweight(flyweight& x):h(x.h){} | |
188 | |
189 /* template ctors */ | |
190 | |
191 #define BOOST_FLYWEIGHT_PERFECT_FWD_NAME explicit flyweight | |
192 #define BOOST_FLYWEIGHT_PERFECT_FWD_BODY(n) \ | |
193 :h(core::insert(BOOST_PP_ENUM_PARAMS(n,t))){} | |
194 #include <boost/flyweight/detail/perfect_fwd.hpp> | |
195 | |
196 flyweight& operator=(const flyweight& x){h=x.h;return *this;} | |
197 flyweight& operator=(const value_type& x){return operator=(flyweight(x));} | |
198 | |
199 /* convertibility to underlying type */ | |
200 | |
201 const key_type& get_key()const{return core::key(h);} | |
202 const value_type& get()const{return core::value(h);} | |
203 operator const value_type&()const{return get();} | |
204 | |
205 /* exact type equality */ | |
206 | |
207 friend bool operator==(const flyweight& x,const flyweight& y) | |
208 { | |
209 return &x.get()==&y.get(); | |
210 } | |
211 | |
212 /* modifiers */ | |
213 | |
214 void swap(flyweight& x){boost::swap(h,x.h);} | |
215 | |
216 private: | |
217 handle_type h; | |
218 }; | |
219 | |
220 #define BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(n) \ | |
221 typename Arg##n##1,typename Arg##n##2,typename Arg##n##3, \ | |
222 typename Arg##n##4,typename Arg##n##5 | |
223 #define BOOST_FLYWEIGHT_TEMPL_ARGS(n) \ | |
224 Arg##n##1,Arg##n##2,Arg##n##3,Arg##n##4,Arg##n##5 | |
225 | |
226 /* Comparison. Unlike exact type comparison defined above, intertype | |
227 * comparison just forwards to the underlying objects. | |
228 */ | |
229 | |
230 template< | |
231 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1), | |
232 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2) | |
233 > | |
234 bool operator==( | |
235 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x, | |
236 const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y) | |
237 { | |
238 return x.get()==y.get(); | |
239 } | |
240 | |
241 template< | |
242 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1), | |
243 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2) | |
244 > | |
245 bool operator<( | |
246 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x, | |
247 const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y) | |
248 { | |
249 return x.get()<y.get(); | |
250 } | |
251 | |
252 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) | |
253 template< | |
254 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1), | |
255 typename T2 | |
256 > | |
257 bool operator==( | |
258 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,const T2& y) | |
259 { | |
260 return x.get()==y; | |
261 } | |
262 | |
263 template< | |
264 typename T1, | |
265 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2) | |
266 > | |
267 bool operator==( | |
268 const T1& x,const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y) | |
269 { | |
270 return x==y.get(); | |
271 } | |
272 | |
273 template< | |
274 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1), | |
275 typename T2 | |
276 > | |
277 bool operator<( | |
278 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,const T2& y) | |
279 { | |
280 return x.get()<y; | |
281 } | |
282 | |
283 template< | |
284 typename T1, | |
285 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2) | |
286 > | |
287 bool operator<( | |
288 const T1& x,const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y) | |
289 { | |
290 return x<y.get(); | |
291 } | |
292 #endif /* !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) */ | |
293 | |
294 /* rest of comparison operators */ | |
295 | |
296 #define BOOST_FLYWEIGHT_COMPLETE_COMP_OPS(t,a1,a2) \ | |
297 template<t> \ | |
298 inline bool operator!=(const a1& x,const a2& y) \ | |
299 { \ | |
300 return !(x==y); \ | |
301 } \ | |
302 \ | |
303 template<t> \ | |
304 inline bool operator>(const a1& x,const a2& y) \ | |
305 { \ | |
306 return y<x; \ | |
307 } \ | |
308 \ | |
309 template<t> \ | |
310 inline bool operator>=(const a1& x,const a2& y) \ | |
311 { \ | |
312 return !(x<y); \ | |
313 } \ | |
314 \ | |
315 template<t> \ | |
316 inline bool operator<=(const a1& x,const a2& y) \ | |
317 { \ | |
318 return !(y<x); \ | |
319 } | |
320 | |
321 BOOST_FLYWEIGHT_COMPLETE_COMP_OPS( | |
322 typename T1 BOOST_PP_COMMA() | |
323 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1) BOOST_PP_COMMA() | |
324 typename T2 BOOST_PP_COMMA() | |
325 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2), | |
326 flyweight< | |
327 T1 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(1) | |
328 >, | |
329 flyweight< | |
330 T2 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(2) | |
331 >) | |
332 | |
333 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) | |
334 BOOST_FLYWEIGHT_COMPLETE_COMP_OPS( | |
335 typename T1 BOOST_PP_COMMA() | |
336 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1) BOOST_PP_COMMA() | |
337 typename T2, | |
338 flyweight< | |
339 T1 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(1) | |
340 >, | |
341 T2) | |
342 | |
343 BOOST_FLYWEIGHT_COMPLETE_COMP_OPS( | |
344 typename T1 BOOST_PP_COMMA() | |
345 typename T2 BOOST_PP_COMMA() | |
346 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2), | |
347 T1, | |
348 flyweight< | |
349 T2 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(2) | |
350 >) | |
351 #endif /* !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) */ | |
352 | |
353 /* specialized algorithms */ | |
354 | |
355 template<typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)> | |
356 void swap( | |
357 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x, | |
358 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& y) | |
359 { | |
360 x.swap(y); | |
361 } | |
362 | |
363 template< | |
364 BOOST_TEMPLATED_STREAM_ARGS(ElemType,Traits) | |
365 BOOST_TEMPLATED_STREAM_COMMA | |
366 typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_) | |
367 > | |
368 BOOST_TEMPLATED_STREAM(ostream,ElemType,Traits)& operator<<( | |
369 BOOST_TEMPLATED_STREAM(ostream,ElemType,Traits)& out, | |
370 const flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x) | |
371 { | |
372 return out<<x.get(); | |
373 } | |
374 | |
375 template< | |
376 BOOST_TEMPLATED_STREAM_ARGS(ElemType,Traits) | |
377 BOOST_TEMPLATED_STREAM_COMMA | |
378 typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_) | |
379 > | |
380 BOOST_TEMPLATED_STREAM(istream,ElemType,Traits)& operator>>( | |
381 BOOST_TEMPLATED_STREAM(istream,ElemType,Traits)& in, | |
382 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x) | |
383 { | |
384 typedef typename flyweight< | |
385 T,BOOST_FLYWEIGHT_TEMPL_ARGS(_) | |
386 >::value_type value_type; | |
387 | |
388 /* value_type need not be default ctble but must be copy ctble */ | |
389 value_type t(x.get()); | |
390 in>>t; | |
391 x=t; | |
392 return in; | |
393 } | |
394 | |
395 } /* namespace flyweights */ | |
396 | |
397 } /* namespace boost */ | |
398 | |
399 #undef BOOST_FLYWEIGHT_COMPLETE_COMP_OPS | |
400 #undef BOOST_FLYWEIGHT_TEMPL_ARGS | |
401 #undef BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS | |
402 | |
403 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) | |
404 #pragma warning(pop) | |
405 #endif | |
406 | |
407 #endif |