-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconstexpr_map.hpp
74 lines (59 loc) · 2.76 KB
/
constexpr_map.hpp
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
#pragma once
#include <algorithm>
#include <concepts>
#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>
#include "get_nth_element.hpp"
#include "constant_parameter.hpp"
namespace mlib {
template <auto T> static constexpr auto c_p = constexpr_parameter<T>{};
template <auto A, auto B> struct member_map {
constexpr auto operator[](constexpr_parameter<A>) const noexcept {
return B;
}
constexpr auto key() { return A; }
constexpr auto value() { return B; }
template<auto X> constexpr auto has_key() { return X == A; }
template<auto X> constexpr auto has_value() { return X == B; }
};
template <auto... members>
struct constexpr_map : constexpr_parameter<members>::type... {
using decltype(members)::operator[]...;
template<auto T> constexpr auto get_member() const noexcept -> decltype(auto)
{
return mlib::get_nth_element<T>(members...);
}
template <auto T> constexpr auto lookup() const noexcept {
return this->operator[](constexpr_parameter<T>{});
}
template <auto T> constexpr auto get() const noexcept {
return this->operator[](constexpr_parameter<T>{});
}
template <auto T>
constexpr auto has_value(constexpr_parameter<T>) const noexcept {
return[]<std::size_t... indexes>(std::index_sequence<indexes...>) {
return ((mlib::get_nth_element<indexes>(members...).template has_value<T>() || ...)) || get_nth_element<sizeof...(members) - 1>(members...).template has_value<T>();
}(std::make_index_sequence<sizeof...(members) - 1>{});
}
template <auto T>
constexpr auto has_key(constexpr_parameter<T>) const noexcept {
return[]<std::size_t... indexes>(std::index_sequence<indexes...>) {
return ((mlib::get_nth_element<indexes>(members...).template has_key<T>() || ...)) || get_nth_element<sizeof...(members) - 1>(members...).template has_key<T>();
}(std::make_index_sequence<sizeof...(members) - 1>{});
}
constexpr auto get_keys() const noexcept {
return[]<std::size_t... indexes>(std::index_sequence<indexes...>) {
return std::make_tuple(
(mlib::get_nth_element<indexes>(members...).key())...);
}(std::make_index_sequence<sizeof...(members)>{});
}
constexpr auto get_values() const noexcept {
return [] <std::size_t... indexes>(std::index_sequence<indexes...>) {
return std::make_tuple(
(mlib::get_nth_element<indexes>(members...).value())...);
}(std::make_index_sequence<sizeof...(members)>{});
}
};
} // namespace mlib