File indexing completed on 2025-01-18 09:38:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
0015 #define BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
0016
0017 #if defined(_MSC_VER)
0018 # pragma once
0019 #endif
0020
0021 #include <boost/assert.hpp>
0022 #include <boost/mpl/int.hpp>
0023 #include <boost/type_traits/aligned_storage.hpp>
0024 #include <boost/type_traits/alignment_of.hpp>
0025
0026 namespace boost { namespace iostreams { namespace detail {
0027
0028
0029 template<class T>
0030 class aligned_storage
0031 {
0032
0033 union dummy_u
0034 {
0035 char data[ sizeof(T) ];
0036 BOOST_DEDUCED_TYPENAME type_with_alignment<
0037 ::boost::alignment_of<T>::value >::type aligner_;
0038 } dummy_ ;
0039
0040 public:
0041
0042 void const* address() const { return &dummy_.data[0]; }
0043 void * address() { return &dummy_.data[0]; }
0044 };
0045
0046 template<typename T>
0047 class optional {
0048 public:
0049 typedef T element_type;
0050 optional() : initialized_(false) { }
0051 optional(const T& t) : initialized_(false) { reset(t); }
0052 ~optional() { reset(); }
0053 T& operator*()
0054 {
0055 BOOST_ASSERT(initialized_);
0056 return *static_cast<T*>(address());
0057 }
0058 const T& operator*() const
0059 {
0060 BOOST_ASSERT(initialized_);
0061 return *static_cast<const T*>(address());
0062 }
0063 T* operator->()
0064 {
0065 BOOST_ASSERT(initialized_);
0066 return static_cast<T*>(address());
0067 }
0068 const T* operator->() const
0069 {
0070 BOOST_ASSERT(initialized_);
0071 return static_cast<const T*>(address());
0072 }
0073 T* get()
0074 {
0075 BOOST_ASSERT(initialized_);
0076 return static_cast<T*>(address());
0077 }
0078 const T* get() const
0079 {
0080 BOOST_ASSERT(initialized_);
0081 return static_cast<const T*>(address());
0082 }
0083 void reset()
0084 {
0085 if (initialized_) {
0086 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \
0087 BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \
0088
0089 T* t = static_cast<T*>(address());
0090 t->~T();
0091 #else
0092 static_cast<T*>(address())->T::~T();
0093 #endif
0094 initialized_ = false;
0095 }
0096 }
0097 void reset(const T& t)
0098 {
0099 reset();
0100 new (address()) T(t);
0101 initialized_ = true;
0102 }
0103 private:
0104 optional(const optional&);
0105 optional& operator=(const optional&);
0106 void* address() { return &storage_; }
0107 const void* address() const { return &storage_; }
0108 aligned_storage<T> storage_;
0109 bool initialized_;
0110 };
0111
0112 } } }
0113
0114 #endif