Warning, file /include/boost/flyweight/detail/flyweight_core.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
0010 #define BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <boost/core/no_exceptions_support.hpp>
0018 #include <boost/config/workaround.hpp>
0019 #include <boost/flyweight/detail/perfect_fwd.hpp>
0020 #include <boost/mpl/apply.hpp>
0021 #include <boost/type_traits/declval.hpp>
0022 #include <utility>
0023
0024 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
0025 #pragma warning(push)
0026 #pragma warning(disable:4101)
0027 #endif
0028
0029
0030
0031
0032
0033
0034 namespace boost{
0035
0036 namespace flyweights{
0037
0038 namespace detail{
0039
0040 template<
0041 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0042 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0043 >
0044 class flyweight_core;
0045
0046 template<
0047 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0048 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0049 >
0050 struct flyweight_core_tracking_helper
0051 {
0052 private:
0053 typedef flyweight_core<
0054 ValuePolicy,Tag,TrackingPolicy,
0055 FactorySpecifier,LockingPolicy,
0056 HolderSpecifier
0057 > core;
0058 typedef typename core::handle_type handle_type;
0059 typedef typename core::entry_type entry_type;
0060
0061 public:
0062 static const entry_type& entry(const handle_type& h)
0063 {
0064 return core::entry(h);
0065 }
0066
0067 template<typename Checker>
0068 static void erase(const handle_type& h,Checker chk)
0069 {
0070 typedef typename core::lock_type lock_type;
0071 core::init();
0072 lock_type lock(core::mutex());(void)lock;
0073 if(chk(h))core::factory().erase(h);
0074 }
0075 };
0076
0077
0078
0079
0080
0081
0082 template<typename Factory,typename Entry,typename F>
0083 typename Factory::handle_type
0084 insert_and_visit(Factory& fac,const Entry& x,F f)
0085 {
0086 typedef typename Factory::handle_type handle_type;
0087
0088 handle_type h(fac.insert(x));
0089 BOOST_TRY{
0090 f(fac.entry(h));
0091 }
0092 BOOST_CATCH(...){
0093 fac().erase(h);
0094 BOOST_RETHROW;
0095 }
0096 BOOST_CATCH_END
0097 return h;
0098 }
0099
0100 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0101 template<typename Factory,typename Entry,typename F>
0102 typename Factory::handle_type
0103 insert_and_visit(Factory& fac,Entry&& x,F f)
0104 {
0105 typedef typename Factory::handle_type handle_type;
0106
0107 handle_type h(fac.insert(std::forward<Entry>(x)));
0108 BOOST_TRY{
0109 f(fac.entry(h));
0110 }
0111 BOOST_CATCH(...){
0112 fac.erase(h);
0113 BOOST_RETHROW;
0114 }
0115 BOOST_CATCH_END
0116 return h;
0117 }
0118 #endif
0119
0120 template<
0121 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0122 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0123 >
0124 class flyweight_core
0125 {
0126 public:
0127 typedef typename ValuePolicy::key_type key_type;
0128 typedef typename ValuePolicy::value_type value_type;
0129 typedef typename ValuePolicy::rep_type rep_type;
0130 typedef typename mpl::apply2<
0131 typename TrackingPolicy::entry_type,
0132 rep_type,
0133 key_type
0134 >::type entry_type;
0135 typedef typename mpl::apply2<
0136 FactorySpecifier,
0137 entry_type,
0138 key_type
0139 >::type factory_type;
0140 typedef typename factory_type::handle_type base_handle_type;
0141 typedef typename mpl::apply2<
0142 typename TrackingPolicy::handle_type,
0143 base_handle_type,
0144 flyweight_core_tracking_helper<
0145 ValuePolicy,Tag,TrackingPolicy,
0146 FactorySpecifier,LockingPolicy,
0147 HolderSpecifier
0148 >
0149 >::type handle_type;
0150 typedef typename LockingPolicy::mutex_type mutex_type;
0151 typedef typename LockingPolicy::lock_type lock_type;
0152
0153 static bool init()
0154 {
0155 if(static_initializer)return true;
0156 else{
0157 holder_arg& a=holder_type::get();
0158 static_factory_ptr=&a.factory;
0159 static_mutex_ptr=&a.mutex;
0160 static_initializer=(static_factory_ptr!=0);
0161 return static_initializer;
0162 }
0163 }
0164
0165
0166
0167 #define BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY(args) \
0168 { \
0169 return insert_rep(rep_type(BOOST_FLYWEIGHT_FORWARD(args))); \
0170 }
0171
0172 BOOST_FLYWEIGHT_PERFECT_FWD(
0173 static handle_type insert,
0174 BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY)
0175
0176 #undef BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY
0177
0178 static handle_type insert(const value_type& x){return insert_value(x);}
0179 static handle_type insert(value_type& x){return insert_value(x);}
0180
0181 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0182 static handle_type insert(const value_type&& x){return insert_value(x);}
0183 static handle_type insert(value_type&& x){return insert_value(std::move(x));}
0184 #endif
0185
0186 static const entry_type& entry(const base_handle_type& h)
0187 {
0188 return factory().entry(h);
0189 }
0190
0191 static const value_type& value(const handle_type& h)
0192 {
0193 return static_cast<const rep_type&>(entry(h));
0194 }
0195
0196 static const key_type& key(const handle_type& h)
0197 BOOST_NOEXCEPT_IF(noexcept(
0198 static_cast<const rep_type&>(boost::declval<const entry_type&>())))
0199 {
0200 return static_cast<const rep_type&>(entry(h));
0201 }
0202
0203 static factory_type& factory()
0204 {
0205 return *static_factory_ptr;
0206 }
0207
0208 static mutex_type& mutex()
0209 {
0210 return *static_mutex_ptr;
0211 }
0212
0213 private:
0214 struct holder_arg
0215 {
0216 factory_type factory;
0217 mutex_type mutex;
0218 };
0219 typedef typename mpl::apply1<
0220 HolderSpecifier,
0221 holder_arg
0222 >::type holder_type;
0223
0224
0225
0226 struct key_construct_value
0227 {
0228 void operator()(const entry_type& e)const
0229 {
0230 ValuePolicy::key_construct_value(static_cast<const rep_type&>(e));
0231 }
0232 };
0233
0234 struct copy_construct_value
0235 {
0236 copy_construct_value(const value_type& x_):x(x_){}
0237
0238 void operator()(const entry_type& e)const
0239 {
0240 ValuePolicy::copy_construct_value(static_cast<const rep_type&>(e),x);
0241 }
0242
0243 const value_type& x;
0244 };
0245
0246 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0247 struct move_construct_value
0248 {
0249 move_construct_value(value_type&& x_):x(x_){}
0250
0251 void operator()(const entry_type& e)const
0252 {
0253 ValuePolicy::move_construct_value(
0254 static_cast<const rep_type&>(e),std::move(x));
0255 }
0256
0257 value_type& x;
0258 };
0259 #endif
0260
0261 static handle_type insert_rep(const rep_type& x)
0262 {
0263 init();
0264 entry_type e(x);
0265 lock_type lock(mutex());(void)lock;
0266
0267 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0268 return static_cast<handle_type>(
0269 insert_and_visit(factory(),std::move(e),key_construct_value()));
0270 #else
0271 return static_cast<handle_type>(
0272 insert_and_visit(factory(),e,key_construct_value()));
0273 #endif
0274 }
0275
0276 static handle_type insert_value(const value_type& x)
0277 {
0278 init();
0279 entry_type e((rep_type(x)));
0280 lock_type lock(mutex());(void)lock;
0281
0282 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0283 return static_cast<handle_type>(
0284 insert_and_visit(factory(),std::move(e),copy_construct_value(x)));
0285 #else
0286 return static_cast<handle_type>(
0287 insert_and_visit(factory(),e,copy_construct_value(x)));
0288 #endif
0289 }
0290
0291 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0292 static handle_type insert_rep(rep_type&& x)
0293 {
0294 init();
0295 entry_type e(std::move(x));
0296 lock_type lock(mutex());(void)lock;
0297
0298 return static_cast<handle_type>(
0299 insert_and_visit(factory(),std::move(e),key_construct_value()));
0300 }
0301
0302 static handle_type insert_value(value_type&& x)
0303 {
0304 init();
0305 entry_type e(rep_type(std::move(x)));
0306 lock_type lock(mutex());(void)lock;
0307
0308 return static_cast<handle_type>(
0309 insert_and_visit(
0310 factory(),std::move(e),move_construct_value(std::move(x))));
0311 }
0312 #endif
0313
0314 static bool static_initializer;
0315 static factory_type* static_factory_ptr;
0316 static mutex_type* static_mutex_ptr;
0317 };
0318
0319 template<
0320 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0321 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0322 >
0323 bool
0324 flyweight_core<
0325 ValuePolicy,Tag,TrackingPolicy,
0326 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_initializer=
0327 flyweight_core<
0328 ValuePolicy,Tag,TrackingPolicy,
0329 FactorySpecifier,LockingPolicy,HolderSpecifier>::init();
0330
0331 template<
0332 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0333 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0334 >
0335 typename flyweight_core<
0336 ValuePolicy,Tag,TrackingPolicy,
0337 FactorySpecifier,LockingPolicy,HolderSpecifier>::factory_type*
0338 flyweight_core<
0339 ValuePolicy,Tag,TrackingPolicy,
0340 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_factory_ptr=0;
0341
0342 template<
0343 typename ValuePolicy,typename Tag,typename TrackingPolicy,
0344 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
0345 >
0346 typename flyweight_core<
0347 ValuePolicy,Tag,TrackingPolicy,
0348 FactorySpecifier,LockingPolicy,HolderSpecifier>::mutex_type*
0349 flyweight_core<
0350 ValuePolicy,Tag,TrackingPolicy,
0351 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_mutex_ptr=0;
0352
0353 }
0354
0355 }
0356
0357 }
0358
0359 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
0360 #pragma warning(pop)
0361 #endif
0362
0363 #endif