mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-11-14 10:39:05 +00:00
fix sprout::tuples::get
This commit is contained in:
parent
9069a110e9
commit
196aa8dfbd
2 changed files with 104 additions and 13 deletions
|
@ -26,9 +26,11 @@
|
||||||
#ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
#ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
||||||
# define SPROUT_NOEXCEPT noexcept
|
# define SPROUT_NOEXCEPT noexcept
|
||||||
# define SPROUT_NOEXCEPT_EXPR(EXPR) noexcept(EXPR)
|
# define SPROUT_NOEXCEPT_EXPR(EXPR) noexcept(EXPR)
|
||||||
|
# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) noexcept(EXPR)
|
||||||
#else // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
#else // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
||||||
# define SPROUT_NOEXCEPT
|
# define SPROUT_NOEXCEPT
|
||||||
# define SPROUT_NOEXCEPT_EXPR(EXPR)
|
# define SPROUT_NOEXCEPT_EXPR(EXPR)
|
||||||
|
# define SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(EXPR, C) C
|
||||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
#endif // #ifndef SPROUT_CONFIG_DISABLE_NOEXCEPT
|
||||||
|
|
||||||
#ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES
|
#ifndef SPROUT_CONFIG_DISABLE_TEMPLATE_ALIASES
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type_traits/enabler_if.hpp>
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/tuple/tuple/tuple.hpp>
|
#include <sprout/tuple/tuple/tuple.hpp>
|
||||||
|
|
||||||
|
@ -50,19 +51,6 @@ namespace sprout {
|
||||||
: public sprout::tuples::tuple_element<I, T>
|
: public sprout::tuples::tuple_element<I, T>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
//
|
|
||||||
// get
|
|
||||||
//
|
|
||||||
template<std::size_t I, typename T>
|
|
||||||
inline SPROUT_CONSTEXPR auto
|
|
||||||
get(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::get<I>(sprout::forward<T>(t))))
|
|
||||||
-> decltype(std::get<I>(sprout::forward<T>(t)))
|
|
||||||
{
|
|
||||||
return std::get<I>(sprout::forward<T>(t));
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// get
|
|
||||||
//
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<std::size_t I, typename Head, typename... Tail>
|
template<std::size_t I, typename Head, typename... Tail>
|
||||||
inline SPROUT_CONSTEXPR typename std::add_lvalue_reference<Head>::type
|
inline SPROUT_CONSTEXPR typename std::add_lvalue_reference<Head>::type
|
||||||
|
@ -75,6 +63,9 @@ namespace sprout {
|
||||||
return sprout::tuples::detail::tuple_impl<I, Head, Tail...>::head(t);
|
return sprout::tuples::detail::tuple_impl<I, Head, Tail...>::head(t);
|
||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
//
|
||||||
|
// get
|
||||||
|
//
|
||||||
template<std::size_t I, typename... Types>
|
template<std::size_t I, typename... Types>
|
||||||
inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type&
|
inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type&
|
||||||
get(sprout::tuples::tuple<Types...>& t) SPROUT_NOEXCEPT {
|
get(sprout::tuples::tuple<Types...>& t) SPROUT_NOEXCEPT {
|
||||||
|
@ -94,6 +85,104 @@ namespace sprout {
|
||||||
}
|
}
|
||||||
} // namespace tuples
|
} // namespace tuples
|
||||||
|
|
||||||
|
namespace tuple_detail {
|
||||||
|
struct not_found_adl_get {};
|
||||||
|
|
||||||
|
template<std::size_t I>
|
||||||
|
sprout::tuple_detail::not_found_adl_get get(...);
|
||||||
|
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct has_std_get_test {
|
||||||
|
public:
|
||||||
|
template<
|
||||||
|
typename U = T,
|
||||||
|
typename = decltype(std::get<I>(std::declval<U>()))
|
||||||
|
>
|
||||||
|
static std::true_type test(int);
|
||||||
|
static std::false_type test(...);
|
||||||
|
};
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct has_std_get
|
||||||
|
: public decltype(sprout::tuple_detail::has_std_get_test<I, T>::test(0))
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct has_adl_get_test {
|
||||||
|
public:
|
||||||
|
template<
|
||||||
|
typename U = T,
|
||||||
|
typename sprout::enabler_if<
|
||||||
|
!std::is_same<decltype(get<I>(std::declval<U>())), sprout::tuple_detail::not_found_adl_get>::value
|
||||||
|
&& !sprout::tuple_detail::has_std_get<I, T>::value
|
||||||
|
>::type = sprout::enabler
|
||||||
|
>
|
||||||
|
static std::true_type test(int);
|
||||||
|
static std::false_type test(...);
|
||||||
|
};
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct has_adl_get
|
||||||
|
: public decltype(sprout::tuple_detail::has_adl_get_test<I, T>::test(0))
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename T, typename = void>
|
||||||
|
struct noexcept_get;
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct noexcept_get<I, T, typename std::enable_if<sprout::tuple_detail::has_adl_get<I, T>::value>::type>
|
||||||
|
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(get<I>(std::declval<T>()), false)>
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct noexcept_get<I, T, typename std::enable_if<sprout::tuple_detail::has_std_get<I, T>::value>::type>
|
||||||
|
: public std::integral_constant<bool, SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(std::get<I>(std::declval<T>()), false)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename T, typename = void>
|
||||||
|
struct get_result;
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct get_result<I, T, typename std::enable_if<sprout::tuple_detail::has_adl_get<I, T>::value>::type> {
|
||||||
|
public:
|
||||||
|
typedef decltype(get<I>(std::declval<T>())) type;
|
||||||
|
};
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct get_result<I, T, typename std::enable_if<sprout::tuple_detail::has_std_get<I, T>::value>::type> {
|
||||||
|
public:
|
||||||
|
typedef decltype(std::get<I>(std::declval<T>())) type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
std::size_t I, typename T,
|
||||||
|
typename sprout::enabler_if<sprout::tuple_detail::has_adl_get<I, T>::value>::type = sprout::enabler
|
||||||
|
>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::tuple_detail::get_result<I, T>::type
|
||||||
|
get_impl(T&& t)
|
||||||
|
SPROUT_NOEXCEPT_EXPR((sprout::tuple_detail::noexcept_get<I, T>::value))
|
||||||
|
{
|
||||||
|
return get<I>(sprout::forward<T>(t));
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
std::size_t I, typename T,
|
||||||
|
typename sprout::enabler_if<sprout::tuple_detail::has_std_get<I, T>::value>::type = sprout::enabler
|
||||||
|
>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::tuple_detail::get_result<I, T>::type
|
||||||
|
get_impl(T&& t)
|
||||||
|
SPROUT_NOEXCEPT_EXPR((sprout::tuple_detail::noexcept_get<I, T>::value))
|
||||||
|
{
|
||||||
|
return std::get<I>(sprout::forward<T>(t));
|
||||||
|
}
|
||||||
|
} // namespace tuple_detail
|
||||||
|
|
||||||
|
namespace tuples {
|
||||||
|
//
|
||||||
|
// get
|
||||||
|
//
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
inline SPROUT_CONSTEXPR typename sprout::tuple_detail::get_result<I, T>::type
|
||||||
|
get(T&& t)
|
||||||
|
SPROUT_NOEXCEPT_EXPR((sprout::tuple_detail::noexcept_get<I, T>::value))
|
||||||
|
{
|
||||||
|
return sprout::tuple_detail::get_impl<I>(sprout::forward<T>(t));
|
||||||
|
}
|
||||||
|
} // namespace tuples
|
||||||
|
|
||||||
using sprout::tuples::tuple_size;
|
using sprout::tuples::tuple_size;
|
||||||
using sprout::tuples::tuple_element;
|
using sprout::tuples::tuple_element;
|
||||||
using sprout::tuples::get;
|
using sprout::tuples::get;
|
||||||
|
|
Loading…
Reference in a new issue