]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/flyweight/detail/flyweight_core.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / flyweight / detail / flyweight_core.hpp
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)
5 *
6 * See http://www.boost.org/libs/flyweight for library home page.
7 */
8
9 #ifndef BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
10 #define BOOST_FLYWEIGHT_DETAIL_FLYWEIGHT_CORE_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
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>
21
22 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
23 #pragma warning(push)
24 #pragma warning(disable:4101) /* unreferenced local vars */
25 #endif
26
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.
30 */
31
32 namespace boost{
33
34 namespace flyweights{
35
36 namespace detail{
37
38 template<
39 typename ValuePolicy,typename Tag,typename TrackingPolicy,
40 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
41 >
42 class flyweight_core;
43
44 template<
45 typename ValuePolicy,typename Tag,typename TrackingPolicy,
46 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
47 >
48 struct flyweight_core_tracking_helper
49 {
50 private:
51 typedef flyweight_core<
52 ValuePolicy,Tag,TrackingPolicy,
53 FactorySpecifier,LockingPolicy,
54 HolderSpecifier
55 > core;
56 typedef typename core::handle_type handle_type;
57 typedef typename core::entry_type entry_type;
58
59 public:
60 static const entry_type& entry(const handle_type& h)
61 {
62 return core::entry(h);
63 }
64
65 template<typename Checker>
66 static void erase(const handle_type& h,Checker chk)
67 {
68 typedef typename core::lock_type lock_type;
69 core::init();
70 lock_type lock(core::mutex());(void)lock;
71 if(chk(h))core::factory().erase(h);
72 }
73 };
74
75 template<
76 typename ValuePolicy,typename Tag,typename TrackingPolicy,
77 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
78 >
79 class flyweight_core
80 {
81 public:
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,
87 rep_type,
88 key_type
89 >::type entry_type;
90 typedef typename mpl::apply2<
91 FactorySpecifier,
92 entry_type,
93 key_type
94 >::type factory_type;
95 typedef typename factory_type::handle_type base_handle_type;
96 typedef typename mpl::apply2<
97 typename TrackingPolicy::handle_type,
98 base_handle_type,
99 flyweight_core_tracking_helper<
100 ValuePolicy,Tag,TrackingPolicy,
101 FactorySpecifier,LockingPolicy,
102 HolderSpecifier
103 >
104 >::type handle_type;
105 typedef typename LockingPolicy::mutex_type mutex_type;
106 typedef typename LockingPolicy::lock_type lock_type;
107
108 static bool init()
109 {
110 if(static_initializer)return true;
111 else{
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;
117 }
118 }
119
120 /* insert overloads*/
121
122 #define BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY(args) \
123 { \
124 return insert_rep(rep_type(BOOST_FLYWEIGHT_FORWARD(args))); \
125 }
126
127 BOOST_FLYWEIGHT_PERFECT_FWD(
128 static handle_type insert,
129 BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY)
130
131 #undef BOOST_FLYWEIGHT_PERFECT_FWD_INSERT_BODY
132
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);}
135
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));}
139 #endif
140
141 static const entry_type& entry(const base_handle_type& h)
142 {
143 return factory().entry(h);
144 }
145
146 static const value_type& value(const handle_type& h)
147 {
148 return static_cast<const rep_type&>(entry(h));
149 }
150
151 static const key_type& key(const handle_type& h)
152 {
153 return static_cast<const rep_type&>(entry(h));
154 }
155
156 static factory_type& factory()
157 {
158 return *static_factory_ptr;
159 }
160
161 static mutex_type& mutex()
162 {
163 return *static_mutex_ptr;
164 }
165
166 private:
167 struct holder_arg
168 {
169 factory_type factory;
170 mutex_type mutex;
171 };
172 typedef typename mpl::apply1<
173 HolderSpecifier,
174 holder_arg
175 >::type holder_type;
176
177 static handle_type insert_rep(const rep_type& x)
178 {
179 init();
180 entry_type e(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)));
184 #else
185 base_handle_type h(factory().insert(e));
186 #endif
187
188 BOOST_TRY{
189 ValuePolicy::construct_value(
190 static_cast<const rep_type&>(entry(h)));
191 }
192 BOOST_CATCH(...){
193 factory().erase(h);
194 BOOST_RETHROW;
195 }
196 BOOST_CATCH_END
197 return static_cast<handle_type>(h);
198 }
199
200 static handle_type insert_value(const value_type& x)
201 {
202 init();
203 entry_type e((rep_type(x)));
204 lock_type lock(mutex());(void)lock;
205
206 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
207 base_handle_type h(factory().insert(std::move(e)));
208 #else
209 base_handle_type h(factory().insert(e));
210 #endif
211
212 BOOST_TRY{
213 ValuePolicy::copy_value(
214 static_cast<const rep_type&>(entry(h)));
215 }
216 BOOST_CATCH(...){
217 factory().erase(h);
218 BOOST_RETHROW;
219 }
220 BOOST_CATCH_END
221 return static_cast<handle_type>(h);
222 }
223
224 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
225 static handle_type insert_rep(rep_type&& x)
226 {
227 init();
228 entry_type e(std::move(x));
229 lock_type lock(mutex());(void)lock;
230 base_handle_type h(factory().insert(std::move(e)));
231
232 BOOST_TRY{
233 ValuePolicy::construct_value(
234 static_cast<const rep_type&>(entry(h)));
235 }
236 BOOST_CATCH(...){
237 factory().erase(h);
238 BOOST_RETHROW;
239 }
240 BOOST_CATCH_END
241 return static_cast<handle_type>(h);
242 }
243
244 static handle_type insert_value(value_type&& x)
245 {
246 init();
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)));
250 BOOST_TRY{
251 ValuePolicy::move_value(
252 static_cast<const rep_type&>(entry(h)));
253 }
254 BOOST_CATCH(...){
255 factory().erase(h);
256 BOOST_RETHROW;
257 }
258 BOOST_CATCH_END
259 return static_cast<handle_type>(h);
260 }
261 #endif
262
263 static bool static_initializer;
264 static factory_type* static_factory_ptr;
265 static mutex_type* static_mutex_ptr;
266 };
267
268 template<
269 typename ValuePolicy,typename Tag,typename TrackingPolicy,
270 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
271 >
272 bool
273 flyweight_core<
274 ValuePolicy,Tag,TrackingPolicy,
275 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_initializer=
276 flyweight_core<
277 ValuePolicy,Tag,TrackingPolicy,
278 FactorySpecifier,LockingPolicy,HolderSpecifier>::init();
279
280 template<
281 typename ValuePolicy,typename Tag,typename TrackingPolicy,
282 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
283 >
284 typename flyweight_core<
285 ValuePolicy,Tag,TrackingPolicy,
286 FactorySpecifier,LockingPolicy,HolderSpecifier>::factory_type*
287 flyweight_core<
288 ValuePolicy,Tag,TrackingPolicy,
289 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_factory_ptr=0;
290
291 template<
292 typename ValuePolicy,typename Tag,typename TrackingPolicy,
293 typename FactorySpecifier,typename LockingPolicy,typename HolderSpecifier
294 >
295 typename flyweight_core<
296 ValuePolicy,Tag,TrackingPolicy,
297 FactorySpecifier,LockingPolicy,HolderSpecifier>::mutex_type*
298 flyweight_core<
299 ValuePolicy,Tag,TrackingPolicy,
300 FactorySpecifier,LockingPolicy,HolderSpecifier>::static_mutex_ptr=0;
301
302 } /* namespace flyweights::detail */
303
304 } /* namespace flyweights */
305
306 } /* namespace boost */
307
308 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
309 #pragma warning(pop)
310 #endif
311
312 #endif