Skip to content

Instantly share code, notes, and snippets.

@aliakseis
Created June 23, 2019 13:24
Show Gist options
  • Select an option

  • Save aliakseis/f24775bfa016b5a7d49b2d0413451ab0 to your computer and use it in GitHub Desktop.

Select an option

Save aliakseis/f24775bfa016b5a7d49b2d0413451ab0 to your computer and use it in GitHub Desktop.
Reflection on C++ 17 variation
// https://gist.github.com/utilForever/1a058050b8af3ef46b58bcfa01d5375d
#include <tuple>
#include <type_traits>
#include <cassert>
#include <iostream>
template <class T, class... TArgs>
decltype(void(T{std::declval<TArgs>()...}), std::true_type{}) test_is_braces_constructible(int);
template <class, class...> std::false_type test_is_braces_constructible(...);
template <class T, class... TArgs> using is_braces_constructible
= decltype(test_is_braces_constructible<std::decay_t<T>, TArgs...>(0));
struct any_type {
template<class T>
constexpr operator T(); // non explicit
};
#define PARAMS_MACRO_1(macro) macro(1)
#define PARAMS_MACRO_2(macro) PARAMS_MACRO_1(macro), macro(2)
#define PARAMS_MACRO_3(macro) PARAMS_MACRO_2(macro), macro(3)
#define PARAMS_MACRO_4(macro) PARAMS_MACRO_3(macro), macro(4)
#define PARAMS_MACRO_5(macro) PARAMS_MACRO_4(macro), macro(5)
#define PARAMS_MACRO_6(macro) PARAMS_MACRO_5(macro), macro(6)
#define PARAMS_MACRO_7(macro) PARAMS_MACRO_6(macro), macro(7)
#define PARAMS_MACRO_8(macro) PARAMS_MACRO_7(macro), macro(8)
#define PARAMS_MACRO_9(macro) PARAMS_MACRO_8(macro), macro(9)
#define GENERATE_MULTIPARAMS(macro) \
macro(PARAMS_MACRO_1) \
macro(PARAMS_MACRO_2) \
macro(PARAMS_MACRO_3) \
macro(PARAMS_MACRO_4) \
macro(PARAMS_MACRO_5) \
macro(PARAMS_MACRO_6) \
macro(PARAMS_MACRO_7) \
macro(PARAMS_MACRO_8) \
macro(PARAMS_MACRO_9)
#define TYPE_MACRO(v) any_type
#define ARGS_MACRO(v) p##v
#define TO_TUPLE_MACRO(macro) \
template<typename T, std::enable_if_t < \
is_braces_constructible<T, macro(TYPE_MACRO)>::value \
&& !is_braces_constructible<T, macro(TYPE_MACRO), any_type>::value \
, int> = 0> \
auto to_tuple(T&& object) noexcept \
{ \
auto&&[macro(ARGS_MACRO)] = object; \
return std::make_tuple(macro(ARGS_MACRO)); \
}
GENERATE_MULTIPARAMS(TO_TUPLE_MACRO)
int main() {
{
struct s {
int p1;
double p2;
};
auto t = to_tuple(s{1, 2.0});
static_assert(std::is_same<std::tuple<int, double>, decltype(t)>{});
assert(1 == std::get<0>(t));
assert(2.0 == std::get<1>(t));
}
{
struct s {
struct nested { } p1;
int p2;
int p3;
s* p4;
};
auto t = to_tuple(s{s::nested{}, 42, 87, nullptr});
static_assert(std::is_same<std::tuple<s::nested, int, int, s*>, decltype(t)>{});
assert(42 == std::get<1>(t));
assert(87 == std::get<2>(t));
assert(nullptr == std::get<3>(t));
}
std::cout << "ok.\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment