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

@ -8,6 +8,7 @@
#ifndef SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP #ifndef SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP
#define SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP #define SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP
#include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp> #include <sprout/workaround/std/cstddef.hpp>
#include <sprout/functional/hash/hash_fwd.hpp> #include <sprout/functional/hash/hash_fwd.hpp>
@ -17,7 +18,7 @@ namespace sprout {
// to_hash // to_hash
// //
// effect: // effect:
// sprout::hash_value_traits<T>::hash_value(v) // sprout::hash_value_traits<typename std::remove_reference<T>::type>::hash_value(v)
// [default] // [default]
// ADL callable hash_value(v) -> hash_value(v) // ADL callable hash_value(v) -> hash_value(v)
// [default] // [default]
@ -27,7 +28,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR std::size_t inline SPROUT_CONSTEXPR std::size_t
to_hash(T&& v) { to_hash(T&& v) {
return sprout::hash_value_traits<T>::hash_value(v); return sprout::hash_value_traits<typename std::remove_reference<T>::type>::hash_value(v);
} }
} // namespace sprout } // namespace sprout

View file

@ -16,6 +16,10 @@
#include <sprout/type_traits/integral_constant.hpp> #include <sprout/type_traits/integral_constant.hpp>
#include <sprout/adl/not_found.hpp> #include <sprout/adl/not_found.hpp>
namespace sprout_adl {
sprout::not_found_via_adl get_addressof(...);
} // namespace sprout_adl
namespace sprout { namespace sprout {
namespace detail { namespace detail {
struct address_op_helper {}; 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> template<typename T>
struct addressof_traits_default<T, true> { inline SPROUT_CONSTEXPR typename std::enable_if<
public: sprout::detail::has_address_op<T>::value,
template<typename U> T*
static U* >::type
get_addressof(U& t) SPROUT_NOEXCEPT { get_addressof_impl(T& t) SPROUT_NOEXCEPT {
return std::addressof(t); return std::addressof(t);
} }
};
template<typename T> template<typename T>
struct addressof_traits_default<T, false> { inline SPROUT_CONSTEXPR typename std::enable_if<
public: !sprout::detail::has_address_op<T>::value,
template<typename U> T*
static SPROUT_CONSTEXPR U* >::type
get_addressof(U& t) SPROUT_NOEXCEPT { get_addressof_impl(T& t) SPROUT_NOEXCEPT {
return &t; return &t;
} }
};
} // namespace detail } // 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 // address_traits
// //
template<typename T> template<typename T>
struct address_traits struct address_traits {
: public sprout::detail::addressof_traits_default<T> 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> template<typename T>
struct address_traits<T const> struct address_traits<T const>
: public sprout::address_traits<T> : public sprout::address_traits<T>
@ -115,33 +132,14 @@ namespace sprout {
{}; {};
} // 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 { namespace sprout {
// //
// addressof // addressof
// //
// effect: // effect:
// sprout::address_traits<T>::get_addressof(t)
// [default]
// ADL callable get_addressof(t) -> get_addressof(t) // ADL callable get_addressof(t) -> get_addressof(t)
// otherwise -> sprout::address_traits<T>::get_addressof(t)
// [default] // [default]
// no overloaded operator&() -> &t // no overloaded operator&() -> &t
// otherwise -> std::addressof(t) // otherwise -> std::addressof(t)
@ -149,7 +147,7 @@ namespace sprout {
template<typename T> template<typename T>
inline SPROUT_CONSTEXPR T* inline SPROUT_CONSTEXPR T*
addressof(T& t) SPROUT_NOEXCEPT { addressof(T& t) SPROUT_NOEXCEPT {
return sprout_addressof_detail::call_get_addressof(t); return sprout::address_traits<T>::get_addressof(t);
} }
} // namespace sprout } // namespace sprout

View file

@ -24,8 +24,6 @@ namespace sprout_adl {
} // namespace sprout_adl } // namespace sprout_adl
namespace sprout_tuple_detail { namespace sprout_tuple_detail {
using sprout_adl::tuple_get;
template<std::size_t I, typename T> template<std::size_t I, typename T>
inline SPROUT_CONSTEXPR decltype(std::get<I>(std::declval<T&>())) inline SPROUT_CONSTEXPR decltype(std::get<I>(std::declval<T&>()))
tuple_get(T& t) tuple_get(T& t)
@ -50,14 +48,6 @@ namespace sprout_tuple_detail {
{ {
return std::get<I>(t); return std::get<I>(t);
} }
template<std::size_t I, typename T>
inline SPROUT_CONSTEXPR decltype(tuple_get<I>(std::declval<T>()))
call_tuple_get(T&& t)
SPROUT_NOEXCEPT_IF_EXPR(tuple_get<I>(std::declval<T>()))
{
return tuple_get<I>(SPROUT_FORWARD(T, t));
}
} // namespace sprout_tuple_detail } // namespace sprout_tuple_detail
namespace sprout { namespace sprout {
@ -71,17 +61,23 @@ namespace sprout {
template<std::size_t I> template<std::size_t I>
static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple>::template lvalue_reference<I>::type static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple>::template lvalue_reference<I>::type
tuple_get(Tuple& t) SPROUT_NOEXCEPT { tuple_get(Tuple& t) SPROUT_NOEXCEPT {
return sprout_tuple_detail::call_tuple_get<I>(t); using sprout_tuple_detail::tuple_get;
using sprout_adl::tuple_get;
return tuple_get<I>(t);
} }
template<std::size_t I> template<std::size_t I>
static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple>::template rvalue_reference<I>::type static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple>::template rvalue_reference<I>::type
tuple_get(Tuple&& t) SPROUT_NOEXCEPT { tuple_get(Tuple&& t) SPROUT_NOEXCEPT {
return sprout_tuple_detail::call_tuple_get<I>(sprout::move(t)); using sprout_tuple_detail::tuple_get;
using sprout_adl::tuple_get;
return tuple_get<I>(sprout::move(t));
} }
template<std::size_t I> template<std::size_t I>
static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple const>::template lvalue_reference<I>::type static SPROUT_CONSTEXPR typename sprout::tuples::tuple_traits<Tuple const>::template lvalue_reference<I>::type
tuple_get(Tuple const& t) SPROUT_NOEXCEPT { tuple_get(Tuple const& t) SPROUT_NOEXCEPT {
return sprout_tuple_detail::call_tuple_get<I>(t); using sprout_tuple_detail::tuple_get;
using sprout_adl::tuple_get;
return tuple_get<I>(t);
} }
}; };
template<typename Tuple> template<typename Tuple>