4
4
5
5
#include < stdx/compiler.hpp>
6
6
#include < stdx/ct_string.hpp>
7
+ #include < stdx/type_traits.hpp>
7
8
8
9
#include < boost/mp11/algorithm.hpp>
9
10
10
11
namespace stdx {
11
12
inline namespace v1 {
13
+ namespace _env {
12
14
template <auto Query, auto Value> struct ct_prop {
13
15
[[nodiscard]] CONSTEVAL static auto query (decltype (Query)) noexcept {
14
16
return Value;
15
17
}
16
18
};
17
19
18
- namespace _env {
19
20
template <typename Q, typename Env>
20
21
concept valid_query_for = requires (Env const &e) { e.query (Q{}); };
21
22
@@ -38,6 +39,9 @@ template <typename... Envs> struct env {
38
39
}
39
40
};
40
41
42
+ template <typename T>
43
+ concept envlike = is_specialization_of_v<T, env>;
44
+
41
45
namespace _env {
42
46
template <typename T> struct autowrap {
43
47
// NOLINTNEXTLINE(google-explicit-constructor)
@@ -64,25 +68,28 @@ template <auto V> struct wrap {
64
68
template <typename > struct for_each_pair ;
65
69
template <std::size_t ... Is> struct for_each_pair <std::index_sequence<Is...>> {
66
70
template <auto ... Args>
67
- using type =
68
- env< ct_prop<boost::mp11::mp_at_c<boost::mp11::mp_list<wrap<Args>...>,
69
- 2 * Is>::value.value,
70
- boost::mp11::mp_at_c<boost::mp11::mp_list<wrap<Args>...>,
71
- (2 * Is) + 1 >::value.value>...>;
71
+ using type = env<
72
+ _env:: ct_prop<boost::mp11::mp_at_c<boost::mp11::mp_list<wrap<Args>...>,
73
+ 2 * Is>::value.value,
74
+ boost::mp11::mp_at_c<boost::mp11::mp_list<wrap<Args>...>,
75
+ (2 * Is) + 1 >::value.value>...>;
72
76
};
73
77
74
- template <typename Env = env<>>
78
+ template <envlike Env = env<>>
75
79
constexpr auto make_env = []<autowrap... Args> {
76
80
using new_env_t = typename for_each_pair<
77
81
std::make_index_sequence<sizeof ...(Args) / 2 >>::template type<Args...>;
78
82
return boost::mp11::mp_append<new_env_t , Env>{};
79
83
};
80
84
} // namespace _env
81
85
82
- template <typename Env, _env::autowrap... Args>
86
+ template <envlike Env, _env::autowrap... Args>
83
87
using extend_env_t =
84
88
decltype (_env::make_env<Env>.template operator ()<Args...>());
85
89
90
+ template <envlike... Envs>
91
+ using append_env_t = boost::mp11::mp_reverse<boost::mp11::mp_append<Envs...>>;
92
+
86
93
template <_env::autowrap... Args>
87
94
using make_env_t = extend_env_t <env<>, Args...>;
88
95
} // namespace v1
0 commit comments