|
@@ -55,9 +55,47 @@ struct tuple_size<std::tuple<Types...>>
|
|
|
|
|
|
namespace __helpers {
|
|
|
|
|
|
+template <std::size_t I, typename... Types>
|
|
|
+class tuple_impl;
|
|
|
+
|
|
|
+template <>
|
|
|
+class tuple_impl<0> {
|
|
|
+ template <std::size_t, typename...>
|
|
|
+ friend class tuple_impl;
|
|
|
+
|
|
|
+ template <std::size_t J, typename... UTypes>
|
|
|
+ friend constexpr auto std::get(std::tuple<UTypes...>& tpl) noexcept
|
|
|
+ -> tuple_element_t<J, std::tuple<UTypes...>>&;
|
|
|
+ template <std::size_t J, typename... UTypes>
|
|
|
+ friend constexpr auto std::get(std::tuple<UTypes...>&& tpl) noexcept
|
|
|
+ -> tuple_element_t<J, std::tuple<UTypes...>>&&;
|
|
|
+ template <std::size_t J, typename... UTypes>
|
|
|
+ friend constexpr auto std::get(const std::tuple<UTypes...>& tpl) noexcept
|
|
|
+ -> tuple_element_t<J, std::tuple<UTypes...>> const&;
|
|
|
+ template <std::size_t J, typename... UTypes>
|
|
|
+ friend constexpr auto std::get(const std::tuple<UTypes...>&& tpl) noexcept
|
|
|
+ -> tuple_element_t<J, std::tuple<UTypes...>> const&&;
|
|
|
+
|
|
|
+ template <std::size_t> constexpr void _getl(void) const = delete;
|
|
|
+ template <std::size_t> constexpr void _getr(void) const = delete;
|
|
|
+public:
|
|
|
+ constexpr tuple_impl() noexcept = default;
|
|
|
+
|
|
|
+ constexpr tuple_impl(const tuple_impl& arg) noexcept = default;
|
|
|
+ constexpr tuple_impl(tuple_impl&& arg) noexcept = default;
|
|
|
+
|
|
|
+ template <typename... UTypes>
|
|
|
+ constexpr tuple_impl(const std::tuple<UTypes...>& other) = delete;
|
|
|
+ template <typename... UTypes>
|
|
|
+ constexpr tuple_impl(std::tuple<UTypes...>&& other) = delete;
|
|
|
+
|
|
|
+ constexpr tuple_impl& operator=(const tuple_impl& other) noexcept = default;
|
|
|
+ constexpr tuple_impl& operator=(tuple_impl&& other) noexcept = default;
|
|
|
+};
|
|
|
+
|
|
|
template <std::size_t I, typename Type, typename... Types>
|
|
|
-class tuple_impl {
|
|
|
- template <std::size_t, typename, typename...>
|
|
|
+class tuple_impl<I, Type, Types...> {
|
|
|
+ template <std::size_t, typename...>
|
|
|
friend class tuple_impl;
|
|
|
|
|
|
template <std::size_t J, typename... UTypes>
|
|
@@ -139,7 +177,7 @@ public:
|
|
|
|
|
|
template <std::size_t I, typename Type>
|
|
|
class tuple_impl<I, Type> {
|
|
|
- template <std::size_t, typename, typename...>
|
|
|
+ template <std::size_t, typename...>
|
|
|
friend class tuple_impl;
|
|
|
|
|
|
template <std::size_t J, typename... UTypes>
|
|
@@ -157,14 +195,30 @@ class tuple_impl<I, Type> {
|
|
|
|
|
|
Type val;
|
|
|
|
|
|
- template <std::size_t>
|
|
|
- constexpr Type& _getl(void) { return val; }
|
|
|
- template <std::size_t>
|
|
|
- constexpr Type const& _getl(void) const { return val; }
|
|
|
- template <std::size_t>
|
|
|
- constexpr Type&& _getr(void) { return std::move(val); }
|
|
|
- template <std::size_t>
|
|
|
- constexpr Type const&& _getr(void) const { return std::move(val); }
|
|
|
+ template <std::size_t J>
|
|
|
+ constexpr Type& _getl(void)
|
|
|
+ {
|
|
|
+ static_assert(J == I);
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+ template <std::size_t J>
|
|
|
+ constexpr Type const& _getl(void) const
|
|
|
+ {
|
|
|
+ static_assert(J == I);
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+ template <std::size_t J>
|
|
|
+ constexpr Type&& _getr(void)
|
|
|
+ {
|
|
|
+ static_assert(J == I);
|
|
|
+ return std::move(val);
|
|
|
+ }
|
|
|
+ template <std::size_t J>
|
|
|
+ constexpr Type const&& _getr(void) const
|
|
|
+ {
|
|
|
+ static_assert(J == I);
|
|
|
+ return std::move(val);
|
|
|
+ }
|
|
|
|
|
|
public:
|
|
|
constexpr tuple_impl()
|