Chris@16
|
1 // Copyright Daniel Wallin 2006. Use, modification and distribution is
|
Chris@16
|
2 // subject to the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
4
|
Chris@16
|
5 //
|
Chris@16
|
6 // 2009.10.21 TDS remove depenency on boost::python::detail::referent_storage
|
Chris@16
|
7 //
|
Chris@16
|
8 #ifndef BOOST_PARAMETER_MAYBE_091021_HPP
|
Chris@16
|
9 # define BOOST_PARAMETER_MAYBE_091021_HPP
|
Chris@16
|
10
|
Chris@16
|
11 # include <boost/mpl/if.hpp>
|
Chris@16
|
12 # include <boost/mpl/identity.hpp>
|
Chris@16
|
13 # include <boost/type_traits/is_reference.hpp>
|
Chris@16
|
14 # include <boost/type_traits/add_reference.hpp>
|
Chris@16
|
15 # include <boost/optional.hpp>
|
Chris@16
|
16 # include <boost/aligned_storage.hpp>
|
Chris@16
|
17 # include <boost/type_traits/remove_cv.hpp>
|
Chris@16
|
18 # include <boost/type_traits/add_const.hpp>
|
Chris@16
|
19 # include <boost/parameter/aux_/is_maybe.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost { namespace parameter { namespace aux {
|
Chris@16
|
22
|
Chris@16
|
23 template <class T> struct referent_size;
|
Chris@16
|
24
|
Chris@16
|
25 template <class T>
|
Chris@16
|
26 struct referent_size<T&>
|
Chris@16
|
27 {
|
Chris@16
|
28 BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(T));
|
Chris@16
|
29 };
|
Chris@16
|
30
|
Chris@16
|
31 // A metafunction returning a POD type which can store U, where T ==
|
Chris@16
|
32 // U&. If T is not a reference type, returns a POD which can store T.
|
Chris@16
|
33 template <class T>
|
Chris@16
|
34 struct referent_storage
|
Chris@16
|
35 {
|
Chris@16
|
36 typedef typename boost::aligned_storage<
|
Chris@16
|
37 referent_size<T>::value
|
Chris@16
|
38 >::type type;
|
Chris@16
|
39 };
|
Chris@16
|
40
|
Chris@16
|
41 template <class T>
|
Chris@16
|
42 struct maybe : maybe_base
|
Chris@16
|
43 {
|
Chris@16
|
44 typedef typename add_reference<
|
Chris@16
|
45 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
46 T const
|
Chris@16
|
47 # else
|
Chris@16
|
48 typename add_const<T>::type
|
Chris@16
|
49 # endif
|
Chris@16
|
50 >::type reference;
|
Chris@16
|
51
|
Chris@16
|
52 typedef typename remove_cv<
|
Chris@16
|
53 BOOST_DEDUCED_TYPENAME remove_reference<reference>::type
|
Chris@16
|
54 >::type non_cv_value;
|
Chris@16
|
55
|
Chris@16
|
56 explicit maybe(T value_)
|
Chris@16
|
57 : value(value_)
|
Chris@16
|
58 , constructed(false)
|
Chris@16
|
59 {}
|
Chris@16
|
60
|
Chris@16
|
61 maybe()
|
Chris@16
|
62 : constructed(false)
|
Chris@16
|
63 {}
|
Chris@16
|
64
|
Chris@16
|
65 ~maybe()
|
Chris@16
|
66 {
|
Chris@16
|
67 if (constructed)
|
Chris@16
|
68 this->destroy();
|
Chris@16
|
69 }
|
Chris@16
|
70
|
Chris@16
|
71 reference construct(reference value_) const
|
Chris@16
|
72 {
|
Chris@16
|
73 return value_;
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 template <class U>
|
Chris@16
|
77 reference construct2(U const& value_) const
|
Chris@16
|
78 {
|
Chris@16
|
79 new (m_storage.address()) non_cv_value(value_);
|
Chris@16
|
80 constructed = true;
|
Chris@16
|
81 return *(non_cv_value*)m_storage.address();
|
Chris@16
|
82 }
|
Chris@16
|
83
|
Chris@16
|
84 template <class U>
|
Chris@16
|
85 reference construct(U const& value_) const
|
Chris@16
|
86 {
|
Chris@16
|
87 return this->construct2(value_);
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 void destroy()
|
Chris@16
|
91 {
|
Chris@16
|
92 ((non_cv_value*)m_storage.address())->~non_cv_value();
|
Chris@16
|
93 }
|
Chris@16
|
94
|
Chris@16
|
95 typedef reference(maybe<T>::*safe_bool)() const;
|
Chris@16
|
96
|
Chris@16
|
97 operator safe_bool() const
|
Chris@16
|
98 {
|
Chris@16
|
99 return value ? &maybe<T>::get : 0 ;
|
Chris@16
|
100 }
|
Chris@16
|
101
|
Chris@16
|
102 reference get() const
|
Chris@16
|
103 {
|
Chris@16
|
104 return value.get();
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 private:
|
Chris@16
|
108 boost::optional<T> value;
|
Chris@16
|
109 mutable bool constructed;
|
Chris@16
|
110
|
Chris@16
|
111
|
Chris@16
|
112 mutable typename referent_storage<
|
Chris@16
|
113 reference
|
Chris@16
|
114 >::type m_storage;
|
Chris@16
|
115 };
|
Chris@16
|
116
|
Chris@16
|
117 }}} // namespace boost::parameter::aux
|
Chris@16
|
118
|
Chris@16
|
119 #endif // BOOST_PARAMETER_MAYBE_060211_HPP
|
Chris@16
|
120
|