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