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