#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace hysj::inline _HYSJ_VERSION_NAMESPACE::graphs{ namespace connected_components{ #define HYSJ_GRAPHS_CONNECTED_COMPONENTS_EVENT_TAGS \ (component_begin) \ (member) \ (component_end) enum class event_tag : unsigned { HYSJ_SPLAT(0,HYSJ_GRAPHS_CONNECTED_COMPONENTS_EVENT_TAGS) }; HYSJ_MIRROR_ENUM(event_tag, HYSJ_GRAPHS_CONNECTED_COMPONENTS_EVENT_TAGS) #define HYSJ_LAMBDA(id) \ using id##_tag_type = constant_t; \ inline constexpr auto id##_tag = constant_c; HYSJ_MAP_LAMBDA(HYSJ_GRAPHS_CONNECTED_COMPONENTS_EVENT_TAGS) #undef HYSJ_LAMBDA namespace events{ template struct component{ static constexpr constant_t tag{}; auto operator<=>(const component &) const = default; friend HYSJ_MIRROR_STRUCT(component); }; using component_begin = component; using component_end = component; template struct member{ static constexpr member_tag_type tag{}; element_id element; auto operator<=>(const member &) const = default; friend HYSJ_MIRROR_STRUCT(member,element); }; } template struct bidirectional_dfs_output{ CCInput cc_input; CCOutput cc_output; template auto operator()(DFSProtoPromise,const auto &,auto dfs_event) -> coroutines::return_object_t { auto &dfs_promise = HYSJ_PROMISE(DFSProtoPromise); if constexpr(dfs_event.tag == dfs::root_tag) co_await (cc_output(dfs_promise, events::component_begin{}), void_qua{})(); if constexpr(dfs_event.tag == any_of(dfs::root_tag,dfs::sprout_tag, dfs::climb_tag,dfs::frond_tag, dfs::vine_tag,dfs::liana_tag, dfs::weed_tag)) co_await (cc_output(dfs_promise, events::member{ .element = dfs_event.element }), void_qua{})(); if constexpr(dfs_event.tag == dfs::palm_tag) co_await (cc_output(dfs_promise, events::component_end{}), void_qua{})(); co_return; } }; inline constexpr auto make_bidirectional_dfs_output = [](auto cc_input,auto cc_output){ return combine<0>( bidirectional_dfs_output{ .cc_input = cc_input, .cc_output = cc_output }, std::bind_front(coroutines::get_proto_promise,type_c)); }; template struct input{ DFSFactory dfs_factory; friend HYSJ_MIRROR_STRUCT(input,dfs_factory); }; //FIXME: constrain - jeh auto algorithm(auto cc_proto_promise, auto cc_input, auto cc_output){ return cc_input.dfs_factory( cc_proto_promise, make_bidirectional_dfs_output(cc_input,cc_output)); } } //connected_components namespace cc = connected_components; } //hysj::graphs #include