mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2025-07-14 15:04:09 +00:00
add SFINAE: tuple flexibly construction
This commit is contained in:
parent
f905d1f02a
commit
a1c119a9bb
3 changed files with 107 additions and 33 deletions
|
@ -34,6 +34,12 @@ namespace testspr {
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::tuple<long, float>(1l, 1.0f));
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::flexibly_construct, 1l);
|
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::flexibly_construct, 1l);
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
|
@ -50,11 +56,6 @@ namespace testspr {
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::tuple<long, float>(1l, 1.0f));
|
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::flexibly_construct, sprout::tuples::tuple<long>(1l));
|
SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple<int, double>(sprout::tuples::flexibly_construct, sprout::tuples::tuple<long>(1l));
|
||||||
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
TESTSPR_BOTH_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
|
@ -78,24 +79,12 @@ namespace testspr {
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
auto tup3 = tup2;
|
|
||||||
tup3 = sprout::tuples::tuple<long>(1l);
|
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 0.0);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
auto tup3 = tup2;
|
auto tup3 = tup2;
|
||||||
tup3 = sprout::tuples::tuple<long, float>(1l, 1.0f);
|
tup3 = sprout::tuples::tuple<long, float>(1l, 1.0f);
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
auto tup3 = tup2;
|
|
||||||
tup3 = sprout::tuples::tuple<long, float, char>(1l, 1.0f, '-');
|
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1);
|
|
||||||
TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap
|
// swap
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,32 +69,47 @@ namespace sprout {
|
||||||
typename
|
typename
|
||||||
>
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::pair<UTypes...>&& t)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::pair<UTypes...>&& t)
|
||||||
: impl_type(sprout::move(t.first), sprout::move(t.second))
|
: impl_type(sprout::forward<typename sprout::pair<UTypes...>::first_type>(t.first), sprout::forward<typename sprout::pair<UTypes...>::second_type>(t.second))
|
||||||
{}
|
{}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements)
|
||||||
: impl_type(sprout::forward<UTypes>(elements)...)
|
: impl_type(sprout::forward<UTypes>(elements)...)
|
||||||
{}
|
{}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const& t)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const& t)
|
||||||
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...> const&>(t))
|
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...> const&>(t))
|
||||||
{}
|
{}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&& t)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&& t)
|
||||||
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
||||||
{}
|
{}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...> const& t)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...> const& t)
|
||||||
: impl_type(t.first, t.second)
|
: impl_type(t.first, t.second)
|
||||||
{}
|
{}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...>&& t)
|
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...>&& t)
|
||||||
: impl_type(sprout::move(t.first), sprout::move(t.second))
|
: impl_type(sprout::forward<typename sprout::pair<UTypes...>::first_type>(t.first), sprout::forward<typename sprout::pair<UTypes...>::second_type>(t.second))
|
||||||
{}
|
{}
|
||||||
// tuple assignment
|
// tuple assignment
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
|
@ -110,13 +125,19 @@ namespace sprout {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
sprout::tuples::tuple<Types...>& sprout::tuples::tuple<Types...>::operator=(sprout::tuples::tuple<UTypes...> const& rhs) {
|
sprout::tuples::tuple<Types...>& sprout::tuples::tuple<Types...>::operator=(sprout::tuples::tuple<UTypes...> const& rhs) {
|
||||||
static_cast<impl_type&>(*this) = rhs;
|
static_cast<impl_type&>(*this) = rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename
|
||||||
|
>
|
||||||
sprout::tuples::tuple<Types...>& sprout::tuples::tuple<Types...>::operator=(sprout::tuples::tuple<UTypes...>&& rhs) {
|
sprout::tuples::tuple<Types...>& sprout::tuples::tuple<Types...>::operator=(sprout::tuples::tuple<UTypes...>&& rhs) {
|
||||||
static_cast<impl_type&>(*this) = sprout::move(rhs);
|
static_cast<impl_type&>(*this) = sprout::move(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/index_tuple.hpp>
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/utility/move.hpp>
|
#include <sprout/utility/move.hpp>
|
||||||
#include <sprout/utility/swap.hpp>
|
#include <sprout/utility/swap.hpp>
|
||||||
|
#include <sprout/utility/pack.hpp>
|
||||||
#include <sprout/utility/pair/pair_fwd.hpp>
|
#include <sprout/utility/pair/pair_fwd.hpp>
|
||||||
#include <sprout/type_traits/is_convert_constructible.hpp>
|
#include <sprout/type_traits/is_convert_constructible.hpp>
|
||||||
#include <sprout/tpp/algorithm/all_of.hpp>
|
#include <sprout/tpp/algorithm/all_of.hpp>
|
||||||
|
@ -241,12 +243,39 @@ namespace sprout {
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type;
|
typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type;
|
||||||
|
private:
|
||||||
|
template<typename TndexTuple, typename... Utypes>
|
||||||
|
struct is_flexibly_constructible_impl;
|
||||||
|
template<sprout::index_t... Indexes, typename... Utypes>
|
||||||
|
struct is_flexibly_constructible_impl<sprout::index_tuple<Indexes...>, Utypes...>
|
||||||
|
: public sprout::tpp::all_of<
|
||||||
|
sprout::is_convert_constructible<
|
||||||
|
typename sprout::tppack_at<Indexes, Types...>::type,
|
||||||
|
typename sprout::tppack_at<Indexes, Utypes...>::type
|
||||||
|
>...
|
||||||
|
>
|
||||||
|
{};
|
||||||
public:
|
public:
|
||||||
struct has_nothrow_swap
|
struct has_nothrow_swap
|
||||||
: public sprout::tpp::all_of_c<
|
: public sprout::tpp::all_of_c<
|
||||||
SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::swap(std::declval<Types&>(), std::declval<Types&>()), false)...
|
SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::swap(std::declval<Types&>(), std::declval<Types&>()), false)...
|
||||||
>
|
>
|
||||||
{};
|
{};
|
||||||
|
template<typename... UTypes>
|
||||||
|
struct is_flexibly_constructible
|
||||||
|
: public is_flexibly_constructible_impl<
|
||||||
|
typename sprout::index_range<0, (sizeof...(UTypes) < sizeof...(Types) ? sizeof...(UTypes) : sizeof...(Types))>::type,
|
||||||
|
UTypes...
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
template<typename... UTypes>
|
||||||
|
struct is_rvref_flexibly_constructible
|
||||||
|
: public is_flexibly_constructible<UTypes&&...>
|
||||||
|
{};
|
||||||
|
template<typename... UTypes>
|
||||||
|
struct is_clvref_flexibly_constructible
|
||||||
|
: public is_flexibly_constructible<UTypes const&...>
|
||||||
|
{};
|
||||||
public:
|
public:
|
||||||
// tuple construction
|
// tuple construction
|
||||||
SPROUT_CONSTEXPR tuple();
|
SPROUT_CONSTEXPR tuple();
|
||||||
|
@ -288,23 +317,58 @@ namespace sprout {
|
||||||
>::type
|
>::type
|
||||||
>
|
>
|
||||||
SPROUT_CONSTEXPR tuple(sprout::pair<UTypes...>&& t);
|
SPROUT_CONSTEXPR tuple(sprout::pair<UTypes...>&& t);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
is_rvref_flexibly_constructible<UTypes...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements);
|
explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
is_clvref_flexibly_constructible<UTypes...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const& t);
|
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const& t);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
is_rvref_flexibly_constructible<UTypes...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&& t);
|
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&& t);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
is_clvref_flexibly_constructible<UTypes...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...> const& t);
|
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...> const& t);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
is_rvref_flexibly_constructible<UTypes...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...>&& t);
|
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UTypes...>&& t);
|
||||||
// tuple assignment
|
// tuple assignment
|
||||||
tuple& operator=(tuple const& rhs);
|
tuple& operator=(tuple const& rhs);
|
||||||
tuple& operator=(tuple&& rhs)
|
tuple& operator=(tuple&& rhs)
|
||||||
SPROUT_NOEXCEPT_EXPR(sprout::tpp::all_of<std::is_nothrow_move_assignable<Types>...>::value);
|
SPROUT_NOEXCEPT_EXPR(sprout::tpp::all_of<std::is_nothrow_move_assignable<Types>...>::value);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of<std::is_assignable<Types&, UTypes const&>...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
tuple& operator=(sprout::tuples::tuple<UTypes...> const& rhs);
|
tuple& operator=(sprout::tuples::tuple<UTypes...> const& rhs);
|
||||||
template<typename... UTypes>
|
template<
|
||||||
|
typename... UTypes,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of<std::is_assignable<Types&, UTypes&&>...>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
tuple& operator=(sprout::tuples::tuple<UTypes...>&& rhs);
|
tuple& operator=(sprout::tuples::tuple<UTypes...>&& rhs);
|
||||||
// tuple swap
|
// tuple swap
|
||||||
void swap(tuple& other)
|
void swap(tuple& other)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue