diff --git a/Property_map/include/CGAL/Dynamic_property_map.h b/Property_map/include/CGAL/Dynamic_property_map.h index 949eed33382..c9d5df75ad6 100644 --- a/Property_map/include/CGAL/Dynamic_property_map.h +++ b/Property_map/include/CGAL/Dynamic_property_map.h @@ -20,6 +20,7 @@ #include +#include #include namespace CGAL { @@ -154,108 +155,133 @@ struct Dynamic_with_index } // namespace internal +struct dynamic_property_t {}; + template -struct dynamic_vertex_property_t +struct dynamic_vertex_property_t : public dynamic_property_t { dynamic_vertex_property_t() {} + + using value_type = T; + + template + struct property_map { + using descriptor = typename boost::graph_traits::vertex_descriptor; + using vertex_descriptor = descriptor; + }; }; template -struct dynamic_halfedge_property_t +struct dynamic_halfedge_property_t : public dynamic_property_t { dynamic_halfedge_property_t() {} + + using value_type = T; + + template + struct property_map { + using descriptor = typename boost::graph_traits::halfedge_descriptor; + using halfedge_descriptor = descriptor; + }; }; template -struct dynamic_edge_property_t +struct dynamic_edge_property_t : public dynamic_property_t { dynamic_edge_property_t() {} + + using value_type = T; + + template + struct property_map { + using descriptor = typename boost::graph_traits::edge_descriptor; + using edge_descriptor = descriptor; + }; }; template -struct dynamic_face_property_t +struct dynamic_face_property_t : public dynamic_property_t { dynamic_face_property_t() {} + + using value_type = T; + + template + struct property_map + { + using descriptor = typename boost::graph_traits::face_descriptor; + using face_descriptor = descriptor; + }; +}; + +template +constexpr bool is_dynamic_property_tag() +{ + return std::is_base_of_v; +} + +template +struct property_map_of_dynamic_property_map : Dynamic_property_tag::template property_map +{ + using descriptor = typename Dynamic_property_tag::template property_map::descriptor; + using type = CGAL::internal::Dynamic_property_map; + using const_type = const type; }; } // namespace CGAL namespace boost { - template struct property_map > + : public CGAL::property_map_of_dynamic_property_map> { - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef CGAL::internal::Dynamic_property_map type; - typedef type const_type; + using vertex_descriptor = typename boost::graph_traits::vertex_descriptor; }; template struct property_map > + : public CGAL::property_map_of_dynamic_property_map> { - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef CGAL::internal::Dynamic_property_map type; - typedef type const_type; + using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; }; template struct property_map > + : public CGAL::property_map_of_dynamic_property_map> { - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - typedef CGAL::internal::Dynamic_property_map type; - typedef type const_type; + using edge_descriptor = typename boost::graph_traits::edge_descriptor; }; template struct property_map > + : public CGAL::property_map_of_dynamic_property_map> { - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef CGAL::internal::Dynamic_property_map type; - typedef type const_type; + using face_descriptor = typename boost::graph_traits::face_descriptor; }; } // namespace boost namespace CGAL { -template -typename boost::property_map >::const_type -get(const CGAL::dynamic_vertex_property_t&, const G&, const T& default_value = T()) -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - return internal::Dynamic_property_map(default_value); -} +template ()>, + typename ...Default_value_args> -template -typename boost::property_map >::const_type -get(const CGAL::dynamic_halfedge_property_t&, const G&, const T& default_value = T()) +auto get(const Dynamic_property_tag&, const G&, Default_value_args&&... default_value_args) { - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - return internal::Dynamic_property_map(default_value); -} - -template -typename boost::property_map >::const_type -get(const CGAL::dynamic_edge_property_t&, const G&, const T& default_value = T()) -{ - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - return internal::Dynamic_property_map(default_value); -} - -template -typename boost::property_map >::const_type -get(const CGAL::dynamic_face_property_t&, const G&, const T& default_value = T()) -{ - typedef typename boost::graph_traits::face_descriptor face_descriptor; - return internal::Dynamic_property_map(default_value); + using Property_map = + internal::Dynamic_property_map; + return Property_map(std::forward(default_value_args)...); } template diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index e9868ef6e07..250630763b7 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -622,7 +622,8 @@ struct Constant_property_map typedef const value_type& reference; typedef boost::read_write_property_map_tag category; - Constant_property_map(const value_type& default_value = value_type()) : default_value (default_value) { } + Constant_property_map() : default_value{} { } + Constant_property_map(const value_type& default_value) : default_value (default_value) { } /// Free function that returns `pm.default_value`. inline friend diff --git a/STL_Extension/include/CGAL/utility.h b/STL_Extension/include/CGAL/utility.h index 88f63fb115b..d356eab10a0 100644 --- a/STL_Extension/include/CGAL/utility.h +++ b/STL_Extension/include/CGAL/utility.h @@ -343,6 +343,12 @@ Scope_exit make_scope_exit(F&& f) { return Scope_exit(std::forward(f)); } +template +struct overloaded : Ts... { + using Ts::operator()...; +}; +template overloaded(Ts...) -> overloaded; + } //namespace CGAL namespace std { diff --git a/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h b/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h index 991d0959489..306313545b3 100644 --- a/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h +++ b/Surface_mesh/include/CGAL/boost/graph/properties_Surface_mesh.h @@ -13,6 +13,7 @@ #ifndef CGAL_PROPERTIES_SURFACE_MESH_H #define CGAL_PROPERTIES_SURFACE_MESH_H +#include #ifndef DOXYGEN_RUNNING #include @@ -23,6 +24,7 @@ #include #include #include +#include #include @@ -351,69 +353,46 @@ struct property_map, CGAL::dynamic_edge_property_t namespace CGAL { // get functions for dynamic properties of mutable Surface_mesh -template -typename boost::property_map, dynamic_vertex_property_t >::type -get(dynamic_vertex_property_t, Surface_mesh& sm, const T& default_value = T()) +template ()>, + typename ...Default_value_args> +auto get(Dynamic_property_tag, Surface_mesh& sm, Default_value_args&&... default_value_args) { - typedef typename boost::property_map, dynamic_vertex_property_t >::SMPM SMPM; - typedef typename boost::property_map, dynamic_vertex_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Vertex_index, T>(std::string(), default_value).first)); -} - -template -typename boost::property_map, dynamic_face_property_t >::type -get(dynamic_face_property_t, Surface_mesh& sm, const T& default_value = T()) -{ - typedef typename boost::property_map, dynamic_face_property_t >::SMPM SMPM; - typedef typename boost::property_map, dynamic_face_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Face_index, T>(std::string(), default_value).first)); -} - -template -typename boost::property_map, dynamic_edge_property_t >::type -get(dynamic_edge_property_t, Surface_mesh& sm, const T& default_value = T()) -{ - typedef typename boost::property_map, dynamic_edge_property_t >::SMPM SMPM; - typedef typename boost::property_map, dynamic_edge_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Edge_index, T>(std::string(), default_value).first)); -} - -template -typename boost::property_map, dynamic_halfedge_property_t >::type -get(dynamic_halfedge_property_t, Surface_mesh& sm, const T& default_value = T()) -{ - typedef typename boost::property_map, dynamic_halfedge_property_t >::SMPM SMPM; - typedef typename boost::property_map, dynamic_halfedge_property_t >::type DPM; - return DPM(sm, new SMPM(sm.template add_property_map::Halfedge_index, T>(std::string(), default_value).first)); + using BPM = typename boost::property_map, Dynamic_property_tag>; + using descriptor = typename Dynamic_property_tag::template property_map>::descriptor; + using value_type = typename Dynamic_property_tag::value_type; + using SMPM = typename BPM::SMPM; + using DPM = typename BPM::type; + auto&& [sm_property_map, ok] = sm.template add_property_map( + std::string(), + std::forward(default_value_args)...); + CGAL_assume(ok); + return DPM(sm, new SMPM(std::forward(sm_property_map))); } // get functions for dynamic properties of const Surface_mesh -template -typename boost::property_map, dynamic_vertex_property_t >::const_type -get(dynamic_vertex_property_t, const Surface_mesh& sm, const T& default_value = T()) -{ - return CGAL::internal::Dynamic_with_index::Vertex_index, T>(num_vertices(sm), default_value); -} - -template -typename boost::property_map, dynamic_face_property_t >::const_type -get(dynamic_face_property_t, const Surface_mesh& sm, const T& default_value = T()) -{ - return CGAL::internal::Dynamic_with_index::Face_index, T>(num_faces(sm), default_value); -} - -template -typename boost::property_map, dynamic_halfedge_property_t >::const_type -get(dynamic_halfedge_property_t, const Surface_mesh& sm, const T& default_value = T()) -{ - return CGAL::internal::Dynamic_with_index::Halfedge_index, T>(num_halfedges(sm), default_value); -} - -template -typename boost::property_map, dynamic_edge_property_t >::const_type -get(dynamic_edge_property_t, const Surface_mesh& sm, const T& default_value = T()) -{ - return CGAL::internal::Dynamic_with_index::Edge_index, T>(num_edges(sm), default_value); +template ()>, + typename... Default_value_args> +auto get(Dynamic_property_tag, const Surface_mesh& sm, Default_value_args&&... default_value_args) { + using graph_traits = boost::graph_traits>; + using vertex_descriptor = typename graph_traits::vertex_descriptor; + using face_descriptor = typename graph_traits::face_descriptor; + using edge_descriptor = typename graph_traits::edge_descriptor; + using halfedge_descriptor = typename graph_traits::halfedge_descriptor; + auto num_elements = CGAL::overloaded{ + [&](vertex_descriptor) { return num_vertices(sm); }, + [&](halfedge_descriptor) { return num_halfedges(sm); }, + [&](edge_descriptor) { return num_edges(sm); }, + [&](face_descriptor) { return num_faces(sm); } + }; + using descriptor = typename Dynamic_property_tag::template property_map>::descriptor; + using value_type = typename Dynamic_property_tag::value_type; + return CGAL::internal::Dynamic_with_index( + num_elements(descriptor{}), + std::forward(default_value_args)...); } // implementation detail: required by Dynamic_property_map_deleter