using Person = tuple<std::string, char, int>;
Person john { "John"s, 'M', 21 }; Person jess { "Jess"s, 'F', 19 };
Person jack = make_tuple("Jack"s, 'M', 20);
std::string john_name = get<0>(john); int jess_age = get<int>(jess);
char gender_jack; tie(ignore, gender_jack, ignore) = jack;
std::set<Person> group { john, jess, jack };
using Hobby = tuple<std::string, int>;
Hobby kongfu { "Kong Fu", 2 };
auto john_hobby = tuple_cat(john, kongfu);
Reference: github /BOT-Man-JL/ORM-Lite
auto usersOrderList = mapper.Query(userModel) .Join(userModel, field(userModel.user_id) == field(orderModel.user_id) ).ToList();
template <typename... Types> class tuple : Types... {};
template <typename T> struct _t_leaf { T _val; };
template <typename... Types> class tuple : _t_leaf<Types>... {};
template <> class tuple<> {}; template <typename Head, typename... Tails>
class tuple<Head, Tails...> { Head _head; tuple<Tails...> _tails; };
template <> class tuple<> {}; template <typename Head, typename... Tails>
class tuple<Head, Tails...> : tuple<Tails...> { Head _head; };
template <size_t, typename T, bool = std::is_empty_v<T> && !std::is_final_v<T>> struct _t_leaf { T _val; };
template <size_t I, typename T> struct _t_leaf<I, T, false> { T _val; };
template <size_t I, typename T> struct _t_leaf<I, T, true> : private T {};
template <typename S, typename... Ts> struct _t_impl;
template <size_t... Is, typename... Ts> struct _t_impl<std::index_sequence<Is...>, Ts...> : _t_leaf<Is, Ts>... {}; template <typename... Ts> class tuple : _t_impl< std::make_index_sequence<sizeof...(Ts)>, Ts...> {};
template <size_t Idx, typename... Ts> struct _t_impl; template <size_t Idx> struct _t_impl<Idx> {};
template <size_t Idx, typename Head, typename... Tails> struct _t_impl<Idx, Head, Tails...> : _t_impl<Idx + 1, Tails...>, _t_leaf<Idx, Head> {}; template <typename... Ts> class tuple : _t_impl<0, Ts...> {};
tuple(); tuple(const Head&, const Tails&...); template <typename T, typename... Ts> tuple(T&& arg, Ts&& ...args);
template <typename... Rhs> tuple(const tuple<Rhs...>& rhs); template <typename... Rhs> tuple(tuple<Rhs...>&& rhs); tuple(const tuple&); tuple(tuple&&);
template <typename T, typename... Ts> tuple(T&& arg, Ts&& ...args) : Tail(std::forward<Ts>(args)...), _val(std::forward<T>(arg)) {}
template <typename... Rhs> tuple(tuple<Rhs...>&& rhs) : Tail(std::move(rhs._tail())), _val(std::move(rhs._head())) {}
tuple<int> t(tuple<int> { 1 });
template <typename T, typename... Ts, typename = std::enable_if_t< std::is_convertible_v<T, Head> > > explicit tuple(T&& arg, Ts&& ...args) : Tail(std::forward<Ts>(args)...), _val(std::forward<T>(arg)) {}
template <size_t I, typename Tuple> struct tuple_element; template <size_t I, typename... Ts> tuple_element<I, tuple<Ts...>>::type& get( tuple<Ts...>&);
template<size_t I, typename T, typename... Ts> struct tuple_element<I, tuple<T, Ts...>> : tuple_element<I - 1, tuple<Ts...>> {};
template <typename T, typename... Ts> struct tuple_element<0, tuple<T, Ts...>> { using type = T; using _tuple = tuple<T, Ts...>; };
template <size_t I, typename...Ts> tuple_element<I, tuple<Ts...>>::type& get( tuple<Ts...>& t) {
return ((tuple_element<I, tuple<Ts...>>:: _tuple&) t)._val;
}

