1 /* Copyright 2006-2018 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
6 * See http://www.boost.org/libs/flyweight for library home page.
9 #ifndef BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
10 #define BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/detail/no_exceptions_support.hpp>
18 #include <boost/detail/workaround.hpp>
19 #include <boost/flyweight/detail/perfect_fwd.hpp>
20 #include <boost/mpl/apply.hpp>
22 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
24 #pragma warning(disable:4101) /* unreferenced local vars */
27 /* flyweight_core provides the inner implementation of flyweight<> by
28 * weaving together a value policy, a flyweight factory, a holder for the
29 * factory,a tracking policy and a locking policy.
39 typename ValuePolicy,typename Tag,typename TrackingPolicy,
40 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
45 typename ValuePolicy,typename Tag,typename TrackingPolicy,
46 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
48 struct flyweight_core_tracking_helper
51 typedef flyweight_core<
52 ValuePolicy,Tag,TrackingPolicy,
53 FactorySpecifier,LockingPolicy,
56 typedef typename core::handle_type handle_type;
57 typedef typename core::entry_type entry_type;
60 static const entry_type& entry(const handle_type& h)
62 return core::entry(h);
65 template<typename Checker>
66 static void erase(const handle_type& h,Checker chk)
68 typedef typename core::lock_type lock_type;
70 lock_type lock(core::mutex());(void)lock;
71 if(chk(h))core::factory().erase(h);
76 typename ValuePolicy,typename Tag,typename TrackingPolicy,
77 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
82 typedef typename ValuePolicy::key_type key_type;
83 typedef typename ValuePolicy::value_type value_type;
84 typedef typename ValuePolicy::rep_type rep_type;
85 typedef typename mpl::apply2<
86 typename TrackingPolicy::entry_type,
90 typedef typename mpl::apply2<
95 typedef typename factory_type::handle_type base_handle_type;
96 typedef typename mpl::apply2<
97 typename TrackingPolicy::handle_type,
99 flyweight_core_tracking_helper<
100 ValuePolicy,Tag,TrackingPolicy,
101 FactorySpecifier,LockingPolicy,
105 typedef typename LockingPolicy::mutex_type mutex_type;
106 typedef typename LockingPolicy::lock_type lock_type;
110 if(static_initializer)return true;
112 holder_arg& a=holder_type::get();
113 static_factory_ptr=&a.factory;
114 static_mutex_ptr=&a.mutex;
115 static_initializer=(static_factory_ptr!=0);
116 return static_initializer;
120 /* insert overloads*/
122 #define BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY(args) \
124 return insert_rep(rep_type(BOOST_FLYWEIGHT_FORWARD(args))); \
127 BOOST_FLYWEIGHT_PERFECT_FWD(
128 static handle_type insert,
129 BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY)
131 #undef BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY
133 static handle_type insert(const value_type& x){return insert_value(x);}
134 static handle_type insert(value_type& x){return insert_value(x);}
136 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
137 static handle_type insert(const value_type&& x){return insert_value(x);}
138 static handle_type insert(value_type&& x){return insert_value(std::move(x));}
141 static const entry_type& entry(const base_handle_type& h)
143 return factory().entry(h);
146 static const value_type& value(const handle_type& h)
148 return static_cast<const rep_type&>(entry(h));
151 static const key_type& key(const handle_type& h)
153 return static_cast<const rep_type&>(entry(h));
156 static factory_type& factory()
158 return *static_factory_ptr;
161 static mutex_type& mutex()
163 return *static_mutex_ptr;
169 factory_type factory;
172 typedef typename mpl::apply1<
177 static handle_type insert_rep(const rep_type& x)
181 lock_type lock(mutex());(void)lock;
182 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
183 base_handle_type h(factory().insert(std::move(e)));
185 base_handle_type h(factory().insert(e));
189 ValuePolicy::construct_value(
190 static_cast<const rep_type&>(entry(h)));
197 return static_cast<handle_type>(h);
200 static handle_type insert_value(const value_type& x)
203 entry_type e((rep_type(x)));
204 lock_type lock(mutex());(void)lock;
206 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
207 base_handle_type h(factory().insert(std::move(e)));
209 base_handle_type h(factory().insert(e));
213 ValuePolicy::copy_value(
214 static_cast<const rep_type&>(entry(h)));
221 return static_cast<handle_type>(h);
224 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
225 static handle_type insert_rep(rep_type&& x)
228 entry_type e(std::move(x));
229 lock_type lock(mutex());(void)lock;
230 base_handle_type h(factory().insert(std::move(e)));
233 ValuePolicy::construct_value(
234 static_cast<const rep_type&>(entry(h)));
241 return static_cast<handle_type>(h);
244 static handle_type insert_value(value_type&& x)
247 entry_type e(rep_type(std::move(x)));
248 lock_type lock(mutex());(void)lock;
249 base_handle_type h(factory().insert(std::move(e)));
251 ValuePolicy::move_value(
252 static_cast<const rep_type&>(entry(h)));
259 return static_cast<handle_type>(h);
263 static bool static_initializer;
264 static factory_type* static_factory_ptr;
265 static mutex_type* static_mutex_ptr;
269 typename ValuePolicy,typename Tag,typename TrackingPolicy,
270 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
274 ValuePolicy,Tag,TrackingPolicy,
275 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_initializer=
277 ValuePolicy,Tag,TrackingPolicy,
278 FactorySpecifier,LockingPolicy,HolderSpecifier>::init();
281 typename ValuePolicy,typename Tag,typename TrackingPolicy,
282 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
284 typename flyweight_core<
285 ValuePolicy,Tag,TrackingPolicy,
286 FactorySpecifier,LockingPolicy,HolderSpecifier>::factory_type*
288 ValuePolicy,Tag,TrackingPolicy,
289 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_factory_ptr=0;
292 typename ValuePolicy,typename Tag,typename TrackingPolicy,
293 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
295 typename flyweight_core<
296 ValuePolicy,Tag,TrackingPolicy,
297 FactorySpecifier,LockingPolicy,HolderSpecifier>::mutex_type*
299 ValuePolicy,Tag,TrackingPolicy,
300 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_mutex_ptr=0;
302 } /* namespace flyweights::detail */
304 } /* namespace flyweights */
306 } /* namespace boost */
308 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))