File indexing completed on 2025-01-18 09:43:29
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_PARAMETER_MAYBE_091021_HPP
0010 #define BOOST_PARAMETER_MAYBE_091021_HPP
0011
0012 namespace boost { namespace parameter { namespace aux {
0013
0014 template <typename T>
0015 struct referent_size;
0016 }}}
0017
0018 #include <boost/parameter/config.hpp>
0019
0020 namespace boost { namespace parameter { namespace aux {
0021
0022 template <typename T>
0023 struct referent_size<T&>
0024 {
0025 BOOST_STATIC_CONSTANT(::std::size_t, value = sizeof(T));
0026 };
0027 }}}
0028
0029 #include <boost/type_traits/aligned_storage.hpp>
0030
0031 namespace boost { namespace parameter { namespace aux {
0032
0033
0034
0035 template <typename T>
0036 struct referent_storage
0037 : ::boost::aligned_storage<
0038 ::boost::parameter::aux::referent_size<T>::value
0039 >
0040 {
0041 };
0042 }}}
0043
0044 #include <boost/parameter/aux_/is_maybe.hpp>
0045 #include <boost/optional/optional.hpp>
0046
0047 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0048 #include <type_traits>
0049 #else
0050 #include <boost/type_traits/add_lvalue_reference.hpp>
0051 #include <boost/type_traits/remove_cv.hpp>
0052 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0053 #include <boost/type_traits/add_const.hpp>
0054 #endif
0055 #endif
0056
0057 namespace boost { namespace parameter { namespace aux {
0058
0059 template <typename T>
0060 struct maybe : ::boost::parameter::aux::maybe_base
0061 {
0062 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0063 typedef typename ::std::add_lvalue_reference<
0064 typename ::std::add_const<T>::type
0065 #else
0066 typedef typename ::boost::add_lvalue_reference<
0067 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0068 T const
0069 #else
0070 typename ::boost::add_const<T>::type
0071 #endif
0072 #endif
0073 >::type reference;
0074
0075 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0076 typedef typename ::std::remove_cv<
0077 typename ::std::remove_reference<reference>::type
0078 #else
0079 typedef typename ::boost::remove_cv<
0080 BOOST_DEDUCED_TYPENAME ::boost::remove_reference<reference>::type
0081 #endif
0082 >::type non_cv_value;
0083
0084 inline explicit maybe(T value_) : value(value_), constructed(false)
0085 {
0086 }
0087
0088 inline maybe() : value(), constructed(false)
0089 {
0090 }
0091
0092 ~maybe()
0093 {
0094 if (this->constructed)
0095 {
0096 this->destroy();
0097 }
0098 }
0099
0100 inline reference construct(reference value_) const
0101 {
0102 return value_;
0103 }
0104
0105 template <typename U>
0106 reference construct2(U const& value_) const
0107 {
0108 new (this->m_storage.address()) non_cv_value(value_);
0109 this->constructed = true;
0110 return *reinterpret_cast<non_cv_value*>(
0111 this->m_storage.address()
0112 );
0113 }
0114
0115 template <typename U>
0116 inline reference construct(U const& value_) const
0117 {
0118 return this->construct2(value_);
0119 }
0120
0121 void destroy()
0122 {
0123 reinterpret_cast<non_cv_value*>(
0124 this->m_storage.address()
0125 )->~non_cv_value();
0126 }
0127
0128 typedef reference(
0129 ::boost::parameter::aux::maybe<T>::*safe_bool
0130 )() const;
0131
0132 inline operator safe_bool() const
0133 {
0134 return this->value ? &::boost::parameter::aux::maybe<T>::get : 0;
0135 }
0136
0137 inline reference get() const
0138 {
0139 return this->value.get();
0140 }
0141
0142 private:
0143 ::boost::optional<T> value;
0144 mutable bool constructed;
0145 mutable typename ::boost::parameter::aux
0146 ::referent_storage<reference>::type m_storage;
0147 };
0148 }}}
0149
0150 #endif
0151