From 428005e2ed95bc1401f97986feff79a32aa20726 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 11:11:39 +0200 Subject: [PATCH 1/6] [ctc] towards variadic contractors --- python/src/core/contractors/codac2_py_Ctc.cpp | 4 +- .../core/contractors/codac2_py_CtcInter.cpp | 4 +- .../core/contractors/codac2_py_CtcUnion.cpp | 4 +- src/core/contractors/codac2_Ctc.h | 49 +++++----------- src/core/contractors/codac2_CtcInter.h | 52 +++++++++++------ src/core/contractors/codac2_CtcUnion.h | 56 ++++++++++++------- 6 files changed, 90 insertions(+), 79 deletions(-) diff --git a/python/src/core/contractors/codac2_py_Ctc.cpp b/python/src/core/contractors/codac2_py_Ctc.cpp index beeffbfee..063f0c73b 100644 --- a/python/src/core/contractors/codac2_py_Ctc.cpp +++ b/python/src/core/contractors/codac2_py_Ctc.cpp @@ -51,7 +51,7 @@ py::class_,pyCtcIntervalVector> export_CtcIntervalVector std::dynamic_pointer_cast>(c1.copy()), std::dynamic_pointer_cast>(c2.copy())); }, - CTCINTER_TYPENAME_C1_CONTRACTEDTYPE_OPERATORAND_CONST_C1_REF_CONST_C2_REF) + CTCINTERTYPE_TYPENAMEC1_CONTRACTEDTYPES_CTC_OPERATORAND_CONST_C1_REF_CONST_C2_REF) .def("__and__", [](const CtcBase& c1, const IntervalVector& x2) { @@ -79,7 +79,7 @@ py::class_,pyCtcIntervalVector> export_CtcIntervalVector std::dynamic_pointer_cast>(c1.copy()), std::dynamic_pointer_cast>(c2.copy())); }, - CTCUNION_TYPENAME_C1_CONTRACTEDTYPE_OPERATOROR_CONST_C1_REF_CONST_C2_REF) + CTCUNIONTYPE_TYPENAMEC1_CONTRACTEDTYPES_CTC_OPERATOROR_CONST_C1_REF_CONST_C2_REF) .def("__or__", [](const CtcBase& c1, const IntervalVector& x2) { diff --git a/python/src/core/contractors/codac2_py_CtcInter.cpp b/python/src/core/contractors/codac2_py_CtcInter.cpp index d3ea61d84..8a381e5fc 100644 --- a/python/src/core/contractors/codac2_py_CtcInter.cpp +++ b/python/src/core/contractors/codac2_py_CtcInter.cpp @@ -48,13 +48,13 @@ void export_CtcInter(py::module& m, py::class_,pyCtcInte "c1"_a, "c2"_a) .def(CONTRACT_BOX_METHOD(CtcInter, - VOID_CTCINTER_X_CONTRACT_X_REF_CONST)) + VOID_CTCINTER_X_CONTRACT_IMPL_X__REF_CONST)) .def("__iand__", [](CtcInter& c1, const CtcBase& c2) { c1 &= std::dynamic_pointer_cast>(c2.copy()); return c1; }, - CTCINTER_X_REF_CTCINTER_X_OPERATORANDEQ_CONST_C_REF) + CTCINTER_X_VARIADIC_REF_CTCINTER_X_OPERATORANDEQ_CONST_SHARED_PTR_CTCBASE_X_VARIADIC_REF) ; } \ No newline at end of file diff --git a/python/src/core/contractors/codac2_py_CtcUnion.cpp b/python/src/core/contractors/codac2_py_CtcUnion.cpp index 2505b2ed5..6832fb952 100644 --- a/python/src/core/contractors/codac2_py_CtcUnion.cpp +++ b/python/src/core/contractors/codac2_py_CtcUnion.cpp @@ -48,13 +48,13 @@ void export_CtcUnion(py::module& m, py::class_,pyCtcInte "c1"_a, "c2"_a) .def(CONTRACT_BOX_METHOD(CtcUnion, - VOID_CTCUNION_X_CONTRACT_X_REF_CONST)) + VOID_CTCUNION_X_CONTRACT_IMPL_X__REF_CONST)) .def("__ior__", [](CtcUnion& c1, const CtcBase& c2) { c1 |= std::dynamic_pointer_cast>(c2.copy()); return c1; }, - CTCUNION_X_REF_CTCUNION_X_OPERATOROREQ_CONST_C_REF) + CTCUNION_X_VARIADIC_REF_CTCUNION_X_OPERATOROREQ_CONST_SHARED_PTR_CTCBASE_X_VARIADIC_REF) ; } \ No newline at end of file diff --git a/src/core/contractors/codac2_Ctc.h b/src/core/contractors/codac2_Ctc.h index cb8f5d68b..e2cc4403d 100644 --- a/src/core/contractors/codac2_Ctc.h +++ b/src/core/contractors/codac2_Ctc.h @@ -18,31 +18,12 @@ namespace codac2 { - //class Ctc - //{ - // public: - // - // //virtual std::shared_ptr copy() const = 0; - //}; - //template - //class Ctc - //{ - // public: - // - // virtual std::shared_ptr> copy() const - // { - // return nullptr; - // } - // - // virtual void contract(X&... x) const = 0; - //}; - - template - class CtcBase// : virtual public Ctc + template + class CtcBase { public: - - using ContractedType = X; + + using ContractedTypes = std::tuple; CtcBase(Index n) : _n(n) @@ -55,36 +36,36 @@ namespace codac2 return _n; } - virtual void contract(X& x) const = 0; + virtual void contract(X&... x) const = 0; - virtual std::shared_ptr> copy() const = 0; + virtual std::shared_ptr> copy() const = 0; protected: const Index _n; }; - template - class Ctc : public CtcBase + template + class Ctc : public CtcBase { public: Ctc(Index n) - : CtcBase(n) + : CtcBase(n) { } - virtual std::shared_ptr> copy() const + virtual std::shared_ptr> copy() const { return std::make_shared(*dynamic_cast(this)); } }; - template - concept IsCtcBaseOrPtr = (std::is_base_of_v,C> - || std::is_same_v>,C>); + template + concept IsCtcBaseOrPtr = (std::is_base_of_v,C> + || std::is_same_v>,C>); - template - concept IsCtcBase = std::is_base_of_v,C>; + template + concept IsCtcBase = std::is_base_of_v,C>; template diff --git a/src/core/contractors/codac2_CtcInter.h b/src/core/contractors/codac2_CtcInter.h index 567c2805b..7187445b2 100644 --- a/src/core/contractors/codac2_CtcInter.h +++ b/src/core/contractors/codac2_CtcInter.h @@ -16,35 +16,36 @@ namespace codac2 { - template - class CtcInter : public Ctc,X> + template + class CtcInter : public Ctc,X...> { public: explicit CtcInter(Index n) - : Ctc,X>(n) + : Ctc,X...>(n) { - if constexpr(std::is_same_v) + if constexpr(std::is_same_v) { assert(n == 1); } } template - requires (IsCtcBaseOrPtr && !std::is_same_v,C>) + requires (IsCtcBaseOrPtr && !std::is_same_v,C>) CtcInter(const C& c) - : Ctc,X>(size_of(c)), _ctcs(c) + : Ctc,X...>(size_of(c)), _ctcs(c) { } template - requires (IsCtcBaseOrPtr && ...) + requires (IsCtcBaseOrPtr && ...) CtcInter(const C&... c) - : Ctc,X>(size_first_item(c...)), _ctcs(c...) + : Ctc,X...>(size_first_item(c...)), _ctcs(c...) { assert_release(all_same_size(c...)); } - void contract(X& x) const + template // single type + void contract_impl(X_& x) const { for(const auto& ci : _ctcs) { @@ -54,16 +55,22 @@ namespace codac2 } } + void contract(X&... x) const + { + // contract_impl(..) method for multiple types is not yet implemented + contract_impl(x...); + } + template - requires std::is_base_of_v,C> - CtcInter& operator&=(const C& c) + requires std::is_base_of_v,C> + CtcInter& operator&=(const C& c) { assert_release(c.size() == this->size()); _ctcs.push_object_back(c); return *this; } - CtcInter& operator&=(const std::shared_ptr>& c) + CtcInter& operator&=(const std::shared_ptr>& c) { assert_release(c->size() == this->size()); _ctcs.push_back(c); @@ -72,16 +79,25 @@ namespace codac2 protected: - Collection> _ctcs; + Collection> _ctcs; + }; + + template <> + class CtcInter<> : public CtcInter + { }; + + template + struct CtcInterType; + + template + struct CtcInterType> { + using Ctc = CtcInter; }; template - requires (std::is_same_v - && std::is_base_of_v,C1> - && std::is_base_of_v,C2>) - inline CtcInter operator&(const C1& c1, const C2& c2) + typename CtcInterType::Ctc operator&(const C1& c1, const C2& c2) { - return CtcInter(c1,c2); + return { c1, c2 }; } template diff --git a/src/core/contractors/codac2_CtcUnion.h b/src/core/contractors/codac2_CtcUnion.h index 6d0b0bb8a..bdee173ca 100644 --- a/src/core/contractors/codac2_CtcUnion.h +++ b/src/core/contractors/codac2_CtcUnion.h @@ -16,35 +16,34 @@ namespace codac2 { - template - class CtcUnion : public Ctc,X> + template + class CtcUnion : public Ctc,X...> { public: explicit CtcUnion(Index n) - : Ctc,X>(n) + : Ctc,X...>(n) { - if constexpr(std::is_same_v) - { - assert(n == 1); - } + if constexpr(std::is_same_v) + assert_release(n == 1); } template - requires (IsCtcBaseOrPtr && !std::is_same_v,C>) + requires (IsCtcBaseOrPtr && !std::is_same_v,C>) CtcUnion(const C& c) - : Ctc,X>(size_of(c)), _ctcs(c) + : Ctc,X...>(size_of(c)), _ctcs(c) { } template - requires (IsCtcBaseOrPtr && ...) + requires (IsCtcBaseOrPtr && ...) CtcUnion(const C&... c) - : Ctc,X>(size_first_item(c...)), _ctcs(c...) + : Ctc,X...>(size_first_item(c...)), _ctcs(c...) { assert_release(all_same_size(c...)); } - void contract(X& x) const + template // single type + void contract_impl(X_& x) const { auto result = x; result.set_empty(); @@ -59,16 +58,22 @@ namespace codac2 x = result; } + void contract(X&... x) const + { + // contract_impl(..) method for multiple types is not yet implemented + contract_impl(x...); + } + template - requires std::is_base_of_v,C> - CtcUnion& operator|=(const C& c) + requires std::is_base_of_v,C> + CtcUnion& operator|=(const C& c) { assert_release(c.size() == this->size()); _ctcs.push_object_back(c); return *this; } - CtcUnion& operator|=(const std::shared_ptr>& c) + CtcUnion& operator|=(const std::shared_ptr>& c) { assert_release(c->size() == this->size()); _ctcs.push_back(c); @@ -77,16 +82,25 @@ namespace codac2 protected: - Collection> _ctcs; + Collection> _ctcs; + }; + + template <> + class CtcUnion<> : public CtcUnion + { }; + + template + struct CtcUnionType; + + template + struct CtcUnionType> { + using Ctc = CtcUnion; }; template - requires (std::is_same_v - && std::is_base_of_v,C1> - && std::is_base_of_v,C2>) - inline CtcUnion operator|(const C1& c1, const C2& c2) + typename CtcUnionType::Ctc operator|(const C1& c1, const C2& c2) { - return CtcUnion(c1,c2); + return { c1, c2 }; } template From 753f83893125f7503d3be7c1f521d40797f68012 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 11:38:12 +0200 Subject: [PATCH 2/6] [ctc] CtcInverse_ -> CtcInverse (full variadic contractor) --- .../core/contractors/codac2_py_CtcInverse.h | 16 +++--- src/core/contractors/codac2_CtcInverse.h | 53 ++++--------------- .../analytic/codac2_AnalyticFunction.h | 4 +- src/core/separators/codac2_SepTransform.h | 2 +- .../contractors/codac2_tests_CtcInverse.cpp | 2 +- 5 files changed, 23 insertions(+), 54 deletions(-) diff --git a/python/src/core/contractors/codac2_py_CtcInverse.h b/python/src/core/contractors/codac2_py_CtcInverse.h index 950ba7c08..c4fefe429 100644 --- a/python/src/core/contractors/codac2_py_CtcInverse.h +++ b/python/src/core/contractors/codac2_py_CtcInverse.h @@ -23,12 +23,12 @@ template void export_CtcInverse(py::module& m, const std::string& export_name, py::class_,pyCtcIntervalVector>& pyctc) { using D = typename T::Domain; - py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); + py::class_> exported(m, export_name.c_str(), pyctc, CTCINVERSE_MAIN); exported .def(py::init&, const D&, bool>(), "f"_a, "y"_a, "with_centered_form"_a = true, - CTCINVERSE_YX_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_EXPRTYPE_Y_TYPE_REF_CONST_TYPENAME_WRAPPER_Y_DOMAIN_REF_BOOL_BOOL); + CTCINVERSE_YX_CTCINVERSE_CONST_ANALYTICFUNCTION_TYPENAME_EXPRTYPE_Y_TYPE_REF_CONST_Y_REF_BOOL_BOOL); if constexpr(std::is_same_v) // contractors only associated with interval vectors { @@ -36,7 +36,7 @@ void export_CtcInverse(py::module& m, const std::string& export_name, py::class_ .def(py::init( [](const py::object& f, const CtcBase& c, bool with_centered_form) { - return std::make_unique>( + return std::make_unique>( cast>(f), c.copy(), with_centered_form); } @@ -45,13 +45,15 @@ void export_CtcInverse(py::module& m, const std::string& export_name, py::class_ "f"_a, "c"_a, "with_centered_form"_a = true); } + using C = CtcInverse; // comma cannot be interpreted by the following macro + exported - .def(CONTRACT_BOX_METHOD(CtcInverse, - VOID_CTCINVERSE__Y_CONTRACT_X_REF_VARIADIC_CONST)) + .def(CONTRACT_BOX_METHOD(C, + VOID_CTCINVERSE_YX_CONTRACT_X_REF_VARIADIC_CONST)) - .def("function", &CtcInverse::function, - CONST_ANALYTICFUNCTION_TYPENAME_EXPRTYPE_Y_TYPE_REF_CTCINVERSE__Y_FUNCTION_CONST) + .def("function", &CtcInverse::function, + CONST_ANALYTICFUNCTION_TYPENAME_EXPRTYPE_Y_TYPE_REF_CTCINVERSE_YX_FUNCTION_CONST) ; } \ No newline at end of file diff --git a/src/core/contractors/codac2_CtcInverse.h b/src/core/contractors/codac2_CtcInverse.h index dc28a4086..d775638f4 100644 --- a/src/core/contractors/codac2_CtcInverse.h +++ b/src/core/contractors/codac2_CtcInverse.h @@ -21,42 +21,35 @@ namespace codac2 { class CtcNot; - template - class CtcInverse_// : virtual public Ctc + template + requires (sizeof...(X) > 0) + class CtcInverse : public Ctc,X...> { public: template requires IsCtcBaseOrPtr - CtcInverse_(const AnalyticFunction::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) - : _f(f), _ctc_y(ctc_y), _with_centered_form(with_centered_form), _is_not_in(is_not_in) + CtcInverse(const AnalyticFunction::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) + : Ctc,X...>(f.args()[0]->size()), _f(f), _ctc_y(ctc_y), _with_centered_form(with_centered_form), _is_not_in(is_not_in) { assert_release([&]() { return f.output_size() == size_of(ctc_y); }() - && "CtcInverse_: invalid dimension of image argument ('y' or 'ctc_y')"); + && "CtcInverse: invalid dimension of image argument ('y' or 'ctc_y')"); } - CtcInverse_(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) - : CtcInverse_(f, CtcWrapper(y), with_centered_form, is_not_in) + CtcInverse(const AnalyticFunction::Type>& f, const Y& y, bool with_centered_form = true, bool is_not_in = false) + : CtcInverse(f, CtcWrapper(y), with_centered_form, is_not_in) { } - //std::shared_ptr> copy() const - //{ - // return std::make_shared>(*this); - //} - - template void contract(X&... x) const { return contract_(*_ctc_y.front(), x...); } - template void contract_(const Y& y, X&... x) const { return contract_(CtcWrapper(y), x...); } - template void contract_(const CtcBase& ctc_y, X&... x) const { ValuesMap v; @@ -100,7 +93,7 @@ namespace codac2 if constexpr(std::is_same_v) { - std::cout << "CtcInverse_: matrices expressions not (yet) supported with centered form" << std::endl; + std::cout << "CtcInverse: matrices expressions not (yet) supported with centered form" << std::endl; } else @@ -134,33 +127,7 @@ namespace codac2 bool _with_centered_form; bool _is_not_in = false; }; - - template - class CtcInverse : public Ctc,X>, public CtcInverse_ - { - public: - - CtcInverse(const AnalyticFunction::Type>& f, const typename Wrapper::Domain& y, bool with_centered_form = true, bool is_not_in = false) - : Ctc,X>(f.args()[0]->size() /* f must have only one arg, see following assert */), - CtcInverse_(f, y, with_centered_form,is_not_in) - { - assert_release(f.args().size() == 1 && "f must have only one arg"); - } - - template - requires IsCtcBaseOrPtr - CtcInverse(const AnalyticFunction::Type>& f, const C& ctc_y, bool with_centered_form = true, bool is_not_in = false) - : Ctc,X>(f.args()[0]->size() /* f must have only one arg, see following assert */), - CtcInverse_(f, ctc_y, with_centered_form,is_not_in) - { - assert_release(f.args().size() == 1 && "f must have only one arg"); - } - - void contract(X& x) const - { - CtcInverse_::contract(x); - } - }; + // Template deduction guides diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index b695e78b1..3c566f891 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -193,8 +193,8 @@ namespace codac2 protected: - template - friend class CtcInverse_; + template + friend class CtcInverse; template void add_value_to_arg_map(ValuesMap& v, const D& x, Index i) const diff --git a/src/core/separators/codac2_SepTransform.h b/src/core/separators/codac2_SepTransform.h index c140b89e1..03e646ea4 100644 --- a/src/core/separators/codac2_SepTransform.h +++ b/src/core/separators/codac2_SepTransform.h @@ -37,7 +37,7 @@ namespace codac2 protected: const Collection _sep; - const CtcInverse _ctc_inv; + const CtcInverse _ctc_inv; const AnalyticFunction _f, _f_inv; }; } \ No newline at end of file diff --git a/tests/core/contractors/codac2_tests_CtcInverse.cpp b/tests/core/contractors/codac2_tests_CtcInverse.cpp index ead697c52..528d2dc97 100644 --- a/tests/core/contractors/codac2_tests_CtcInverse.cpp +++ b/tests/core/contractors/codac2_tests_CtcInverse.cpp @@ -25,7 +25,7 @@ TEST_CASE("CtcInverse") { ScalarVar x,y; AnalyticFunction f { {x,y}, x-y }; - CtcInverse_ c(f, Interval(0.)); + CtcInverse c(f, Interval(0.)); CHECK(c.function().input_size() == 2); Interval a,b; From bd374f5e68cdb6cd7809443434e715f181f37a81 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 12:29:50 +0200 Subject: [PATCH 3/6] [ctc] CtcInverse friendship --- src/core/functions/analytic/codac2_AnalyticFunction.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 3c566f891..0c8479455 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -194,6 +194,7 @@ namespace codac2 protected: template + requires (sizeof...(X) > 0) friend class CtcInverse; template From fed3232ce4a834f28921f58b756a09247c862214 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 17:42:33 +0200 Subject: [PATCH 4/6] [ctc] CtcDist: minor update (in Python: contract method should return the boxes) --- doc/manual/manual/contractors/geometric/src.py | 11 +++++++++-- python/src/core/contractors/codac2_py_CtcDist.cpp | 7 ++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/manual/manual/contractors/geometric/src.py b/doc/manual/manual/contractors/geometric/src.py index 24cb6e7dc..61acf31ac 100644 --- a/doc/manual/manual/contractors/geometric/src.py +++ b/doc/manual/manual/contractors/geometric/src.py @@ -19,18 +19,25 @@ def tests_CtcDist_manual(test): # [ctcdist-1-beg] x = IntervalVector([[2,5],[2,6],[0,0],[0,0],[1,3]]) c = CtcDist() - c.contract(x) + x = c.contract(x) # x = [ [2, 2.23607] ; [2, 2.23607] ; <0, 0> ; <0, 0> ; [2.82842, 3] ] # [ctcdist-1-end] + test.assertTrue(Approx(x,1e-5) == IntervalVector([[2,2.23607],[2,2.23607],[0],[0],[2.82842,3]])) + # [ctcdist-2-beg] a1,a2,b1,b2,d = Interval(2,5),Interval(2,6),Interval(0),Interval(0),Interval(1,3) c = CtcDist() - c.contract(a1,a2,b1,b2,d) + a1,a2,b1,b2,d = c.contract(a1,a2,b1,b2,d) # a1 = [2, 2.23607] ; a2 = [2, 2.23607] ; b1 = <0, 0> ; b2 = <0, 0> ; d = [2.82842, 3] # [ctcdist-2-end] + test.assertTrue(Approx(a1,1e-5) == Interval([2,2.23607])) + test.assertTrue(Approx(a2,1e-5) == Interval([2,2.23607])) + test.assertTrue(Approx(b1,1e-5) == Interval([0])) + test.assertTrue(Approx(b2,1e-5) == Interval([0])) + test.assertTrue(Approx(d,1e-5) == Interval([2.82842,3])) # [ctcdist-3-beg] b1, b2 = Vector([1,2]), Vector([3.6,2.4]) diff --git a/python/src/core/contractors/codac2_py_CtcDist.cpp b/python/src/core/contractors/codac2_py_CtcDist.cpp index 267d628af..f90f5e6bd 100644 --- a/python/src/core/contractors/codac2_py_CtcDist.cpp +++ b/python/src/core/contractors/codac2_py_CtcDist.cpp @@ -31,7 +31,12 @@ void export_CtcDist(py::module& m, py::class_,pyCtcInter .def(CONTRACT_BOX_METHOD(CtcDist, VOID_CTCDIST_CONTRACT_INTERVALVECTOR_REF_CONST)) - .def("contract", (void (CtcDist::*)(Interval&,Interval&,Interval&,Interval&,Interval&) const)&CtcDist::contract, + .def("contract", + [](const CtcDist& c, Interval& a1, Interval& a2, Interval& b1, Interval& b2, Interval& d) + { + c.contract(a1,a2,b1,b2,d); + return std::make_tuple(a1,a2,b1,b2,d); + }, VOID_CTCDIST_CONTRACT_INTERVAL_REF_INTERVAL_REF_INTERVAL_REF_INTERVAL_REF_INTERVAL_REF_CONST, "a1"_a, "a2"_a, "b1"_a, "b2"_a, "d"_a) ; From 74b3c33f167315cfa4841258968a02e1e67e114b Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 17:46:17 +0200 Subject: [PATCH 5/6] [ctc] CtcInverse: minr update (trying to solve error with clang) --- src/core/functions/analytic/codac2_AnalyticFunction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index 0c8479455..dc6af42c4 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -193,7 +193,7 @@ namespace codac2 protected: - template + template requires (sizeof...(X) > 0) friend class CtcInverse; From a6387e993e0e095badd26fb640cec721a303f8f4 Mon Sep 17 00:00:00 2001 From: Simon Rohou Date: Tue, 20 May 2025 19:53:58 +0200 Subject: [PATCH 6/6] [ctc] CtcInverse: minor update (trying to solve error with clang) --- .../analytic/codac2_AnalyticFunction.h | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/core/functions/analytic/codac2_AnalyticFunction.h b/src/core/functions/analytic/codac2_AnalyticFunction.h index dc6af42c4..b4a9cbf80 100644 --- a/src/core/functions/analytic/codac2_AnalyticFunction.h +++ b/src/core/functions/analytic/codac2_AnalyticFunction.h @@ -191,11 +191,29 @@ namespace codac2 return os; } - protected: + // not working with Clang: template + // not working with Clang: requires (sizeof...(X) > 0) + // not working with Clang: friend class CtcInverse; + + // So, the following methods are temporarily public + + // protected: + + template + void fill_from_args(ValuesMap& v, const Args&... x) const + { + Index i = 0; + (add_value_to_arg_map(v, x, i++), ...); + } + + template + void intersect_from_args(const ValuesMap& v, Args&... x) const + { + Index i = 0; + (intersect_value_from_arg_map(v, x, i++), ...); + } - template - requires (sizeof...(X) > 0) - friend class CtcInverse; + protected: template void add_value_to_arg_map(ValuesMap& v, const D& x, Index i) const @@ -218,13 +236,6 @@ namespace codac2 std::make_shared(typename D_TYPE::Domain(x).mid(), x, d, true); } - template - void fill_from_args(ValuesMap& v, const Args&... x) const - { - Index i = 0; - (add_value_to_arg_map(v, x, i++), ...); - } - template void intersect_value_from_arg_map(const ValuesMap& v, D& x, Index i) const { @@ -232,13 +243,6 @@ namespace codac2 x &= std::dynamic_pointer_cast::Type>(v.at(this->args()[i]->unique_id()))->a; } - template - void intersect_from_args(const ValuesMap& v, Args&... x) const - { - Index i = 0; - (intersect_value_from_arg_map(v, x, i++), ...); - } - template auto eval_(const Args&... x) const {