You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
120 lines
2.7 KiB
120 lines
2.7 KiB
// Copyright Daniel Wallin 2006. Use, modification and distribution is |
|
// subject to the Boost Software License, Version 1.0. (See accompanying |
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
|
|
// |
|
// 2009.10.21 TDS remove depenency on boost::python::detail::referent_storage |
|
// |
|
#ifndef BOOST_PARAMETER_MAYBE_091021_HPP |
|
# define BOOST_PARAMETER_MAYBE_091021_HPP |
|
|
|
# include <boost/mpl/if.hpp> |
|
# include <boost/mpl/identity.hpp> |
|
# include <boost/type_traits/is_reference.hpp> |
|
# include <boost/type_traits/add_reference.hpp> |
|
# include <boost/optional.hpp> |
|
# include <boost/aligned_storage.hpp> |
|
# include <boost/type_traits/remove_cv.hpp> |
|
# include <boost/type_traits/add_const.hpp> |
|
# include <boost/parameter/aux_/is_maybe.hpp> |
|
|
|
namespace boost { namespace parameter { namespace aux { |
|
|
|
template <class T> struct referent_size; |
|
|
|
template <class T> |
|
struct referent_size<T&> |
|
{ |
|
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(T)); |
|
}; |
|
|
|
// A metafunction returning a POD type which can store U, where T == |
|
// U&. If T is not a reference type, returns a POD which can store T. |
|
template <class T> |
|
struct referent_storage |
|
{ |
|
typedef typename boost::aligned_storage< |
|
referent_size<T>::value |
|
>::type type; |
|
}; |
|
|
|
template <class T> |
|
struct maybe : maybe_base |
|
{ |
|
typedef typename add_reference< |
|
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
|
T const |
|
# else |
|
typename add_const<T>::type |
|
# endif |
|
>::type reference; |
|
|
|
typedef typename remove_cv< |
|
BOOST_DEDUCED_TYPENAME remove_reference<reference>::type |
|
>::type non_cv_value; |
|
|
|
explicit maybe(T value_) |
|
: value(value_) |
|
, constructed(false) |
|
{} |
|
|
|
maybe() |
|
: constructed(false) |
|
{} |
|
|
|
~maybe() |
|
{ |
|
if (constructed) |
|
this->destroy(); |
|
} |
|
|
|
reference construct(reference value_) const |
|
{ |
|
return value_; |
|
} |
|
|
|
template <class U> |
|
reference construct2(U const& value_) const |
|
{ |
|
new (m_storage.address()) non_cv_value(value_); |
|
constructed = true; |
|
return *(non_cv_value*)m_storage.address(); |
|
} |
|
|
|
template <class U> |
|
reference construct(U const& value_) const |
|
{ |
|
return this->construct2(value_); |
|
} |
|
|
|
void destroy() |
|
{ |
|
((non_cv_value*)m_storage.address())->~non_cv_value(); |
|
} |
|
|
|
typedef reference(maybe<T>::*safe_bool)() const; |
|
|
|
operator safe_bool() const |
|
{ |
|
return value ? &maybe<T>::get : 0 ; |
|
} |
|
|
|
reference get() const |
|
{ |
|
return value.get(); |
|
} |
|
|
|
private: |
|
boost::optional<T> value; |
|
mutable bool constructed; |
|
|
|
|
|
mutable typename referent_storage< |
|
reference |
|
>::type m_storage; |
|
}; |
|
|
|
}}} // namespace boost::parameter::aux |
|
|
|
#endif // BOOST_PARAMETER_MAYBE_060211_HPP |
|
|
|
|