1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
#pragma once
#include <concepts>
#include <iterator>
namespace misc
{
// Concept describing a const Container through which you can iterate
// Needs methods begin() and end().
template <typename Container>
concept ConstIterable =
requires(Container c) {
{
c.begin() != c.end()
} -> std::same_as<bool>;
{
c.begin()
} -> std::convertible_to<typename Container::const_iterator>;
{
*c.begin()
} -> std::convertible_to<const typename Container::value_type&>;
};
// Concept describing a Container through which you can iterate
// Needs methods begin() and end().
template <typename Container>
concept Iterable = ConstIterable<Container>
&& requires(Container c) {
{
c.begin()
} -> std::same_as<typename Container::iterator>;
{
*c.begin()
} -> std::same_as<typename Container::value_type&>;
};
// Concept discribing a map.
// Needs methods lower_bound() and emplace(key, value).
template <typename M>
concept Map =
requires(M map,
const typename M::key_type key,
const typename M::mapped_type value,
const typename M::iterator i) {
{
map.lower_bound(key)
} -> std::same_as<typename M::iterator>;
{
map.key_comp()
};
{
map.emplace(key, value)
} -> std::same_as<std::pair<typename M::iterator, bool>>;
requires std::same_as<
std::remove_cvref_t<decltype(*i)>,
std::pair<typename M::key_type const, typename M::mapped_type>>;
};
// Concept describing a ConstIterable but adds a constraint on the value_type
// the held type should be convertible into T
template <typename Container, typename T>
concept ConstIterableType = ConstIterable<Container>
&& std::convertible_to<typename Container::value_type, T>;
// Concept describing an Iterable but adds a constraint on the value_type
// the held type should be convertible into T
template <typename Container, typename T>
concept IterableType = Iterable<Container>
&& std::convertible_to<typename Container::value_type, T>;
// Concept describing an iterator on a type T
template <typename Iter, typename T>
concept Iterator =
std::forward_iterator<Iter> && std::same_as<typename Iter::value_type, T>;
} // namespace misc
|