]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/chrono/include/boost/chrono/io/utility/ios_base_state_ptr.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / chrono / include / boost / chrono / io / utility / ios_base_state_ptr.hpp
CommitLineData
7c673cae
FG
1// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
2
3// Copyright 2011 Vicente J. Botet Escriba
4
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8// See http://www.boost.org/libs/chrono for documentation.
9
10#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
11#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
12
13#include <ios>
14#include <boost/assert.hpp>
15
16/**
17 *
18
19
20 */
21namespace boost
22{
23 namespace chrono
24 {
25 namespace detail
26 {
27
28 /**
29 * xalloc key holder.
30 */
31 template <typename T>
32 struct xalloc_key_holder
33 {
34 static int value; //< the xalloc value associated to T.
35 static bool initialized; //< whether the value has been initialized or not.
36 };
37
38 template <typename T>
39 int xalloc_key_holder<T>::value = 0;
40
41 template <typename T>
42 bool xalloc_key_holder<T>::initialized = false;
43
44 }
45
46 /**
47 * xalloc key initialiazer.
48 *
49 * Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
50 */
51 template <typename T>
52 struct xalloc_key_initializer
53 {
54 xalloc_key_initializer()
55 {
56 if (!detail::xalloc_key_holder<T>::initialized)
57 {
58 detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
59 detail::xalloc_key_holder<T>::initialized = true;
60 }
61 }
62 };
63 /**
64 * @c ios_state_ptr is a smart pointer to a ios_base specific state.
65 */
66 template <typename Final, typename T>
67 class ios_state_ptr
68 {
69 ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
70
71 public:
72 /**
73 * The pointee type
74 */
75 typedef T element_type;
76 /**
77 * Explicit constructor.
78 * @param ios the ios
79 * @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
80 */
81 explicit ios_state_ptr(std::ios_base& ios) :
82 ios_(ios)
83 {
84
85 }
86 /**
87 * Nothing to do as xalloc index can not be removed.
88 */
89 ~ios_state_ptr()
90 {
91 }
92
93 /**
94 * @Effects Allocates the index if not already done.
95 * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
96 * Retrieves the associated ios pointer
97 * @return the retrieved pointer statically casted to const.
98 */
99 T const* get() const BOOST_NOEXCEPT
100 {
101 register_once(index(), ios_);
102 void* &pw = ios_.pword(index());
103 if (pw == 0)
104 {
105 return 0;
106 }
107 return static_cast<const T*> (pw);
108 }
109 /**
110 * @Effects Allocates the index if not already done.
111 * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
112 * Retrieves the associated ios pointer
113 * @return the retrieved pointer.
114 */
115 T * get() BOOST_NOEXCEPT
116 {
117 register_once(index(), ios_);
118 void* &pw = ios_.pword(index());
119 if (pw == 0)
120 {
121 return 0;
122 }
123 return static_cast<T*> (pw);
124 }
125 /**
126 * @Effects as if @c return get();
127 * @return the retrieved pointer.
128 */
129 T * operator->()BOOST_NOEXCEPT
130 {
131 return get();
132 }
133 /**
134 * @Effects as if @c return get();
135 * @return the retrieved pointer.
136 */
137 T const * operator->() const BOOST_NOEXCEPT
138 {
139 return get();
140 }
141
142 /**
143 * @Effects as if @c return *get();
144 * @return a reference to the retrieved state.
145 * @Remark The behavior is undefined if @c get()==0.
146 */
147 T & operator*() BOOST_NOEXCEPT
148 {
149 return *get();
150 }
151 /**
152 * @Effects as if @c return *get();
153 * @return a reference to the retrieved state.
154 * @Remark The behavior is undefined if @c get()==0.
155 */
156 T const & operator *() const BOOST_NOEXCEPT
157 {
158 return *get();
159 }
160
161 /**
162 * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
163 * @return the stored state pointer.
164 */
165 T * release() BOOST_NOEXCEPT
166 {
167 void*& pw = ios_.pword(index());
168 T* ptr = static_cast<T*> (pw);
169 pw = 0;
170 return ptr;
171 }
172
173 /**
174 *
175 * @param new_ptr the new pointer.
176 * @Effects deletes the current state and replace it with the new one.
177 */
178 void reset(T* new_ptr = 0)BOOST_NOEXCEPT
179 {
180 register_once(index(), ios_);
181 void*& pw = ios_.pword(index());
182 delete static_cast<T*> (pw);
183 pw = new_ptr;
184 }
185
186#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
187 typedef T* (ios_state_ptr::*bool_type)();
188 operator bool_type() const BOOST_NOEXCEPT
189 {
190 return (get()!=0)?&ios_state_ptr::release:0;
191 }
192 bool operator!() const BOOST_NOEXCEPT
193 {
194 return (get()==0)?&ios_state_ptr::release:0;
195 }
196#else
197 /**
198 * Explicit conversion to bool.
199 */
200 explicit operator bool() const BOOST_NOEXCEPT
201 {
202 return get()!=0;
203 }
204#endif
205
206 std::ios_base& getios()BOOST_NOEXCEPT
207 {
208 return ios_;
209 }
210 std::ios_base& getios() const BOOST_NOEXCEPT
211 {
212 return ios_;
213 }
214 /**
215 * Implicit conversion to the ios_base
216 */
217 operator std::ios_base&() BOOST_NOEXCEPT
218 {
219 return ios_;
220 }
221 /**
222 * Implicit conversion to the ios_base const
223 */
224 operator std::ios_base&() const BOOST_NOEXCEPT
225 {
226 return ios_;
227 }
228 private:
229 static inline bool is_registerd(std::ios_base& ios)
230 {
231 long iw = ios.iword(index());
232 return (iw == 1);
233 }
234 static inline void set_registered(std::ios_base& ios)
235 {
236 long& iw = ios.iword(index());
237 iw = 1;
238 }
239 static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
240 {
241 switch (evt)
242 {
243 case std::ios_base::erase_event:
244 {
245 void*& pw = ios.pword(index);
246 if (pw != 0)
247 {
248 T* ptr = static_cast<T*> (pw);
249 delete ptr;
250 pw = 0;
251 }
252 break;
253 }
254 case std::ios_base::copyfmt_event:
255 {
256 void*& pw = ios.pword(index);
257 if (pw != 0)
258 {
259 pw = new T(*static_cast<T*> (pw));
260 }
261 break;
262 }
263 default:
264 break;
265 }
266 }
267
268 static inline int index()
269 {
270 return detail::xalloc_key_holder<Final>::value;
271 }
272
273 static inline void register_once(int indx, std::ios_base& ios)
274 {
275 // needs a mask registered
276 if (!is_registerd(ios))
277 {
278 set_registered(ios);
279 ios.register_callback(callback, indx);
280 }
281 }
282
283
284 protected:
285 std::ios_base& ios_;
286 //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
287
288 };
289 //template <typename Final, typename T>
290 //detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
291
292
293 /**
294 * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
295 * @tparm T
296 * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
297 */
298 template <typename Final, typename T>
299 class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
300 {
301 typedef ios_state_ptr<Final, T> base_type;
302 public:
303 explicit ios_state_not_null_ptr(std::ios_base& ios) :
304 base_type(ios)
305 {
306 if (this->get() == 0)
307 {
308 this->base_type::reset(new T());
309 }
310 }
311 ~ios_state_not_null_ptr()
312 {
313 }
314
315 void reset(T* new_value) BOOST_NOEXCEPT
316 {
317 BOOST_ASSERT(new_value!=0);
318 this->base_type::reset(new_value);
319 }
320
321 };
322
323 /**
324 * This class is useful to associate some flags to an std::ios_base.
325 */
326 template <typename Final>
327 class ios_flags
328 {
329 public:
330 /**
331 *
332 * @param ios the associated std::ios_base.
333 * @Postcondition <c>flags()==0</c>
334 */
335 explicit ios_flags(std::ios_base& ios) :
336 ios_(ios)
337 {
338 }
339 ~ios_flags()
340 {
341 }
342 /**
343 * @Returns The format control information.
344 */
345 long flags() const BOOST_NOEXCEPT
346 {
347 return value();
348 }
349
350 /**
351 * @param v the new bit mask.
352 * @Postcondition <c>v == flags()</c>.
353 * @Returns The previous value of @c flags().
354 */
355 long flags(long v)BOOST_NOEXCEPT
356 {
357 long tmp = flags();
358 ref() = v;
359 return tmp;
360 }
361
362 /**
363 * @param v the new value
364 * @Effects: Sets @c v in @c flags().
365 * @Returns: The previous value of @c flags().
366 */
367 long setf(long v)
368 {
369 long tmp = value();
370 ref() |= v;
371 return tmp;
372 }
373
374 /**
375 * @param mask the bit mask to clear.
376 * @Effects: Clears @c mask in @c flags().
377 */
378 void unsetf(long mask)
379 {
380 ref() &= ~mask;
381 }
382
383 /**
384 *
385 * @param v
386 * @param mask
387 * @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
388 * @Returns: The previous value of flags().
389 */
390 long setf(long v, long mask)
391 {
392 long tmp = value();
393 unsetf(mask);
394 ref() |= v & mask;
395 return tmp;
396 }
397
398 /**
399 * implicit conversion to the @c ios_base
400 */
401 operator std::ios_base&()BOOST_NOEXCEPT
402 {
403 return ios_;
404 }
405 /**
406 * implicit conversion to the @c ios_base const
407 */
408 operator std::ios_base const&() const BOOST_NOEXCEPT
409 {
410 return ios_;
411 }
412 private:
413 long value() const BOOST_NOEXCEPT
414 {
415 return ios_.iword(index());
416 }
417 long& ref()BOOST_NOEXCEPT
418 {
419 return ios_.iword(index());
420 }
421 static inline int index()
422 {
423 return detail::xalloc_key_holder<Final>::value;
424 }
425 ios_flags& operator=(ios_flags const& rhs) ;
426
427 std::ios_base& ios_;
428 //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
429
430 };
431 //template <typename Final>
432 //detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
433
434 } // namespace chrono
435} // namespace boost
436
437#endif // header