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) :
87 * Nothing to do as xalloc index can not be removed.
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.
99 T const* get() const BOOST_NOEXCEPT
101 register_once(index(), ios_);
102 void* &pw = ios_.pword(index());
107 return static_cast<const T*> (pw);
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.
115 T * get() BOOST_NOEXCEPT
117 register_once(index(), ios_);
118 void* &pw = ios_.pword(index());
123 return static_cast<T*> (pw);
126 * @Effects as if @c return get();
127 * @return the retrieved pointer.
129 T * operator->()BOOST_NOEXCEPT
134 * @Effects as if @c return get();
135 * @return the retrieved pointer.
137 T const * operator->() const BOOST_NOEXCEPT
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.
147 T & operator*() BOOST_NOEXCEPT
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.
156 T const & operator *() const BOOST_NOEXCEPT
162 * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
163 * @return the stored state pointer.
165 T * release() BOOST_NOEXCEPT
167 void*& pw = ios_.pword(index());
168 T* ptr = static_cast<T*> (pw);
175 * @param new_ptr the new pointer.
176 * @Effects deletes the current state and replace it with the new one.
178 void reset(T* new_ptr = 0)BOOST_NOEXCEPT
180 register_once(index(), ios_);
181 void*& pw = ios_.pword(index());
182 delete static_cast<T*> (pw);
186 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
187 typedef T* (ios_state_ptr::*bool_type)();
188 operator bool_type() const BOOST_NOEXCEPT
190 return (get()!=0)?&ios_state_ptr::release:0;
192 bool operator!() const BOOST_NOEXCEPT
194 return (get()==0)?&ios_state_ptr::release:0;
198 * Explicit conversion to bool.
200 explicit operator bool() const BOOST_NOEXCEPT
206 std::ios_base& getios()BOOST_NOEXCEPT
210 std::ios_base& getios() const BOOST_NOEXCEPT
215 * Implicit conversion to the ios_base
217 operator std::ios_base&() BOOST_NOEXCEPT
222 * Implicit conversion to the ios_base const
224 operator std::ios_base&() const BOOST_NOEXCEPT
229 static inline bool is_registerd(std::ios_base& ios)
231 long iw = ios.iword(index());
234 static inline void set_registered(std::ios_base& ios)
236 long& iw = ios.iword(index());
239 static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
243 case std::ios_base::erase_event:
245 void*& pw = ios.pword(index);
248 T* ptr = static_cast<T*> (pw);
254 case std::ios_base::copyfmt_event:
256 void*& pw = ios.pword(index);
259 pw = new T(*static_cast<T*> (pw));
268 static inline int index()
270 return detail::xalloc_key_holder<Final>::value;
273 static inline void register_once(int indx, std::ios_base& ios)
275 // needs a mask registered
276 if (!is_registerd(ios))
279 ios.register_callback(callback, indx);
286 //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
289 //template <typename Final, typename T>
290 //detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
294 * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
296 * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
298 template <typename Final, typename T>
299 class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
301 typedef ios_state_ptr<Final, T> base_type;
303 explicit ios_state_not_null_ptr(std::ios_base& ios) :
306 if (this->get() == 0)
308 this->base_type::reset(new T());
311 ~ios_state_not_null_ptr()
315 void reset(T* new_value) BOOST_NOEXCEPT
317 BOOST_ASSERT(new_value!=0);
318 this->base_type::reset(new_value);
324 * This class is useful to associate some flags to an std::ios_base.
326 template <typename Final>
332 * @param ios the associated std::ios_base.
333 * @Postcondition <c>flags()==0</c>
335 explicit ios_flags(std::ios_base& ios) :
343 * @Returns The format control information.
345 long flags() const BOOST_NOEXCEPT
351 * @param v the new bit mask.
352 * @Postcondition <c>v == flags()</c>.
353 * @Returns The previous value of @c flags().
355 long flags(long v)BOOST_NOEXCEPT
363 * @param v the new value
364 * @Effects: Sets @c v in @c flags().
365 * @Returns: The previous value of @c flags().
375 * @param mask the bit mask to clear.
376 * @Effects: Clears @c mask in @c flags().
378 void unsetf(long mask)
387 * @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
388 * @Returns: The previous value of flags().
390 long setf(long v, long mask)
399 * implicit conversion to the @c ios_base
401 operator std::ios_base&()BOOST_NOEXCEPT
406 * implicit conversion to the @c ios_base const
408 operator std::ios_base const&() const BOOST_NOEXCEPT
413 long value() const BOOST_NOEXCEPT
415 return ios_.iword(index());
417 long& ref()BOOST_NOEXCEPT
419 return ios_.iword(index());
421 static inline int index()
423 return detail::xalloc_key_holder<Final>::value;
425 ios_flags& operator=(ios_flags const& rhs) ;
428 //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
431 //template <typename Final>
432 //detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
434 } // namespace chrono