1
// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
3
// Copyright 2011 Vicente J. Botet Escriba
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)
8
// See http://www.boost.org/libs/chrono for documentation.
10
#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
11
#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
14
#include <boost/assert.hpp>
32
struct xalloc_key_holder
34
static int value; //< the xalloc value associated to T.
35
static bool initialized; //< whether the value has been initialized or not.
39
int xalloc_key_holder<T>::value = 0;
42
bool xalloc_key_holder<T>::initialized = false;
47
* xalloc key initialiazer.
49
* Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
52
struct xalloc_key_initializer
54
xalloc_key_initializer()
56
if (!detail::xalloc_key_holder<T>::initialized)
58
detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
59
detail::xalloc_key_holder<T>::initialized = true;
64
* @c ios_state_ptr is a smart pointer to a ios_base specific state.
66
template <typename Final, typename T>
69
ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
75
typedef T element_type;
77
* Explicit constructor.
79
* @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
81
explicit ios_state_ptr(std::ios_base& ios) :
86
* Nothing to do as xalloc index can not be removed.
93
* @Effects Allocates the index if not already done.
94
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
95
* Retrieves the associated ios pointer
96
* @return the retrieved pointer statically casted to const.
98
T const* get() const BOOST_NOEXCEPT
100
register_once(index(), ios_);
101
void* &pw = ios_.pword(index());
106
return static_cast<const T*> (pw);
109
* @Effects Allocates the index if not already done.
110
* Registers the callback responsible of maintaining the state pointer coherency, if not already done.
111
* Retrieves the associated ios pointer
112
* @return the retrieved pointer.
114
T * get() BOOST_NOEXCEPT
116
register_once(index(), ios_);
117
void* &pw = ios_.pword(index());
122
return static_cast<T*> (pw);
125
* @Effects as if @c return get();
126
* @return the retrieved pointer.
128
T * operator->()BOOST_NOEXCEPT
133
* @Effects as if @c return get();
134
* @return the retrieved pointer.
136
T const * operator->() const BOOST_NOEXCEPT
142
* @Effects as if @c return *get();
143
* @return a reference to the retrieved state.
144
* @Remark The behavior is undefined if @c get()==0.
146
T & operator*() BOOST_NOEXCEPT
151
* @Effects as if @c return *get();
152
* @return a reference to the retrieved state.
153
* @Remark The behavior is undefined if @c get()==0.
155
T const & operator *() const BOOST_NOEXCEPT
161
* @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
162
* @return the stored state pointer.
164
T * release() BOOST_NOEXCEPT
173
* @param new_ptr the new pointer.
174
* @Effects deletes the current state and replace it with the new one.
176
void reset(T* new_ptr = 0)BOOST_NOEXCEPT
178
register_once(index(), ios_);
179
void*& pw = ios_.pword(index());
180
delete static_cast<T*> (pw);
184
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
185
typedef T* (ios_state_ptr::*bool_type)();
186
operator bool_type() const BOOST_NOEXCEPT
188
return (get()!=0)?&ios_state_ptr::release:0;
190
bool operator!() const BOOST_NOEXCEPT
192
return (get()==0)?&ios_state_ptr::release:0;
196
* Explicit conversion to bool.
198
explicit operator bool() const BOOST_NOEXCEPT
204
std::ios_base& getios()BOOST_NOEXCEPT
208
std::ios_base& getios() const BOOST_NOEXCEPT
213
* Implicit conversion to the ios_base
215
operator std::ios_base&() BOOST_NOEXCEPT
220
* Implicit conversion to the ios_base const
222
operator std::ios_base&() const BOOST_NOEXCEPT
227
static inline bool is_registerd(std::ios_base& ios)
229
long iw = ios.iword(index());
232
static inline void set_registered(std::ios_base& ios)
234
long& iw = ios.iword(index());
237
static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
241
case std::ios_base::erase_event:
243
void*& pw = ios.pword(index);
246
T* ptr = static_cast<T*> (pw);
252
case std::ios_base::copyfmt_event:
254
void*& pw = ios.pword(index);
257
pw = new T(*static_cast<T*> (pw));
266
static inline int index()
268
return detail::xalloc_key_holder<Final>::value;
271
static inline void register_once(int indx, std::ios_base& ios)
273
// needs a mask registered
274
if (!is_registerd(ios))
277
ios.register_callback(callback, indx);
284
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
287
//template <typename Final, typename T>
288
//detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
292
* @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
294
* @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
296
template <typename Final, typename T>
297
class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
299
typedef ios_state_ptr<Final, T> base_type;
301
explicit ios_state_not_null_ptr(std::ios_base& ios) :
304
if (this->get() == 0)
306
this->base_type::reset(new T());
309
~ios_state_not_null_ptr()
313
void reset(T* new_value) BOOST_NOEXCEPT
315
BOOST_ASSERT(new_value!=0);
316
this->base_type::reset(new_value);
322
* This class is useful to associate some flags to an std::ios_base.
324
template <typename Final>
330
* @param ios the associated std::ios_base.
331
* @Postcondition <c>flags()==0</c>
333
explicit ios_flags(std::ios_base& ios) :
341
* @Returns The format control information.
343
long flags() const BOOST_NOEXCEPT
349
* @param v the new bit mask.
350
* @Postcondition <c>v == flags()</c>.
351
* @Returns The previous value of @c flags().
353
long flags(long v)BOOST_NOEXCEPT
361
* @param v the new value
362
* @Effects: Sets @c v in @c flags().
363
* @Returns: The previous value of @c flags().
373
* @param mask the bit mask to clear.
374
* @Effects: Clears @c mask in @c flags().
376
void unsetf(long mask)
385
* @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
386
* @Returns: The previous value of flags().
388
long setf(long v, long mask)
397
* implicit conversion to the @c ios_base
399
operator std::ios_base&()BOOST_NOEXCEPT
404
* implicit conversion to the @c ios_base const
406
operator std::ios_base const&() const BOOST_NOEXCEPT
411
long value() const BOOST_NOEXCEPT
413
return ios_.iword(index());
415
long& ref()BOOST_NOEXCEPT
417
return ios_.iword(index());
419
static inline int index()
421
return detail::xalloc_key_holder<Final>::value;
423
ios_flags& operator=(ios_flags const& rhs) ;
426
//static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
429
//template <typename Final>
430
//detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
432
} // namespace chrono