You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.3 KiB

// -*- c++ -*-
// C++11 20.4
#pragma once
#include <cstddef>
#include <utility>
namespace std {
//
// tuple
//
template <class... Types>
class tuple;
template <class T0, class... TN>
class tuple<T0, TN...>
{
T0 car_;
tuple<TN...> cdr_;
template<size_t, typename...>
friend struct __get_impl;
public:
constexpr tuple() : car_(), cdr_() { }
explicit tuple(const T0& car, const TN&... cdr)
: car_(car), cdr_(tuple<TN...>(cdr...)) { }
template<class UType0, class... UTypes>
explicit tuple(UType0 &&car, UTypes&&... cdr)
: car_(std::forward<UType0>(car)),
cdr_(tuple<TN...>(std::forward<UTypes>(cdr)...)) { }
tuple(const tuple&) = default;
tuple(tuple&&) = default;
tuple& operator=(const tuple&) = default;
tuple& operator=(tuple&&) = default;
void swap(tuple& rhs)
{
swap(car_, rhs.car_);
swap(cdr_, rhs.cdr_);
}
};
template <>
class tuple<>
{
public:
constexpr tuple() { }
void swap(tuple& rhs) { }
};
//
// tuple_element
//
template <size_t I, class... Types>
class tuple_element;
template <class T0, class... TN>
class tuple_element<0, tuple<T0, TN...> > {
public:
typedef T0 type;
};
template <size_t I, class T0, class... TN>
class tuple_element<I, tuple<T0, TN...> >
: public tuple_element<I - 1, tuple<TN...> > { };
//
// get
//
template <size_t I, class... Types>
struct __get_impl;
template <class T0, class... TN>
struct __get_impl<0, T0, TN...>
{
static T0 &get(tuple<T0, TN...>& t) noexcept
{
return t.car_;
}
};
template <size_t I, class T0, class... TN>
struct __get_impl<I, T0, TN...>
{
static typename tuple_element<I, tuple<T0, TN...> >::type&
get(tuple<T0, TN...>& t) noexcept
{
return __get_impl<I - 1, TN...>::get(t.cdr_);
}
};
template <size_t I, class... Types>
typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>& t)
noexcept
{
return __get_impl<I, Types...>::get(t);
}
template <size_t I, class... Types>
typename tuple_element<I, tuple<Types...> >::type&& get(tuple<Types...>&& t)
noexcept
{
return std::forward<typename tuple_element<I, tuple<Types...> >
::type&&>(get<I>(t));
}
}