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