// -*- c++ -*- // C++11 20.4 #pragma once #include #include namespace std { // // tuple // template class tuple; template class tuple { T0 car_; tuple cdr_; template friend struct __get_impl; public: constexpr tuple() : car_(), cdr_() { } explicit tuple(const T0& car, const TN&... cdr) : car_(car), cdr_(tuple(cdr...)) { } template explicit tuple(UType0 &&car, UTypes&&... cdr) : car_(std::forward(car)), cdr_(tuple(std::forward(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 class tuple_element; template class tuple_element<0, tuple > { public: typedef T0 type; }; template class tuple_element > : public tuple_element > { }; // // get // template struct __get_impl; template struct __get_impl<0, T0, TN...> { static T0 &get(tuple& t) noexcept { return t.car_; } }; template struct __get_impl { static typename tuple_element >::type& get(tuple& t) noexcept { return __get_impl::get(t.cdr_); } }; template typename tuple_element >::type& get(tuple& t) noexcept { return __get_impl::get(t); } template typename tuple_element >::type&& get(tuple&& t) noexcept { return std::forward > ::type&&>(get(t)); } }