sl@0: // (C) Copyright Jonathan Turkanis 2005. sl@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying sl@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) sl@0: sl@0: // See http://www.boost.org/libs/iostreams for documentation. sl@0: sl@0: // Recent changes to Boost.Optional involving assigment broke Boost.Iostreams, sl@0: // in a way which could be remedied only by relying on the deprecated reset sl@0: // functions; with VC6, even reset didn't work. Until this problem is sl@0: // understood, Iostreams will use a private version of optional with a smart sl@0: // pointer interface. sl@0: sl@0: #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED sl@0: #define BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED sl@0: sl@0: #if defined(_MSC_VER) && (_MSC_VER >= 1020) sl@0: # pragma once sl@0: #endif sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { namespace iostreams { namespace detail { sl@0: sl@0: // Taken from . sl@0: template sl@0: class aligned_storage sl@0: { sl@0: // Borland ICEs if unnamed unions are used for this! sl@0: union dummy_u sl@0: { sl@0: char data[ sizeof(T) ]; sl@0: BOOST_DEDUCED_TYPENAME type_with_alignment< sl@0: ::boost::alignment_of::value >::type aligner_; sl@0: } dummy_ ; sl@0: sl@0: public: sl@0: sl@0: void const* address() const { return &dummy_.data[0]; } sl@0: void * address() { return &dummy_.data[0]; } sl@0: }; sl@0: sl@0: template sl@0: class optional { sl@0: public: sl@0: typedef T element_type; sl@0: optional() : initialized_(false) { } sl@0: optional(const T& t) : initialized_(false) { reset(t); } sl@0: ~optional() { reset(); } sl@0: T& operator*() sl@0: { sl@0: assert(initialized_); sl@0: return *static_cast(address()); sl@0: } sl@0: const T& operator*() const sl@0: { sl@0: assert(initialized_); sl@0: return *static_cast(address()); sl@0: } sl@0: T* operator->() sl@0: { sl@0: assert(initialized_); sl@0: return static_cast(address()); sl@0: } sl@0: const T* operator->() const sl@0: { sl@0: assert(initialized_); sl@0: return static_cast(address()); sl@0: } sl@0: T* get() sl@0: { sl@0: assert(initialized_); sl@0: return static_cast(address()); sl@0: } sl@0: const T* get() const sl@0: { sl@0: assert(initialized_); sl@0: return static_cast(address()); sl@0: } sl@0: void reset() sl@0: { sl@0: if (initialized_) { sl@0: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \ sl@0: BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ sl@0: /**/ sl@0: T* t = static_cast(address()); sl@0: t->~T(); sl@0: #else sl@0: static_cast(address())->T::~T(); sl@0: #endif sl@0: initialized_ = false; sl@0: } sl@0: } sl@0: void reset(const T& t) sl@0: { sl@0: reset(); sl@0: new (address()) T(t); sl@0: initialized_ = true; sl@0: } sl@0: private: sl@0: optional(const optional&); sl@0: optional& operator=(const optional&); sl@0: void* address() { return &storage_; } sl@0: const void* address() const { return &storage_; } sl@0: aligned_storage storage_; sl@0: bool initialized_; sl@0: }; sl@0: sl@0: } } } // End namespaces detail, iostreams, boost. sl@0: sl@0: #endif // #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED