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