Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <tuple>
- #include <utility>
- #include <iostream>
- class Aa {
- public:
- Aa(int a1_, int a2_): a1(a1_), a2(a2_) {}
- template<std::size_t N>
- decltype(auto) get() const {
- if constexpr (N == 0) return a1;
- else if constexpr (N == 1) return a2;
- }
- private:
- int a1;
- int a2;
- };
- class Bb {
- public:
- Bb(Aa a_, int b_): a(a_), b(b_) {}
- template<std::size_t N>
- decltype(auto) get() const {
- if constexpr (N == 0) return a;
- else if constexpr (N == 1) return b;
- }
- private:
- Aa a;
- int b;
- };
- namespace std {
- // Aa
- template<>
- struct tuple_size<Aa> : std::integral_constant<std::size_t, 2> {};
- template<std::size_t N>
- struct tuple_element<N, Aa> {
- using type = decltype(std::declval<Aa>().get<N>());
- };
- // Bb
- template<>
- struct tuple_size<Bb> : std::integral_constant<std::size_t, 2> {};
- template<std::size_t N>
- struct tuple_element<N, Bb> {
- using type = decltype(std::declval<Bb>().get<N>());
- };
- }
- template
- <
- typename T,
- typename tp_enabled =
- std::void_t
- <
- decltype(std::tuple_size<T>::value),
- decltype(std::declval<T&>().template get<std::size_t(0)>())
- >
- >
- constexpr auto
- is_tuple_like(int const)noexcept->bool
- {
- return true;
- }
- template
- <typename T, typename tp_arg>
- constexpr auto
- is_tuple_like(tp_arg const)noexcept->bool
- {
- return false;
- }
- template<typename T>
- auto encode(T const& t, std::ostream& os)->
- std::enable_if_t<is_tuple_like<T>(0)>
- {
- encode_impl(t, os, std::make_index_sequence<std::tuple_size<T>::value>{ });
- os << std::endl;
- }
- template
- <bool is_last, typename T>
- auto
- encode_one(T const& t, std::ostream& os)->
- std::enable_if_t<!is_tuple_like<T>(0)>
- {
- os << t << (is_last ? " " : ", ");
- }
- template
- <bool is_last, typename T>
- auto
- encode_one(T const& t, std::ostream& os)->
- std::enable_if_t<is_tuple_like<T>(0)>
- {
- encode_impl(t, os, std::make_index_sequence<std::tuple_size<T>::value>{ });
- os << (is_last ? " " : ", ");
- }
- template
- <typename T, std::size_t... I>
- void encode_impl(T const& t, std::ostream& os, std::index_sequence<I...> const)
- {
- constexpr auto last = sizeof...(I) - 1;
- os << "{ ";
- [[maybe_unused]] int const temp[] =
- { (encode_one<I == last>(t.template get<I>(), os), 0)... };
- os << "}";
- }
- int main () {
- auto a = Aa(1, 1);
- encode(a, std::cout);
- auto b = Bb(a, 1);
- encode(b, std::cout);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement