diff --git a/examples/example1/example1.cpp b/examples/example1/example1.cpp index 45f35b7..148ee2f 100644 --- a/examples/example1/example1.cpp +++ b/examples/example1/example1.cpp @@ -71,7 +71,7 @@ auto main() -> int { auto camera_source = kangaru::external_reference_source{camera}; auto model_source = kangaru::object_source{model}; - auto source = kangaru::with_tree_recursion{ + auto source = kangaru::with_recursion{ kangaru::with_construction{ kangaru::tie(camera_source, model_source), kangaru::non_empty_construction{}, diff --git a/include/kangaru/detail/recursive_source.hpp b/include/kangaru/detail/recursive_source.hpp index 9648c7e..334cfea 100644 --- a/include/kangaru/detail/recursive_source.hpp +++ b/include/kangaru/detail/recursive_source.hpp @@ -131,7 +131,7 @@ namespace kangaru { constexpr auto operator()(Source&& source) const { return make_injector(KANGARU5_FWD(source))(construct{}); } - + private: KANGARU5_NO_UNIQUE_ADDRESS MakeInjector make_injector; @@ -199,61 +199,6 @@ namespace kangaru { using placeholder_construct = basic_placeholder_construct; - template - struct with_recursion { - constexpr explicit with_recursion(Source source) noexcept - requires (std::default_initializable) : - source{std::move(source)}, construct{} {} - - constexpr with_recursion(Source source, Construct construct) noexcept : - source{std::move(source)}, construct{std::move(construct)} {} - - Source source; - - private: - template Self> - requires wrapping_source_of - friend constexpr auto provide(provide_tag, Self&& source) -> T { - return provide(provide_tag_v, KANGARU5_FWD(source).source); - } - - template Self> - requires (not wrapping_source_of and callable_template1>>) - friend constexpr auto provide(provide_tag, Self&& source) -> T { - return source.construct.template operator()(ref(source)); - } - - KANGARU5_NO_UNIQUE_ADDRESS - Construct construct; - }; - - template - using with_recursive_construct = with_recursion; - - template requires source> - inline constexpr auto make_source_with_recursive_construct(Source&& source) { - return with_recursive_construct>{KANGARU5_FWD(source)}; - } - - template - using with_unsafe_exhaustive_recursive_construct = with_recursion; - - template requires source> - inline constexpr auto make_source_with_unsafe_exhaustive_recursive_construct(Source&& source) { - return with_unsafe_exhaustive_recursive_construct>{KANGARU5_FWD(source)}; - } - - template - using with_exhaustive_recursive_construct = with_recursion; - - template requires source> - inline constexpr auto make_source_with_exhaustive_recursive_construct(Source&& source) { - return with_exhaustive_recursive_construct>{KANGARU5_FWD(source)}; - } - - template - concept construction_tree_needs = not source_of>, Tree>; - // deep template struct rebind_wrapper {}; @@ -301,8 +246,8 @@ namespace kangaru { }; template - struct with_tree_recursion { - explicit constexpr with_tree_recursion(Source source) noexcept : source{std::move(source)} {} + struct with_recursion { + explicit constexpr with_recursion(Source source) noexcept : source{std::move(source)} {} template auto test() { @@ -313,7 +258,7 @@ namespace kangaru { private: template requires (not rebindable_wrapping_source and not reference_wrapper) - constexpr static auto rebind_tree_for(forwarded auto&& self, Leaf&) noexcept -> auto { + constexpr static auto rebind_tree_for(forwarded auto&& self, Leaf&) noexcept -> auto { if constexpr (source_of and reference_wrapper) { return self.source; } else if constexpr (source_of) { @@ -321,17 +266,17 @@ namespace kangaru { } else if constexpr (reference_wrapper) { return make_source_with_filter_passthrough(self); } else { - return make_source_with_filter_passthrough(with_tree_recursion{kangaru::ref(self.source)}); + return make_source_with_filter_passthrough(with_recursion{kangaru::ref(self.source)}); } } template - constexpr static auto rebind_tree_for(forwarded auto&& self, Wrapper& source) noexcept -> auto { + constexpr static auto rebind_tree_for(forwarded auto&& self, Wrapper& source) noexcept -> auto { return typename rebind_wrapper::template ttype(KANGARU5_FWD(self), source.source))>{rebind_tree_for(KANGARU5_FWD(self), source.source)}; } template - constexpr static auto rebind_tree_for(forwarded auto&& self, Wrapper& source) noexcept -> auto { + constexpr static auto rebind_tree_for(forwarded auto&& self, Wrapper& source) noexcept -> auto { return typename rebind_wrapper::template ttype(KANGARU5_FWD(self), source.source)), decltype(kangaru::ref(source))>{ rebind_tree_for(KANGARU5_FWD(self), source.source), kangaru::ref(source), @@ -339,24 +284,66 @@ namespace kangaru { } template requires reference_wrapper - constexpr auto rebind_tree_for(forwarded auto&& self, Wrapper wrapper) -> auto { + constexpr auto rebind_tree_for(forwarded auto&& self, Wrapper wrapper) -> auto { return rebind_tree_for(KANGARU5_FWD(self), wrapper.unwrap()); } - template Self, typename T> + template Self, typename T> using rebind_tree_t = decltype(std::declval().template rebind_tree_for(std::declval(), std::declval().source)); public: - template Self> requires (not wrapping_source_of) + template Self> requires (not wrapping_source_of) friend constexpr auto provide(provide_tag tag, Self&& source) -> T requires source_of, T> { return provide(tag, source.template rebind_tree_for(KANGARU5_FWD(source), KANGARU5_FWD(source).source)); } - template Self> requires wrapping_source_of + template Self> requires wrapping_source_of friend constexpr auto provide(provide_tag tag, Self&& source) -> T { return provide(tag, KANGARU5_FWD(source).source); } }; + + template + struct with_construction { + explicit constexpr with_construction(Source source) noexcept + requires std::default_initializable : + source{std::move(source)} {} + + constexpr with_construction(Source source, Construct construct) noexcept : + source{std::move(source)}, + construct{std::move(construct)} {} + + template Self> requires wrapping_source_of + friend constexpr auto provide(provide_tag, Self&& source) -> T { + return provide(provide_tag_v, KANGARU5_FWD(source).source); + } + + template Self> requires (callable_template1> and not wrapping_source_of) + friend constexpr auto provide(provide_tag, Self&& source) -> T { + return source.construct.template operator()(KANGARU5_FWD(source).source); + } + + Source source; + + private: + Construct construct; + }; + + template requires (source> and movable_object>) + inline constexpr auto make_source_with_construction(Source&& source, Construct&& construct) { + return with_construction, std::remove_cvref_t>{KANGARU5_FWD(source), KANGARU5_FWD(construct)}; + } + + template + concept construction_tree_needs = not source_of< + with_recursion< + with_construction< + noop_source, + placeholder_construct_except + > + >&, + Tree + >; } #include "undef.hpp" diff --git a/include/kangaru/detail/source_from_tag.hpp b/include/kangaru/detail/source_from_tag.hpp index 195139b..36d3417 100644 --- a/include/kangaru/detail/source_from_tag.hpp +++ b/include/kangaru/detail/source_from_tag.hpp @@ -14,37 +14,6 @@ #include "define.hpp" namespace kangaru { - template - struct with_construction { - explicit constexpr with_construction(Source source) noexcept - requires std::default_initializable : - source{std::move(source)} {} - - constexpr with_construction(Source source, Construct construct) noexcept : - source{std::move(source)}, - construct{std::move(construct)} {} - - template Self> requires wrapping_source_of - friend constexpr auto provide(provide_tag, Self&& source) -> T { - return provide(provide_tag_v, KANGARU5_FWD(source).source); - } - - template Self> requires (callable_template1> and not wrapping_source_of) - friend constexpr auto provide(provide_tag, Self&& source) -> T { - return source.construct.template operator()(KANGARU5_FWD(source).source); - } - - Source source; - - private: - Construct construct; - }; - - template requires (source> and movable_object>) - inline constexpr auto make_source_with_construction(Source&& source, Construct&& construct) { - return with_construction, std::remove_cvref_t>{KANGARU5_FWD(source), KANGARU5_FWD(construct)}; - } - template struct with_source_from_tag { explicit constexpr with_source_from_tag(Source source) noexcept : diff --git a/tests/src/5-runtime-source.cpp b/tests/src/5-runtime-source.cpp index ce37a06..eeeb71b 100644 --- a/tests/src/5-runtime-source.cpp +++ b/tests/src/5-runtime-source.cpp @@ -104,7 +104,7 @@ TEST_CASE("Runtime source will cache sources results", "[deducer]") { static_assert(kangaru::stateful_rebindable_wrapping_source>); static_assert(kangaru::stateful_rebindable_wrapping_source>>); - auto basic_recursion_test = kangaru::with_tree_recursion>>{ + auto basic_recursion_test = kangaru::with_recursion>>{ kangaru::with_cache>{kangaru::with_heap_storage{increment_source{}}} }; @@ -112,7 +112,7 @@ TEST_CASE("Runtime source will cache sources results", "[deducer]") { } SECTION("Recursion with heap and cache and construction") { - auto source = kangaru::with_tree_recursion{ + auto source = kangaru::with_recursion{ kangaru::make_source_with_dereference( kangaru::make_source_with_cache( kangaru::make_source_with_heap_storage( @@ -129,7 +129,7 @@ TEST_CASE("Runtime source will cache sources results", "[deducer]") { } SECTION("Support the service idiom and cache and construction") { - auto source = kangaru::with_tree_recursion{ + auto source = kangaru::with_recursion{ kangaru::with_source_from_tag{ kangaru::make_source_with_cache( kangaru::make_source_with_heap_storage(