// Copyright (c) 2019 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Sebastien Loriot #ifndef CGAL_NAMED_FUNCTION_PARAMETERS_H #define CGAL_NAMED_FUNCTION_PARAMETERS_H #ifndef CGAL_NO_STATIC_ASSERTION_TESTS #include #endif #include #include #include #include #include #define CGAL_NP_TEMPLATE_PARAMETERS NP_T=bool, typename NP_Tag=CGAL::internal_np::all_default_t, typename NP_Base=CGAL::internal_np::No_property #define CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT NP_T, typename NP_Tag, typename NP_Base #define CGAL_NP_CLASS CGAL::Named_function_parameters #define CGAL_NP_TEMPLATE_PARAMETERS_1 NP_T1=bool, typename NP_Tag1=CGAL::internal_np::all_default_t, typename NP_Base1=CGAL::internal_np::No_property #define CGAL_NP_CLASS_1 CGAL::Named_function_parameters #define CGAL_NP_TEMPLATE_PARAMETERS_2 NP_T2=bool, typename NP_Tag2=CGAL::internal_np::all_default_t, typename NP_Base2=CGAL::internal_np::No_property #define CGAL_NP_CLASS_2 CGAL::Named_function_parameters #define CGAL_NP_TEMPLATE_PARAMETERS_VARIADIC NP_T, typename ... NP_Tag, typename ... NP_Base namespace CGAL { namespace internal_np{ struct No_property {}; struct Param_not_found {}; enum all_default_t { all_default }; // define enum types and values for new named parameters #define CGAL_add_named_parameter(X, Y, Z) \ enum X { Y }; #include #undef CGAL_add_named_parameter template struct Named_params_impl : Base { typename std::conditional::value, T, std::reference_wrapper >::type v; // copy of the parameter if copyable Named_params_impl(const T& v, const Base& b) : Base(b) , v(v) {} }; // partial specialization for base class of the recursive nesting template 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) : v(v) {} }; // 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> { typedef typename Get_param::type type; typedef typename Get_param::reference reference; }; // helper to choose the default template struct Lookup_named_param_def { typedef typename internal_np::Get_param::type NP_type; typedef typename internal_np::Get_param::reference NP_reference; typedef typename boost::mpl::if_< boost::is_same, D, NP_type>::type type; typedef typename boost::mpl::if_< boost::is_same, D&, NP_reference>::type 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 CGAL_static_assertion( (!boost::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(); } template< typename T, typename Tag> T& get_parameter_reference_impl(const Named_params_impl, Tag, No_property>& np, Tag) { return np.v.get(); } template typename Get_param, Query_tag>::reference get_parameter_reference_impl(const Named_params_impl& np, Query_tag tag) { CGAL_static_assertion( (!boost::is_same::value) ); return get_parameter_reference_impl(static_cast(np), tag); } } // end of internal_np namespace template struct Named_function_parameters : internal_np::Named_params_impl { 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) {} // 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 \ { \ typedef Named_function_parameters Params;\ return Params(k, *this); \ } #include #undef CGAL_add_named_parameter template Named_function_parameters combine(const Named_function_parameters& np) const { return Named_function_parameters(np.v,*this); } template auto combine(const Named_function_parameters& np, const NPS& ... nps) const { return Named_function_parameters(np.v,*this).combine(nps...); } }; namespace parameters { typedef Named_function_parameters Default_named_parameters; #ifndef CGAL_NO_DEPRECATED_CODE Default_named_parameters inline all_default() { return Default_named_parameters(); } #endif Default_named_parameters inline default_values() { return Default_named_parameters(); } template Named_function_parameters inline no_parameters(Named_function_parameters) { typedef Named_function_parameters Params; return Params(); } // define free functions 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); \ } #include #undef CGAL_add_named_parameter #ifndef CGAL_NO_DEPRECATED_CODE 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); } }; // TODO: need to make sure this works when using several compilation units const Boost_parameter_compatibility_wrapper max_iteration_number; const Boost_parameter_compatibility_wrapper convergence; const Boost_parameter_compatibility_wrapper freeze_bound; const Boost_parameter_compatibility_wrapper time_limit; const Boost_parameter_compatibility_wrapper seeds_begin; const Boost_parameter_compatibility_wrapper seeds_end; const Boost_parameter_compatibility_wrapper mark; const Boost_parameter_compatibility_wrapper do_freeze; const Boost_parameter_compatibility_wrapper sliver_criterion; const Boost_parameter_compatibility_wrapper perturbation_vector; //Compatibility wrappers for exude_mesh_3.h const Boost_parameter_compatibility_wrapper sliver_bound; const Boost_parameter_compatibility_wrapper mesh_topology; const Boost_parameter_compatibility_wrapper dump_after_init_prefix; const Boost_parameter_compatibility_wrapper dump_after_refine_surface_prefix; const Boost_parameter_compatibility_wrapper dump_after_refine_prefix; const Boost_parameter_compatibility_wrapper dump_after_glob_opt_prefix; const Boost_parameter_compatibility_wrapper dump_after_perturb_prefix; const Boost_parameter_compatibility_wrapper dump_after_exude_prefix; const Boost_parameter_compatibility_wrapper number_of_initial_points; const Boost_parameter_compatibility_wrapper maximal_number_of_vertices; const Boost_parameter_compatibility_wrapper nonlinear_growth_of_balls; const Boost_parameter_compatibility_wrapper pointer_to_error_code; const Boost_parameter_compatibility_wrapper pointer_to_stop_atomic_boolean; const Boost_parameter_compatibility_wrapper exude_param; const Boost_parameter_compatibility_wrapper perturb_param; const Boost_parameter_compatibility_wrapper odt_param; const Boost_parameter_compatibility_wrapper lloyd_param; const Boost_parameter_compatibility_wrapper reset_param; const Boost_parameter_compatibility_wrapper mesh_options_param; const Boost_parameter_compatibility_wrapper manifold_options_param; const Boost_parameter_compatibility_wrapper features_param; const Boost_parameter_compatibility_wrapper function; const Boost_parameter_compatibility_wrapper bounding_object; const Boost_parameter_compatibility_wrapper image; const Boost_parameter_compatibility_wrapper iso_value; const Boost_parameter_compatibility_wrapper image_values_to_subdomain_indices; const Boost_parameter_compatibility_wrapper value_outside; const Boost_parameter_compatibility_wrapper relative_error_bound; const Boost_parameter_compatibility_wrapper p_rng; const Boost_parameter_compatibility_wrapper null_subdomain_index; const Boost_parameter_compatibility_wrapper construct_surface_patch_index; const Boost_parameter_compatibility_wrapper weights; const Boost_parameter_compatibility_wrapper edge_size; const Boost_parameter_compatibility_wrapper edge_sizing_field; const Boost_parameter_compatibility_wrapper facet_angle; const Boost_parameter_compatibility_wrapper facet_size; const Boost_parameter_compatibility_wrapper facet_sizing_field; const Boost_parameter_compatibility_wrapper facet_distance; const Boost_parameter_compatibility_wrapper facet_topology; const Boost_parameter_compatibility_wrapper cell_radius_edge; const Boost_parameter_compatibility_wrapper cell_radius_edge_ratio; const Boost_parameter_compatibility_wrapper cell_size; const Boost_parameter_compatibility_wrapper cell_sizing_field; const Boost_parameter_compatibility_wrapper sizing_field; #endif // function to extract a parameter template typename internal_np::Get_param, Query_tag>::type get_parameter(const Named_function_parameters& np, Query_tag tag) { return internal_np::get_parameter_impl(static_cast&>(np), tag); } template typename internal_np::Get_param, Query_tag>::reference get_parameter_reference(const Named_function_parameters& np, Query_tag tag) { return internal_np::get_parameter_reference_impl( static_cast&>(np), 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; } // 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) { return t; } template struct is_default_parameter { typedef typename internal_np::Lookup_named_param_def::type NP_type; static const bool value = boost::is_same::value; typedef CGAL::Boolean_tag type; }; } // end of parameters namespace namespace internal_np { template auto combine_named_parameters(const Named_function_parameters& np, const NPS& ... nps) { return np.combine(nps ...); } } // end of internal_np namespace #ifndef CGAL_NO_DEPRECATED_CODE namespace Polygon_mesh_processing { namespace parameters = CGAL::parameters; } #endif } //namespace CGAL #ifndef CGAL_NO_STATIC_ASSERTION_TESTS // code added to avoid silent runtime issues in non-updated code namespace boost { template void get_param(CGAL::Named_function_parameters, Tag2) { CGAL_static_assertion(B && "You must use CGAL::parameters::get_parameter instead of boost::get_param"); } } #endif #endif // CGAL_BOOST_FUNCTION_PARAMS_HPP