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
115 lines
2.3 KiB
6 years ago
|
// -*- 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));
|
||
|
}
|
||
|
}
|