in include/AbstractDomain.h [69:90]
virtual ~AbstractDomain() {
// The destructor is the only method that is guaranteed to be created when a
// class template is instantiated. This is a good place to perform all the
// sanity checks on the template parameters.
static_assert(std::is_base_of<AbstractDomain<Derived>, Derived>::value,
"Derived doesn't inherit from AbstractDomain");
static_assert(std::is_default_constructible<Derived>::value,
"Derived is not default constructible");
static_assert(std::is_copy_constructible<Derived>::value,
"Derived is not copy constructible");
static_assert(std::is_copy_assignable<Derived>::value,
"Derived is not copy assignable");
// top() and bottom() are factory methods that respectively produce the top
// and bottom values. We define default implementations for them in terms
// of set_to_{top, bottom}, but implementors may wish to override those
// implementations with more efficient versions. Here we check that any
// such overrides bear the correct method signature.
static_assert(std::is_same<decltype(Derived::bottom()), Derived>::value,
"Derived::bottom() does not exist");
static_assert(std::is_same<decltype(Derived::top()), Derived>::value,
"Derived::top() does not exist");
}