43 lines
1.1 KiB
C++
43 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include <ranges>
|
|
#include <concepts>
|
|
|
|
namespace clice {
|
|
|
|
namespace ranges = std::ranges;
|
|
namespace views = std::views;
|
|
|
|
enum class RangeKind {
|
|
Map = 0,
|
|
Set,
|
|
Sequence,
|
|
Invalid,
|
|
};
|
|
|
|
template <typename Range>
|
|
constexpr inline RangeKind range_kind = [] {
|
|
if constexpr(std::same_as<Range, std::remove_cvref_t<ranges::range_reference_t<Range>>>) {
|
|
return RangeKind::Invalid;
|
|
} else if constexpr(requires { typename Range::key_type; }) {
|
|
if constexpr(requires { typename Range::mapped_type; }) {
|
|
return RangeKind::Map;
|
|
} else {
|
|
return RangeKind::Set;
|
|
}
|
|
} else {
|
|
return RangeKind::Sequence;
|
|
}
|
|
}();
|
|
|
|
template <typename Range>
|
|
concept map_range = ranges::input_range<Range> && range_kind<Range> == RangeKind::Map;
|
|
|
|
template <typename Range>
|
|
concept set_range = ranges::input_range<Range> && range_kind<Range> == RangeKind::Set;
|
|
|
|
template <typename Range>
|
|
concept sequence_range = ranges::input_range<Range> && range_kind<Range> == RangeKind::Sequence;
|
|
|
|
} // namespace clice
|