]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/flyweight/include/boost/flyweight/flyweight.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / flyweight / include / boost / flyweight / flyweight.hpp
CommitLineData
7c673cae
FG
1/* Flyweight class.
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#ifndef BOOST_FLYWEIGHT_FLYWEIGHT_HPP
12#define BOOST_FLYWEIGHT_FLYWEIGHT_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 <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/detail/perfect_fwd.hpp>
24#include <boost/flyweight/factory_tag.hpp>
25#include <boost/flyweight/flyweight_fwd.hpp>
26#include <boost/flyweight/locking_tag.hpp>
27#include <boost/flyweight/simple_locking_fwd.hpp>
28#include <boost/flyweight/static_holder_fwd.hpp>
29#include <boost/flyweight/hashed_factory_fwd.hpp>
30#include <boost/flyweight/holder_tag.hpp>
31#include <boost/flyweight/refcounted_fwd.hpp>
32#include <boost/flyweight/tag.hpp>
33#include <boost/flyweight/tracking_tag.hpp>
34#include <boost/mpl/assert.hpp>
35#include <boost/mpl/if.hpp>
36#include <boost/mpl/not.hpp>
37#include <boost/mpl/or.hpp>
38#include <boost/parameter/binding.hpp>
39#include <boost/type_traits/is_same.hpp>
40#include <boost/utility/swap.hpp>
41
42#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
43#include <boost/utility/enable_if.hpp>
44#include <boost/type_traits/is_convertible.hpp>
45#include <initializer_list>
46#endif
47
48#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
49#pragma warning(push)
50#pragma warning(disable:4520) /* multiple default ctors */
51#pragma warning(disable:4521) /* multiple copy ctors */
52#endif
53
54namespace boost{
55
56namespace flyweights{
57
58namespace detail{
59
60/* Used for the detection of unmatched template args in a
61 * flyweight instantiation.
62 */
63
64struct unmatched_arg;
65
66/* Boost.Parameter structures for use in flyweight.
67 * NB: these types are derived from instead of typedef'd to force their
68 * instantiation, which solves http://bugs.sun.com/view_bug.do?bug_id=6782987
69 * as found out by Simon Atanasyan.
70 */
71
72struct flyweight_signature:
73 parameter::parameters<
74 parameter::optional<
75 parameter::deduced<tag<> >,
76 detail::is_tag<boost::mpl::_>
77 >,
78 parameter::optional<
79 parameter::deduced<tracking<> >,
80 is_tracking<boost::mpl::_>
81 >,
82 parameter::optional<
83 parameter::deduced<factory<> >,
84 is_factory<boost::mpl::_>
85 >,
86 parameter::optional<
87 parameter::deduced<locking<> >,
88 is_locking<boost::mpl::_>
89 >,
90 parameter::optional<
91 parameter::deduced<holder<> >,
92 is_holder<boost::mpl::_>
93 >
94 >
95{};
96
97struct flyweight_unmatched_signature:
98 parameter::parameters<
99 parameter::optional<
100 parameter::deduced<
101 detail::unmatched_arg
102 >,
103 mpl::not_<
104 mpl::or_<
105 detail::is_tag<boost::mpl::_>,
106 is_tracking<boost::mpl::_>,
107 is_factory<boost::mpl::_>,
108 is_locking<boost::mpl::_>,
109 is_holder<boost::mpl::_>
110 >
111 >
112 >
113 >
114{};
115
116} /* namespace flyweights::detail */
117
118template<
119 typename T,
120 typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
121>
122class flyweight
123{
124private:
125 typedef typename mpl::if_<
126 detail::is_value<T>,
127 T,
128 detail::default_value_policy<T>
129 >::type value_policy;
130 typedef typename detail::
131 flyweight_signature::bind<
132 Arg1,Arg2,Arg3,Arg4,Arg5
133 >::type args;
134 typedef typename parameter::binding<
135 args,tag<>,mpl::na
136 >::type tag_type;
137 typedef typename parameter::binding<
138 args,tracking<>,refcounted
139 >::type tracking_policy;
140 typedef typename parameter::binding<
141 args,factory<>,hashed_factory<>
142 >::type factory_specifier;
143 typedef typename parameter::binding<
144 args,locking<>,simple_locking
145 >::type locking_policy;
146 typedef typename parameter::binding<
147 args,holder<>,static_holder
148 >::type holder_specifier;
149
150 typedef typename detail::
151 flyweight_unmatched_signature::bind<
152 Arg1,Arg2,Arg3,Arg4,Arg5
153 >::type unmatched_args;
154 typedef typename parameter::binding<
155 unmatched_args,detail::unmatched_arg,
156 detail::unmatched_arg
157 >::type unmatched_arg_detected;
158
159 /* You have passed a type in the specification of a flyweight type that
160 * could not be interpreted as a valid argument.
161 */
162 BOOST_MPL_ASSERT_MSG(
163 (is_same<unmatched_arg_detected,detail::unmatched_arg>::value),
164 INVALID_ARGUMENT_TO_FLYWEIGHT,
165 (flyweight));
166
167 typedef detail::flyweight_core<
168 value_policy,tag_type,tracking_policy,
169 factory_specifier,locking_policy,
170 holder_specifier
171 > core;
172 typedef typename core::handle_type handle_type;
173
174public:
175 typedef typename value_policy::key_type key_type;
176 typedef typename value_policy::value_type value_type;
177
178 /* static data initialization */
179
180 static bool init(){return core::init();}
181
182 class initializer
183 {
184 public:
185 initializer():b(init()){}
186 private:
187 bool b;
188 };
189
190 /* construct/copy/destroy */
191
192 flyweight():h(core::insert()){}
193
194#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
195 :h(core::insert(BOOST_FLYWEIGHT_FORWARD(args))){}
196
197 BOOST_FLYWEIGHT_PERFECT_FWD_WITH_ARGS(
198 explicit flyweight,
199 BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY)
200
201#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY
202
203#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
204 template<typename V>
205 flyweight(
206 std::initializer_list<V> list,
207 typename boost::enable_if<
208 boost::is_convertible<std::initializer_list<V>,key_type> >::type* =0):
209 h(core::insert(list)){}
210#endif
211
212 flyweight(const flyweight& x):h(x.h){}
213 flyweight(flyweight& x):h(x.h){}
214
215#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
216 flyweight(const flyweight&& x):h(x.h){}
217 flyweight(flyweight&& x):h(x.h){}
218#endif
219
220#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
221 template<typename V>
222 typename boost::enable_if<
223 boost::is_convertible<std::initializer_list<V>,key_type>,flyweight&>::type
224 operator=(std::initializer_list<V> list)
225 {
226 return operator=(flyweight(list));
227 }
228#endif
229
230 flyweight& operator=(const flyweight& x){h=x.h;return *this;}
231 flyweight& operator=(const value_type& x){return operator=(flyweight(x));}
232
233#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
234 flyweight& operator=(value_type&& x)
235 {
236 return operator=(flyweight(std::move(x)));
237 }
238#endif
239
240 /* convertibility to underlying type */
241
242 const key_type& get_key()const{return core::key(h);}
243 const value_type& get()const{return core::value(h);}
244 operator const value_type&()const{return get();}
245
246 /* exact type equality */
247
248 friend bool operator==(const flyweight& x,const flyweight& y)
249 {
250 return &x.get()==&y.get();
251 }
252
253 /* modifiers */
254
255 void swap(flyweight& x){boost::swap(h,x.h);}
256
257private:
258 handle_type h;
259};
260
261#define BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(n) \
262typename Arg##n##1,typename Arg##n##2,typename Arg##n##3, \
263typename Arg##n##4,typename Arg##n##5
264#define BOOST_FLYWEIGHT_TEMPL_ARGS(n) \
265Arg##n##1,Arg##n##2,Arg##n##3,Arg##n##4,Arg##n##5
266
267/* Comparison. Unlike exact type comparison defined above, intertype
268 * comparison just forwards to the underlying objects.
269 */
270
271template<
272 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1),
273 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2)
274>
275bool operator==(
276 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,
277 const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y)
278{
279 return x.get()==y.get();
280}
281
282template<
283 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1),
284 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2)
285>
286bool operator<(
287 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,
288 const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y)
289{
290 return x.get()<y.get();
291}
292
293#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
294template<
295 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1),
296 typename T2
297>
298bool operator==(
299 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,const T2& y)
300{
301 return x.get()==y;
302}
303
304template<
305 typename T1,
306 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2)
307>
308bool operator==(
309 const T1& x,const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y)
310{
311 return x==y.get();
312}
313
314template<
315 typename T1,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1),
316 typename T2
317>
318bool operator<(
319 const flyweight<T1,BOOST_FLYWEIGHT_TEMPL_ARGS(1)>& x,const T2& y)
320{
321 return x.get()<y;
322}
323
324template<
325 typename T1,
326 typename T2,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2)
327>
328bool operator<(
329 const T1& x,const flyweight<T2,BOOST_FLYWEIGHT_TEMPL_ARGS(2)>& y)
330{
331 return x<y.get();
332}
333#endif /* !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) */
334
335/* rest of comparison operators */
336
337#define BOOST_FLYWEIGHT_COMPLETE_COMP_OPS(t,a1,a2) \
338template<t> \
339inline bool operator!=(const a1& x,const a2& y) \
340{ \
341 return !(x==y); \
342} \
343 \
344template<t> \
345inline bool operator>(const a1& x,const a2& y) \
346{ \
347 return y<x; \
348} \
349 \
350template<t> \
351inline bool operator>=(const a1& x,const a2& y) \
352{ \
353 return !(x<y); \
354} \
355 \
356template<t> \
357inline bool operator<=(const a1& x,const a2& y) \
358{ \
359 return !(y<x); \
360}
361
362BOOST_FLYWEIGHT_COMPLETE_COMP_OPS(
363 typename T1 BOOST_PP_COMMA()
364 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1) BOOST_PP_COMMA()
365 typename T2 BOOST_PP_COMMA()
366 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2),
367 flyweight<
368 T1 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(1)
369 >,
370 flyweight<
371 T2 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(2)
372 >)
373
374#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
375BOOST_FLYWEIGHT_COMPLETE_COMP_OPS(
376 typename T1 BOOST_PP_COMMA()
377 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(1) BOOST_PP_COMMA()
378 typename T2,
379 flyweight<
380 T1 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(1)
381 >,
382 T2)
383
384BOOST_FLYWEIGHT_COMPLETE_COMP_OPS(
385 typename T1 BOOST_PP_COMMA()
386 typename T2 BOOST_PP_COMMA()
387 BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(2),
388 T1,
389 flyweight<
390 T2 BOOST_PP_COMMA() BOOST_FLYWEIGHT_TEMPL_ARGS(2)
391 >)
392#endif /* !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) */
393
394/* specialized algorithms */
395
396template<typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)>
397void swap(
398 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x,
399 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& y)
400{
401 x.swap(y);
402}
403
404template<
405 BOOST_TEMPLATED_STREAM_ARGS(ElemType,Traits)
406 BOOST_TEMPLATED_STREAM_COMMA
407 typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)
408>
409BOOST_TEMPLATED_STREAM(ostream,ElemType,Traits)& operator<<(
410 BOOST_TEMPLATED_STREAM(ostream,ElemType,Traits)& out,
411 const flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x)
412{
413 return out<<x.get();
414}
415
416template<
417 BOOST_TEMPLATED_STREAM_ARGS(ElemType,Traits)
418 BOOST_TEMPLATED_STREAM_COMMA
419 typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)
420>
421BOOST_TEMPLATED_STREAM(istream,ElemType,Traits)& operator>>(
422 BOOST_TEMPLATED_STREAM(istream,ElemType,Traits)& in,
423 flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x)
424{
425 typedef typename flyweight<
426 T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)
427 >::value_type value_type;
428
429 /* value_type need not be default ctble but must be copy ctble */
430 value_type t(x.get());
431 in>>t;
432 x=t;
433 return in;
434}
435
436} /* namespace flyweights */
437
438} /* namespace boost */
439
440#if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
441
442/* hash support */
443
444#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
445namespace std{
446
447template<typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)>
448BOOST_FLYWEIGHT_STD_HASH_STRUCT_KEYWORD
449hash<boost::flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)> >
450{
451public:
452 typedef std::size_t result_type;
453 typedef boost::flyweight<
454 T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)> argument_type;
455
456 result_type operator()(const argument_type& x)const
457 {
458 typedef typename argument_type::value_type value_type;
459
460 std::hash<const value_type*> h;
461 return h(&x.get());
462 }
463};
464
465} /* namespace std */
466#endif /* !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) */
467
468namespace boost{
469#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
470namespace flyweights{
471#endif
472
473template<typename T,BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS(_)>
474std::size_t hash_value(const flyweight<T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)>& x)
475{
476 typedef typename flyweight<
477 T,BOOST_FLYWEIGHT_TEMPL_ARGS(_)
478 >::value_type value_type;
479
480 boost::hash<const value_type*> h;
481 return h(&x.get());
482}
483
484#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
485} /* namespace flyweights */
486#endif
487} /* namespace boost */
488#endif /* !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT) */
489
490#undef BOOST_FLYWEIGHT_COMPLETE_COMP_OPS
491#undef BOOST_FLYWEIGHT_TEMPL_ARGS
492#undef BOOST_FLYWEIGHT_TYPENAME_TEMPL_ARGS
493
494#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
495#pragma warning(pop)
496#endif
497
498#endif