25namespace sequoia::object
37 requires ((is_suite_v<Ts> && ...) || ((!is_suite_v<Ts>) && ...))
44 requires ((is_suite_v<Ts> && ...) || ((!is_suite_v<Ts>) && ...))
49 std::tuple<Ts...> values;
51 suite(std::string name, Ts&&... ts)
52 : name{std::move(name)}
53 , values{std::forward<Ts>(ts)...} {}
66 using type = std::tuple<Ts...>;
70 requires ((!is_suite_v<Ts>) && ...)
73 using type = std::tuple<Ts...>;
79 using type = leaf_extractor_t<leaf_extractor_t<Ts>...>;
82 template<
class... Ts,
class... Us>
85 using type = std::tuple<Ts..., Us...>;
88 template<
class... Ts,
class... Us>
91 using type = std::tuple<leaf_extractor_t<
suite<Ts...>>, Us...>;
94 template<
class... Ts,
class... Us>
97 using type = std::tuple<Ts..., leaf_extractor_t<
suite<Us...>>>;
100 template<
class T,
class U,
class... Vs>
103 using type = leaf_extractor_t<leaf_extractor_t<T, U>, Vs...>;
106 template<
class T,
class Transform>
109 template<
class T,
class Transform>
112 template<
class... Ts,
class Transform>
113 requires (std::invocable<Transform, Ts> && ...)
116 using type = std::variant<std::remove_cvref_t<std::invoke_result_t<Transform, Ts>>...>;
119 template<
class T,
class... Ts,
class Transform>
120 requires (std::is_same_v<std::remove_cvref_t<std::invoke_result_t<Transform, T>>, std::remove_cvref_t<std::invoke_result_t<Transform, Ts>>> && ...)
123 using type = std::remove_cvref_t<std::invoke_result_t<Transform, T>>;
126 template<
class... Ts,
class Transform>
136 template<
class... Ts>
146 using type = std::variant<T>;
149 template<
class... Ts,
class T>
150 requires (std::is_same_v<Ts, T> || ...)
153 using type = std::variant<Ts...>;
156 template<
class... Ts,
class T>
159 using type = std::variant<Ts..., T>;
162 template<
class... Ts,
class T,
class... Us>
165 using type = faithful_variant_t<faithful_variant_t<std::variant<Ts...>, T>, Us...>;
168 template<
class T,
class... Ts>
171 using type = faithful_variant_t<std::variant<T>, Ts...>;
175 template<
class T, std::invocable<T> Transform>
178 using type = std::invoke_result_t<Transform, T>;
181 template<
class T,
class Transform>
182 using to_variant_or_unique_type_t =
typename to_variant_or_unique_type<T, Transform>::type;
184 template<
class... Ts, std::invocable<
suite<Ts...>> Transform>
187 using variant_type = faithful_variant_t<std::invoke_result_t<Transform,
suite<Ts...>>, to_variant_or_unique_type_t<Ts, Transform>...>;
188 using type = std::conditional_t<std::variant_size_v<variant_type> == 1, std::variant_alternative_t<0, variant_type>, variant_type>;
193 template<
class... Ts,
class Fn>
196 [&] <std::size_t... Is> (std::index_sequence<Is...>) {
197 (fn(std::get<Is>(s.values)), ...);
198 }(std::make_index_sequence<
sizeof...(Ts)>{});
201 template<
class... Ts,
class Filter,
class Transform,
class Container,
class... PreviousSuites>
202 requires (is_suite_v<PreviousSuites> && ...) && ((!is_suite_v<Ts>) && ...)
203 Container&& extract_leaves(suite<Ts...>& s, Filter&& filter, Transform t, Container&& c,
const PreviousSuites&... previous)
206 [&] <
class V> (V&& val) {
207 if(filter(val, previous..., s)) c.emplace_back(t(std::move(val)));
211 extract_leaves(s, emplacer);
212 return std::forward<Container>(c);
215 template<
class... Ts,
class Filter,
class Transform,
class Container,
class... PreviousSuites>
216 requires (is_suite_v<PreviousSuites> && ...) && ((is_suite_v<Ts>) && ...)
217 Container&& extract_leaves(suite<Ts...>& s, Filter&& filter, Transform t, Container&& c,
const PreviousSuites&... previous)
220 [&]<
class V>(V&& val) { extract_leaves(std::forward<V>(val), std::forward<Filter>(filter), t, std::forward<Container>(c), previous..., s); }
223 extract_leaves(s, extractor);
224 return std::forward<Container>(c);
227 template<
class... Ts,
230 std::integral SizeType =
typename Tree::size_type,
232 requires maths::dynamic_tree<std::remove_cvref_t<Tree>>
233 Tree&& extract_tree(suite<Ts...>& s, Transform transform, Tree&& tree,
const SizeType parentNode, Fn fn)
235 const auto node{tree.add_node(parentNode, transform(s))};
237 [node, fn, &s] <std::size_t... Is> (std::index_sequence<Is...>) {
238 (fn(node, std::get<Is>(s.values)), ...);
239 }(std::make_index_sequence<
sizeof...(Ts)>{});
241 if(!std::ranges::distance(tree.cedges(node)))
244 return std::forward<Tree>(tree);
248 template<
class... Ts,
class Filter,
class Transform,
class Tree, std::integral SizeType =
typename Tree::size_type,
class... PreviousSuites>
249 requires maths::dynamic_tree<std::remove_cvref_t<Tree>> && (is_suite_v<PreviousSuites> && ...) && ((!is_suite_v<Ts>) && ...)
250 Tree&& extract_tree(suite<Ts...>& s, Filter&& filter, Transform transform, Tree&& tree,
const SizeType parentNode,
const PreviousSuites&... previous)
253 [&](SizeType node,
auto&& val) {
254 if(filter(val, previous..., s))
255 tree.add_node(node, transform(std::move(val)));
259 return impl::extract_tree(s, transform, std::forward<Tree>(tree), parentNode, emplacer);
262 template<
class... Ts,
class Filter,
class Transform,
class Tree, std::integral SizeType =
typename Tree::size_type,
class... PreviousSuites>
263 requires maths::dynamic_tree<std::remove_cvref_t<Tree>> && (is_suite_v<PreviousSuites> && ...) && ((is_suite_v<Ts>) && ...)
264 Tree&& extract_tree(suite<Ts...>& s, Filter&& filter, Transform transform, Tree&& tree,
const SizeType parentNode,
const PreviousSuites&... previous)
267 [&] <
class V> (SizeType node, V&& val) {
268 impl::extract_tree(std::forward<V>(val), std::forward<Filter>(filter), transform, std::forward<Tree>(tree), node, previous..., s);
272 return impl::extract_tree(s, transform, std::forward<Tree>(tree), parentNode, recurser);
276 template<
class Suite,
278 class Transform = std::identity,
279 class Container = std::vector<leaves_to_variant_or_unique_type_t<Suite, Transform>>>
280 requires is_suite_v<Suite>
282 Container extract_leaves(Suite s, Filter&& filter, Transform t = {})
284 return impl::extract_leaves(s, std::forward<Filter>(filter), std::move(t), Container{});
287 template<
class Suite,
290 maths::dynamic_tree Tree = maths::directed_tree<maths::tree_link_direction::forward, maths::null_weight, to_variant_or_unique_type_t<Suite, Transform>>>
291 requires is_suite_v<Suite>
293 Tree extract_tree(Suite s, Filter&& filter, Transform transform)
295 return impl::extract_tree(s, std::forward<Filter>(filter), std::move(transform), Tree{}, Tree::npos);
298 template<
class Suite,
301 maths::dynamic_tree Tree>
302 requires is_suite_v<Suite>
303 Tree& extract_tree(Suite s, Filter&& filter, Transform transform, Tree& tree,
typename Tree::size_type pos)
305 return impl::extract_tree(s, std::forward<Filter>(filter), std::move(transform), tree, pos);
311 requires has_intrinsic_nomenclator<T> || has_extrinsic_nomenclator<T>
313 std::string operator()(
const T& t)
const
315 return object::nomenclature(t);
326 inline constexpr bool granular_filter_for{
327 requires (
const ItemKeyType& val, ItemCompare comp, ItemProjector proj,
const T& t) {
328 { comp(val, proj(t)) } -> std::same_as<bool>;
341 using items_key_type = ItemKeyType;
342 using suites_map_type = std::vector<std::pair<std::string, bool>>;
343 using items_map_type = std::vector<std::pair<ItemKeyType, bool>>;
344 using selected_suites_iterator =
typename suites_map_type::const_iterator;
345 using selected_items_iterator =
typename items_map_type::const_iterator;
346 using optional_suite_selection = std::optional<std::vector<std::string>>;
347 using optional_item_selection = std::optional<std::vector<items_key_type>>;
350 : m_Compare{std::move(compare)}
351 , m_Proj{std::move(proj)}
354 granular_filter(optional_suite_selection selectedSuites, optional_item_selection selectedItems, ItemCompare compare = {}, ItemProjector proj = {})
355 : m_Compare{std::move(compare)}
356 , m_Proj{std::move(proj)}
357 , m_SelectedSuites{make(std::move(selectedSuites))}
358 , m_SelectedItems{make(std::move(selectedItems))}
361 void add_selected_suite(std::string name)
363 add(m_SelectedSuites, std::move(name));
366 void add_selected_item(items_key_type key)
368 add(m_SelectedItems, std::move(key));
371 template<
class T,
class... Suites>
372 requires (is_suite_v<Suites> && ...) && granular_filter_for<ItemKeyType, ItemCompare, ItemProjector, T>
374 bool operator()(
const T& val,
const Suites&... suites)
376 if(!m_SelectedSuites && !m_SelectedItems)
return true;
379 std::array<bool,
sizeof...(Suites) + 1> isFound{ find(m_SelectedItems, val, m_Proj, m_Compare), find(m_SelectedSuites, suites,
item_to_name{}, std::ranges::equal_to{}) ... };
381 return std::ranges::any_of(isFound, [](
bool b) {
return b; });
385 std::optional<std::ranges::subrange<selected_suites_iterator>> selected_suites()
const noexcept
387 return m_SelectedSuites ? std::optional<std::ranges::subrange<selected_suites_iterator>>{{m_SelectedSuites->begin(), m_SelectedSuites->end()}} : std::nullopt;
391 std::optional<std::ranges::subrange<selected_items_iterator>> selected_items()
const noexcept
393 return m_SelectedItems ? std::optional<std::ranges::subrange<selected_items_iterator>>{{m_SelectedItems->begin(), m_SelectedItems->end()}} : std::nullopt;
400 operator bool()
const noexcept
402 return m_SelectedSuites || m_SelectedItems;
405 [[no_unique_address]] ItemCompare m_Compare{};
406 [[no_unique_address]] ItemProjector m_Proj{};
407 std::optional<suites_map_type> m_SelectedSuites{};
408 std::optional<items_map_type> m_SelectedItems{};
411 using opt_map_type = std::optional<std::vector<std::pair<Key, bool>>>;
414 static void add(opt_map_type<Key>& map, Key k)
416 using map_type =
typename opt_map_type<Key>::value_type;
417 if(!map) map = map_type{};
419 map->emplace_back(std::move(k),
false);
424 static opt_map_type<Key> make(std::optional<std::vector<Key>> selected)
426 if(!selected)
return std::nullopt;
428 std::vector<std::pair<Key, bool>> selection{};
429 for (
auto& e : *selected)
430 selection.emplace_back(std::move(e),
false);
435 template<
class Key,
class U,
class Projector,
class Comp>
436 static bool find(opt_map_type<Key>& selected,
const U& u, Projector proj, Comp compare)
440 auto found{std::ranges::find_if(*selected, [&proj, &compare, &u](
const std::pair<Key, bool>& e) {
return compare(e.first, proj(u)); })};
442 if(found != selected->end())
444 found->second =
true;
Restriction of Dynamic Graphs to Trees.
Traits and Concepts for graphs.
Utilities for associating types with names.
Definition: Suite.hpp:339
Definition: Suite.hpp:134
Definition: Suite.hpp:309
Definition: Suite.hpp:107
Definition: Suite.hpp:177