// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_TUPLE_H_ #define CTL_TUPLE_H_ #include "decay.h" #include "enable_if.h" #include "is_same.h" #include "utility.h" namespace ctl { // Forward declaration template class tuple; // Base case for tuple template<> class tuple<> {}; // Recursive case for tuple template class tuple : public tuple { using Base = tuple; public: Head head; constexpr tuple() : Base(), head() { } template::type, tuple>::value>::type> constexpr tuple(H&& h, T&&... t) : Base(ctl::forward(t)...), head(ctl::forward(h)) { } template constexpr tuple(const tuple& other) : Base(static_cast&>(other)), head(other.head) { } template constexpr tuple(tuple&& other) : Base(static_cast&&>(other)) , head(ctl::forward(other.head)) { } tuple(const tuple&) = default; tuple(tuple&&) = default; tuple& operator=(const tuple&) = default; tuple& operator=(tuple&&) = default; }; // Helper struct for getting element type template struct tuple_element; template struct tuple_element> : tuple_element> {}; template struct tuple_element<0, tuple> { using type = Head; }; // Helper function to get element template constexpr typename tuple_element>::type& get(tuple& t) { if constexpr (I == 0) { return t.head; } else { return get(static_cast&>(t)); } } template constexpr const typename tuple_element>::type& get(const tuple& t) { if constexpr (I == 0) { return t.head; } else { return get(static_cast&>(t)); } } // Helper function to create a tuple template constexpr tuple::type...> make_tuple(Types&&... args) { return tuple::type...>( ctl::forward(args)...); } // Helper function for tuple comparison template constexpr bool tuple_equals(const tuple& t, const tuple& u) { if constexpr (I == sizeof...(TTypes)) { return true; } else { return get(t) == get(u) && tuple_equals(t, u); } } // Equality comparison template constexpr bool operator==(const tuple& t, const tuple& u) { return tuple_equals(t, u); } template constexpr bool operator!=(const tuple& t, const tuple& u) { return !(t == u); } } // namespace ctl #endif // CTL_TUPLE_H_