1 // Copyright Daniel Wallin 2006. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 // 7 // 2009.10.21 TDS remove depenency on boost::python::detail::referent_storage 8 // 9 #ifndef BOOST_PARAMETER_MAYBE_091021_HPP 10 #define BOOST_PARAMETER_MAYBE_091021_HPP 11 12 namespace boost { namespace parameter { namespace aux { 13 14 template <typename T> 15 struct referent_size; 16 }}} // namespace boost::parameter::aux 17 18 #include <boost/parameter/config.hpp> 19 20 namespace boost { namespace parameter { namespace aux { 21 22 template <typename T> 23 struct referent_size<T&> 24 { 25 BOOST_STATIC_CONSTANT(::std::size_t, value = sizeof(T)); 26 }; 27 }}} // namespace boost::parameter::aux 28 29 #include <boost/type_traits/aligned_storage.hpp> 30 31 namespace boost { namespace parameter { namespace aux { 32 33 // A metafunction returning a POD type which can store U, where T == U&. 34 // If T is not a reference type, returns a POD which can store T. 35 template <typename T> 36 struct referent_storage 37 : ::boost::aligned_storage< 38 ::boost::parameter::aux::referent_size<T>::value 39 > 40 { 41 }; 42 }}} // namespace boost::parameter::aux 43 44 #include <boost/parameter/aux_/is_maybe.hpp> 45 #include <boost/optional/optional.hpp> 46 47 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 48 #include <type_traits> 49 #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) 50 #include <boost/type_traits/add_lvalue_reference.hpp> 51 #include <boost/type_traits/remove_cv.hpp> 52 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 53 #include <boost/type_traits/add_const.hpp> 54 #endif 55 #endif // BOOST_PARAMETER_CAN_USE_MP11 56 57 namespace boost { namespace parameter { namespace aux { 58 59 template <typename T> 60 struct maybe : ::boost::parameter::aux::maybe_base 61 { 62 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 63 typedef typename ::std::add_lvalue_reference< 64 typename ::std::add_const<T>::type 65 #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) 66 typedef typename ::boost::add_lvalue_reference< 67 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) 68 T const 69 #else 70 typename ::boost::add_const<T>::type 71 #endif 72 #endif // BOOST_PARAMETER_CAN_USE_MP11 73 >::type reference; 74 75 #if defined(BOOST_PARAMETER_CAN_USE_MP11) 76 typedef typename ::std::remove_cv< 77 typename ::std::remove_reference<reference>::type 78 #else 79 typedef typename ::boost::remove_cv< 80 BOOST_DEDUCED_TYPENAME ::boost::remove_reference<reference>::type 81 #endif 82 >::type non_cv_value; 83 maybeboost::parameter::aux::maybe84 inline explicit maybe(T value_) : value(value_), constructed(false) 85 { 86 } 87 maybeboost::parameter::aux::maybe88 inline maybe() : value(), constructed(false) 89 { 90 } 91 ~maybeboost::parameter::aux::maybe92 ~maybe() 93 { 94 if (this->constructed) 95 { 96 this->destroy(); 97 } 98 } 99 constructboost::parameter::aux::maybe100 inline reference construct(reference value_) const 101 { 102 return value_; 103 } 104 105 template <typename U> construct2boost::parameter::aux::maybe106 reference construct2(U const& value_) const 107 { 108 new (this->m_storage.address()) non_cv_value(value_); 109 this->constructed = true; 110 return *reinterpret_cast<non_cv_value*>( 111 this->m_storage.address() 112 ); 113 } 114 115 template <typename U> constructboost::parameter::aux::maybe116 inline reference construct(U const& value_) const 117 { 118 return this->construct2(value_); 119 } 120 destroyboost::parameter::aux::maybe121 void destroy() 122 { 123 reinterpret_cast<non_cv_value*>( 124 this->m_storage.address() 125 )->~non_cv_value(); 126 } 127 128 typedef reference( 129 ::boost::parameter::aux::maybe<T>::*safe_bool 130 )() const; 131 operator safe_boolboost::parameter::aux::maybe132 inline operator safe_bool() const 133 { 134 return this->value ? &::boost::parameter::aux::maybe<T>::get : 0; 135 } 136 getboost::parameter::aux::maybe137 inline reference get() const 138 { 139 return this->value.get(); 140 } 141 142 private: 143 ::boost::optional<T> value; 144 mutable bool constructed; 145 mutable typename ::boost::parameter::aux 146 ::referent_storage<reference>::type m_storage; 147 }; 148 }}} // namespace boost::parameter::aux 149 150 #endif // include guard 151 152