cjdb-ranges
cjdb-ranges copied to clipboard
Add a test suite for checking subsumption hierarchies
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.