diff --git a/libs/tuple/test/tuple.cpp b/libs/tuple/test/tuple.cpp index 82c414b2..b67aca1f 100644 --- a/libs/tuple/test/tuple.cpp +++ b/libs/tuple/test/tuple.cpp @@ -34,6 +34,12 @@ namespace testspr { 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(sprout::tuples::tuple(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(sprout::tuples::flexibly_construct, 1l); 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); } - { - SPROUT_STATIC_CONSTEXPR auto tup3 = sprout::tuples::tuple(sprout::tuples::tuple(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(sprout::tuples::flexibly_construct, sprout::tuples::tuple(1l)); 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<1>(tup3) == 1.0); } - { - auto tup3 = tup2; - tup3 = sprout::tuples::tuple(1l); - TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); - TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 0.0); - } { auto tup3 = tup2; tup3 = sprout::tuples::tuple(1l, 1.0f); TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); } - { - auto tup3 = tup2; - tup3 = sprout::tuples::tuple(1l, 1.0f, '-'); - TESTSPR_ASSERT(sprout::tuples::get<0>(tup3) == 1); - TESTSPR_ASSERT(sprout::tuples::get<1>(tup3) == 1.0); - } // swap { diff --git a/sprout/tuple/tuple/tuple.hpp b/sprout/tuple/tuple/tuple.hpp index bafddac3..15e7841d 100644 --- a/sprout/tuple/tuple/tuple.hpp +++ b/sprout/tuple/tuple/tuple.hpp @@ -69,32 +69,47 @@ namespace sprout { typename > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::pair&& t) - : impl_type(sprout::move(t.first), sprout::move(t.second)) + : impl_type(sprout::forward::first_type>(t.first), sprout::forward::second_type>(t.second)) {} template - template + template< + typename... UTypes, + typename + > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements) : impl_type(sprout::forward(elements)...) {} template - template + template< + typename... UTypes, + typename + > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t) : impl_type(static_cast const&>(t)) {} template - template + template< + typename... UTypes, + typename + > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t) : impl_type(static_cast&&>(t)) {} template - template + template< + typename... UTypes, + typename + > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::pair const& t) : impl_type(t.first, t.second) {} template - template + template< + typename... UTypes, + typename + > inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::pair&& t) - : impl_type(sprout::move(t.first), sprout::move(t.second)) + : impl_type(sprout::forward::first_type>(t.first), sprout::forward::second_type>(t.second)) {} // tuple assignment template @@ -110,13 +125,19 @@ namespace sprout { return *this; } template - template + template< + typename... UTypes, + typename + > sprout::tuples::tuple& sprout::tuples::tuple::operator=(sprout::tuples::tuple const& rhs) { static_cast(*this) = rhs; return *this; } template - template + template< + typename... UTypes, + typename + > sprout::tuples::tuple& sprout::tuples::tuple::operator=(sprout::tuples::tuple&& rhs) { static_cast(*this) = sprout::move(rhs); return *this; diff --git a/sprout/tuple/tuple/tuple_decl.hpp b/sprout/tuple/tuple/tuple_decl.hpp index 150aadba..8ef46639 100644 --- a/sprout/tuple/tuple/tuple_decl.hpp +++ b/sprout/tuple/tuple/tuple_decl.hpp @@ -6,9 +6,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -241,12 +243,39 @@ namespace sprout { { private: typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type; + private: + template + struct is_flexibly_constructible_impl; + template + struct is_flexibly_constructible_impl, Utypes...> + : public sprout::tpp::all_of< + sprout::is_convert_constructible< + typename sprout::tppack_at::type, + typename sprout::tppack_at::type + >... + > + {}; public: struct has_nothrow_swap : public sprout::tpp::all_of_c< SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::swap(std::declval(), std::declval()), false)... > {}; + template + 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 + struct is_rvref_flexibly_constructible + : public is_flexibly_constructible + {}; + template + struct is_clvref_flexibly_constructible + : public is_flexibly_constructible + {}; public: // tuple construction SPROUT_CONSTEXPR tuple(); @@ -288,23 +317,58 @@ namespace sprout { >::type > SPROUT_CONSTEXPR tuple(sprout::pair&& t); - template + template< + typename... UTypes, + typename = typename std::enable_if< + is_rvref_flexibly_constructible::value + >::type + > explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements); - template + template< + typename... UTypes, + typename = typename std::enable_if< + is_clvref_flexibly_constructible::value + >::type + > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t); - template + template< + typename... UTypes, + typename = typename std::enable_if< + is_rvref_flexibly_constructible::value + >::type + > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t); - template + template< + typename... UTypes, + typename = typename std::enable_if< + is_clvref_flexibly_constructible::value + >::type + > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair const& t); - template + template< + typename... UTypes, + typename = typename std::enable_if< + is_rvref_flexibly_constructible::value + >::type + > SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair&& t); // tuple assignment tuple& operator=(tuple const& rhs); tuple& operator=(tuple&& rhs) SPROUT_NOEXCEPT_EXPR(sprout::tpp::all_of...>::value); - template + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value + >::type + > tuple& operator=(sprout::tuples::tuple const& rhs); - template + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value + >::type + > tuple& operator=(sprout::tuples::tuple&& rhs); // tuple swap void swap(tuple& other)