cjdb-ranges icon indicating copy to clipboard operation
cjdb-ranges copied to clipboard

Add a test suite for checking subsumption hierarchies

Open cjdb opened this issue 6 years ago • 0 comments

Is your feature request related to a problem? Please describe. The current mechanism for checking C2 subsumes C1 is completely ad-hoc. It'd be great for there to be a more formal way of checking this.

Describe the solution you'd like Cleanly checking for subsumption may never be possible at a language level, but we might be able to force variable templates to do the check with well-documented values.

// Example 1
enum class subsumes {
   nothing,
   // public concept names here
};

template<typename...>
inline constexpr auto regular_hierarchy = subsumes::nothing;

template<destructible T>
inline constexpr auto regular_hierarchy<T> = subsumes::destructible;

template<default_initializable T>
inline constexpr auto regular_hierarchy<T> = subsumes::default_initializable;

template<move_constructible T>
inline constexpr auto regular_hierarchy<T> = subsumes::move_constructible;

template<copy_constructible T>
inline constexpr auto regular_hierarchy<T> = subsumes::copy_constructible;

template<swappable T>
inline constexpr auto regular_hierarchy<T> = subsumes::swappable;

template<movable T>
inline constexpr auto regular_hierarchy<T> = subsumes::movable;

template<copyable T>
inline constexpr auto regular_hierarchy<T> = subsumes::copyable;

template<semiregular T>
inline constexpr auto regular_hierarchy<T> = subsumes::semiregular;

template<equality_comparable T>
inline constexpr auto regular_hierarchy<T> = subsumes::equality_comparable;

template<regular T>
inline constexpr auto regular_hierarchy<T> = subsumes::regular;

static_assert(regular_hierarchy<std::mutex> == subsumes::default_initializable);
static_assert(regular_hierarchy<std::span<int>> == subsumes::semiregular);
static_assert(regular_hierarchy<int> == subsumes::regular);

Describe alternatives you've considered No alternatives at present.

Additional context The solution needs to be carefully curated, because we'll run into ambiguity problems otherwise.

// Example 2
template<typename...>
inline constexpr auto check_subsumption = subsumes::nothing;

template<semiregular T>
inline constexpr auto check_subsumption<T> = subsumes::semiregular;

template<equality_comparable T>
inline constexpr auto check_subsumption<T> = subsumes::equality_comparable;

template<regular T>
inline constexpr auto check_subsumption = subsumes::regular;

template<totally_ordered T>
inline constexpr auto check_subsumption = subsumes::totally_ordered;

static_assert(check_subsumption<int> == subsumes::regular); // error

In Example 2, we hit the problem that regular<int> and totally_ordered<int> are both satisfied, and thus specialisation becomes ambiguous. While it might be a valid compiler test to add a more specialised check_subsumption that requires both concepts, it doesn't benefit this test suite, which wants to check that regular subsumes semiregular and equality_comparable.

cjdb avatar Oct 13 '19 01:10 cjdb