File indexing completed on 2025-12-16 09:44:20
0001
0002
0003
0004
0005
0006
0007
0008
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
0030
0031 template <typename T>
0032 struct xalloc_key_holder
0033 {
0034 static int value;
0035 static bool initialized;
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
0048
0049
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
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
0074
0075 typedef T element_type;
0076
0077
0078
0079
0080
0081 explicit ios_state_ptr(std::ios_base& ios) :
0082 ios_(ios)
0083 {
0084
0085 }
0086
0087
0088
0089 ~ios_state_ptr()
0090 {
0091 }
0092
0093
0094
0095
0096
0097
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
0111
0112
0113
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
0127
0128
0129 T * operator->()BOOST_NOEXCEPT
0130 {
0131 return get();
0132 }
0133
0134
0135
0136
0137 T const * operator->() const BOOST_NOEXCEPT
0138 {
0139 return get();
0140 }
0141
0142
0143
0144
0145
0146
0147 T & operator*() BOOST_NOEXCEPT
0148 {
0149 return *get();
0150 }
0151
0152
0153
0154
0155
0156 T const & operator *() const BOOST_NOEXCEPT
0157 {
0158 return *get();
0159 }
0160
0161
0162
0163
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
0176
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
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
0216
0217 operator std::ios_base&() BOOST_NOEXCEPT
0218 {
0219 return ios_;
0220 }
0221
0222
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
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
0287
0288 };
0289
0290
0291
0292
0293
0294
0295
0296
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
0325
0326 template <typename Final>
0327 class ios_flags
0328 {
0329 public:
0330
0331
0332
0333
0334
0335 explicit ios_flags(std::ios_base& ios) :
0336 ios_(ios)
0337 {
0338 }
0339 ~ios_flags()
0340 {
0341 }
0342
0343
0344
0345 long flags() const BOOST_NOEXCEPT
0346 {
0347 return value();
0348 }
0349
0350
0351
0352
0353
0354
0355 long flags(long v)BOOST_NOEXCEPT
0356 {
0357 long tmp = flags();
0358 ref() = v;
0359 return tmp;
0360 }
0361
0362
0363
0364
0365
0366
0367 long setf(long v)
0368 {
0369 long tmp = value();
0370 ref() |= v;
0371 return tmp;
0372 }
0373
0374
0375
0376
0377
0378 void unsetf(long mask)
0379 {
0380 ref() &= ~mask;
0381 }
0382
0383
0384
0385
0386
0387
0388
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
0400
0401 operator std::ios_base&()BOOST_NOEXCEPT
0402 {
0403 return ios_;
0404 }
0405
0406
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
0429
0430 };
0431
0432
0433
0434 }
0435 }
0436
0437 #endif