1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

change addressof traits

This commit is contained in:
bolero-MURAKAMI 2016-04-14 23:16:21 +09:00
parent b3ce7296da
commit e5637554d1
3 changed files with 56 additions and 61 deletions

View file

@ -16,6 +16,10 @@
#include <sprout/type_traits/integral_constant.hpp>
#include <sprout/adl/not_found.hpp>
namespace sprout_adl {
sprout::not_found_via_adl get_addressof(...);
} // namespace sprout_adl
namespace sprout {
namespace detail {
struct address_op_helper {};
@ -72,35 +76,48 @@ namespace sprout {
>
{};
template<typename T, bool IsOverloaded = sprout::detail::has_address_op<T>::value>
struct addressof_traits_default;
template<typename T>
struct addressof_traits_default<T, true> {
public:
template<typename U>
static U*
get_addressof(U& t) SPROUT_NOEXCEPT {
return std::addressof(t);
}
};
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::detail::has_address_op<T>::value,
T*
>::type
get_addressof_impl(T& t) SPROUT_NOEXCEPT {
return std::addressof(t);
}
template<typename T>
struct addressof_traits_default<T, false> {
public:
template<typename U>
static SPROUT_CONSTEXPR U*
get_addressof(U& t) SPROUT_NOEXCEPT {
return &t;
}
};
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::detail::has_address_op<T>::value,
T*
>::type
get_addressof_impl(T& t) SPROUT_NOEXCEPT {
return &t;
}
} // namespace detail
} // namespace sprout
namespace sprout_addressof_detail {
template<typename T>
inline SPROUT_CONSTEXPR T*
get_addressof(T& t) SPROUT_NOEXCEPT {
return sprout::detail::get_addressof_impl(t);
}
} // namespace sprout_addressof_detail
namespace sprout {
//
// address_traits
//
template<typename T>
struct address_traits
: public sprout::detail::addressof_traits_default<T>
{};
struct address_traits {
public:
template<typename U>
static SPROUT_CONSTEXPR U*
get_addressof(U& t) SPROUT_NOEXCEPT {
using sprout_addressof_detail::get_addressof;
using sprout_adl::get_addressof;
return get_addressof(t);
}
};
template<typename T>
struct address_traits<T const>
: public sprout::address_traits<T>
@ -115,41 +132,22 @@ namespace sprout {
{};
} // namespace sprout
namespace sprout_adl {
sprout::not_found_via_adl get_addressof(...);
} // namespace sprout_adl
namespace sprout_addressof_detail {
template<typename T>
inline SPROUT_CONSTEXPR T*
get_addressof(T& t) SPROUT_NOEXCEPT {
return sprout::address_traits<T>::get_addressof(t);
}
template<typename T>
inline SPROUT_CONSTEXPR T*
call_get_addressof(T& t) SPROUT_NOEXCEPT {
using sprout_adl::get_addressof;
using sprout_addressof_detail::get_addressof;
return get_addressof(t);
}
} // namespace sprout_addressof_detail
namespace sprout {
//
// addressof
//
// effect:
// ADL callable get_addressof(t) -> get_addressof(t)
// otherwise -> sprout::address_traits<T>::get_addressof(t)
// sprout::address_traits<T>::get_addressof(t)
// [default]
// no overloaded operator&() -> &t
// otherwise -> std::addressof(t)
// ADL callable get_addressof(t) -> get_addressof(t)
// [default]
// no overloaded operator&() -> &t
// otherwise -> std::addressof(t)
//
template<typename T>
inline SPROUT_CONSTEXPR T*
addressof(T& t) SPROUT_NOEXCEPT {
return sprout_addressof_detail::call_get_addressof(t);
return sprout::address_traits<T>::get_addressof(t);
}
} // namespace sprout