| [29] | 1 | // (C) Copyright Jonathan Turkanis 2005. | 
|---|
 | 2 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 
|---|
 | 3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | 
|---|
 | 4 |  | 
|---|
 | 5 | // See http://www.boost.org/libs/iostreams for documentation. | 
|---|
 | 6 |  | 
|---|
 | 7 | // Recent changes to Boost.Optional involving assigment broke Boost.Iostreams, | 
|---|
 | 8 | // in a way which could be remedied only by relying on the deprecated reset | 
|---|
 | 9 | // functions; with VC6, even reset didn't work. Until this problem is  | 
|---|
 | 10 | // understood, Iostreams will use a private version of optional with a smart  | 
|---|
 | 11 | // pointer interface. | 
|---|
 | 12 |  | 
|---|
 | 13 | #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED | 
|---|
 | 14 | #define BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED | 
|---|
 | 15 |  | 
|---|
 | 16 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) | 
|---|
 | 17 | # pragma once | 
|---|
 | 18 | #endif | 
|---|
 | 19 |  | 
|---|
 | 20 | #include <cassert> | 
|---|
 | 21 | #include <boost/mpl/int.hpp> | 
|---|
 | 22 | #include <boost/type_traits/aligned_storage.hpp> | 
|---|
 | 23 | #include <boost/type_traits/alignment_of.hpp> | 
|---|
 | 24 |  | 
|---|
 | 25 | namespace boost { namespace iostreams { namespace detail { | 
|---|
 | 26 |  | 
|---|
 | 27 | // Taken from <boost/optional.hpp>. | 
|---|
 | 28 | template<class T> | 
|---|
 | 29 | class aligned_storage | 
|---|
 | 30 | { | 
|---|
 | 31 |     // Borland ICEs if unnamed unions are used for this! | 
|---|
 | 32 |     union dummy_u | 
|---|
 | 33 |     { | 
|---|
 | 34 |         char data[ sizeof(T) ]; | 
|---|
 | 35 |         BOOST_DEDUCED_TYPENAME type_with_alignment< | 
|---|
 | 36 |           ::boost::alignment_of<T>::value >::type aligner_; | 
|---|
 | 37 |     } dummy_ ; | 
|---|
 | 38 |  | 
|---|
 | 39 |   public: | 
|---|
 | 40 |  | 
|---|
 | 41 |     void const* address() const { return &dummy_.data[0]; } | 
|---|
 | 42 |     void      * address()       { return &dummy_.data[0]; } | 
|---|
 | 43 | }; | 
|---|
 | 44 |  | 
|---|
 | 45 | template<typename T> | 
|---|
 | 46 | class optional { | 
|---|
 | 47 | public: | 
|---|
 | 48 |     typedef T element_type; | 
|---|
 | 49 |     optional() : initialized_(false) { } | 
|---|
 | 50 |     optional(const T& t) : initialized_(false) { reset(t); } | 
|---|
 | 51 |     ~optional() { reset(); } | 
|---|
 | 52 |     T& operator*()  | 
|---|
 | 53 |     {  | 
|---|
 | 54 |         assert(initialized_); | 
|---|
 | 55 |         return *static_cast<T*>(address());  | 
|---|
 | 56 |     } | 
|---|
 | 57 |     const T& operator*() const | 
|---|
 | 58 |     {  | 
|---|
 | 59 |         assert(initialized_); | 
|---|
 | 60 |         return *static_cast<const T*>(address());  | 
|---|
 | 61 |     } | 
|---|
 | 62 |     T* operator->()  | 
|---|
 | 63 |     {  | 
|---|
 | 64 |         assert(initialized_); | 
|---|
 | 65 |         return static_cast<T*>(address());  | 
|---|
 | 66 |     } | 
|---|
 | 67 |     const T* operator->() const | 
|---|
 | 68 |     {  | 
|---|
 | 69 |         assert(initialized_); | 
|---|
 | 70 |         return static_cast<const T*>(address());  | 
|---|
 | 71 |     } | 
|---|
 | 72 |     T* get()  | 
|---|
 | 73 |     {  | 
|---|
 | 74 |         assert(initialized_); | 
|---|
 | 75 |         return static_cast<T*>(address());  | 
|---|
 | 76 |     } | 
|---|
 | 77 |     const T* get() const | 
|---|
 | 78 |     {  | 
|---|
 | 79 |         assert(initialized_); | 
|---|
 | 80 |         return static_cast<const T*>(address());  | 
|---|
 | 81 |     } | 
|---|
 | 82 |     void reset()  | 
|---|
 | 83 |     { | 
|---|
 | 84 |         if (initialized_) {  | 
|---|
 | 85 |         #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \ | 
|---|
 | 86 |             BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ | 
|---|
 | 87 |             /**/ | 
|---|
 | 88 |             T* t = static_cast<T*>(address()); | 
|---|
 | 89 |             t->~T(); | 
|---|
 | 90 |         #else | 
|---|
 | 91 |             static_cast<T*>(address())->T::~T(); | 
|---|
 | 92 |         #endif | 
|---|
 | 93 |             initialized_ = false; | 
|---|
 | 94 |         } | 
|---|
 | 95 |     } | 
|---|
 | 96 |     void reset(const T& t)  | 
|---|
 | 97 |     { | 
|---|
 | 98 |         reset(); | 
|---|
 | 99 |         new (address()) T(t);  | 
|---|
 | 100 |         initialized_ = true; | 
|---|
 | 101 |     } | 
|---|
 | 102 | private: | 
|---|
 | 103 |     optional(const optional&); | 
|---|
 | 104 |     optional& operator=(const optional&); | 
|---|
 | 105 |     void* address() { return &storage_; } | 
|---|
 | 106 |     const void* address() const { return &storage_; } | 
|---|
 | 107 |     aligned_storage<T>  storage_; | 
|---|
 | 108 |     bool                initialized_; | 
|---|
 | 109 | }; | 
|---|
 | 110 |  | 
|---|
 | 111 | } } } // End namespaces detail, iostreams, boost. | 
|---|
 | 112 |  | 
|---|
 | 113 | #endif // #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED | 
|---|