Skip to content

Instantly share code, notes, and snippets.

@EricWF
Last active January 10, 2019 10:48
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 EricWF/88ceadf2bcdeef9f9d268b3a743dcd04 to your computer and use it in GitHub Desktop.
Save EricWF/88ceadf2bcdeef9f9d268b3a743dcd04 to your computer and use it in GitHub Desktop.
#include <tuple>
#include <array>
using namespace std;
template <bool Enable, class ...Class>
constexpr std::enable_if_t<Enable, bool> BlowUp() {
static_assert(Enable && sizeof...(Class) != sizeof...(Class));
return true;
}
struct NoAssign {
NoAssign() = default;
NoAssign(NoAssign const&) = default;
template <class T, class = std::enable_if_t<sizeof(T) != sizeof(T)>>
NoAssign& operator=(T) { return *this; }
};
template <int>
struct DieOnAssign {
DieOnAssign() = default;
template <class T, bool = BlowUp<!is_same_v<T, DieOnAssign>, T>()>
DieOnAssign& operator=(T) {
return *this;
}
};
void test_arity_checks() {
{
using T = tuple<int, DieOnAssign<0>, int>;
using P = pair<int, int>;
static_assert(!is_assignable_v<T&, P const&>); // Blows up!
}
{
using T = tuple<int, int, DieOnAssign<1>>;
using A = array<int, 1>;
static_assert(!is_assignable_v<T&, A const&>);
}
}
void test_lazy_eval() {
{
using T1 = tuple<int, NoAssign, DieOnAssign<2>>;
using T2 = tuple<long, long, long>;
static_assert(!is_assignable_v<T1&, T2 const&>); // OK
}
{
using T1 = tuple<NoAssign, DieOnAssign<3>>;
using T2 = pair<long, double>;
static_assert(!is_assignable_v<T1&, T2 const&>); // Blows up!
}
}
int main() {
test_arity_checks();
test_lazy_eval();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment