summaryrefslogtreecommitdiff
path: root/boost/chrono/io/utility/ios_base_state_ptr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/chrono/io/utility/ios_base_state_ptr.hpp')
-rw-r--r--boost/chrono/io/utility/ios_base_state_ptr.hpp436
1 files changed, 436 insertions, 0 deletions
diff --git a/boost/chrono/io/utility/ios_base_state_ptr.hpp b/boost/chrono/io/utility/ios_base_state_ptr.hpp
new file mode 100644
index 0000000000..f7dfdddca0
--- /dev/null
+++ b/boost/chrono/io/utility/ios_base_state_ptr.hpp
@@ -0,0 +1,436 @@
+// boost/chrono/utility/ios_base_pword_ptr.hpp ------------------------------------------------------------//
+
+// Copyright 2011 Vicente J. Botet Escriba
+
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/chrono for documentation.
+
+#ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
+#define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
+
+#include <ios>
+#include <boost/assert.hpp>
+
+/**
+ *
+
+
+ */
+namespace boost
+{
+ namespace chrono
+ {
+ namespace detail
+ {
+
+ /**
+ * xalloc key holder.
+ */
+ template <typename T>
+ struct xalloc_key_holder
+ {
+ static int value; //< the xalloc value associated to T.
+ static bool initialized; //< whether the value has been initialized or not.
+ };
+
+ template <typename T>
+ int xalloc_key_holder<T>::value = 0;
+
+ template <typename T>
+ bool xalloc_key_holder<T>::initialized = false;
+
+ }
+
+ /**
+ * xalloc key initialiazer.
+ *
+ * Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
+ */
+ template <typename T>
+ struct xalloc_key_initializer
+ {
+ xalloc_key_initializer()
+ {
+ if (!detail::xalloc_key_holder<T>::initialized)
+ {
+ detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
+ detail::xalloc_key_holder<T>::initialized = true;
+ }
+ }
+ };
+ /**
+ * @c ios_state_ptr is a smart pointer to a ios_base specific state.
+ */
+ template <typename Final, typename T>
+ class ios_state_ptr
+ {
+ ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
+
+ public:
+ /**
+ * The pointee type
+ */
+ typedef T element_type;
+ /**
+ * Explicit constructor.
+ * @param ios the ios
+ * @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
+ */
+ explicit ios_state_ptr(std::ios_base& ios) :
+ ios_(ios)
+ {
+
+ }
+ /**
+ * Nothing to do as xalloc index can not be removed.
+ */
+ ~ios_state_ptr()
+ {
+ }
+
+ /**
+ * @Effects Allocates the index if not already done.
+ * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
+ * Retrieves the associated ios pointer
+ * @return the retrieved pointer statically casted to const.
+ */
+ T const* get() const BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void* &pw = ios_.pword(index());
+ if (pw == 0)
+ {
+ return 0;
+ }
+ return static_cast<const T*> (pw);
+ }
+ /**
+ * @Effects Allocates the index if not already done.
+ * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
+ * Retrieves the associated ios pointer
+ * @return the retrieved pointer.
+ */
+ T * get() BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void* &pw = ios_.pword(index());
+ if (pw == 0)
+ {
+ return 0;
+ }
+ return static_cast<T*> (pw);
+ }
+ /**
+ * @Effects as if @c return get();
+ * @return the retrieved pointer.
+ */
+ T * operator->()BOOST_NOEXCEPT
+ {
+ return get();
+ }
+ /**
+ * @Effects as if @c return get();
+ * @return the retrieved pointer.
+ */
+ T const * operator->() const BOOST_NOEXCEPT
+ {
+ return get();
+ }
+
+ /**
+ * @Effects as if @c return *get();
+ * @return a reference to the retrieved state.
+ * @Remark The behavior is undefined if @c get()==0.
+ */
+ T & operator*() BOOST_NOEXCEPT
+ {
+ return *get();
+ }
+ /**
+ * @Effects as if @c return *get();
+ * @return a reference to the retrieved state.
+ * @Remark The behavior is undefined if @c get()==0.
+ */
+ T const & operator *() const BOOST_NOEXCEPT
+ {
+ return *get();
+ }
+
+ /**
+ * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
+ * @return the stored state pointer.
+ */
+ T * release() BOOST_NOEXCEPT
+ {
+ T const* f = get();
+ reset();
+ return f;
+ }
+
+ /**
+ *
+ * @param new_ptr the new pointer.
+ * @Effects deletes the current state and replace it with the new one.
+ */
+ void reset(T* new_ptr = 0)BOOST_NOEXCEPT
+ {
+ register_once(index(), ios_);
+ void*& pw = ios_.pword(index());
+ delete static_cast<T*> (pw);
+ pw = new_ptr;
+ }
+
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ typedef T* (ios_state_ptr::*bool_type)();
+ operator bool_type() const BOOST_NOEXCEPT
+ {
+ return (get()!=0)?&ios_state_ptr::release:0;
+ }
+ bool operator!() const BOOST_NOEXCEPT
+ {
+ return (get()==0)?&ios_state_ptr::release:0;
+ }
+#else
+ /**
+ * Explicit conversion to bool.
+ */
+ explicit operator bool() const BOOST_NOEXCEPT
+ {
+ return get()!=0;
+ }
+#endif
+
+ std::ios_base& getios()BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ std::ios_base& getios() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * Implicit conversion to the ios_base
+ */
+ operator std::ios_base&() BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * Implicit conversion to the ios_base const
+ */
+ operator std::ios_base&() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ private:
+ static inline bool is_registerd(std::ios_base& ios)
+ {
+ long iw = ios.iword(index());
+ return (iw == 1);
+ }
+ static inline void set_registered(std::ios_base& ios)
+ {
+ long& iw = ios.iword(index());
+ iw = 1;
+ }
+ static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
+ {
+ switch (evt)
+ {
+ case std::ios_base::erase_event:
+ {
+ void*& pw = ios.pword(index);
+ if (pw != 0)
+ {
+ T* ptr = static_cast<T*> (pw);
+ delete ptr;
+ pw = 0;
+ }
+ break;
+ }
+ case std::ios_base::copyfmt_event:
+ {
+ void*& pw = ios.pword(index);
+ if (pw != 0)
+ {
+ pw = new T(*static_cast<T*> (pw));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ static inline int index()
+ {
+ return detail::xalloc_key_holder<Final>::value;
+ }
+
+ static inline void register_once(int indx, std::ios_base& ios)
+ {
+ // needs a mask registered
+ if (!is_registerd(ios))
+ {
+ set_registered(ios);
+ ios.register_callback(callback, indx);
+ }
+ }
+
+
+ protected:
+ std::ios_base& ios_;
+ //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
+
+ };
+ //template <typename Final, typename T>
+ //detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
+
+
+ /**
+ * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
+ * @tparm T
+ * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
+ */
+ template <typename Final, typename T>
+ class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
+ {
+ typedef ios_state_ptr<Final, T> base_type;
+ public:
+ explicit ios_state_not_null_ptr(std::ios_base& ios) :
+ base_type(ios)
+ {
+ if (this->get() == 0)
+ {
+ this->base_type::reset(new T());
+ }
+ }
+ ~ios_state_not_null_ptr()
+ {
+ }
+
+ void reset(T* new_value) BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(new_value!=0);
+ this->base_type::reset(new_value);
+ }
+
+ };
+
+ /**
+ * This class is useful to associate some flags to an std::ios_base.
+ */
+ template <typename Final>
+ class ios_flags
+ {
+ public:
+ /**
+ *
+ * @param ios the associated std::ios_base.
+ * @Postcondition <c>flags()==0</c>
+ */
+ explicit ios_flags(std::ios_base& ios) :
+ ios_(ios)
+ {
+ }
+ ~ios_flags()
+ {
+ }
+ /**
+ * @Returns The format control information.
+ */
+ long flags() const BOOST_NOEXCEPT
+ {
+ return value();
+ }
+
+ /**
+ * @param v the new bit mask.
+ * @Postcondition <c>v == flags()</c>.
+ * @Returns The previous value of @c flags().
+ */
+ long flags(long v)BOOST_NOEXCEPT
+ {
+ long tmp = flags();
+ ref() = v;
+ return tmp;
+ }
+
+ /**
+ * @param v the new value
+ * @Effects: Sets @c v in @c flags().
+ * @Returns: The previous value of @c flags().
+ */
+ long setf(long v)
+ {
+ long tmp = value();
+ ref() |= v;
+ return tmp;
+ }
+
+ /**
+ * @param mask the bit mask to clear.
+ * @Effects: Clears @c mask in @c flags().
+ */
+ void unsetf(long mask)
+ {
+ ref() &= ~mask;
+ }
+
+ /**
+ *
+ * @param v
+ * @param mask
+ * @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
+ * @Returns: The previous value of flags().
+ */
+ long setf(long v, long mask)
+ {
+ long tmp = value();
+ unsetf(mask);
+ ref() |= v & mask;
+ return tmp;
+ }
+
+ /**
+ * implicit conversion to the @c ios_base
+ */
+ operator std::ios_base&()BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ /**
+ * implicit conversion to the @c ios_base const
+ */
+ operator std::ios_base const&() const BOOST_NOEXCEPT
+ {
+ return ios_;
+ }
+ private:
+ long value() const BOOST_NOEXCEPT
+ {
+ return ios_.iword(index());
+ }
+ long& ref()BOOST_NOEXCEPT
+ {
+ return ios_.iword(index());
+ }
+ static inline int index()
+ {
+ return detail::xalloc_key_holder<Final>::value;
+ }
+ ios_flags& operator=(ios_flags const& rhs) ;
+
+ std::ios_base& ios_;
+ //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
+
+ };
+ //template <typename Final>
+ //detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
+
+ } // namespace chrono
+} // namespace boost
+
+#endif // header