123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- // 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 == BOOST_NULLPTR)
- {
- return BOOST_NULLPTR;
- }
- 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
- {
- void*& pw = ios_.pword(index());
- T* ptr = static_cast<T*> (pw);
- pw = 0;
- return ptr;
- }
- /**
- *
- * @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 != BOOST_NULLPTR)
- {
- T* ptr = static_cast<T*> (pw);
- delete ptr;
- pw = BOOST_NULLPTR;
- }
- break;
- }
- case std::ios_base::copyfmt_event:
- {
- void*& pw = ios.pword(index);
- if (pw != BOOST_NULLPTR)
- {
- 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() == BOOST_NULLPTR)
- {
- this->base_type::reset(new T());
- }
- }
- ~ios_state_not_null_ptr()
- {
- }
- void reset(T* new_value) BOOST_NOEXCEPT
- {
- BOOST_ASSERT(new_value!=BOOST_NULLPTR);
- 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
|