1#ifndef _BBM_NAMED_UTIL_H_
2#define _BBM_NAMED_UTIL_H_
19 template<
typename TUP, string_literal... NAMES>
requires bbm::is_tuple_v<TUP>
26 template<
typename T>
requires is_named_v<T> && is_tuple_v<typename T::value_type>
39 template<
typename... T>
requires (is_named_v<T> && ...)
43 auto merge = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
45 constexpr auto names = std::tuple_cat( std::decay_t<T>::names...);
46 return make_named< std::get<IDX>(names)... >( std::tuple_cat(t.values()...) );
51 else return merge(std::make_index_sequence< (std::tuple_size_v<std::decay_t<T>> + ...) >{});
55 template<
typename... T>
requires (is_named_v<T> && ...)
67 template<
size_t START,
size_t COUNT,
typename NAMED>
requires is_named_v<NAMED> && ((START+COUNT) <= std::decay_t<NAMED>::size)
71 if constexpr (COUNT == 0)
return named<std::tuple<>{};
77 auto extract = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
82 return extract(std::make_index_sequence<COUNT>{});
87 template<
size_t START,
size_t COUNT,
typename NAMED>
requires is_named_v<NAMED> && ((START+COUNT) <= std::decay_t<NAMED>::size)
103 return static_cast<named<T, (PREFIX+NAMES)...
>>(t);
107 template<
string_literal PREFIX,
typename T>
requires is_named_v<T>
123 return static_cast<named<T, (NAMES + POSTFIX)...
>>(t);
127 template<
string_literal POSTFIX,
typename T>
requires is_named_v<T>
134 template<
string_literal PREFIX,
string_literal SEP,
bool cat_names,
typename T>
135 inline constexpr auto named_flatten(T&& t)
138 if constexpr (!is_named_v<T>) {
return make_named<PREFIX>(std::forward_as_tuple(t)); }
143 auto flatten = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
145 constexpr auto names = std::decay_t<T>::names;
146 return named_cat( (named_flatten<std::get<IDX>(names), SEP, cat_names>(std::get<IDX>(std::forward<T>(t))) )...);
150 auto result = flatten(std::make_index_sequence<std::decay_t<T>::size>{});
153 if constexpr (cat_names && !PREFIX.empty)
return prefix_names<PREFIX + SEP>( result );
169 template<
typename T>
requires is_named_v<T>
170 inline constexpr auto named_flatten(T&& t) {
return bbm::detail::named_flatten<
"",
"",
false>(std::forward<T>(t)); }
184 template<string_literal SEP=
".",
typename T>
requires is_named_v<T>
185 inline constexpr auto merge_named_flatten(T&& t) {
return bbm::detail::named_flatten<
"", SEP,
true>(std::forward<T>(t)); }
190 template<
typename NAMED>
191 inline constexpr bool is_named_sorted(
void)
193 auto all_sorted = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
195 return ((std::decay_t<NAMED>::template name<IDX> < std::decay_t<NAMED>::template name<IDX+1>) && ...);
198 if constexpr (std::decay_t<NAMED>::size <= 1)
return true;
199 else return all_sorted(std::make_index_sequence<std::decay_t<NAMED>::size - 1>{});
206 template<
typename NAMED>
requires is_named_v<NAMED>
212 template<
string_literal NAME,
typename NAMED,
size_t START=0,
size_t END = NAMED::size>
213 inline constexpr size_t binary_search_named(
void)
215 if constexpr (START >= END)
return START;
218 constexpr size_t IDX = (START + END) / 2;
219 if constexpr (IDX == NAMED::size)
return IDX;
220 else if constexpr (NAMED::template name<IDX> == NAME)
return IDX;
221 else if constexpr (NAMED::template name<IDX> < NAME)
return binary_search_named<NAME, NAMED, IDX+1, END>();
222 else return binary_search_named<NAME, NAMED, START, IDX>();
234 template<
string_literal NAME,
typename NAMED>
requires is_named_v<NAMED> && is_named_sorted_v<NAMED>
250 template<
typename NAMED,
size_t IDX=0,
typename PARTIAL=named<std::tuple<>>>
254 if constexpr (std::decay_t<NAMED>::size <= IDX)
return partial;
260 auto insert = []<string_literal NAME>(
auto&& t,
auto&& n)
262 using N =
decltype(n);
263 using T =
decltype(t);
264 constexpr size_t INSERT = binary_search_named_v<NAME, N>;
265 if constexpr (INSERT == 0)
return named_cat( make_named<NAME>(std::forward<T>(t)), std::forward<N>(n) );
266 else if constexpr (INSERT == std::decay_t<N>::size)
return named_cat( std::forward<N>(n), make_named<NAME>(std::forward<T>(t)) );
267 else return named_cat( subnamed<0, INSERT>(std::forward<N>(n)), make_named<NAME>(std::forward<T>(t)),
subnamed<INSERT, std::decay_t<N>::size - INSERT>(std::forward<N>(n)) );
271 return sort_named<NAMED, IDX+1>( std::forward<NAMED>(named), insert.template
operator()< std::decay_t<NAMED>::template name<IDX> >( std::get<IDX>(std::forward<NAMED>(named)), partial) );
291 template<
size_t START,
size_t END,
typename NAMED,
typename PROCESS,
typename... Ts>
292 inline auto binary_search_named(
const std::string& str, NAMED&& named, PROCESS&& process, Ts&&... context)
295 if constexpr (START >= END)
return process.template
operator()<START>(str, std::forward<NAMED>(named), std::forward<Ts>(context)...);
300 constexpr size_t IDX = (START+END) / 2;
301 static constexpr size_t size = std::decay_t<NAMED>::size;
302 std::string name(std::decay_t<NAMED>::template name<IDX>);
305 if(IDX ==
size || name == str)
return process.template operator()<IDX>(str, std::forward<NAMED>(named), std::forward<Ts>(context)...);
308 else if(name < str)
return binary_search_named<IDX+1, END>(str, std::forward<NAMED>(named), std::forward<PROCESS>(process), std::forward<Ts>(context)...);
311 else return binary_search_named<START, IDX>(str, std::forward<NAMED>(named), std::forward<PROCESS>(process), std::forward<Ts>(context)...);
354 template<
typename NAMED,
typename PROCESS,
typename... Ts>
requires
356 is_named_sorted_v<NAMED> &&
357 requires(PROCESS&& p)
358 { p.template operator()<size_t(0)>(std::declval<std::string>(), std::declval<NAMED>(), std::declval<Ts>()...); }
361 return bbm::detail::binary_search_named<0, std::decay_t<NAMED>::size>(str, std::forward<NAMED>(
named), std::forward<PROCESS>(process), std::forward<Ts>(context)...);
376 template<
typename NAMED,
typename PROCESS,
typename... Ts>
requires
378 requires(PROCESS&& p)
379 { p.template operator()<size_t(0)>(std::declval<std::string>(), std::declval<NAMED>(), std::declval<Ts>()...); }
382 using result_t =
decltype( process.template operator()<size_t(0)>(std::declval<std::string>(), std::declval<NAMED>(), std::declval<Ts>()...) );
385 if constexpr (std::is_void_v<result_t>)
389 CONSTFOR(IDX, std::decay_t<NAMED>::size,
391 if(str == std::string(std::decay_t<NAMED>::template name<IDX>)) process.template
operator()<IDX>(str, std::forward<NAMED>(
named), std::forward<Ts>(context)...);
395 if(!found) process.template operator()<std::decay_t<NAMED>::size>(str, std::forward<NAMED>(
named), std::forward<Ts>(context)...);
405 CONSTFOR(IDX, std::decay_t<NAMED>::size,
407 if(str == std::string(std::decay_t<NAMED>::template name<IDX>))
409 result = process.template operator()<IDX>(str, std::forward<NAMED>(
named), std::forward<Ts>(context)...);
415 if(!found) result = process.template operator()<std::decay_t<NAMED>::size>(str, std::forward<NAMED>(
named), std::forward<Ts>(context)...);
#define CONSTFOR(IDX, NUMITR,...)
HELPER MACRO.
Definition: constfor.h:63
Definition: aggregatebsdf.h:29
constexpr auto named_cat(T &&... t)
cat named types
Definition: named_util.h:40
constexpr auto merge_named_flatten(T &&t)
flatten a named type with merging names
Definition: named_util.h:185
constexpr named< anonymize_t< T >, NAMES... > make_named(T &&t)
Make a named of a gettable type (with size == #NAMES); renames if the type is a named container.
Definition: named.h:293
decltype(prefix_names< PREFIX >(std::declval< T >())) prefix_names_t
type of named tuple with pre-fixed name.
Definition: named_util.h:108
constexpr auto value_copy_named(const named< TUP, NAMES... > &src)
value copy a named tuple
Definition: named_util.h:20
auto linear_search_named(const std::string &str, NAMED &&named, PROCESS &&process, Ts &&... context)
linear search for unsorted named tuples
Definition: named_util.h:380
constexpr auto sort_named(NAMED &&named, PARTIAL &&partial=PARTIAL{})
sort a named tuple by name using insert-sort.
Definition: named_util.h:251
constexpr auto subnamed(NAMED &&named)
get a subset of a named tuple
Definition: named_util.h:68
auto binary_search_named(const std::string &str, NAMED &&named, PROCESS &&process, Ts &&... context)
Run-time binary search for a matching name in a named tuple based on a string. The (index of the) fou...
Definition: named_util.h:359
decltype(subnamed< START, COUNT, NAMED >(std::declval< NAMED >())) subnamed_t
type of subnamed
Definition: named_util.h:88
static constexpr bool is_named_sorted_v
true if named tuple is sorted by name
Definition: named_util.h:207
static constexpr size_t binary_search_named_v
binary search a sorted named tuple
Definition: named_util.h:235
size_t size(T &&t)
Definition: iterator_util.h:22
decltype(value_copy_named(std::declval< T >())) value_copy_named_t
type of value copying a named typle
Definition: named_util.h:27
constexpr auto named_flatten(T &&t)
flatten a named type without merging names
Definition: named_util.h:170
constexpr auto prefix_names(named< T, NAMES... > t)
prefix names in type
Definition: named_util.h:101
decltype(named_cat(std::declval< T >()...)) named_cat_t
type of concatting multiple named tuples.
Definition: named_util.h:56
constexpr auto postfix_names(named< T, NAMES... > t)
postfix names in type
Definition: named_util.h:121
constexpr auto value_copy_tuple(const std::tuple< ARGS... > &tup)
Value-copy a tuple.
Definition: tuple.h:61
decltype(post_names< POSTFIX >(std::declval< T >())) postfix_names_t
type of named tuple with post-fixed name.
Definition: named_util.h:128
named container
Definition: named.h:131
constexpr T & values(void)
\names Querry/cast values from the underlying container
Definition: named.h:182
Definition: string_literal.h:16
A wrapper for STL containers such as tuple, pair, and array. These containers force the programmer to...