diff --git a/include/proxy/v4/proxy.h b/include/proxy/v4/proxy.h index 95442a81..1fd7aac6 100644 --- a/include/proxy/v4/proxy.h +++ b/include/proxy/v4/proxy.h @@ -1931,52 +1931,34 @@ using observer_upward_conversion_conv = recursive_reduction_t< reduction_traits::template type, conv_impl, Os...>; -template -using observer_indirect_conv = - conv_impl...>; +template +using observer_indirect_conv = conv_impl; -template -struct observer_conv_traits : inapplicable_traits {}; -template - requires(C::is_direct && std::is_same_v) -struct observer_conv_traits - : applicable_traits, - std::type_identity +struct observer_conv_traits : std::type_identity {}; +template + requires( + C::is_direct && + std::is_same_v) +struct observer_conv_traits + : std::type_identity> {}; -template +template requires(!C::is_direct) -struct observer_conv_traits - : applicable_traits, - std::type_identity< - instantiated_t> {}; - -template -struct observer_conv_reduction : std::type_identity {}; -template - requires(observer_conv_traits::applicable) -struct observer_conv_reduction, I> +struct observer_conv_traits : std::type_identity< - std::tuple::type>> {}; -template + instantiated_t> {}; +template struct observer_facade_conv_impl { - using convention_types = recursive_reduction_t< - reduction_traits::template type, std::tuple<>, - Cs...>; + using convention_types = + composite_t, typename observer_conv_traits::type...>; }; -template -struct observer_refl_reduction : std::type_identity {}; -template - requires(!R::is_direct) -struct observer_refl_reduction, R> - : std::type_identity> {}; template struct observer_facade_refl_impl { - using reflection_types = recursive_reduction_t< - reduction_traits::template type, std::tuple<>, - Rs...>; + using reflection_types = + composite_t, std::conditional_t...>; }; template @@ -2040,7 +2022,7 @@ struct weak_facade_impl { template struct observer_facade : details::instantiated_t, + typename F::convention_types>, details::instantiated_t { static constexpr std::size_t max_size = sizeof(void*); diff --git a/tests/proxy_view_tests.cpp b/tests/proxy_view_tests.cpp index 9d6b1b5f..cb684a53 100644 --- a/tests/proxy_view_tests.cpp +++ b/tests/proxy_view_tests.cpp @@ -38,6 +38,38 @@ static_assert( SupportsToString>())>); static_assert(sizeof(pro::proxy_view) == 3 * sizeof(void*)); +template +using AreEqualOverload = bool(const pro::proxy_indirect_accessor& rhs, + double eps) const; + +template +bool AreEqualImpl(const T& lhs, const pro::proxy_indirect_accessor& rhs, + double eps) { + return lhs.AreEqual(proxy_cast(rhs), eps); +} + +PRO_DEF_FREE_AS_MEM_DISPATCH(MemAreEqual, AreEqualImpl, AreEqual); + +struct EqualableQuantity + : pro::facade_builder // + ::add_skill // for proxy_cast + ::add_convention> // + ::build {}; + +class Point_2 { +public: + Point_2(double x, double y) : x_(x), y_(y) {} + Point_2(const Point_2&) = default; + Point_2& operator=(const Point_2&) = default; + bool AreEqual(const Point_2& rhs, double eps) const { + return std::abs(x_ - rhs.x_) < eps && std::abs(y_ - rhs.y_) < eps; + } + +private: + double x_, y_; +}; + } // namespace proxy_view_tests_details namespace details = proxy_view_tests_details; @@ -132,3 +164,18 @@ TEST(ProxyViewTests, TestUpwardConversion_FromValue) { ASSERT_EQ(ToString(*p2), "123"); ASSERT_EQ(ToString(*p3), "123"); } + +TEST(ProxyViewTests, TestFacadeAware) { + details::Point_2 v1{1, 1}; + details::Point_2 v2{1, 0}; + details::Point_2 v3{1.0000001, 1.0000001}; + pro::proxy_view p1 = + pro::make_proxy_view(v1); + pro::proxy_view p2 = + pro::make_proxy_view(v2); + pro::proxy_view p3 = + pro::make_proxy_view(v3); + ASSERT_TRUE(p1->AreEqual(*p1, 1e-6)); + ASSERT_FALSE(p1->AreEqual(*p2, 1e-6)); + ASSERT_TRUE(p1->AreEqual(*p3, 1e-6)); +}