Skip to content

Instantly share code, notes, and snippets.

@qrealka
Created February 17, 2020 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qrealka/7628cfc44bf9e1ecc8cfbdeb9cd0c19b to your computer and use it in GitHub Desktop.
Save qrealka/7628cfc44bf9e1ecc8cfbdeb9cd0c19b to your computer and use it in GitHub Desktop.
compare generic struct
// based on https://stackoverflow.com/a/60080443
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
template<class T,
typename std::enable_if< !std::is_class<T>{}, bool>::type = true
>
auto refl_tie( T const& t )
RETURNS(std::cref(t))
template<class...Ts,
typename std::enable_if< (sizeof...(Ts) > 1), bool>::type = true
>
auto refl_tie( Ts const&... ts )
RETURNS(std::make_tuple(refl_tie(ts)...))
// prevent array members from decaying to pointers and
// falling back on pointer-equality (which you probably don't want from arrays).
template<class T, std::size_t N, class...Ts>
auto refl_tie( T(&t)[N], Ts&&... ) = delete;
// c++17 only
template<class T, std::size_t N, std::size_t...Is>
auto array_refl( T const(&t)[N], std::index_sequence<Is...> )
RETURNS( std::array<decltype( refl_tie(t[0]) ), N>{ refl_tie( t[Is] )... } )
template<class T, std::size_t N>
auto refl_tie( T const(&t)[N] )
RETURNS( array_refl( t, std::make_index_sequence<N>{} ) )
template<class T, class A>
auto refl_tie( std::vector<T, A> const& v )
RETURNS( std::tie(v) )
// tests:
struct foo {
int x;
};
struct bar {
foo f1, f2;
};
auto refl_tie( foo const& s )
RETURNS( refl_tie( s.x ) )
auto refl_tie( bar const& s )
RETURNS( refl_tie( s.f1, s.f2 ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment