source: NonGTP/Boost/boost/iostreams/detail/optional.hpp @ 857

Revision 857, 3.2 KB checked in by igarcia, 18 years ago (diff)
Line 
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
25namespace boost { namespace iostreams { namespace detail {
26
27// Taken from <boost/optional.hpp>.
28template<class T>
29class 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
45template<typename T>
46class optional {
47public:
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    }
102private:
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
Note: See TracBrowser for help on using the repository browser.