Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:20

0001 //  boost/chrono/utility/ios_base_pword_ptr.hpp  ------------------------------------------------------------//
0002 
0003 //  Copyright 2011 Vicente J. Botet Escriba
0004 
0005 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 //  See http://www.boost.org/libs/chrono for documentation.
0009 
0010 #ifndef BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
0011 #define BOOST_CHRONO_UTILITY_IOS_BASE_STATE_PTR_HPP
0012 
0013 #include <ios>
0014 #include <boost/assert.hpp>
0015 
0016 /**
0017  *
0018 
0019 
0020  */
0021 namespace boost
0022 {
0023   namespace chrono
0024   {
0025     namespace detail
0026     {
0027 
0028       /**
0029        * xalloc key holder.
0030        */
0031       template <typename T>
0032       struct xalloc_key_holder
0033       {
0034         static int value; //< the xalloc value associated to T.
0035         static bool initialized; //< whether the value has been initialized or not.
0036       };
0037 
0038       template <typename T>
0039       int xalloc_key_holder<T>::value = 0;
0040 
0041       template <typename T>
0042       bool xalloc_key_holder<T>::initialized = false;
0043 
0044     }
0045 
0046     /**
0047      * xalloc key initialiazer.
0048      *
0049      * Declare a static variable of this type to ensure that the xalloc_key_holder<T> is initialized correctly.
0050      */
0051     template <typename T>
0052     struct xalloc_key_initializer
0053     {
0054       xalloc_key_initializer()
0055       {
0056         if (!detail::xalloc_key_holder<T>::initialized)
0057         {
0058           detail::xalloc_key_holder<T>::value = std::ios_base::xalloc();
0059           detail::xalloc_key_holder<T>::initialized = true;
0060         }
0061       }
0062     };
0063     /**
0064      * @c ios_state_ptr is a smart pointer to a ios_base specific state.
0065      */
0066     template <typename Final, typename T>
0067     class ios_state_ptr
0068     {
0069       ios_state_ptr& operator=(ios_state_ptr const& rhs) ;
0070 
0071     public:
0072       /**
0073        * The pointee type
0074        */
0075       typedef T element_type;
0076       /**
0077        * Explicit constructor.
0078        * @param ios the ios
0079        * @Effects Constructs a @c ios_state_ptr by storing the associated @c ios.
0080        */
0081       explicit ios_state_ptr(std::ios_base& ios) :
0082         ios_(ios)
0083       {
0084 
0085       }
0086       /**
0087        * Nothing to do as xalloc index can not be removed.
0088        */
0089       ~ios_state_ptr()
0090       {
0091       }
0092 
0093       /**
0094        * @Effects Allocates the index if not already done.
0095        * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
0096        * Retrieves the associated ios pointer
0097        * @return the retrieved pointer statically casted to const.
0098        */
0099       T const* get() const BOOST_NOEXCEPT
0100       {
0101         register_once(index(), ios_);
0102         void* &pw = ios_.pword(index());
0103         if (pw == 0)
0104         {
0105           return 0;
0106         }
0107         return static_cast<const T*> (pw);
0108       }
0109       /**
0110        * @Effects Allocates the index if not already done.
0111        * Registers the callback responsible of maintaining the state pointer coherency, if not already done.
0112        * Retrieves the associated ios pointer
0113        * @return the retrieved pointer.
0114        */
0115       T * get() BOOST_NOEXCEPT
0116       {
0117         register_once(index(), ios_);
0118         void* &pw = ios_.pword(index());
0119         if (pw == BOOST_NULLPTR)
0120         {
0121           return BOOST_NULLPTR;
0122         }
0123         return static_cast<T*> (pw);
0124       }
0125       /**
0126        * @Effects as if @c return get();
0127        * @return the retrieved pointer.
0128        */
0129       T * operator->()BOOST_NOEXCEPT
0130       {
0131         return get();
0132       }
0133       /**
0134        * @Effects as if @c return get();
0135        * @return the retrieved pointer.
0136        */
0137       T const * operator->() const BOOST_NOEXCEPT
0138       {
0139         return get();
0140       }
0141 
0142       /**
0143        * @Effects as if @c return *get();
0144        * @return a reference to the retrieved state.
0145        * @Remark The behavior is undefined if @c get()==0.
0146        */
0147       T & operator*() BOOST_NOEXCEPT
0148       {
0149         return *get();
0150       }
0151       /**
0152        * @Effects as if @c return *get();
0153        * @return a reference to the retrieved state.
0154        * @Remark The behavior is undefined if @c get()==0.
0155        */
0156       T const & operator *() const BOOST_NOEXCEPT
0157       {
0158         return *get();
0159       }
0160 
0161       /**
0162        * @Effects reset the current pointer after storing in a temporary variable the pointer to the current state.
0163        * @return the stored state pointer.
0164        */
0165       T * release() BOOST_NOEXCEPT
0166       {
0167         void*& pw = ios_.pword(index());
0168         T* ptr = static_cast<T*> (pw);
0169         pw = 0;
0170         return ptr;
0171       }
0172 
0173       /**
0174        *
0175        * @param new_ptr the new pointer.
0176        * @Effects deletes the current state and replace it with the new one.
0177        */
0178       void reset(T* new_ptr = 0)BOOST_NOEXCEPT
0179       {
0180         register_once(index(), ios_);
0181         void*& pw = ios_.pword(index());
0182         delete static_cast<T*> (pw);
0183         pw = new_ptr;
0184       }
0185 
0186 #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
0187         typedef T* (ios_state_ptr::*bool_type)();
0188         operator bool_type() const BOOST_NOEXCEPT
0189         {
0190             return (get()!=0)?&ios_state_ptr::release:0;
0191         }
0192         bool operator!() const BOOST_NOEXCEPT
0193         {
0194           return (get()==0)?&ios_state_ptr::release:0;
0195         }
0196 #else
0197         /**
0198          * Explicit conversion to bool.
0199          */
0200         explicit operator bool() const BOOST_NOEXCEPT
0201         {
0202           return get()!=0;
0203         }
0204 #endif
0205 
0206       std::ios_base& getios()BOOST_NOEXCEPT
0207       {
0208         return ios_;
0209       }
0210       std::ios_base& getios() const BOOST_NOEXCEPT
0211       {
0212         return ios_;
0213       }
0214       /**
0215        * Implicit conversion to the ios_base
0216        */
0217       operator std::ios_base&() BOOST_NOEXCEPT
0218       {
0219         return ios_;
0220       }
0221       /**
0222        * Implicit conversion to the ios_base const
0223        */
0224       operator std::ios_base&() const BOOST_NOEXCEPT
0225       {
0226         return ios_;
0227       }
0228     private:
0229       static inline bool is_registerd(std::ios_base& ios)
0230       {
0231         long iw = ios.iword(index());
0232         return (iw == 1);
0233       }
0234       static inline void set_registered(std::ios_base& ios)
0235       {
0236         long& iw = ios.iword(index());
0237         iw = 1;
0238       }
0239       static inline void callback(std::ios_base::event evt, std::ios_base& ios, int index)
0240       {
0241         switch (evt)
0242         {
0243         case std::ios_base::erase_event:
0244         {
0245           void*& pw = ios.pword(index);
0246           if (pw != BOOST_NULLPTR)
0247           {
0248             T* ptr = static_cast<T*> (pw);
0249             delete ptr;
0250             pw = BOOST_NULLPTR;
0251           }
0252           break;
0253         }
0254         case std::ios_base::copyfmt_event:
0255         {
0256           void*& pw = ios.pword(index);
0257           if (pw != BOOST_NULLPTR)
0258           {
0259             pw = new T(*static_cast<T*> (pw));
0260           }
0261           break;
0262         }
0263         default:
0264           break;
0265         }
0266       }
0267 
0268       static inline int index()
0269       {
0270         return detail::xalloc_key_holder<Final>::value;
0271       }
0272 
0273       static inline void register_once(int indx, std::ios_base& ios)
0274       {
0275         // needs a mask registered
0276         if (!is_registerd(ios))
0277         {
0278           set_registered(ios);
0279           ios.register_callback(callback, indx);
0280         }
0281       }
0282 
0283 
0284     protected:
0285       std::ios_base& ios_;
0286       //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
0287 
0288     };
0289     //template <typename Final, typename T>
0290     //detail::xalloc_key_initializer<Final> ios_state_ptr<Final,T>::xalloc_key_initializer_;
0291 
0292 
0293     /**
0294      * @c ios_state_not_null_ptr is a non null variant of @c ios_state_ptr.
0295      * @tparm T
0296      * @Requires @c T must be @c DefaultConstructible and @c HeapAllocatable
0297      */
0298     template <typename Final, typename T>
0299     class ios_state_not_null_ptr: public ios_state_ptr<Final, T>
0300     {
0301       typedef ios_state_ptr<Final, T> base_type;
0302     public:
0303       explicit ios_state_not_null_ptr(std::ios_base& ios) :
0304       base_type(ios)
0305       {
0306         if (this->get() == BOOST_NULLPTR)
0307         {
0308           this->base_type::reset(new T());
0309         }
0310       }
0311       ~ios_state_not_null_ptr()
0312       {
0313       }
0314 
0315       void reset(T* new_value) BOOST_NOEXCEPT
0316       {
0317         BOOST_ASSERT(new_value!=BOOST_NULLPTR);
0318         this->base_type::reset(new_value);
0319       }
0320 
0321     };
0322 
0323     /**
0324      * This class is useful to associate some flags to an std::ios_base.
0325      */
0326     template <typename Final>
0327     class ios_flags
0328     {
0329     public:
0330       /**
0331        *
0332        * @param ios the associated std::ios_base.
0333        * @Postcondition <c>flags()==0</c>
0334        */
0335       explicit ios_flags(std::ios_base& ios) :
0336         ios_(ios)
0337       {
0338       }
0339       ~ios_flags()
0340       {
0341       }
0342       /**
0343        * @Returns The format control information.
0344        */
0345       long flags() const BOOST_NOEXCEPT
0346       {
0347         return value();
0348       }
0349 
0350       /**
0351        * @param v the new bit mask.
0352        * @Postcondition <c>v == flags()</c>.
0353        * @Returns The previous value of @c flags().
0354        */
0355       long flags(long v)BOOST_NOEXCEPT
0356       {
0357         long tmp = flags();
0358         ref() = v;
0359         return tmp;
0360       }
0361 
0362       /**
0363        * @param v the new value
0364        * @Effects: Sets @c v in @c flags().
0365        * @Returns: The previous value of @c flags().
0366        */
0367       long setf(long v)
0368       {
0369         long tmp = value();
0370         ref() |= v;
0371         return tmp;
0372       }
0373 
0374       /**
0375        * @param mask the bit mask to clear.
0376        * @Effects: Clears @c mask in @c flags().
0377        */
0378       void unsetf(long mask)
0379       {
0380         ref() &= ~mask;
0381       }
0382 
0383       /**
0384        *
0385        * @param v
0386        * @param mask
0387        * @Effects: Clears @c mask in @c flags(), sets <c>v & mask</c> in @c flags().
0388        * @Returns: The previous value of flags().
0389        */
0390       long setf(long v, long mask)
0391       {
0392         long tmp = value();
0393         unsetf(mask);
0394         ref() |= v & mask;
0395         return tmp;
0396       }
0397 
0398       /**
0399        * implicit conversion to the @c ios_base
0400        */
0401       operator std::ios_base&()BOOST_NOEXCEPT
0402       {
0403         return ios_;
0404       }
0405       /**
0406        * implicit conversion to the @c ios_base const
0407        */
0408       operator std::ios_base const&() const BOOST_NOEXCEPT
0409       {
0410         return ios_;
0411       }
0412     private:
0413       long value() const BOOST_NOEXCEPT
0414       {
0415         return ios_.iword(index());
0416       }
0417       long& ref()BOOST_NOEXCEPT
0418       {
0419         return ios_.iword(index());
0420       }
0421       static inline int index()
0422       {
0423         return detail::xalloc_key_holder<Final>::value;
0424       }
0425       ios_flags& operator=(ios_flags const& rhs) ;
0426 
0427       std::ios_base& ios_;
0428       //static detail::xalloc_key_initializer<Final> xalloc_key_initializer_;
0429 
0430     };
0431     //template <typename Final>
0432     //detail::xalloc_key_initializer<Final> ios_flags<Final>::xalloc_key_initializer_;
0433 
0434   } // namespace chrono
0435 } // namespace boost
0436 
0437 #endif // header