From 3733f17044e548a20f673f82a5753c91611d87b5 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 8 Oct 2026 10:29:07 +0200 Subject: [PATCH 1/7] improve the CGAL named parameters API and implementation I have also added new tests. --- .../test_pmp_np_function.cpp | 28 +- .../include/CGAL/Named_function_parameters.h | 499 ++++++------------ .../internal/parameters_interface.h | 24 + .../STL_Extension/test_cgal_named_params.cpp | 181 +++++-- 4 files changed, 339 insertions(+), 393 deletions(-) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_np_function.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_np_function.cpp index 4499c0b7bbb6..ce21db8ae42b 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_np_function.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_np_function.cpp @@ -1,4 +1,7 @@ +#include #include +#include +#include #include #include @@ -6,9 +9,18 @@ #include +#include +#include +#include + +#include +#include +#include + +#include +#include #include #include -#include namespace CGAL { @@ -65,11 +77,15 @@ void my_function_with_named_parameters(PolygonMesh& mesh, const NamedParameters& VCM vcm_np = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained)); + auto vcmap = choose_parameter(get_parameter(np, internal_np::vertex_color_map), + CGAL::dynamic_vertex_property_t{}, mesh, false); //demonstrates usage for those values. for(auto v : vertices(mesh)) { std::cout<<"vertex #"< Vertex_constrained_pmap; Vertex_constrained_pmap vcm_pmap(vcm); CGAL::my_function_with_named_parameters(sm); + + VCmap colors; + for(auto v : vertices(sm)) + colors[v] = false; + Vertex_constrained_pmap color_pmap(colors); + CGAL::my_function_with_named_parameters(sm, CGAL::parameters::vertex_is_constrained_map(vcm_pmap) + .vertex_color_map(color_pmap) .do_project(true)); + for(auto v : vertices(sm)) + assert(colors[v]); + return 0; } diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index 6d29bfc39405..0ac50aa8aa0d 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -12,6 +12,7 @@ #ifndef CGAL_NAMED_FUNCTION_PARAMETERS_H #define CGAL_NAMED_FUNCTION_PARAMETERS_H +#include #ifndef CGAL_NO_STATIC_ASSERTION_TESTS #include #endif @@ -21,6 +22,7 @@ #include +#include #include #include @@ -43,25 +45,36 @@ namespace internal_np{ struct No_property {}; struct Param_not_found {}; +template +inline constexpr bool is_param_not_found_v = std::is_same_v, Param_not_found>; + enum all_default_t { all_default }; +// helper for getting references +template +T get_reference(const T& t) +{ + return t; +} + +template +T& get_reference(const std::reference_wrapper& r) +{ + return r.get(); +} + // define enum types and values for new named parameters -#define CGAL_add_named_parameter(X, Y, Z) \ - enum X { Y }; -#define CGAL_add_named_parameter_with_compatibility(X, Y, Z) \ - enum X { Y }; -#define CGAL_add_named_parameter_with_compatibility_cref_only(X, Y, Z) \ - enum X { Y }; -#define CGAL_add_named_parameter_with_compatibility_ref_only(X, Y, Z) \ +#define CGAL_add_named_parameter(X, Y, Z) \ enum X { Y }; -#define CGAL_add_extra_named_parameter_with_compatibility(X, Y, Z) #include -#undef CGAL_add_named_parameter -#undef CGAL_add_named_parameter_with_compatibility -#undef CGAL_add_named_parameter_with_compatibility_cref_only -#undef CGAL_add_named_parameter_with_compatibility_ref_only -#undef CGAL_add_extra_named_parameter_with_compatibility +} // end namespace internal_np + +// forward-declaration of Named_function_parameters +template +struct Named_function_parameters; + +namespace internal_np { template struct Named_params_impl : Base { @@ -71,6 +84,11 @@ struct Named_params_impl : Base : Base(b) , v(v) {} + + constexpr decltype(auto) parameter(Tag) const noexcept { return v; } + static constexpr bool has_parameter(Tag) noexcept { return true; } + using Base::parameter; + using Base::has_parameter; }; // partial specialization for base class of the recursive nesting @@ -79,60 +97,23 @@ struct Named_params_impl { typename std::conditional::value, T, std::reference_wrapper >::type v; // copy of the parameter if copyable - Named_params_impl(const T& v) + constexpr Named_params_impl(const T& v) : v(v) {} + constexpr decltype(auto) parameter(Tag) const noexcept { return v; } + static constexpr bool has_parameter(Tag) noexcept { return true; } }; // Helper class to get the type of a named parameter pack given a query tag template struct Get_param; -template< typename T, typename Tag, typename Query_tag> -struct Get_param< Named_params_impl, Query_tag > -{ - typedef Param_not_found type; - typedef Param_not_found reference; -}; - -template< typename T, typename Tag, typename Base> -struct Get_param< Named_params_impl, Tag > -{ - typedef typename std::conditional::value, - T, std::reference_wrapper >::type type; - typedef typename std::conditional::value, - T, const T&>::type reference; -}; - -template< typename T, typename Tag> -struct Get_param< Named_params_impl, Tag > -{ - typedef typename std::conditional::value, - T, std::reference_wrapper >::type type; - typedef typename std::conditional::value, - T, const T&>::type reference; -}; - -template< typename T, typename Tag, typename Base> -struct Get_param< Named_params_impl, Tag, Base>, Tag > -{ - typedef std::reference_wrapper type; - typedef T& reference; -}; - -template< typename T, typename Tag> -struct Get_param< Named_params_impl, Tag, No_property>, Tag > -{ - typedef std::reference_wrapper type; - typedef T& reference; -}; - - -template< typename T, typename Tag, typename Base, typename Query_tag> -struct Get_param< Named_params_impl, Query_tag> +template +struct Get_param, Query_tag> { - typedef typename Get_param::type type; - typedef typename Get_param::reference reference; + using type = decltype(std::declval>().parameter(Query_tag{})); + using reference = + decltype(get_reference(std::declval>().parameter(Query_tag{}))); }; // helper to choose the default @@ -143,207 +124,97 @@ struct Lookup_named_param_def typedef typename internal_np::Get_param::reference NP_reference; typedef std::conditional_t< - std::is_same_v, + internal_np::is_param_not_found_v, D, NP_type> type; typedef std::conditional_t< - std::is_same_v, + internal_np::is_param_not_found_v, D&, NP_reference> reference; }; -// helper function to extract the value from a named parameter pack given a query tag -template -typename std::conditional::value, - T, std::reference_wrapper >::type -get_parameter_impl(const Named_params_impl& np, Tag) -{ - return np.v; -} - -template< typename T, typename Tag, typename Query_tag> -Param_not_found get_parameter_impl(const Named_params_impl&, Query_tag) -{ - return Param_not_found(); -} - -template< typename T, typename Tag> -typename std::conditional::value, - T, std::reference_wrapper >::type -get_parameter_impl(const Named_params_impl& np, Tag) -{ - return np.v; -} - -template -typename Get_param, Query_tag>::type -get_parameter_impl(const Named_params_impl& np, Query_tag tag) -{ -#ifndef CGAL_NO_STATIC_ASSERTION_TEST - static_assert(!std::is_same::value); -#endif - return get_parameter_impl(static_cast(np), tag); -} - - -// helper for getting references -template -const T& get_reference(const T& t) -{ - return t; -} - -template -T& get_reference(const std::reference_wrapper& r) -{ - return r.get(); -} - -// helper function to extract the reference from a named parameter pack given a query tag -template -typename std::conditional::value, - T, const T& >::type -get_parameter_reference_impl(const Named_params_impl& np, Tag) -{ - return get_reference(np.v); -} - -template< typename T, typename Tag, typename Query_tag> -Param_not_found -get_parameter_reference_impl(const Named_params_impl&, Query_tag) -{ - return Param_not_found(); -} - -template< typename T, typename Tag> -typename std::conditional::value, - T, const T& >::type -get_parameter_reference_impl(const Named_params_impl& np, Tag) -{ - return get_reference(np.v); -} - -template -T& -get_parameter_reference_impl(const Named_params_impl, Tag, Base>& np, Tag) -{ - return np.v.get(); -} +} // end of internal_np namespace -template< typename T, typename Tag> -T& -get_parameter_reference_impl(const Named_params_impl, Tag, No_property>& np, Tag) +template +constexpr decltype(auto) parameter_or([[maybe_unused]] const Named_function_parameters& np, + [[maybe_unused]] Query_tag tag, + [[maybe_unused]] U&& default_value) { - return np.v.get(); + return np.parameter_or(tag, std::forward(default_value)); } -template -typename Get_param, Query_tag>::reference -get_parameter_reference_impl(const Named_params_impl& np, Query_tag tag) +template +constexpr decltype(auto) parameter_or([[maybe_unused]] const Named_function_parameters& np, + [[maybe_unused]] Query_tag tag) { - static_assert(!std::is_same::value); - return get_parameter_reference_impl(static_cast(np), tag); + return np.template parameter_or(tag); } -} // end of internal_np namespace - -template -struct Named_function_parameters; - namespace parameters{ typedef Named_function_parameters Default_named_parameters; -Default_named_parameters -inline default_values(); +inline constexpr Default_named_parameters default_values(); // function to extract a parameter template -typename internal_np::Get_param, Query_tag>::type +constexpr decltype(auto) get_parameter(const Named_function_parameters& np, Query_tag tag) { - return internal_np::get_parameter_impl(static_cast&>(np), tag); + return np.parameter(tag); } template -typename internal_np::Get_param, Query_tag>::reference +constexpr decltype(auto) get_parameter_reference(const Named_function_parameters& np, Query_tag tag) { - return internal_np::get_parameter_reference_impl( - static_cast&>(np), - tag); + return internal_np::get_reference(np.parameter(tag)); } // Two parameters, non-trivial default value -template -D& choose_parameter(const internal_np::Param_not_found&, D& d) -{ - return d; -} - -template -const D& choose_parameter(const internal_np::Param_not_found&, const D& d) -{ - return d; -} - -template -D choose_parameter(const internal_np::Param_not_found&, D&& d) -{ - return std::forward(d); -} - -template -T& choose_parameter(T& t, D&) -{ - return t; -} - template -const T& choose_parameter(const T& t, const D&) -{ - return t; +constexpr decltype(auto) choose_parameter([[maybe_unused]] T&& t, [[maybe_unused]] D&& d) { + if constexpr (internal_np::is_param_not_found_v) { + return std::forward(d); + } else { + return std::forward(t); + } } // single parameter so that we can avoid a default construction -template -D choose_parameter(const internal_np::Param_not_found&) -{ - return D(); -} - template -const T& choose_parameter(const T& t) +constexpr decltype(auto) choose_parameter([[maybe_unused]] T&& t) { - return t; + if constexpr (internal_np::is_param_not_found_v) { + return D{}; + } else { + return std::forward(t); + } } // version with a dynamic property tag with initialization -template -auto -choose_parameter(const internal_np::Param_not_found&, Tag tag, Graph& graph, const V& default_value) -{ - return get(tag, graph, default_value); -} - -template -auto -choose_parameter(const internal_np::Param_not_found&, Tag tag, Graph& graph) -{ - return get(tag, graph); -} - template -const T& choose_parameter(const T& t, Tag, Graph&, const V&) -{ - return t; +constexpr decltype(auto) choose_parameter([[maybe_unused]] T&& t, + [[maybe_unused]] Tag tag, + [[maybe_unused]] Graph& graph, + [[maybe_unused]] const V& default_value) { + if constexpr (internal_np::is_param_not_found_v) { + return get(tag, graph, default_value); + } else { + return std::forward(t); + } } template -const T& choose_parameter(const T& t, Tag, Graph&) +constexpr decltype(auto) +choose_parameter([[maybe_unused]] T&& t, [[maybe_unused]] Tag tag, [[maybe_unused]] Graph& graph) { - return t; + if constexpr (internal_np::is_param_not_found_v) { + return get(tag, graph); + } else { + return std::forward(t); + } } } // parameters namespace @@ -366,62 +237,65 @@ struct Named_function_parameters typedef internal_np::Named_params_impl base; typedef Named_function_parameters self; - Named_function_parameters() : base(T()) {} - Named_function_parameters(const T& v) : base(v) {} - Named_function_parameters(const T& v, const Base& b) : base(v, b) {} + using base::parameter; + using base::has_parameter; + constexpr auto parameter(...) const { return internal_np::Param_not_found(); } + static constexpr bool has_parameter(...) { return false; } + + template + constexpr decltype(auto) parameter_or([[maybe_unused]] Query_tag tag, [[maybe_unused]] D&& default_value) const { + if constexpr (has_parameter(Query_tag())) { + return parameter(tag); + } else { + return std::forward(default_value); + } + } + + template + constexpr decltype(auto) parameter_or([[maybe_unused]] Query_tag tag) const { + if constexpr (has_parameter(Query_tag())) { + return parameter(tag); + } else { + return D{}; + } + } + + constexpr Named_function_parameters() : base(T()) {} + constexpr Named_function_parameters(const T& v) : base(v) {} + constexpr Named_function_parameters(const T& v, const Base& b) : base(v, b) {} // create the functions for new named parameters and the one imported boost // used to concatenate several parameters #define CGAL_add_named_parameter(X, Y, Z) \ template \ - Named_function_parameters \ - Z(const K& k) const \ + constexpr auto Z(const K& k) const \ { \ - typedef Named_function_parameters Params;\ + using Params = Named_function_parameters;\ return Params(k, *this); \ } #define CGAL_add_named_parameter_with_compatibility(X, Y, Z) \ + CGAL_add_named_parameter(X, Y, Z) +#define CGAL_add_extra_named_parameter_with_compatibility(X, Y, Z) \ + CGAL_add_named_parameter(X, Y, Z) +#define CGAL_add_named_parameter_with_compatibility_cref_only(X, Y, Z)\ template \ - Named_function_parameters \ - Z(const K& k) const \ - { \ - typedef Named_function_parameters Params;\ - return Params(k, *this); \ - } -#define CGAL_add_named_parameter_with_compatibility_cref_only(X, Y, Z) \ - template \ - Named_function_parameters, \ - internal_np::X, self> \ - Z(const K& k) const \ + constexpr auto Z(const K& k) const \ { \ - typedef Named_function_parameters,\ - internal_np::X, self> Params; \ + using Params = \ + Named_function_parameters, \ + internal_np::X, self>; \ return Params(std::cref(k), *this); \ } #define CGAL_add_named_parameter_with_compatibility_ref_only(X, Y, Z) \ template \ - Named_function_parameters, \ - internal_np::X, self> \ - Z(K& k) const \ + constexpr auto Z(K& k) const \ { \ - typedef Named_function_parameters, \ - internal_np::X, self> Params; \ + using Params = \ + Named_function_parameters, \ + internal_np::X, self>; \ return Params(std::ref(k), *this); \ } -#define CGAL_add_extra_named_parameter_with_compatibility(X, Y, Z) \ - template \ - Named_function_parameters \ - Z(const K& k) const \ - { \ - typedef Named_function_parameters Params;\ - return Params(k, *this); \ - } #include -#undef CGAL_add_named_parameter -#undef CGAL_add_named_parameter_with_compatibility -#undef CGAL_add_named_parameter_with_compatibility_cref_only -#undef CGAL_add_named_parameter_with_compatibility_ref_only -#undef CGAL_add_extra_named_parameter_with_compatibility // inject mesh specific named parameter functions #define CGAL_NP_BASE self @@ -433,14 +307,14 @@ struct Named_function_parameters #undef CGAL_NP_BUILD template - Named_function_parameters + constexpr Named_function_parameters combine(const Named_function_parameters& np) const { return Named_function_parameters(np.v,*this); } template - auto + constexpr auto combine(const Named_function_parameters& np, const NPS& ... nps) const { return Named_function_parameters(np.v,*this).combine(nps...); @@ -452,8 +326,7 @@ struct Named_function_parameters namespace parameters { -Default_named_parameters -inline default_values() +inline constexpr Default_named_parameters default_values() { return Default_named_parameters(); } @@ -470,111 +343,55 @@ template struct Boost_parameter_compatibility_wrapper { template - Named_function_parameters - operator()(const K& p) const - { - typedef Named_function_parameters Params; - return Params(p); - } - - template - Named_function_parameters - operator=(const K& p) const - { - typedef Named_function_parameters Params; - return Params(p); - } -}; - -template -struct Boost_parameter_compatibility_wrapper -{ - template - Named_function_parameters, Tag> - operator()(const K& p) const - { - typedef Named_function_parameters, Tag> Params; - return Params(std::cref(p)); - } - - template - Named_function_parameters, Tag> - operator=(const K& p) const - { - typedef Named_function_parameters, Tag> Params; - return Params(std::cref(p)); - } -}; - -template -struct Boost_parameter_compatibility_wrapper -{ - template - Named_function_parameters, Tag> - operator()(K& p) const + constexpr auto operator()(const K& p) const { - typedef Named_function_parameters, Tag> Params; - return Params(std::ref(p)); + if constexpr (ref_only) + { + if constexpr (ref_is_const) + { + using Params = Named_function_parameters, Tag>; + return Params(std::cref(p)); + } + else + { + using Params = Named_function_parameters, Tag>; + return Params(std::ref(p)); + } + } + else + { + using Params = Named_function_parameters; + return Params(p); + } } template - Named_function_parameters, Tag> - operator=(std::reference_wrapper p) const + constexpr auto operator=(const K& p) const { - typedef Named_function_parameters, Tag> Params; - return Params(std::ref(p)); + return operator()(p); } }; // define free functions and Boost_parameter_compatibility_wrapper for named parameters -#define CGAL_add_named_parameter(X, Y, Z) \ - template \ - Named_function_parameters \ - Z(const K& p) \ - { \ - typedef Named_function_parameters Params;\ - return Params(p); \ +#define CGAL_add_named_parameter(X, Y, Z) \ + template \ + constexpr auto Z(const K& p) { \ + using Params = Named_function_parameters; \ + return Params(p); \ } #define CGAL_add_named_parameter_with_compatibility(X, Y, Z) \ - inline const Boost_parameter_compatibility_wrapper Z; + inline constexpr Boost_parameter_compatibility_wrapper Z; #define CGAL_add_named_parameter_with_compatibility_cref_only(X, Y, Z) \ - inline const Boost_parameter_compatibility_wrapper Z; + inline constexpr Boost_parameter_compatibility_wrapper Z; #define CGAL_add_named_parameter_with_compatibility_ref_only(X, Y, Z) \ - inline const Boost_parameter_compatibility_wrapper Z; + inline constexpr Boost_parameter_compatibility_wrapper Z; #define CGAL_add_extra_named_parameter_with_compatibility(X, Y, Z) \ - inline const Boost_parameter_compatibility_wrapper Z; + inline constexpr Boost_parameter_compatibility_wrapper Z; #include -#undef CGAL_add_named_parameter -#undef CGAL_add_extra_named_parameter_with_compatibility -#undef CGAL_add_named_parameter_with_compatibility -#undef CGAL_add_named_parameter_with_compatibility_cref_only -#undef CGAL_add_named_parameter_with_compatibility_ref_only - -// Version with three parameters for dynamic property maps -template -D choose_parameter(const internal_np::Param_not_found&, Dynamic_tag tag, PolygonMesh& pm) -{ - return get(tag, pm); -} - -template -const T& choose_parameter(const T& t, Dynamic_tag, PolygonMesh&) -{ - return t; -} template -struct is_default_parameter -{ - typedef typename internal_np::Lookup_named_param_def::type NP_type; - - static const bool value = std::is_same::value; - - typedef CGAL::Boolean_tag type; -}; +using is_default_parameter = Boolean_tag; } // end of parameters namespace diff --git a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h index 22796bcb1311..838be6fdc424 100644 --- a/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h +++ b/STL_Extension/include/CGAL/STL_Extension/internal/parameters_interface.h @@ -9,6 +9,24 @@ // // Author(s) : Maxime Gimeno +#include + +#ifndef CGAL_add_named_parameter_with_compatibility +# define CGAL_add_named_parameter_with_compatibility(X, Y, Z) CGAL_add_named_parameter(X, Y, Z) +#endif + +#ifndef CGAL_add_named_parameter_with_compatibility_cref_only +# define CGAL_add_named_parameter_with_compatibility_cref_only(X, Y, Z) CGAL_add_named_parameter(X, Y, Z) +#endif + +#ifndef CGAL_add_named_parameter_with_compatibility_ref_only +# define CGAL_add_named_parameter_with_compatibility_ref_only(X, Y, Z) CGAL_add_named_parameter(X, Y, Z) +#endif + +#ifndef CGAL_add_extra_named_parameter_with_compatibility +# define CGAL_add_extra_named_parameter_with_compatibility(X, Y, Z) +#endif + // List of named parameters that we use in CGAL CGAL_add_named_parameter(vertex_point_t, vertex_point, vertex_point_map) CGAL_add_named_parameter(halfedge_index_t, halfedge_index, halfedge_index_map) @@ -456,3 +474,9 @@ CGAL_add_named_parameter(computation_policy_t, computation_policy, computation_p //List of named parameters used in Mesh_smoothing_3 CGAL_add_named_parameter(max_number_of_evaluations_t, max_number_of_evaluations, max_number_of_evaluations) + +#undef CGAL_add_named_parameter +#undef CGAL_add_named_parameter_with_compatibility +#undef CGAL_add_extra_named_parameter_with_compatibility +#undef CGAL_add_named_parameter_with_compatibility_cref_only +#undef CGAL_add_named_parameter_with_compatibility_ref_only diff --git a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp index 4e6b703cb9b5..e67695eaf9ff 100644 --- a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp +++ b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp @@ -1,118 +1,197 @@ #include #include -#include +#include +#include #include +#include +#include namespace inp = CGAL::internal_np; namespace params = CGAL::parameters; template -struct A -{ - A(int v):v(v){} - int v; -}; +using Static_int = std::integral_constant; -struct B +struct Non_copyable { - B(){} - B(const B&) = delete; + int value = 0; + Non_copyable() = default; + Non_copyable(const Non_copyable&) = delete; }; template void check_same_type(T) { - static const bool b = std::is_same< A, T >::value; + static const bool b = std::is_same_v, T>; static_assert(b); assert(b); } -template -void test_values_and_types(const NamedParameters& np) +void test_values_and_types() { + auto np = params::vertex_index_map(Static_int<0>()) + .visitor(Static_int<1>()); using params::get_parameter; + using CGAL::parameter_or; // test values - assert(get_parameter(np, inp::vertex_index).v == 0); - assert(get_parameter(np, inp::visitor).v == 1); + assert(get_parameter(np, inp::vertex_index).value == 0); + assert(np.parameter(inp::vertex_index).value == 0); + assert(get_parameter(np, inp::visitor).value == 1); + assert(np.parameter(inp::visitor).value == 1); // test types check_same_type<0>(get_parameter(np, inp::vertex_index)); + check_same_type<0>(np.parameter(inp::vertex_index)); + check_same_type<0>(parameter_or(np, inp::vertex_index, Static_int<42>{})); + check_same_type<0>(parameter_or>(np, inp::vertex_index)); check_same_type<1>(get_parameter(np, inp::visitor)); + check_same_type<1>(np.parameter(inp::visitor)); + check_same_type<1>(parameter_or(np, inp::visitor, Static_int<42>{})); + check_same_type<1>(parameter_or>(np, inp::visitor)); + + auto v = parameter_or(np, inp::face_color_map, Static_int<42>{}); + assert(v.value == 42); + assert(v.value == np.parameter_or(inp::face_color_map, Static_int<42>{}).value); + + auto v2 = parameter_or>(np, inp::face_color_map); + assert(v2.value == 42); + assert(v2.value == np.parameter_or>(inp::face_color_map).value); } -template -void test_no_copyable(const NamedParameters& np) +void test_missing_parameters() { - typedef typename inp::Get_param::type NP_type; - static_assert(std::is_same >::value); + const auto np = params::default_values(); + using NamedParameters = decltype(np); + + static_assert(!NamedParameters::has_parameter(inp::vertex_index)); + static_assert(params::is_default_parameter::value); + static_assert(std::is_same_v); + + Static_int<4> fallback; + Static_int<4>& result = CGAL::parameter_or(np, inp::vertex_index, fallback); + assert(&result == &fallback); + + Static_int<4>& member_result = np.parameter_or(inp::vertex_index, fallback); + assert(&member_result == &fallback); - const A<4>& a = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), A<4>(4)); - assert(a.v==4); + auto default_constructed = CGAL::parameter_or>(np, inp::vertex_index); + assert(default_constructed.value == 42); } -template -void test_references(const NamedParameters& np) +void test_compatibility_aliases() { - typedef A<2> Default_type; - Default_type default_value(2); + auto np = params::default_values() + .seeds(Static_int<5>{}) + .time_limit(0.5) + .max_iteration_number(9); + + static_assert(!params::is_default_parameter::value); + static_assert(!params::is_default_parameter::value); + static_assert(!params::is_default_parameter::value); + assert(params::get_parameter(np, inp::seeds).value == 5); + assert(params::get_parameter(np, inp::maximum_running_time) == 0.5); + assert(params::get_parameter(np, inp::number_of_iterations) == 9); +} + +void test_no_copyable() +{ + Non_copyable b; + auto np = params::visitor(b); + using NamedParameters = decltype(np); + using NP_type = typename inp::Get_param::type; + static_assert(std::is_same_v>); + + const Static_int<4>& a = params::choose_parameter( + params::get_parameter_reference(np, inp::edge_index), Static_int<4>()); + assert(a.value == 4); +} + +void test_references() +{ + Non_copyable b; + auto v = Static_int<0>(); + auto np = params::visitor(std::ref(b)) + .vertex_point_map(b) + .vertex_index_map(v) + .face_index_map(std::cref(b)); + using NamedParameters = decltype(np); + using Default_type = Static_int<2>; + Default_type default_value; // std::reference_wrapper - typedef typename inp::Lookup_named_param_def::reference Visitor_reference_type; - static_assert(std::is_same::value); - Visitor_reference_type vis_ref = params::choose_parameter(params::get_parameter_reference(np, inp::visitor), default_value); + using Visitor_reference_type = + typename inp::Lookup_named_param_def::reference; + static_assert(std::is_same_v); + Visitor_reference_type vis_ref = + params::choose_parameter(params::get_parameter_reference(np, inp::visitor), default_value); CGAL_USE(vis_ref); + assert(&vis_ref == &b); + vis_ref.value = 42; + assert(b.value == 42); // std::reference_wrapper of const - typedef typename inp::Lookup_named_param_def::reference FIM_reference_type; - static_assert(std::is_same::value); - FIM_reference_type fim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::face_index), default_value); + using FIM_reference_type = + typename inp::Lookup_named_param_def::reference; + static_assert(std::is_same_v); + FIM_reference_type fim_ref = + params::choose_parameter(params::get_parameter_reference(np, inp::face_index), default_value); CGAL_USE(fim_ref); + assert(&fim_ref == &b); // non-copyable - typedef typename inp::Lookup_named_param_def::reference VPM_reference_type; - static_assert(std::is_same::value); - VPM_reference_type vpm_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_point), default_value); + using VPM_reference_type = + typename inp::Lookup_named_param_def::reference; + static_assert(std::is_same_v); + VPM_reference_type vpm_ref = + params::choose_parameter(params::get_parameter_reference(np, inp::vertex_point), default_value); CGAL_USE(vpm_ref); + assert(&vpm_ref == &b); // passed by copy - typedef typename inp::Lookup_named_param_def::reference VIM_reference_type; - static_assert(std::is_same, VIM_reference_type>::value); - VIM_reference_type vim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_index), default_value); + using VIM_reference_type = + typename inp::Lookup_named_param_def::reference; + static_assert(std::is_same_v, VIM_reference_type>); + VIM_reference_type vim_ref = + params::choose_parameter(params::get_parameter_reference(np, inp::vertex_index), default_value); CGAL_USE(vim_ref); + assert(&vim_ref != &v); // default - typedef typename inp::Lookup_named_param_def::reference EIM_reference_type; - static_assert(std::is_same::value); - EIM_reference_type eim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), default_value); - assert(&eim_ref==&default_value); + using EIM_reference_type = + typename inp::Lookup_named_param_def::reference; + static_assert(std::is_same_v); + EIM_reference_type eim_ref = + params::choose_parameter(params::get_parameter_reference(np, inp::edge_index), default_value); + assert(&eim_ref == &default_value); } int main() { - test_values_and_types(params::vertex_index_map(A<0>(0)).visitor(A<1>(1))); + test_values_and_types(); + + test_missing_parameters(); + + test_compatibility_aliases(); - B b; - test_no_copyable(params::visitor(b)); + test_no_copyable(); - test_references(params::visitor(std::ref(b)) - .vertex_point_map(b) - .vertex_index_map(A<0>(0)) - .face_index_map(std::reference_wrapper(b)) - ); + test_references(); // test that, in case of duplicates, the last parameter value is kept auto np = params::visitor(1).visitor(2); + static_assert(decltype(np)::has_parameter(inp::visitor)); assert(params::get_parameter(np, inp::visitor) == 2); + assert(CGAL::parameter_or(np, inp::visitor, 3) == 2); auto d = CGAL::parameters::default_values(); - static_assert(std::is_same::value); + static_assert(std::is_same_v); #ifndef CGAL_NO_DEPRECATED_CODE auto d1 = CGAL::parameters::all_default(); - static_assert(std::is_same::value); + static_assert(std::is_same_v); auto d2 = CGAL::Polygon_mesh_processing::parameters::all_default(); - static_assert(std::is_same::value); + static_assert(std::is_same_v); #endif return EXIT_SUCCESS; From 73bb4de53598cc90300bf16e6d1bf3d84a542ada Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 8 Oct 2026 15:48:47 +0200 Subject: [PATCH 2/7] NP: fix Boost_parameter_compatibility_wrapper --- .../include/CGAL/Named_function_parameters.h | 15 ++++++++------- .../test/STL_Extension/test_cgal_named_params.cpp | 9 +++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index 0ac50aa8aa0d..a604e03985b5 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -343,25 +343,26 @@ template struct Boost_parameter_compatibility_wrapper { template - constexpr auto operator()(const K& p) const + constexpr auto operator()(K&& p) const { + using KK = CGAL::cpp20::remove_cvref_t; if constexpr (ref_only) { if constexpr (ref_is_const) { - using Params = Named_function_parameters, Tag>; - return Params(std::cref(p)); + using Params = Named_function_parameters, Tag>; + return Params{std::cref(std::forward(p))}; } else { - using Params = Named_function_parameters, Tag>; - return Params(std::ref(p)); + using Params = Named_function_parameters, Tag>; + return Params{std::ref(std::forward(p))}; } } else { using Params = Named_function_parameters; - return Params(p); + return Params{std::forward(p)}; } } @@ -377,7 +378,7 @@ struct Boost_parameter_compatibility_wrapper template \ constexpr auto Z(const K& p) { \ using Params = Named_function_parameters; \ - return Params(p); \ + return Params{p}; \ } #define CGAL_add_named_parameter_with_compatibility(X, Y, Z) \ diff --git a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp index e67695eaf9ff..cf50398e1d42 100644 --- a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp +++ b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp @@ -13,6 +13,14 @@ namespace params = CGAL::parameters; template using Static_int = std::integral_constant; +void test_all_cgal_named_params() { + struct A{}; + A a; +#define CGAL_add_named_parameter(X, Y, Z) \ + (void)params::Z(a).Z(a); +#include +} + struct Non_copyable { int value = 0; @@ -169,6 +177,7 @@ void test_references() int main() { + test_all_cgal_named_params(); test_values_and_types(); test_missing_parameters(); From 98a1fe931cea5c0e9ae3dcec66d68d4edb5a8aa3 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 8 Oct 2026 16:36:33 +0200 Subject: [PATCH 3/7] NP: fix Boost_parameter_compatibility_wrapper, again --- .../include/CGAL/Named_function_parameters.h | 6 +++--- STL_Extension/include/CGAL/type_traits.h | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index a604e03985b5..7e31d469c449 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -345,7 +345,7 @@ struct Boost_parameter_compatibility_wrapper template constexpr auto operator()(K&& p) const { - using KK = CGAL::cpp20::remove_cvref_t; + using KK = cpp20::remove_cvref_t>; if constexpr (ref_only) { if constexpr (ref_is_const) @@ -367,9 +367,9 @@ struct Boost_parameter_compatibility_wrapper } template - constexpr auto operator=(const K& p) const + constexpr auto operator=(K&& p) const { - return operator()(p); + return operator()(std::forward(p)); } }; diff --git a/STL_Extension/include/CGAL/type_traits.h b/STL_Extension/include/CGAL/type_traits.h index d28840945e43..4c894a96ff3a 100644 --- a/STL_Extension/include/CGAL/type_traits.h +++ b/STL_Extension/include/CGAL/type_traits.h @@ -15,6 +15,7 @@ #include #include +#include #include namespace CGAL { @@ -54,6 +55,21 @@ namespace cpp20 { template< class T > using remove_cvref_t = typename remove_cvref::type; + template + struct unwrap_reference { using type = T; }; + + template + struct unwrap_reference> { using type = U&; }; + + template + using unwrap_reference_t = typename unwrap_reference::type; + + template + struct unwrap_ref_decay : unwrap_reference> {}; + + template + using unwrap_ref_decay_t = typename unwrap_ref_decay::type; + } // end namespace cpp20 namespace details { From a9f990bb86583d592af896f206af200d0db8e723 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Thu, 8 Oct 2026 17:54:25 +0200 Subject: [PATCH 4/7] NP: fix Boost_parameter_compatibility_wrapper --- STL_Extension/include/CGAL/Named_function_parameters.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index 7e31d469c449..5610d422f7ee 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -351,12 +351,14 @@ struct Boost_parameter_compatibility_wrapper if constexpr (ref_is_const) { using Params = Named_function_parameters, Tag>; - return Params{std::cref(std::forward(p))}; + const auto& ref = cpp20::unwrap_reference_t(p); + return Params{std::cref(ref)}; } else { using Params = Named_function_parameters, Tag>; - return Params{std::ref(std::forward(p))}; + auto& ref = cpp20::unwrap_reference_t(p); + return Params{std::ref(ref)}; } } else From 41557b3241242b92ae7060d1c5f6bb68c754e87c Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 9 Oct 2026 10:24:43 +0200 Subject: [PATCH 5/7] check_headers now checks also check_headers_linked_twice --- Installation/CMakeLists.txt | 59 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index dd0795da1402..4383c19b0903 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -830,6 +830,7 @@ if(CGAL_BRANCH_BUILD) find_package(GMP REQUIRED) find_package(Doxygen REQUIRED) find_package(Eigen3 REQUIRED) + include(CGAL_Eigen3_support) get_target_property(CGAL_EIGEN_3_INCLUDE_DIRS Eigen3::Eigen INTERFACE_INCLUDE_DIRECTORIES) find_package(Qt6 COMPONENTS Core Widgets OpenGL Gui REQUIRED) set(CMAKE_POLICY_DEFAULT_CMP0167 NEW) @@ -843,23 +844,18 @@ if(CGAL_BRANCH_BUILD) find_package(OpenMesh) find_package(OpenCV QUIET) - set(compile_options - "\ -${CMAKE_CXX_FLAGS} -DCGAL_EIGEN3_ENABLED -DCGAL_PROFILE \ -${Qt6Widgets_DEFINITIONS} ${Qt6OpenGL_DEFINITIONS} ${Qt6Gui_DEFINITIONS} \ -${Qt6OpenGL_EXECUTABLE_COMPILE_FLAGS} -fPIC \ -${Qt6Gui_EXECUTABLE_COMPILE_FLAGS} \ -${CGAL_3RD_PARTY_DEFINITIONS} ${CGAL_Qt6_3RD_PARTY_DEFINITIONS} \ -${CGAL_DEFINITIONS}" -std=c++17) + set(compile_options ${CMAKE_CXX_FLAGS} -DCGAL_EIGEN3_ENABLED -DCGAL_PROFILE ${Qt6Widgets_DEFINITIONS} + ${Qt6OpenGL_DEFINITIONS} ${Qt6Gui_DEFINITIONS} ${Qt6OpenGL_EXECUTABLE_COMPILE_FLAGS} -fPIC + ${Qt6Gui_EXECUTABLE_COMPILE_FLAGS} ${CGAL_3RD_PARTY_DEFINITIONS} ${CGAL_Qt6_3RD_PARTY_DEFINITIONS} + ${CGAL_DEFINITIONS} -std=c++17) message("COMPILATION OPTIONS ARE : ${compile_options}") if(NOT OpenMesh_FOUND) - set(compile_options - "${compile_options} \ --DCGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H \ --DCGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H \ --DCGAL_PROPERTIES_POLYMESH_ARRAYKERNELT_H \ --DCGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H") + list(APPEND compile_options + -DCGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H + -DCGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H + -DCGAL_PROPERTIES_POLYMESH_ARRAYKERNELT_H + -DCGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H) message( STATUS "Skip headers \ @@ -870,17 +866,17 @@ ${CGAL_DEFINITIONS}" -std=c++17) because OpenMesh_FOUND is false.") endif() if(NOT OpenCV_FOUND) - set(compile_options "${compile_options} \ --DCGAL_CLASSIFICATION_OPENCV_RANDOM_FOREST_CLASSIFIER_H") + list(APPEND compile_options + -DCGAL_CLASSIFICATION_OPENCV_RANDOM_FOREST_CLASSIFIER_H) message(STATUS "Skip header \ \"CGAL/Classification/OpenCV_random_forest_classifier.h\" \ because OpenCV_FOUND is false") endif() if(LEDA_FOUND) - set(compile_options "${compile_options} -DCGAL_USE_LEDA") + list(APPEND compile_options -DCGAL_USE_LEDA) endif() if(NOT IPE_FOUND) - set(compile_options "${compile_options} -DCGAL_IPELET_BASE_H=1") + list(APPEND compile_options -DCGAL_IPELET_BASE_H=1) message(STATUS "Skip header \"CGAL/CGAL_ipelet_base.h\" \ because IPE_FOUND is false.") endif() @@ -929,7 +925,6 @@ You must disable CGAL_ENABLE_CHECK_HEADERS.") ${GMP_INCLUDE_DIR} ${Qt6OpenGL_INCLUDE_DIRS} ${Qt6Widgets_INCLUDE_DIRS} - ${Qt6Gui_DEFINITIONS} ${CGAL_3RD_PARTY_INCLUDE_DIRS} ${CGAL_Qt6_3RD_PARTY_INCLUDE_DIRS}) list(APPEND include_options "-I${incdir}") @@ -1062,6 +1057,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" endif() # end the if on list_of_documented_headers endforeach() # look on headers add_custom_target(check_pkg_${package}_headers + COMMENT "Check headers for package ${package}" DEPENDS ${check_pkg_headers_depends}) add_custom_command( OUTPUT ${CGAL_BINARY_DIR}/package_info/${package}/included_headers @@ -1078,6 +1074,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" ${check_pkg_headers_depends}) add_custom_target( pkg_${package}_deps + COMMENT "Compute dependencies for package ${package}" DEPENDS ${CGAL_BINARY_DIR}/package_info/${package}/dependencies) list(APPEND check_pkg_target_list check_pkg_${package}_headers) list(APPEND packages_deps @@ -1095,26 +1092,28 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" file(COPY_FILE ${CGAL_BINARY_DIR}/test_headers.cpp ${CGAL_BINARY_DIR}/test_headers2.cpp) file(APPEND ${CGAL_BINARY_DIR}/test_headers.cpp "int main(){}\n") - add_custom_target(check_headers DEPENDS ${check_pkg_target_list}) + # New check that headers can be included in different compilation units, that can be linked + # together. That checks for missing `inline` keywords. + add_executable(check_headers_linked_twice + ${CGAL_BINARY_DIR}/test_headers.cpp + ${CGAL_BINARY_DIR}/test_headers2.cpp) + target_link_libraries(check_headers_linked_twice PRIVATE CGAL::CGAL CGAL::CGAL_Qt6 Qt6::Widgets CGAL::Eigen3_support) + target_compile_options(check_headers_linked_twice PRIVATE ${compile_options} ${include_options}) + if(VTK_FOUND) + target_link_libraries(check_headers_linked_twice PRIVATE VTK::IOImage) + endif() + + add_custom_target(check_headers DEPENDS ${check_pkg_target_list} check_headers_linked_twice) string(REPLACE " " ";" compile_options ${compile_options}) string(REPLACE " " ";" include_options ${include_options_str}) add_custom_command( TARGET check_headers + COMMENT "Check that all headers can be included in the same translation unit" POST_BUILD COMMAND ${CMAKE_CXX_COMPILER} ${compile_options} ${include_options} -x c++ -fsyntax-only ${CGAL_BINARY_DIR}/test_headers.cpp) - # New check that headers can be included in different compilation units, that can be linked - # together. That checks for missing `inline` keywords. - add_executable(check_headers_linked_twice - ${CGAL_BINARY_DIR}/test_headers.cpp - ${CGAL_BINARY_DIR}/test_headers2.cpp) - target_link_libraries(check_headers_linked_twice PRIVATE CGAL::CGAL CGAL::CGAL_Qt6 Qt6::Widgets) - if(VTK_FOUND) - target_link_libraries(check_headers_linked_twice PRIVATE VTK::IOImage) - endif() - target_compile_options(check_headers_linked_twice PRIVATE ${compile_options} ${include_options}) add_custom_target(packages_dependencies DEPENDS ${packages_deps}) message( From ae3e09dae86941ba2537a53922777d500ebafe52 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 9 Oct 2026 10:25:13 +0200 Subject: [PATCH 6/7] test and fix ref_only and cref_only with more cases --- .../include/CGAL/Named_function_parameters.h | 12 ++++++--- .../STL_Extension/test_cgal_named_params.cpp | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/STL_Extension/include/CGAL/Named_function_parameters.h b/STL_Extension/include/CGAL/Named_function_parameters.h index 5610d422f7ee..e89472498a48 100644 --- a/STL_Extension/include/CGAL/Named_function_parameters.h +++ b/STL_Extension/include/CGAL/Named_function_parameters.h @@ -242,6 +242,12 @@ struct Named_function_parameters constexpr auto parameter(...) const { return internal_np::Param_not_found(); } static constexpr bool has_parameter(...) { return false; } + template + constexpr decltype(auto) parameter_ref([[maybe_unused]] Query_tag tag) const { + static_assert(has_parameter(Query_tag()), "Parameter not found"); + return internal_np::get_reference(parameter(tag)); + } + template constexpr decltype(auto) parameter_or([[maybe_unused]] Query_tag tag, [[maybe_unused]] D&& default_value) const { if constexpr (has_parameter(Query_tag())) { @@ -345,18 +351,18 @@ struct Boost_parameter_compatibility_wrapper template constexpr auto operator()(K&& p) const { - using KK = cpp20::remove_cvref_t>; if constexpr (ref_only) { + using Pointed_type = std::remove_reference_t>; if constexpr (ref_is_const) { - using Params = Named_function_parameters, Tag>; + using Params = Named_function_parameters, Tag>; const auto& ref = cpp20::unwrap_reference_t(p); return Params{std::cref(ref)}; } else { - using Params = Named_function_parameters, Tag>; + using Params = Named_function_parameters, Tag>; auto& ref = cpp20::unwrap_reference_t(p); return Params{std::ref(ref)}; } diff --git a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp index cf50398e1d42..95959f8d3fa5 100644 --- a/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp +++ b/STL_Extension/test/STL_Extension/test_cgal_named_params.cpp @@ -175,6 +175,29 @@ void test_references() assert(&eim_ref == &default_value); } + +void test_ref_only_parameters() +{ + int i = 42; + auto np_ref_only_i = params::weights(i).weights(i); + auto& ref_i = np_ref_only_i.parameter_ref(CGAL::internal_np::weights_param_t{}); + assert(&ref_i == &i); + + const int ci = 43; + auto np_cref_only_ci = params::image(ci).image(ci); + auto& ref_ci = np_cref_only_ci.parameter_ref(CGAL::internal_np::image_3_param_t{}); + assert(&ref_ci == &ci); + + auto np_ref_only_ci = params::weights(ci).weights(ci); + auto& ref_ci2 = np_ref_only_ci.parameter_ref(CGAL::internal_np::weights_param_t{}); + assert(&ref_ci2 == &ci); + + auto np_cref_only_2 = params::image(2*3).image(2*3); + auto& ref_2 = np_cref_only_2.parameter_ref(CGAL::internal_np::image_3_param_t{}); + static_assert(std::is_const_v>); + assert(np_cref_only_2.parameter_ref(CGAL::internal_np::image_3_param_t{}) == 6); +} + int main() { test_all_cgal_named_params(); @@ -188,6 +211,8 @@ int main() test_references(); + test_ref_only_parameters(); + // test that, in case of duplicates, the last parameter value is kept auto np = params::visitor(1).visitor(2); static_assert(decltype(np)::has_parameter(inp::visitor)); From 1e194496ca92486ac173d24ee50a92843afb1712 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Fri, 9 Oct 2026 13:37:47 +0200 Subject: [PATCH 7/7] fix -fsyntax-only --- Installation/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 4383c19b0903..62339554756b 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -848,7 +848,7 @@ if(CGAL_BRANCH_BUILD) ${Qt6OpenGL_DEFINITIONS} ${Qt6Gui_DEFINITIONS} ${Qt6OpenGL_EXECUTABLE_COMPILE_FLAGS} -fPIC ${Qt6Gui_EXECUTABLE_COMPILE_FLAGS} ${CGAL_3RD_PARTY_DEFINITIONS} ${CGAL_Qt6_3RD_PARTY_DEFINITIONS} ${CGAL_DEFINITIONS} -std=c++17) - message("COMPILATION OPTIONS ARE : ${compile_options}") + message("COMPILATION OPTIONS ARE: ${compile_options}") if(NOT OpenMesh_FOUND) list(APPEND compile_options @@ -1105,14 +1105,13 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" add_custom_target(check_headers DEPENDS ${check_pkg_target_list} check_headers_linked_twice) - string(REPLACE " " ";" compile_options ${compile_options}) string(REPLACE " " ";" include_options ${include_options_str}) add_custom_command( TARGET check_headers COMMENT "Check that all headers can be included in the same translation unit" POST_BUILD COMMAND ${CMAKE_CXX_COMPILER} ${compile_options} ${include_options} -x - c++ -fsyntax-only ${CGAL_BINARY_DIR}/test_headers.cpp) + c++ -fsyntax-only "${CGAL_BINARY_DIR}/test_headers.cpp") add_custom_target(packages_dependencies DEPENDS ${packages_deps})