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...> m_Values;
51 suite(std::string name, Ts&&... ts)
52 : m_Name{std::move(name)}
53 , m_Values{std::forward<Ts>(ts)...} {}
56 const std::string& name()
const noexcept {
return m_Name; }
59 const std::tuple<Ts...>& values()
const noexcept {
return m_Values; }
62 std::tuple<Ts...>& values()
noexcept {
return m_Values; }
75 using type = std::tuple<Ts...>;
79 requires ((!is_suite_v<Ts>) && ...)
82 using type = std::tuple<Ts...>;
88 using type = leaf_extractor_t<leaf_extractor_t<Ts>...>;
91 template<
class... Ts,
class... Us>
94 using type = std::tuple<Ts..., Us...>;
97 template<
class... Ts,
class... Us>
100 using type = std::tuple<leaf_extractor_t<
suite<Ts...>>, Us...>;
103 template<
class... Ts,
class... Us>
106 using type = std::tuple<Ts..., leaf_extractor_t<
suite<Us...>>>;
109 template<
class T,
class U,
class... Vs>
112 using type = leaf_extractor_t<leaf_extractor_t<T, U>, Vs...>;
115 template<
class T,
class Transform>
118 template<
class T,
class Transform>
121 template<
class... Ts,
class Transform>
122 requires (std::invocable<Transform, Ts> && ...)
125 using type = std::variant<std::remove_cvref_t<std::invoke_result_t<Transform, Ts>>...>;
128 template<
class T,
class... Ts,
class Transform>
129 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>>> && ...)
132 using type = std::remove_cvref_t<std::invoke_result_t<Transform, T>>;
135 template<
class... Ts,
class Transform>
145 template<
class... Ts>
155 using type = std::variant<T>;
158 template<
class... Ts,
class T>
159 requires (std::is_same_v<Ts, T> || ...)
162 using type = std::variant<Ts...>;
165 template<
class... Ts,
class T>
168 using type = std::variant<Ts..., T>;
171 template<
class... Ts,
class T,
class... Us>
174 using type = faithful_variant_t<faithful_variant_t<std::variant<Ts...>, T>, Us...>;
177 template<
class T,
class... Ts>
180 using type = faithful_variant_t<std::variant<T>, Ts...>;
184 template<
class T, std::invocable<T> Transform>
187 using type = std::invoke_result_t<Transform, T>;
190 template<
class T,
class Transform>
191 using to_variant_or_unique_type_t =
typename to_variant_or_unique_type<T, Transform>::type;
193 template<
class... Ts, std::invocable<
suite<Ts...>> Transform>
196 using variant_type = faithful_variant_t<std::invoke_result_t<Transform,
suite<Ts...>>, to_variant_or_unique_type_t<Ts, Transform>...>;
197 using type = std::conditional_t<std::variant_size_v<variant_type> == 1, std::variant_alternative_t<0, variant_type>, variant_type>;
202 template<
class... Ts,
class Fn>
205 [&] <std::size_t... Is> (std::index_sequence<Is...>) {
206 (fn(std::get<Is>(s.values())), ...);
207 }(std::make_index_sequence<
sizeof...(Ts)>{});
210 template<
class... Ts,
class Filter,
class Transform,
class Container,
class... PreviousSuites>
211 requires (is_suite_v<PreviousSuites> && ...) && ((!is_suite_v<Ts>) && ...)
212 Container&& extract_leaves(suite<Ts...>& s, Filter&& filter, Transform t, Container&& c,
const PreviousSuites&... previous)
215 [&] <
class V> (V&& val) {
216 if(filter(val, previous..., s)) c.emplace_back(t(std::move(val)));
220 extract_leaves(s, emplacer);
221 return std::forward<Container>(c);
224 template<
class... Ts,
class Filter,
class Transform,
class Container,
class... PreviousSuites>
225 requires (is_suite_v<PreviousSuites> && ...) && ((is_suite_v<Ts>) && ...)
226 Container&& extract_leaves(suite<Ts...>& s, Filter&& filter, Transform t, Container&& c,
const PreviousSuites&... previous)
229 [&]<
class V>(V&& val) { extract_leaves(std::forward<V>(val), std::forward<Filter>(filter), t, std::forward<Container>(c), previous..., s); }
232 extract_leaves(s, extractor);
233 return std::forward<Container>(c);
236 template<
class... Ts,
239 std::integral SizeType =
typename Tree::size_type,
241 requires maths::dynamic_tree<std::remove_cvref_t<Tree>>
242 Tree&& extract_tree(suite<Ts...>& s, Transform transform, Tree&& tree,
const SizeType parentNode, Fn fn)
244 const auto node{tree.add_node(parentNode, transform(s))};
246 [node, fn, &s] <std::size_t... Is> (std::index_sequence<Is...>) {
247 (fn(node, std::get<Is>(s.values())), ...);
248 }(std::make_index_sequence<
sizeof...(Ts)>{});
250 if(!std::ranges::distance(tree.cedges(node)))
253 return std::forward<Tree>(tree);
257 template<
class... Ts,
class Filter,
class Transform,
class Tree, std::integral SizeType =
typename Tree::size_type,
class... PreviousSuites>
258 requires maths::dynamic_tree<std::remove_cvref_t<Tree>> && (is_suite_v<PreviousSuites> && ...) && ((!is_suite_v<Ts>) && ...)
259 Tree&& extract_tree(suite<Ts...>& s, Filter&& filter, Transform transform, Tree&& tree,
const SizeType parentNode,
const PreviousSuites&... previous)
262 [&](SizeType node,
auto&& val) {
263 if(filter(val, previous..., s))
264 tree.add_node(node, transform(std::move(val)));
268 return impl::extract_tree(s, transform, std::forward<Tree>(tree), parentNode, emplacer);
271 template<
class... Ts,
class Filter,
class Transform,
class Tree, std::integral SizeType =
typename Tree::size_type,
class... PreviousSuites>
272 requires maths::dynamic_tree<std::remove_cvref_t<Tree>> && (is_suite_v<PreviousSuites> && ...) && ((is_suite_v<Ts>) && ...)
273 Tree&& extract_tree(suite<Ts...>& s, Filter&& filter, Transform transform, Tree&& tree,
const SizeType parentNode,
const PreviousSuites&... previous)
276 [&] <
class V> (SizeType node, V&& val) {
277 impl::extract_tree(std::forward<V>(val), std::forward<Filter>(filter), transform, std::forward<Tree>(tree), node, previous..., s);
281 return impl::extract_tree(s, transform, std::forward<Tree>(tree), parentNode, recurser);
285 template<
class Suite,
287 class Transform = std::identity,
288 class Container = std::vector<leaves_to_variant_or_unique_type_t<Suite, Transform>>>
289 requires is_suite_v<Suite>
291 Container extract_leaves(Suite s, Filter&& filter, Transform t = {})
293 return impl::extract_leaves(s, std::forward<Filter>(filter), std::move(t), Container{});
296 template<
class Suite,
299 maths::dynamic_tree Tree = maths::directed_tree<maths::tree_link_direction::forward, maths::null_weight, to_variant_or_unique_type_t<Suite, Transform>>>
300 requires is_suite_v<Suite>
302 Tree extract_tree(Suite s, Filter&& filter, Transform transform)
304 return impl::extract_tree(s, std::forward<Filter>(filter), std::move(transform), Tree{}, Tree::npos);
307 template<
class Suite,
310 maths::dynamic_tree Tree>
311 requires is_suite_v<Suite>
312 Tree& extract_tree(Suite s, Filter&& filter, Transform transform, Tree& tree,
typename Tree::size_type pos)
314 return impl::extract_tree(s, std::forward<Filter>(filter), std::move(transform), tree, pos);
320 requires has_intrinsic_nomenclator<T> || has_extrinsic_nomenclator<T>
322 std::string operator()(
const T& t)
const
324 return object::nomenclature(t);
335 inline constexpr bool granular_filter_for{
336 requires (
const ItemKeyType& val, ItemCompare comp, ItemProjector proj,
const T& t) {
337 { comp(val, proj(t)) } -> std::same_as<bool>;
350 using items_key_type = ItemKeyType;
351 using suites_map_type = std::vector<std::pair<std::string, bool>>;
352 using items_map_type = std::vector<std::pair<ItemKeyType, bool>>;
353 using selected_suites_iterator =
typename suites_map_type::const_iterator;
354 using selected_items_iterator =
typename items_map_type::const_iterator;
355 using optional_suite_selection = std::optional<std::vector<std::string>>;
356 using optional_item_selection = std::optional<std::vector<items_key_type>>;
359 : m_Compare{std::move(compare)}
360 , m_Proj{std::move(proj)}
363 granular_filter(optional_suite_selection selectedSuites, optional_item_selection selectedItems, ItemCompare compare = {}, ItemProjector proj = {})
364 : m_Compare{std::move(compare)}
365 , m_Proj{std::move(proj)}
366 , m_SelectedSuites{make(std::move(selectedSuites))}
367 , m_SelectedItems{make(std::move(selectedItems))}
370 void add_selected_suite(std::string name)
372 add(m_SelectedSuites, std::move(name));
375 void add_selected_item(items_key_type key)
377 add(m_SelectedItems, std::move(key));
380 template<
class T,
class... Suites>
381 requires (is_suite_v<Suites> && ...) && granular_filter_for<ItemKeyType, ItemCompare, ItemProjector, T>
383 bool operator()(
const T& val,
const Suites&... suites)
385 if(!m_SelectedSuites && !m_SelectedItems)
return true;
388 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{}) ... };
390 return std::ranges::any_of(isFound, [](
bool b) {
return b; });
394 std::optional<std::ranges::subrange<selected_suites_iterator>> selected_suites()
const noexcept
396 return m_SelectedSuites ? std::optional<std::ranges::subrange<selected_suites_iterator>>{{m_SelectedSuites->begin(), m_SelectedSuites->end()}} : std::nullopt;
400 std::optional<std::ranges::subrange<selected_items_iterator>> selected_items()
const noexcept
402 return m_SelectedItems ? std::optional<std::ranges::subrange<selected_items_iterator>>{{m_SelectedItems->begin(), m_SelectedItems->end()}} : std::nullopt;
409 operator bool()
const noexcept
411 return m_SelectedSuites || m_SelectedItems;
414 [[no_unique_address]] ItemCompare m_Compare{};
415 [[no_unique_address]] ItemProjector m_Proj{};
416 std::optional<suites_map_type> m_SelectedSuites{};
417 std::optional<items_map_type> m_SelectedItems{};
420 using opt_map_type = std::optional<std::vector<std::pair<Key, bool>>>;
423 static void add(opt_map_type<Key>& map, Key k)
425 using map_type =
typename opt_map_type<Key>::value_type;
426 if(!map) map = map_type{};
428 map->emplace_back(std::move(k),
false);
433 static opt_map_type<Key> make(std::optional<std::vector<Key>> selected)
435 if(!selected)
return std::nullopt;
437 std::vector<std::pair<Key, bool>> selection{};
438 for (
auto& e : *selected)
439 selection.emplace_back(std::move(e),
false);
444 template<
class Key,
class U,
class Projector,
class Comp>
445 static bool find(opt_map_type<Key>& selected,
const U& u, Projector proj, Comp compare)
449 auto found{std::ranges::find_if(*selected, [&proj, &compare, &u](
const std::pair<Key, bool>& e) {
return compare(e.first, proj(u)); })};
451 if(found != selected->end())
453 found->second =
true;
Restriction of Dynamic Graphs to Trees.
Traits and Concepts for graphs.
Utilities for associating types with names.
Definition: Suite.hpp:348
Definition: Suite.hpp:143
Definition: Suite.hpp:318
Definition: Suite.hpp:116
Definition: Suite.hpp:186