mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
reimplementation tuple class
This commit is contained in:
parent
0c15b01b0d
commit
3b0ab6f5fd
11 changed files with 438 additions and 371 deletions
|
@ -36,7 +36,7 @@ Supported Compilers
|
|||
Linux:
|
||||
|
||||
* GCC, C++11/14 mode: 4.7.0, 4.7.1, 4.7.2, 4.7.3, 4.7.4, 4.8.0, 4.8.1, 4.8.2, 4.8.3, 4.9.0
|
||||
* Clang, C++11/14 mode: 3.2, 3.3, 3.4, 3.4.1
|
||||
* Clang, C++11/14 mode: 3.2, 3.3, 3.4, 3.4.1, 3.5.0
|
||||
|
||||
*******************************************************************************
|
||||
Author
|
||||
|
|
|
@ -10,47 +10,43 @@
|
|||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/type_traits/integral_constant.hpp>
|
||||
#include <sprout/type/type_tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace tpp {
|
||||
namespace detail {
|
||||
template<bool... Values>
|
||||
struct all_of_impl;
|
||||
template<>
|
||||
struct all_of_impl<>
|
||||
: public sprout::true_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last, bool = (Last - First == 1)>
|
||||
struct all_of_impl
|
||||
: public std::tuple_element<First, Tup>::type
|
||||
{};
|
||||
template<>
|
||||
struct all_of_impl<true>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
template<>
|
||||
struct all_of_impl<false>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct all_of_impl<true, Tail...>
|
||||
: public sprout::integral_constant<bool, sprout::tpp::detail::all_of_impl<Tail...>::value>
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct all_of_impl<false, Tail...>
|
||||
: public sprout::false_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last>
|
||||
struct all_of_impl<Tup, First, Last, false>
|
||||
: public sprout::integral_constant<
|
||||
bool,
|
||||
sprout::tpp::detail::all_of_impl<Tup, First, (First + Last) / 2>::value
|
||||
&& sprout::tpp::detail::all_of_impl<Tup, (First + Last) / 2, Last>::value
|
||||
>
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// all_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct all_of_c
|
||||
: public sprout::tpp::detail::all_of_impl<Values...>
|
||||
{};
|
||||
//
|
||||
// all_of
|
||||
//
|
||||
template<typename... Types>
|
||||
struct all_of
|
||||
: public sprout::tpp::all_of_c<Types::value...>
|
||||
: public sprout::tpp::detail::all_of_impl<sprout::types::type_tuple<Types...>, 0, sizeof...(Types)>
|
||||
{};
|
||||
template<>
|
||||
struct all_of<>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
//
|
||||
// all_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct all_of_c
|
||||
: public sprout::tpp::all_of<sprout::integral_constant<bool, Values>...>
|
||||
{};
|
||||
} // namespace tpp
|
||||
} // namespace sprout
|
||||
|
|
|
@ -8,48 +8,45 @@
|
|||
#ifndef SPROUT_TPP_ALGORITHM_ANY_OF_HPP
|
||||
#define SPROUT_TPP_ALGORITHM_ANY_OF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/type_traits/integral_constant.hpp>
|
||||
#include <sprout/type/type_tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace tpp {
|
||||
namespace detail {
|
||||
template<bool... Values>
|
||||
struct any_of_impl;
|
||||
template<>
|
||||
struct any_of_impl<>
|
||||
: public sprout::false_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last, bool = (Last - First == 1)>
|
||||
struct any_of_impl
|
||||
: public std::tuple_element<First, Tup>::type
|
||||
{};
|
||||
template<>
|
||||
struct any_of_impl<true>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
template<>
|
||||
struct any_of_impl<false>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct any_of_impl<true, Tail...>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct any_of_impl<false, Tail...>
|
||||
: public sprout::integral_constant<bool, sprout::tpp::detail::any_of_impl<Tail...>::value>
|
||||
template<typename Tup, std::size_t First, std::size_t Last>
|
||||
struct any_of_impl<Tup, First, Last, false>
|
||||
: public sprout::integral_constant<
|
||||
bool,
|
||||
sprout::tpp::detail::any_of_impl<Tup, First, (First + Last) / 2>::value
|
||||
|| sprout::tpp::detail::any_of_impl<Tup, (First + Last) / 2, Last>::value
|
||||
>
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// any_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct any_of_c
|
||||
: public sprout::tpp::detail::any_of_impl<Values...>
|
||||
{};
|
||||
//
|
||||
// any_of
|
||||
//
|
||||
template<typename... Types>
|
||||
struct any_of
|
||||
: public sprout::tpp::any_of_c<Types::value...>
|
||||
: public sprout::tpp::detail::any_of_impl<sprout::types::type_tuple<Types...>, 0, sizeof...(Types)>
|
||||
{};
|
||||
template<>
|
||||
struct any_of<>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
//
|
||||
// any_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct any_of_c
|
||||
: public sprout::tpp::any_of<sprout::integral_constant<bool, Values>...>
|
||||
{};
|
||||
} // namespace tpp
|
||||
} // namespace sprout
|
||||
|
|
|
@ -8,48 +8,45 @@
|
|||
#ifndef SPROUT_TPP_ALGORITHM_NONE_OF_HPP
|
||||
#define SPROUT_TPP_ALGORITHM_NONE_OF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/type_traits/integral_constant.hpp>
|
||||
#include <sprout/type/type_tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace tpp {
|
||||
namespace detail {
|
||||
template<bool... Values>
|
||||
struct none_of_impl;
|
||||
template<>
|
||||
struct none_of_impl<>
|
||||
: public sprout::true_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last, bool = (Last - First == 1)>
|
||||
struct none_of_impl
|
||||
: public sprout::integral_constant<bool, !std::tuple_element<First, Tup>::type::value>
|
||||
{};
|
||||
template<>
|
||||
struct none_of_impl<true>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
template<>
|
||||
struct none_of_impl<false>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct none_of_impl<true, Tail...>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct none_of_impl<false, Tail...>
|
||||
: public sprout::integral_constant<bool, sprout::tpp::detail::none_of_impl<Tail...>::value>
|
||||
template<typename Tup, std::size_t First, std::size_t Last>
|
||||
struct none_of_impl<Tup, First, Last, false>
|
||||
: public sprout::integral_constant<
|
||||
bool,
|
||||
sprout::tpp::detail::none_of_impl<Tup, First, (First + Last) / 2>::value
|
||||
&& sprout::tpp::detail::none_of_impl<Tup, (First + Last) / 2, Last>::value
|
||||
>
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// none_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct none_of_c
|
||||
: public sprout::tpp::detail::none_of_impl<Values...>
|
||||
{};
|
||||
//
|
||||
// none_of
|
||||
//
|
||||
template<typename... Types>
|
||||
struct none_of
|
||||
: public sprout::tpp::none_of_c<Types::value...>
|
||||
: public sprout::tpp::detail::none_of_impl<sprout::types::type_tuple<Types...>, 0, sizeof...(Types)>
|
||||
{};
|
||||
template<>
|
||||
struct none_of<>
|
||||
: public sprout::true_type
|
||||
{};
|
||||
//
|
||||
// none_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct none_of_c
|
||||
: public sprout::tpp::none_of<sprout::integral_constant<bool, Values>...>
|
||||
{};
|
||||
} // namespace tpp
|
||||
} // namespace sprout
|
||||
|
|
|
@ -8,50 +8,98 @@
|
|||
#ifndef SPROUT_TPP_ALGORITHM_ONE_OF_HPP
|
||||
#define SPROUT_TPP_ALGORITHM_ONE_OF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/tpp/algorithm/none_of.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/type_traits/integral_constant.hpp>
|
||||
#include <sprout/type/type_tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace tpp {
|
||||
namespace detail {
|
||||
template<bool... Values>
|
||||
struct one_of_impl;
|
||||
template<>
|
||||
struct one_of_impl<>
|
||||
: public sprout::false_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last, bool = (Last - First == 1)>
|
||||
struct one_of_impl_1
|
||||
: public sprout::integral_constant<bool, !std::tuple_element<First, Tup>::type::value>
|
||||
{};
|
||||
template<>
|
||||
struct one_of_impl<true>
|
||||
: public sprout::true_type
|
||||
template<typename Tup, std::size_t First, std::size_t Last>
|
||||
struct one_of_impl_1<Tup, First, Last, false>
|
||||
: public sprout::integral_constant<
|
||||
bool,
|
||||
sprout::tpp::detail::one_of_impl_1<Tup, First, (First + Last) / 2>::value
|
||||
&& sprout::tpp::detail::one_of_impl_1<Tup, (First + Last) / 2, Last>::value
|
||||
>
|
||||
{};
|
||||
template<>
|
||||
struct one_of_impl<false>
|
||||
: public sprout::false_type
|
||||
|
||||
template<typename Tup, std::size_t First, std::size_t Last, bool = (Last - First == 1)>
|
||||
struct one_of_impl
|
||||
: public std::tuple_element<First, Tup>::type
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct one_of_impl<true, Tail...>
|
||||
: public sprout::tpp::none_of_c<Tail...>
|
||||
{};
|
||||
template<bool... Tail>
|
||||
struct one_of_impl<false, Tail...>
|
||||
: public sprout::integral_constant<bool, sprout::tpp::detail::one_of_impl<Tail...>::value>
|
||||
template<typename Tup, std::size_t First, std::size_t Last>
|
||||
struct one_of_impl<Tup, First, Last, false>
|
||||
: public sprout::integral_constant<
|
||||
bool,
|
||||
sprout::tpp::detail::one_of_impl<Tup, First, (First + Last) / 2>::value
|
||||
? sprout::tpp::detail::one_of_impl_1<Tup, (First + Last) / 2, Last>::value
|
||||
: sprout::tpp::detail::one_of_impl<Tup, (First + Last) / 2, Last>::value
|
||||
>
|
||||
{};
|
||||
} // namespace detail
|
||||
//
|
||||
// one_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct one_of_c
|
||||
: public sprout::tpp::detail::one_of_impl<Values...>
|
||||
{};
|
||||
//
|
||||
// one_of
|
||||
//
|
||||
template<typename... Types>
|
||||
struct one_of
|
||||
: public sprout::tpp::one_of_c<Types::value...>
|
||||
: public sprout::tpp::detail::one_of_impl<sprout::types::type_tuple<Types...>, 0, sizeof...(Types)>
|
||||
{};
|
||||
template<>
|
||||
struct one_of<>
|
||||
: public sprout::false_type
|
||||
{};
|
||||
//
|
||||
// one_of_c
|
||||
//
|
||||
template<bool... Values>
|
||||
struct one_of_c
|
||||
: public sprout::tpp::one_of<sprout::integral_constant<bool, Values>...>
|
||||
{};
|
||||
// namespace detail {
|
||||
// template<bool... Values>
|
||||
// struct one_of_impl;
|
||||
// template<>
|
||||
// struct one_of_impl<>
|
||||
// : public sprout::false_type
|
||||
// {};
|
||||
// template<>
|
||||
// struct one_of_impl<true>
|
||||
// : public sprout::true_type
|
||||
// {};
|
||||
// template<>
|
||||
// struct one_of_impl<false>
|
||||
// : public sprout::false_type
|
||||
// {};
|
||||
// template<bool... Tail>
|
||||
// struct one_of_impl<true, Tail...>
|
||||
// : public sprout::tpp::none_of_c<Tail...>
|
||||
// {};
|
||||
// template<bool... Tail>
|
||||
// struct one_of_impl<false, Tail...>
|
||||
// : public sprout::integral_constant<bool, sprout::tpp::detail::one_of_impl<Tail...>::value>
|
||||
// {};
|
||||
// } // namespace detail
|
||||
// //
|
||||
// // one_of_c
|
||||
// //
|
||||
// template<bool... Values>
|
||||
// struct one_of_c
|
||||
// : public sprout::tpp::detail::one_of_impl<Values...>
|
||||
// {};
|
||||
// //
|
||||
// // one_of
|
||||
// //
|
||||
// template<typename... Types>
|
||||
// struct one_of
|
||||
// : public sprout::tpp::one_of_c<Types::value...>
|
||||
// {};
|
||||
} // namespace tpp
|
||||
} // namespace sprout
|
||||
|
||||
|
|
|
@ -23,36 +23,23 @@
|
|||
|
||||
namespace sprout {
|
||||
namespace tuples {
|
||||
namespace detail {
|
||||
template<std::size_t I, typename Head, typename... Tail>
|
||||
inline SPROUT_CONSTEXPR typename std::add_lvalue_reference<Head>::type
|
||||
get_helper(sprout::tuples::detail::tuple_impl<I, Head, Tail...>& t) SPROUT_NOEXCEPT {
|
||||
return sprout::tuples::detail::tuple_impl<I, Head, Tail...>::head(t);
|
||||
}
|
||||
template<std::size_t I, typename Head, typename... Tail>
|
||||
inline SPROUT_CONSTEXPR typename std::add_lvalue_reference<typename std::add_const<Head>::type>::type
|
||||
get_helper(sprout::tuples::detail::tuple_impl<I, Head, Tail...> const& t) SPROUT_NOEXCEPT {
|
||||
return sprout::tuples::detail::tuple_impl<I, Head, Tail...>::head(t);
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// tuple_get
|
||||
//
|
||||
template<std::size_t I, typename... Types>
|
||||
inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type&
|
||||
tuple_get(sprout::tuples::tuple<Types...>& t) SPROUT_NOEXCEPT {
|
||||
return sprout::tuples::detail::get_helper<I>(t);
|
||||
return sprout::tuples::detail::tuple_access<Types...>::template get<I>(t);
|
||||
}
|
||||
template<std::size_t I, typename... Types>
|
||||
inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type&&
|
||||
tuple_get(sprout::tuples::tuple<Types...>&& t) SPROUT_NOEXCEPT {
|
||||
typedef typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type type;
|
||||
return SPROUT_FORWARD(type, sprout::tuples::tuple_get<I>(t));
|
||||
return sprout::tuples::detail::tuple_access<Types...>::template get<I>(sprout::move(t));
|
||||
}
|
||||
template<std::size_t I, typename... Types>
|
||||
inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::tuples::tuple<Types...> >::type const&
|
||||
tuple_get(sprout::tuples::tuple<Types...> const& t) SPROUT_NOEXCEPT {
|
||||
return sprout::tuples::detail::get_helper<I>(t);
|
||||
return sprout::tuples::detail::tuple_access<Types...>::template get<I>(t);
|
||||
}
|
||||
} // namespace tuples
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sprout/config.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/utility/pair/pair_decl.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/tuple/tuple/tuple_decl.hpp>
|
||||
#include <sprout/tuple/flexibly_construct.hpp>
|
||||
|
||||
|
@ -26,7 +27,7 @@ namespace sprout {
|
|||
typename
|
||||
>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::pair<UType1, UType2> const& t)
|
||||
: impl_type(t.first, t.second)
|
||||
: base_type(t.first, t.second)
|
||||
{}
|
||||
template<typename... Types>
|
||||
template<
|
||||
|
@ -34,7 +35,7 @@ namespace sprout {
|
|||
typename
|
||||
>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::pair<UType1, UType2>&& t)
|
||||
: impl_type(SPROUT_FORWARD(UType1, t.first), SPROUT_FORWARD(UType2, t.second))
|
||||
: base_type(SPROUT_FORWARD(UType1, t.first), SPROUT_FORWARD(UType2, t.second))
|
||||
{}
|
||||
|
||||
template<typename... Types>
|
||||
|
@ -43,7 +44,12 @@ namespace sprout {
|
|||
typename
|
||||
>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2> const& t)
|
||||
: impl_type(t.first, t.second)
|
||||
: base_type(
|
||||
sprout::tuples::flexibly_construct_t(),
|
||||
sprout::index_range<0, 2>::make(),
|
||||
sprout::index_range<2, sizeof...(Types)>::make(),
|
||||
t.first, t.second
|
||||
)
|
||||
{}
|
||||
template<typename... Types>
|
||||
template<
|
||||
|
@ -51,7 +57,12 @@ namespace sprout {
|
|||
typename
|
||||
>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<Types...>::tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2>&& t)
|
||||
: impl_type(SPROUT_FORWARD(UType1, t.first), SPROUT_FORWARD(UType2, t.second))
|
||||
: base_type(
|
||||
sprout::tuples::flexibly_construct_t(),
|
||||
sprout::index_range<0, 2>::make(),
|
||||
sprout::index_range<2, sizeof...(Types)>::make(),
|
||||
SPROUT_FORWARD(UType1, t.first), SPROUT_FORWARD(UType2, t.second)
|
||||
)
|
||||
{}
|
||||
// tuple assignment
|
||||
template<typename... Types>
|
||||
|
@ -61,8 +72,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CXX14_CONSTEXPR sprout::tuples::tuple<Types...>&
|
||||
sprout::tuples::tuple<Types...>::operator=(sprout::pair<UType1, UType2> const& rhs) {
|
||||
sprout::tuples::detail::tuple_impl<0, Types...>::head(*this) = rhs.first;
|
||||
sprout::tuples::detail::tuple_impl<1, Types...>::head(*this) = rhs.second;
|
||||
base_type::template get<0>(*this) = rhs.first;
|
||||
base_type::template get<1>(*this) = rhs.second;
|
||||
return *this;
|
||||
}
|
||||
template<typename... Types>
|
||||
|
@ -72,8 +83,8 @@ namespace sprout {
|
|||
>
|
||||
inline SPROUT_CXX14_CONSTEXPR sprout::tuples::tuple<Types...>&
|
||||
sprout::tuples::tuple<Types...>::operator=(sprout::pair<UType1, UType2>&& rhs) {
|
||||
sprout::tuples::detail::tuple_impl<0, Types...>::head(*this) = sprout::move(rhs.first);
|
||||
sprout::tuples::detail::tuple_impl<1, Types...>::head(*this) = sprout::move(rhs.second);
|
||||
base_type::template get<0>(*this) = sprout::move(rhs.first);
|
||||
base_type::template get<1>(*this) = sprout::move(rhs.second);
|
||||
return *this;
|
||||
}
|
||||
} // namespace tuples
|
||||
|
|
|
@ -8,20 +8,22 @@
|
|||
#ifndef SPROUT_TUPLE_TUPLE_TUPLE_DECL_HPP
|
||||
#define SPROUT_TUPLE_TUPLE_TUPLE_DECL_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/detail/predef.hpp>
|
||||
#include <sprout/detail/nil_base.hpp>
|
||||
#include <sprout/index_tuple/metafunction.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/utility/move.hpp>
|
||||
#include <sprout/utility/swap.hpp>
|
||||
#include <sprout/utility/eat.hpp>
|
||||
#include <sprout/utility/pack.hpp>
|
||||
#include <sprout/utility/pair/pair_fwd.hpp>
|
||||
#include <sprout/type_traits/integral_constant.hpp>
|
||||
#include <sprout/type_traits/is_convert_constructible.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
#include <sprout/tpp/algorithm/all_of.hpp>
|
||||
#include <sprout/tuple/tuple/tuple_fwd.hpp>
|
||||
#include <sprout/tuple/flexibly_construct.hpp>
|
||||
|
@ -29,244 +31,170 @@
|
|||
namespace sprout {
|
||||
namespace tuples {
|
||||
namespace detail {
|
||||
template<typename Dummy, typename T, T Value>
|
||||
struct dummy_integral_constant
|
||||
: public sprout::integral_constant<T, Value>
|
||||
{};
|
||||
template<typename... Types>
|
||||
class tuple_access;
|
||||
|
||||
template<std::size_t Index, typename Head, bool IsEmpty>
|
||||
class head_base;
|
||||
// EBO disabled
|
||||
// template<std::size_t Index, typename Head>
|
||||
// class head_base<Index, Head, true>
|
||||
// : public Head
|
||||
// {
|
||||
// public:
|
||||
// static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
||||
// return t;
|
||||
// }
|
||||
// static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
||||
// return t;
|
||||
// }
|
||||
// public:
|
||||
// SPROUT_CONSTEXPR head_base()
|
||||
// : Head()
|
||||
// {}
|
||||
// SPROUT_CONSTEXPR head_base(Head const& v)
|
||||
// : Head(v)
|
||||
// {}
|
||||
// template<typename UHead>
|
||||
// explicit SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||
// : Head(SPROUT_FORWARD(UHead, v))
|
||||
// {}
|
||||
// };
|
||||
template<std::size_t Index, typename Head>
|
||||
class head_base<Index, Head, true> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
||||
return t.head_;
|
||||
}
|
||||
static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
||||
return t.head_;
|
||||
}
|
||||
private:
|
||||
Head head_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR head_base()
|
||||
: head_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR head_base(Head const& v)
|
||||
: head_(v)
|
||||
{}
|
||||
template<typename UHead>
|
||||
explicit SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||
: head_(SPROUT_FORWARD(UHead, v))
|
||||
{}
|
||||
};
|
||||
template<std::size_t Index, typename Head>
|
||||
class head_base<Index, Head, false> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
||||
return t.head_;
|
||||
}
|
||||
static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
||||
return t.head_;
|
||||
}
|
||||
private:
|
||||
Head head_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR head_base()
|
||||
: head_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR head_base(Head const& v)
|
||||
: head_(v)
|
||||
{}
|
||||
template<typename UHead>
|
||||
explicit SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||
: head_(SPROUT_FORWARD(UHead, v))
|
||||
{}
|
||||
};
|
||||
struct from_tuple_construct_t {};
|
||||
struct few_construct_t {};
|
||||
struct excess_construct_t {};
|
||||
|
||||
template<std::size_t Index, typename... Types>
|
||||
class tuple_impl;
|
||||
template<std::size_t Index>
|
||||
class tuple_impl<Index> {
|
||||
template<sprout::index_t I, typename IdentityType>
|
||||
struct element_holder {
|
||||
public:
|
||||
template<typename...>
|
||||
friend class tuple;
|
||||
template<std::size_t, typename...>
|
||||
friend class sprout::tuples::detail::tuple_impl;
|
||||
typedef typename IdentityType::type value_type;
|
||||
private:
|
||||
value_type value_;
|
||||
public:
|
||||
explicit SPROUT_CONSTEXPR element_holder()
|
||||
: value_()
|
||||
{}
|
||||
element_holder(element_holder const&) = default;
|
||||
element_holder(element_holder&&) = default;
|
||||
template<typename T>
|
||||
explicit SPROUT_CONSTEXPR element_holder(T&& value)
|
||||
: value_(SPROUT_FORWARD(T, value))
|
||||
{}
|
||||
protected:
|
||||
SPROUT_CXX14_CONSTEXPR void swap(tuple_impl&) SPROUT_NOEXCEPT {}
|
||||
public:
|
||||
SPROUT_CONSTEXPR tuple_impl() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
|
||||
template<typename... UTypes>
|
||||
explicit SPROUT_CONSTEXPR tuple_impl(UTypes&&...) SPROUT_NOEXCEPT {}
|
||||
tuple_impl(tuple_impl const&) = default;
|
||||
tuple_impl(tuple_impl&&) = default;
|
||||
template<typename... UTypes>
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UTypes...> const&) SPROUT_NOEXCEPT {}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UTypes...>&&) SPROUT_NOEXCEPT {}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(tuple_impl const&) SPROUT_NOEXCEPT {
|
||||
return *this;
|
||||
static SPROUT_CONSTEXPR value_type&
|
||||
get(element_holder& t) {
|
||||
return t.value_;
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(tuple_impl&&) SPROUT_NOEXCEPT {
|
||||
return *this;
|
||||
static SPROUT_CONSTEXPR value_type&&
|
||||
get(element_holder&& t) {
|
||||
return sprout::move(t.value_);
|
||||
}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UTypes...> const&) SPROUT_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UTypes...>&&) SPROUT_NOEXCEPT {
|
||||
return *this;
|
||||
static SPROUT_CONSTEXPR value_type const&
|
||||
get(element_holder const& t) {
|
||||
return t.value_;
|
||||
}
|
||||
};
|
||||
template<std::size_t Index, typename Head, typename... Tail>
|
||||
class tuple_impl<Index, Head, Tail...>
|
||||
: public sprout::tuples::detail::tuple_impl<Index + 1, Tail...>
|
||||
, private sprout::tuples::detail::head_base<Index, Head, std::is_empty<Head>::value>
|
||||
|
||||
template<typename IndexTuple, typename... Types>
|
||||
class tuple_base;
|
||||
template<sprout::index_t... Indexes, typename... Types>
|
||||
class tuple_base<sprout::index_tuple<Indexes...>, Types...>
|
||||
: public sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >...
|
||||
{
|
||||
template<typename IndexTuple, typename... UTypes>
|
||||
friend class sprout::tuples::detail::tuple_base;
|
||||
protected:
|
||||
template<sprout::index_t I, typename IdentityType>
|
||||
static IdentityType element_helper(sprout::tuples::detail::element_holder<I, IdentityType> const&);
|
||||
template<sprout::index_t I>
|
||||
static sprout::detail::nil_base element_helper(...);
|
||||
template<std::size_t I>
|
||||
struct element
|
||||
: public sprout::identity<decltype(element_helper<I>(std::declval<tuple_base>()))>::type
|
||||
{};
|
||||
struct size
|
||||
: public sprout::integral_constant<std::size_t, sizeof...(Types)>
|
||||
{};
|
||||
public:
|
||||
template<typename...>
|
||||
friend class tuple;
|
||||
template<std::size_t, typename...>
|
||||
friend class sprout::tuples::detail::tuple_impl;
|
||||
public:
|
||||
typedef sprout::tuples::detail::tuple_impl<Index + 1, Tail...> inherited_type;
|
||||
typedef sprout::tuples::detail::head_base<Index, Head, std::is_empty<Head>::value> base_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR Head& head(tuple_impl& t) SPROUT_NOEXCEPT {
|
||||
return base_type::head(t);
|
||||
}
|
||||
static SPROUT_CONSTEXPR Head const& head(tuple_impl const& t) SPROUT_NOEXCEPT {
|
||||
return base_type::head(t);
|
||||
}
|
||||
static SPROUT_CONSTEXPR inherited_type& tail(tuple_impl& t) SPROUT_NOEXCEPT {
|
||||
return t;
|
||||
}
|
||||
static SPROUT_CONSTEXPR inherited_type const& tail(tuple_impl const& t) SPROUT_NOEXCEPT {
|
||||
return t;
|
||||
}
|
||||
public:
|
||||
SPROUT_CXX14_CONSTEXPR void swap(tuple_impl& t)
|
||||
SPROUT_NOEXCEPT_IF(
|
||||
SPROUT_NOEXCEPT_EXPR(sprout::swap(head(std::declval<tuple_impl&>()), head(t)))
|
||||
&& SPROUT_NOEXCEPT_EXPR(std::declval<inherited_type&>().swap(tail(t)))
|
||||
)
|
||||
{
|
||||
sprout::swap(head(*this), head(t));
|
||||
inherited_type::swap(tail(t));
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR tuple_impl()
|
||||
: inherited_type()
|
||||
, base_type()
|
||||
SPROUT_CONSTEXPR tuple_base()
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >()...
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR tuple_impl(Head const& h, Tail const&... tail)
|
||||
: inherited_type(tail...)
|
||||
, base_type(h)
|
||||
{}
|
||||
template<typename UHead, typename... UTail>
|
||||
explicit SPROUT_CONSTEXPR tuple_impl(UHead&& h, UTail&&... tail)
|
||||
: inherited_type(SPROUT_FORWARD(UTail, tail)...)
|
||||
, base_type(SPROUT_FORWARD(UHead, h))
|
||||
{}
|
||||
tuple_impl(tuple_impl const&) = default;
|
||||
#if SPROUT_GCC_IN_RANGE((4, 8, 0), (4, 8, 2))
|
||||
tuple_impl(tuple_impl&&) = default;
|
||||
#else
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t)
|
||||
SPROUT_NOEXCEPT_IF(std::is_nothrow_move_constructible<Head>::value && std::is_nothrow_move_constructible<inherited_type>::value)
|
||||
: inherited_type(sprout::move(tail(t)))
|
||||
, base_type(SPROUT_FORWARD(Head, head(t)))
|
||||
{}
|
||||
#endif
|
||||
template<typename... UTypes>
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UTypes...> const& t)
|
||||
: inherited_type(sprout::tuples::detail::tuple_impl<Index, UTypes...>::tail(t))
|
||||
, base_type(sprout::tuples::detail::tuple_impl<Index, UTypes...>::head(t))
|
||||
explicit SPROUT_CONSTEXPR tuple_base(UTypes&&... args)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(SPROUT_FORWARD(UTypes, args))...
|
||||
{}
|
||||
template<typename UHead, typename... UTail>
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UHead, UTail...>&& t)
|
||||
: inherited_type(sprout::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t)))
|
||||
, base_type(SPROUT_FORWARD(UHead, (sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t))))
|
||||
template<typename Tuple>
|
||||
SPROUT_CONSTEXPR tuple_base(sprout::tuples::detail::from_tuple_construct_t, Tuple&& t)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(std::decay<Tuple>::type::template get<Indexes>(SPROUT_FORWARD(Tuple, t)))...
|
||||
{}
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index> const&)
|
||||
: inherited_type()
|
||||
, base_type()
|
||||
|
||||
template<
|
||||
typename... UTypes, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) == sizeof...(UTypes))>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, UTypes&&... args)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(SPROUT_FORWARD(UTypes, args))...
|
||||
{}
|
||||
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index>&&)
|
||||
: inherited_type()
|
||||
, base_type()
|
||||
template<
|
||||
typename... UTypes, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) > sizeof...(UTypes))>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, UTypes&&... args)
|
||||
: sprout::tuples::detail::element_holder<Is, sprout::identity<typename sprout::pack_element<Is, Types...>::type> >(SPROUT_FORWARD(UTypes, args))...
|
||||
, sprout::tuples::detail::element_holder<Js, sprout::identity<typename sprout::pack_element<Js, Types...>::type> >()...
|
||||
{}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(tuple_impl const& t) {
|
||||
head(*this) = head(t);
|
||||
tail(*this) = tail(t);
|
||||
return *this;
|
||||
template<
|
||||
typename... UTypes, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) < sizeof...(UTypes))>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, UTypes&&... args)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(sprout::pack_get<Indexes>(SPROUT_FORWARD(UTypes, args)...))...
|
||||
{}
|
||||
|
||||
template<
|
||||
typename Tuple, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) == std::decay<Tuple>::type::size::value)>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::detail::from_tuple_construct_t, sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, Tuple&& t)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(std::decay<Tuple>::type::template get<Indexes>(SPROUT_FORWARD(Tuple, t)))...
|
||||
{}
|
||||
template<
|
||||
typename Tuple, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) > std::decay<Tuple>::type::size::value)>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::detail::from_tuple_construct_t, sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, Tuple&& t)
|
||||
: sprout::tuples::detail::element_holder<Is, sprout::identity<typename sprout::pack_element<Is, Types...>::type> >(std::decay<Tuple>::type::template get<Is>(SPROUT_FORWARD(Tuple, t)))...
|
||||
, sprout::tuples::detail::element_holder<Js, sprout::identity<typename sprout::pack_element<Js, Types...>::type> >()...
|
||||
{}
|
||||
template<
|
||||
typename Tuple, sprout::index_t... Is, sprout::index_t... Js,
|
||||
typename sprout::enabler_if<(sizeof...(Types) < std::decay<Tuple>::type::size::value)>::type = sprout::enabler
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple_base(sprout::tuples::detail::from_tuple_construct_t, sprout::tuples::flexibly_construct_t, sprout::index_tuple<Is...>, sprout::index_tuple<Js...>, Tuple&& t)
|
||||
: sprout::tuples::detail::element_holder<Indexes, sprout::identity<Types> >(std::decay<Tuple>::type::template get<Indexes>(SPROUT_FORWARD(Tuple, t)))...
|
||||
{}
|
||||
private:
|
||||
template<std::size_t I, typename IdentityType>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&
|
||||
get_impl(sprout::tuples::detail::element_holder<I, IdentityType>& value) {
|
||||
return sprout::tuples::detail::element_holder<I, IdentityType>::get(value);
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(tuple_impl&& t)
|
||||
SPROUT_NOEXCEPT_IF(std::is_nothrow_move_assignable<Head>::value && std::is_nothrow_move_assignable<inherited_type>::value)
|
||||
{
|
||||
head(*this) = SPROUT_FORWARD(Head, head(t));
|
||||
tail(*this) = sprout::move(tail(t));
|
||||
return *this;
|
||||
template<std::size_t I, typename IdentityType>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&&
|
||||
get_impl(sprout::tuples::detail::element_holder<I, IdentityType>&& value) {
|
||||
return sprout::tuples::detail::element_holder<I, IdentityType>::get(sprout::move(value));
|
||||
}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UTypes...> const& t) {
|
||||
head(*this) = sprout::tuples::detail::tuple_impl<Index, UTypes...>::head(t);
|
||||
tail(*this) = sprout::tuples::detail::tuple_impl<Index, UTypes...>::tail(t);
|
||||
return *this;
|
||||
template<std::size_t I, typename IdentityType>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type const&
|
||||
get_impl(sprout::tuples::detail::element_holder<I, IdentityType> const& value) {
|
||||
return sprout::tuples::detail::element_holder<I, IdentityType>::get(value);
|
||||
}
|
||||
template<typename UHead, typename... UTail>
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>&& t) {
|
||||
head(*this) = SPROUT_FORWARD(UHead, (sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t)));
|
||||
tail(*this) = sprout::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t));
|
||||
return *this;
|
||||
protected:
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&
|
||||
get(tuple_base& t) {
|
||||
return get_impl<I>(t);
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index> const&) {
|
||||
*this = sprout::move(tuple_impl());
|
||||
return *this;
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&&
|
||||
get(tuple_base&& t) {
|
||||
return get_impl<I>(sprout::move(t));
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index>&&) {
|
||||
*this = sprout::move(tuple_impl());
|
||||
return *this;
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type const&
|
||||
get(tuple_base const& t) {
|
||||
return get_impl<I>(t);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// tuple
|
||||
//
|
||||
template<typename... Types>
|
||||
class tuple
|
||||
: public sprout::tuples::detail::tuple_impl<0, Types...>
|
||||
: public sprout::tuples::detail::tuple_base<typename sprout::make_index_tuple<sizeof...(Types)>::type, Types...>
|
||||
{
|
||||
template<typename... UTypes>
|
||||
friend class sprout::tuples::tuple;
|
||||
template<typename... UTypes>
|
||||
friend class sprout::tuples::detail::tuple_access;
|
||||
private:
|
||||
typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type;
|
||||
typedef typename sprout::make_index_tuple<sizeof...(Types)>::type index_tuple_type;
|
||||
typedef sprout::tuples::detail::tuple_base<index_tuple_type, Types...> base_type;
|
||||
private:
|
||||
template<typename TndexTuple, typename... Utypes>
|
||||
template<typename IndexTuple, typename... Utypes>
|
||||
struct is_flexibly_convert_constructible_impl;
|
||||
template<sprout::index_t... Indexes, typename... Utypes>
|
||||
struct is_flexibly_convert_constructible_impl<sprout::index_tuple<Indexes...>, Utypes...>
|
||||
|
@ -278,7 +206,7 @@ namespace sprout {
|
|||
>
|
||||
{};
|
||||
|
||||
template<typename TndexTuple, typename... Utypes>
|
||||
template<typename IndexTuple, typename... Utypes>
|
||||
struct is_flexibly_assignable_impl;
|
||||
template<sprout::index_t... Indexes, typename... Utypes>
|
||||
struct is_flexibly_assignable_impl<sprout::index_tuple<Indexes...>, Utypes...>
|
||||
|
@ -353,13 +281,30 @@ namespace sprout {
|
|||
struct is_clvref_fixedly_assignable
|
||||
: public is_fixedly_assignable<UTypes const&...>
|
||||
{};
|
||||
private:
|
||||
template<sprout::index_t... Indexes>
|
||||
SPROUT_CXX14_CONSTEXPR void
|
||||
swap_impl(tuple& other, sprout::index_tuple<Indexes...>) {
|
||||
sprout::eat((sprout::swap(base_type::template get<Indexes>(*this), base_type::template get<Indexes>(other)), 0)...);
|
||||
}
|
||||
template<typename Tuple>
|
||||
SPROUT_CXX14_CONSTEXPR void
|
||||
assign(Tuple&& t) {
|
||||
assign_impl(SPROUT_FORWARD(Tuple, t), index_tuple_type());
|
||||
}
|
||||
template<typename Tuple, sprout::index_t... Indexes>
|
||||
SPROUT_CXX14_CONSTEXPR void
|
||||
assign_impl(Tuple&& t, sprout::index_tuple<Indexes...>) {
|
||||
typedef typename std::decay<Tuple>::type type;
|
||||
sprout::eat((sprout::eat(base_type::template get<Indexes>(*this) = sprout::move(type::template get<Indexes>(SPROUT_FORWARD(Tuple, t)))), 0)...);
|
||||
}
|
||||
public:
|
||||
// tuple construction
|
||||
SPROUT_CONSTEXPR tuple()
|
||||
: impl_type()
|
||||
: base_type()
|
||||
{}
|
||||
explicit SPROUT_CONSTEXPR tuple(Types const&... elements)
|
||||
: impl_type(elements...)
|
||||
: base_type(elements...)
|
||||
{}
|
||||
template<
|
||||
typename... UTypes,
|
||||
|
@ -368,7 +313,7 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple(UTypes&&... elements)
|
||||
: impl_type(SPROUT_FORWARD(UTypes, elements)...)
|
||||
: base_type(SPROUT_FORWARD(UTypes, elements)...)
|
||||
{}
|
||||
tuple(tuple const&) = default;
|
||||
tuple(tuple&&) = default;
|
||||
|
@ -379,7 +324,7 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...> const& t)
|
||||
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...> const&>(t))
|
||||
: base_type(sprout::tuples::detail::from_tuple_construct_t(), t)
|
||||
{}
|
||||
template<
|
||||
typename... UTypes,
|
||||
|
@ -388,7 +333,7 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...>&& t)
|
||||
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
||||
: base_type(sprout::tuples::detail::from_tuple_construct_t(), sprout::move(t))
|
||||
{}
|
||||
template<
|
||||
typename UType1, typename UType2,
|
||||
|
@ -404,7 +349,6 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
SPROUT_CONSTEXPR tuple(sprout::pair<UType1, UType2>&& t);
|
||||
|
||||
template<
|
||||
typename... UTypes,
|
||||
typename = typename std::enable_if<
|
||||
|
@ -412,7 +356,12 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements)
|
||||
: impl_type(SPROUT_FORWARD(UTypes, elements)...)
|
||||
: base_type(
|
||||
sprout::tuples::flexibly_construct_t(),
|
||||
sprout::index_range<0, sizeof...(UTypes)>::make(),
|
||||
sprout::index_range<sizeof...(UTypes), sizeof...(Types)>::make(),
|
||||
SPROUT_FORWARD(UTypes, elements)...
|
||||
)
|
||||
{}
|
||||
template<
|
||||
typename... UTypes,
|
||||
|
@ -421,8 +370,14 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
SPROUT_CONSTEXPR 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))
|
||||
: base_type(
|
||||
sprout::tuples::detail::from_tuple_construct_t(), sprout::tuples::flexibly_construct_t(),
|
||||
sprout::index_range<0, sizeof...(UTypes)>::make(),
|
||||
sprout::index_range<sizeof...(UTypes), sizeof...(Types)>::make(),
|
||||
t
|
||||
)
|
||||
{}
|
||||
|
||||
template<
|
||||
typename... UTypes,
|
||||
typename = typename std::enable_if<
|
||||
|
@ -430,7 +385,12 @@ namespace sprout {
|
|||
>::type
|
||||
>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&& t)
|
||||
: impl_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
|
||||
: base_type(
|
||||
sprout::tuples::detail::from_tuple_construct_t(), sprout::tuples::flexibly_construct_t(),
|
||||
sprout::index_range<0, sizeof...(UTypes)>::make(),
|
||||
sprout::index_range<sizeof...(UTypes), sizeof...(Types)>::make(),
|
||||
sprout::move(t)
|
||||
)
|
||||
{}
|
||||
template<
|
||||
typename UType1, typename UType2,
|
||||
|
@ -447,14 +407,16 @@ namespace sprout {
|
|||
>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2>&& t);
|
||||
// tuple assignment
|
||||
SPROUT_CXX14_CONSTEXPR tuple& operator=(tuple const& rhs) {
|
||||
static_cast<impl_type&>(*this) = rhs;
|
||||
SPROUT_CXX14_CONSTEXPR tuple&
|
||||
operator=(tuple const& rhs) {
|
||||
assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
SPROUT_CXX14_CONSTEXPR tuple& operator=(tuple&& rhs)
|
||||
SPROUT_CXX14_CONSTEXPR tuple&
|
||||
operator=(tuple&& rhs)
|
||||
SPROUT_NOEXCEPT_IF(sprout::tpp::all_of<std::is_nothrow_move_assignable<Types>...>::value)
|
||||
{
|
||||
static_cast<impl_type&>(*this) = sprout::move(rhs);
|
||||
assign(sprout::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
template<
|
||||
|
@ -463,8 +425,9 @@ namespace sprout {
|
|||
sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of<std::is_assignable<Types&, UTypes const&>...>::value
|
||||
>::type
|
||||
>
|
||||
SPROUT_CXX14_CONSTEXPR tuple& operator=(sprout::tuples::tuple<UTypes...> const& rhs) {
|
||||
static_cast<impl_type&>(*this) = rhs;
|
||||
SPROUT_CXX14_CONSTEXPR tuple&
|
||||
operator=(sprout::tuples::tuple<UTypes...> const& rhs) {
|
||||
assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
template<
|
||||
|
@ -473,8 +436,9 @@ namespace sprout {
|
|||
sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of<std::is_assignable<Types&, UTypes&&>...>::value
|
||||
>::type
|
||||
>
|
||||
SPROUT_CXX14_CONSTEXPR tuple& operator=(sprout::tuples::tuple<UTypes...>&& rhs) {
|
||||
static_cast<impl_type&>(*this) = sprout::move(rhs);
|
||||
SPROUT_CXX14_CONSTEXPR tuple&
|
||||
operator=(sprout::tuples::tuple<UTypes...>&& rhs) {
|
||||
assign(sprout::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
template<
|
||||
|
@ -492,29 +456,37 @@ namespace sprout {
|
|||
>
|
||||
SPROUT_CXX14_CONSTEXPR tuple& operator=(sprout::pair<UType1, UType2>&& rhs);
|
||||
// tuple swap
|
||||
SPROUT_CXX14_CONSTEXPR void swap(tuple& other)
|
||||
SPROUT_CXX14_CONSTEXPR void
|
||||
swap(tuple& other)
|
||||
SPROUT_NOEXCEPT_IF(sprout::tpp::all_of_c<SPROUT_NOEXCEPT_EXPR(sprout::swap(std::declval<Types&>(), std::declval<Types&>()))...>::value)
|
||||
{
|
||||
impl_type::swap(other);
|
||||
swap_impl(other, index_tuple_type());
|
||||
}
|
||||
};
|
||||
template<>
|
||||
class tuple<> {
|
||||
template<typename... UTypes>
|
||||
friend class sprout::tuples::detail::tuple_access;
|
||||
protected:
|
||||
template<std::size_t I>
|
||||
struct element
|
||||
: public sprout::detail::nil_base
|
||||
{};
|
||||
public:
|
||||
// tuple construction
|
||||
SPROUT_CONSTEXPR tuple() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
|
||||
tuple(tuple const&) = default;
|
||||
tuple(tuple&&) = default;
|
||||
template<typename... UTypes>
|
||||
explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&...) {}
|
||||
explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&...) SPROUT_NOEXCEPT {}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const&) {}
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...> const&) SPROUT_NOEXCEPT {}
|
||||
template<typename... UTypes>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&&) {}
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple<UTypes...>&&) SPROUT_NOEXCEPT {}
|
||||
template<typename UType1, typename UType2>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2> const&) {}
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2> const&) SPROUT_NOEXCEPT {}
|
||||
template<typename UType1, typename UType2>
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2>&&) {}
|
||||
SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair<UType1, UType2>&&) SPROUT_NOEXCEPT {}
|
||||
// tuple swap
|
||||
SPROUT_CXX14_CONSTEXPR void swap(tuple&) SPROUT_NOEXCEPT {}
|
||||
};
|
||||
|
@ -529,6 +501,36 @@ namespace sprout {
|
|||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<typename... Types>
|
||||
class tuple_access {
|
||||
public:
|
||||
template<std::size_t I>
|
||||
struct element
|
||||
: public sprout::tuples::tuple<Types...>::template element<I>
|
||||
{};
|
||||
struct size
|
||||
: public sprout::integral_constant<std::size_t, sizeof...(Types)>
|
||||
{};
|
||||
public:
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&
|
||||
get(sprout::tuples::tuple<Types...>& t) {
|
||||
return sprout::tuples::tuple<Types...>::template get<I>(t);
|
||||
}
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type&&
|
||||
get(sprout::tuples::tuple<Types...>&& t) {
|
||||
return sprout::tuples::tuple<Types...>::template get<I>(sprout::move(t));
|
||||
}
|
||||
template<std::size_t I>
|
||||
static SPROUT_CONSTEXPR typename element<I>::type const&
|
||||
get(sprout::tuples::tuple<Types...> const& t) {
|
||||
return sprout::tuples::tuple<Types...>::template get<I>(t);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace tuples
|
||||
|
||||
using sprout::tuples::tuple;
|
||||
|
@ -553,7 +555,8 @@ namespace std {
|
|||
//
|
||||
template<std::size_t I, typename... Types>
|
||||
struct tuple_element<I, sprout::tuples::tuple<Types...> >
|
||||
: public sprout::pack_element<I, Types...>
|
||||
// : public sprout::pack_element<I, Types...>
|
||||
: public sprout::tuples::detail::tuple_access<Types...>::template element<I>
|
||||
{};
|
||||
#if defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/type_traits/identity.hpp>
|
||||
#include <sprout/type/iterator.hpp>
|
||||
#include <sprout/type/iterator/index_iterator.hpp>
|
||||
#include <sprout/type/type_tuple_decl.hpp>
|
||||
|
@ -25,6 +26,11 @@ namespace sprout {
|
|||
typedef type_tuple type;
|
||||
typedef sprout::types::index_iterator<type_tuple, 0> begin;
|
||||
typedef sprout::types::index_iterator<type_tuple, sizeof...(Types)> end;
|
||||
public:
|
||||
template<typename... UTypes>
|
||||
struct apply
|
||||
: public sprout::identity<type_tuple<Types..., UTypes...> >
|
||||
{};
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t static_size = sizeof...(Types);
|
||||
};
|
||||
|
|
21
sprout/utility/eat.hpp
Normal file
21
sprout/utility/eat.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*=============================================================================
|
||||
Copyright (c) 2011-2014 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_UTILITY_EAT_HPP
|
||||
#define SPROUT_UTILITY_EAT_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// eat
|
||||
//
|
||||
inline SPROUT_CXX14_CONSTEXPR void
|
||||
eat(...) SPROUT_NOEXCEPT {}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_UTILITY_EAT_HPP
|
|
@ -15,5 +15,6 @@
|
|||
#include <sprout/utility/swap.hpp>
|
||||
#include <sprout/utility/exchange.hpp>
|
||||
#include <sprout/utility/unmove.hpp>
|
||||
#include <sprout/utility/eat.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_UTILITY_OPERATION_HPP
|
||||
|
|
Loading…
Reference in a new issue