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