3#include <boost/mp11/algorithm.hpp>
4#include <boost/mp11/detail/mp_append.hpp>
5#include <boost/mp11/detail/mp_list.hpp>
6#include <boost/mp11/detail/mp_rename.hpp>
7#include <boost/mp11/integral.hpp>
8#include <boost/mp11/list.hpp>
28 consteval explicit Assignment(std::string_view name_, std::string_view exec_name_)
34 consteval explicit Assignment(std::string_view exec_name_out)
35 :
name{exec_name_out.substr(0, exec_name_out.find(
'.'))}
55namespace detail::meta {
57using namespace boost::mp11;
62template <
template <
typename...>
class TypeList,
typename... Ts>
67 return std::same_as<NormalizedT<T>, T>;
71 std::same_as<NormalizedTypeList<std::tuple, int, int&, const int, const int&>, std::tuple<int, int, int, int>>);
77using TypeOrMonostate = std::conditional_t<std::same_as<NormalizedT<T>,
void>, std::monostate, T>;
79template <std::size_t I,
typename... Ts>
80using Get = mp_at<mp_list<Ts...>, mp_int<I>>;
82template <
typename List,
typename T>
83static constexpr bool Has = mp_find<List, T>::value != mp_size<List>::value;
85template <
typename Orig,
typename... New>
88template <
typename Orig,
typename First,
typename... New>
91 static constexpr bool DoAddFirst = !Has<Orig, First>;
93 using FirstMergeRes = std::conditional_t<DoAddFirst, WithAddedFirst, Orig>;
98template <
typename Orig>
104template <
typename Orig,
typename... New>
107static_assert(std::same_as<MergeUnq<mp_list<int>,
int>, mp_list<int>>);
108static_assert(std::same_as<MergeUnq<mp_list<int>, int,
int>, mp_list<int>>);
109static_assert(std::same_as<MergeUnq<mp_list<int>,
double>, mp_list<int, double>>);
110static_assert(std::same_as<MergeUnq<mp_list<int>, double, int,
double>, mp_list<int, double>>);
111static_assert(std::same_as<MergeUnq<mp_list<int, double>, double, int,
double>, mp_list<int, double>>);
115template <
typename... MetadataTypes>
121 "To prevent dangling references and other issues, all type parameters of Metadata should be normalized."
122 "Use the provided deduction guide.");
124 template <
typename... Args>
126 requires(
sizeof...(Args) != 1 ||
128 explicit consteval Metadata(Args&&... args);
130 template <
typename... Args>
131 friend consteval auto create(Args&&... args);
133 template <
typename OtherMetadataType>
134 consteval auto operator|(OtherMetadataType&& attr)
const;
136 template <
typename... OtherMetadataTypes>
139 template <
typename MetadataType>
140 constexpr std::optional<MetadataType>
get()
const;
142 template <
typename MetadataType,
typename Func>
143 constexpr std::optional<detail::meta::TypeOrMonostate<std::invoke_result_t<Func, MetadataType>>>
146 template <
typename T>
147 static consteval bool has();
150 template <
typename... LArgs,
typename... RArgs, std::size_t I = 0>
151 static consteval auto merge_impl(std::tuple<LArgs...> largs, std::tuple<RArgs...> rargs);
153 template <
typename... LArgs,
typename RArg>
154 static consteval auto merge_impl(std::tuple<LArgs...> largs, RArg&& rarg);
156 template <
typename... Args>
157 explicit consteval Metadata(std::tuple<Args...> data);
159 std::tuple<MetadataTypes...> data_;
161 template <
typename... Ts>
166template <
typename... Args>
169template <
typename... Args>
172template <
typename... Args>
174 return (
Metadata<>{} | ... | std::forward<Args>(args));
179template <
typename... MetadataTypes>
180template <
typename... Args>
181 requires(
sizeof...(Args) != 1 ||
184 : data_{std::forward<Args>(args)...} {}
186template <
typename... MetadataTypes>
187template <
typename... Args>
191template <
typename... MetadataTypes>
192template <
typename... OtherMetadataTypes>
194 return (*
this | ... | std::get<OtherMetadataTypes>(other.data_));
197template <
typename... MetadataTypes>
198template <
typename OtherMetadataType>
200 using boost::mp11::mp_apply;
202 auto merge_res = merge_impl(data_, std::forward<OtherMetadataType>(attr));
204 using MetadataType = mp_apply<
Metadata,
decltype(merge_res)>;
206 return MetadataType{merge_res};
209template <
typename... MetadataTypes>
210template <
typename MetadataType>
212 if constexpr (has<MetadataType>()) {
213 return std::get<MetadataType>(data_);
219template <
typename... MetadataTypes>
220template <
typename MetadataType,
typename Func>
221constexpr std::optional<detail::meta::TypeOrMonostate<std::invoke_result_t<Func, MetadataType>>>
223 if constexpr (has<MetadataType>()) {
224 return std::invoke(std::forward<Func>(func), *get<MetadataType>());
230template <
typename... MetadataTypes>
233 using boost::mp11::mp_find, boost::mp11::mp_list;
235 using TypeList = mp_list<MetadataTypes...>;
236 constexpr auto IDX = mp_find<TypeList, T>::value;
238 return IDX <
sizeof...(MetadataTypes);
241template <
typename... MetadataTypes>
242template <
typename... LArgs,
typename... RArgs, std::size_t I>
244 if constexpr (I >=
sizeof...(LArgs)) {
247 largs = merge_impl<I + 1>(largs, rargs);
249 return merge_impl(largs, std::get<I>(rargs));
253template <
typename... MetadataTypes>
254template <
typename... LArgs,
typename RArg>
255consteval auto Metadata<MetadataTypes...>::merge_impl(std::tuple<LArgs...> largs, RArg&& rarg) {
258 using Ls = mp_list<LArgs...>;
259 using R = NormalizedT<RArg>;
261 constexpr auto IDX = mp_find<Ls, R>::value;
263 if constexpr (IDX ==
sizeof...(LArgs)) {
265 return std::tuple_cat(largs,
266 std::tuple{std::forward<RArg>(rarg)});
269 std::get<IDX>(largs) = std::forward<RArg>(rarg);
279template <
typename T =
void>
280static consteval auto global_file_metadata() {