add typed sprout::get

This commit is contained in:
bolero-MURAKAMI 2015-04-10 19:54:05 +09:00
parent 530bc92d0c
commit 84b6d5d994
9 changed files with 190 additions and 4 deletions

View file

@ -193,6 +193,14 @@ namespace testspr {
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
}
// get
TESTSPR_BOTH_ASSERT(sprout::tuples::get<int>(tup1) == 1);
TESTSPR_BOTH_ASSERT(sprout::tuples::get<double>(tup1) == 1.0);
{
auto tup3 = tup1;
TESTSPR_ASSERT(sprout::tuples::get<int>(tup3) == 1);
TESTSPR_ASSERT(sprout::tuples::get<double>(tup3) == 1.0);
}
// tuple_size
TESTSPR_BOTH_ASSERT(sprout::tuples::tuple_size<decltype(tup1)>::value == 2);

View file

@ -19,6 +19,9 @@
#include <sprout/tuple/tuple/tuple_element.hpp>
#include <sprout/tuple/tuple/tuple_traits.hpp>
#include <sprout/tuple/tuple/tuple_access_traits.hpp>
#include <sprout/type/algorithm/find_index.hpp>
#include <sprout/type/algorithm/count.hpp>
#include <sprout/type_traits/remove_cvref.hpp>
#include <sprout/adl/not_found.hpp>
namespace sprout {
@ -107,6 +110,18 @@ namespace sprout {
return sprout_tuple_detail::call_tuple_get<I>(SPROUT_FORWARD(T, t));
}
//
// get
//
template<typename Type, typename T>
inline SPROUT_CONSTEXPR decltype(sprout::tuples::get<(sprout::types::find_index<typename sprout::remove_cvref<T>::type, Type>::value)>(std::declval<T>()))
get(T&& t)
SPROUT_NOEXCEPT_IF_EXPR(sprout::tuples::get<(sprout::types::find_index<typename sprout::remove_cvref<T>::type, Type>::value)>(std::declval<T>()))
{
static_assert(sprout::types::count<typename sprout::remove_cvref<T>::type, Type>::value == 1, "Requires: The type 'Type' occurs exactly once in type list.");
return sprout::tuples::get<(sprout::types::find_index<typename sprout::remove_cvref<T>::type, Type>::value)>(SPROUT_FORWARD(T, t));
}
//
// nested_get
//

View file

@ -11,6 +11,8 @@
#include <sprout/config.hpp>
#include <sprout/type/algorithm/find_index.hpp>
#include <sprout/type/algorithm/find_index_if.hpp>
#include <sprout/type/algorithm/count.hpp>
#include <sprout/type/algorithm/count_if.hpp>
#include <sprout/type/algorithm/lower_bound_index.hpp>
#include <sprout/type/algorithm/upper_bound_index.hpp>
#include <sprout/type/algorithm/fold.hpp>

View file

@ -19,7 +19,7 @@ namespace sprout {
//
template<typename Tuple, typename T>
struct contains
: public sprout::types::find_index<Tuple, T>::found
: public sprout::types::find_index<Tuple, T>::is_found
{};
#if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -19,7 +19,7 @@ namespace sprout {
//
template<typename Tuple, typename Predicate>
struct contains_if
: public sprout::types::find_index_if<Tuple, Predicate>::found
: public sprout::types::find_index_if<Tuple, Predicate>::is_found
{};
#if SPROUT_USE_TEMPLATE_ALIASES

View file

@ -0,0 +1,81 @@
/*=============================================================================
Copyright (c) 2011-2015 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under 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)
=============================================================================*/
#ifndef SPROUT_TYPE_ALGORITHM_COUNT_HPP
#define SPROUT_TYPE_ALGORITHM_COUNT_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type_traits/integral_constant.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename T, std::size_t First,
std::size_t Size,
bool C0 = (Size == 1)
>
struct count_impl;
template<
typename Tuple, typename T, std::size_t First,
std::size_t Size
>
struct count_impl<Tuple, T, First, Size, true>
: public sprout::integral_constant<
std::size_t, (std::is_same<typename sprout::types::tuple_element<First, Tuple>::type, T>::value ? 1 : 0)
>
{};
template<
typename Tuple, typename T, std::size_t First,
std::size_t Size
>
struct count_impl<Tuple, T, First, Size, false>
: public sprout::integral_constant<
std::size_t,
sprout::types::detail::count_impl<
Tuple, T, First,
Size / 2
>::value
+ sprout::types::detail::count_impl<
Tuple, T, First + Size / 2,
Size - Size / 2
>::value
>
{};
template<typename Tuple, typename T, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct count
: public sprout::types::detail::count_impl<Tuple, T, 0, Size>
{};
template<typename Tuple, typename T>
struct count<Tuple, T, 0>
: public sprout::integral_constant<std::size_t, 0>
{};
} // namespace detail
//
// count
//
template<typename Tuple, typename T>
struct count
: public sprout::types::detail::count<Tuple, T>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename T>
using count_t = typename sprout::types::count<Tuple, T>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename T>
SPROUT_STATIC_CONSTEXPR std::size_t count_v = sprout::types::count<Tuple, T>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_COUNT_HPP

View file

@ -0,0 +1,81 @@
/*=============================================================================
Copyright (c) 2011-2015 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under 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)
=============================================================================*/
#ifndef SPROUT_TYPE_ALGORITHM_COUNT_IF_HPP
#define SPROUT_TYPE_ALGORITHM_COUNT_IF_HPP
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/apply.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type_traits/integral_constant.hpp>
namespace sprout {
namespace types {
namespace detail {
template<
typename Tuple, typename Predicate, std::size_t First,
std::size_t Size,
bool C0 = (Size == 1)
>
struct count_if_impl;
template<
typename Tuple, typename Predicate, std::size_t First,
std::size_t Size
>
struct count_if_impl<Tuple, Predicate, First, Size, true>
: public sprout::integral_constant<
std::size_t, (sprout::types::apply<Predicate, typename sprout::types::tuple_element<First, Tuple>::type>::type::value ? 1 : 0)
>
{};
template<
typename Tuple, typename Predicate, std::size_t First,
std::size_t Size
>
struct count_if_impl<Tuple, Predicate, First, Size, false>
: public sprout::integral_constant<
std::size_t,
sprout::types::detail::count_if_impl<
Tuple, Predicate, First,
Size / 2
>::value
+ sprout::types::detail::count_if_impl<
Tuple, Predicate, First + Size / 2,
Size - Size / 2
>::value
>
{};
template<typename Tuple, typename Predicate, std::size_t Size = sprout::types::tuple_size<Tuple>::value>
struct count_if
: public sprout::types::detail::count_if_impl<Tuple, Predicate, 0, Size>
{};
template<typename Tuple, typename Predicate>
struct count_if<Tuple, Predicate, 0>
: public sprout::integral_constant<std::size_t, 0>
{};
} // namespace detail
//
// count_if
//
template<typename Tuple, typename Predicate>
struct count_if
: public sprout::types::detail::count_if<Tuple, Predicate>
{};
#if SPROUT_USE_TEMPLATE_ALIASES
template<typename Tuple, typename Predicate>
using count_if_t = typename sprout::types::count_if<Tuple, Predicate>::type;
#endif // #if SPROUT_USE_TEMPLATE_ALIASES
#if SPROUT_USE_VARIABLE_TEMPLATES
template<typename Tuple, typename Predicate>
SPROUT_STATIC_CONSTEXPR std::size_t count_if_v = sprout::types::count_if<Tuple, Predicate>::value;
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ALGORITHM_COUNT_IF_HPP

View file

@ -21,7 +21,7 @@ namespace sprout {
: public sprout::integral_constant<std::size_t, Found>
{
public:
typedef sprout::bool_constant<Found != sprout::types::tuple_size<Tuple>::value> found;
typedef sprout::bool_constant<Found != sprout::types::tuple_size<Tuple>::value> is_found;
};
} // namespace detail
} // namespace types

View file

@ -8,7 +8,6 @@
#ifndef SPROUT_TYPE_ALGORITHM_FIND_INDEX_IF_HPP
#define SPROUT_TYPE_ALGORITHM_FIND_INDEX_IF_HPP
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/workaround/std/cstddef.hpp>
#include <sprout/type/apply.hpp>