Skip to content

Instantly share code, notes, and snippets.

@tomilov
Last active November 26, 2015 19:45
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 tomilov/b81ac96dba9ac1a14691 to your computer and use it in GitHub Desktop.
Save tomilov/b81ac96dba9ac1a14691 to your computer and use it in GitHub Desktop.
#include <type_traits>
#include <iostream>
#include <cstdlib>
#define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }
struct descriptor
{
std::size_t const s;
bool const * c;
bool const * d;
};
template< descriptor const & x, bool c, bool d, typename ...types >
union U;
template< descriptor const & x, bool c, bool d >
union U< x, c, d >
{
static_assert(c);
static_assert(d);
U() PP
~U() PP
};
template< descriptor const & x, bool c, bool d, typename first, typename ...rest >
union U< x, c, d, first, rest... > // specialize against c and/or d values
{
static constexpr std::size_t s = x.s - sizeof...(rest);
using tail = U< x, x.c[s], x.d[s], rest... >;
first head_;
tail tail_{};
U() PP
~U() { PP; tail_.~tail(); }
};
template< typename ...types >
struct V
{
static constexpr bool c[sizeof...(types) + 1] = {std::is_trivially_constructible< types >{}..., true};
static constexpr bool d[sizeof...(types) + 1] = {std::is_trivially_destructible< types >{}..., true};
static constexpr descriptor x{sizeof...(types), c, d};
U< x, x.c[0], x.d[0], types... > storage_;
V() PP
~V() PP
};
template< typename ...types >
constexpr bool V< types... >::c[sizeof...(types) + 1];
template< typename ...types >
constexpr bool V< types... >::d[sizeof...(types) + 1];
template< typename ...types >
constexpr descriptor V< types... >::x;
int
main()
{
struct S { S() { ; } ~S() { ; } };
V< int, S, double > v;
(void)v;
S s;
(void)s;
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment