// Copyright (c) 2017 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Property_map/include/CGAL/Dynamic_property_map.h $ // $Id: Dynamic_property_map.h 8bb22d5 2020-03-26T14:23:37+01:00 Sébastien Loriot // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Andreas Fabri #ifndef CGAL_DYNAMIC_PROPERTY_MAP_H #define CGAL_DYNAMIC_PROPERTY_MAP_H #include #include #include #include #include #include #include #include namespace CGAL { namespace internal { template struct Dynamic_property_map { typedef K key_type; typedef V value_type; typedef const value_type& reference; typedef boost::read_write_property_map_tag category; Dynamic_property_map(const V& default_value = V()) : map_(new Map()), default_value_(default_value) {} void clear() { if(map_){ map_->clear(); } } friend reference get(const Dynamic_property_map& m, const key_type& k) { typename Map::const_iterator it = m.map_->find(k); if(it == m.map_->end()){ (*(const_cast(m).map_))[k] = m.default_value(); return m.default_value(); } return it->second; } friend void put(const Dynamic_property_map& m, const key_type& k, const value_type& v) { (*(m.map_))[k] = v; } const V& default_value() const { return default_value_; } typedef boost::unordered_map Map; boost::shared_ptr map_; V default_value_; }; template struct Dynamic_property_map_deleter { M& mesh; Dynamic_property_map_deleter(const M& mesh) : mesh(const_cast(mesh)) {} void operator()(PM* pm) const { remove_property(*pm, mesh); delete pm; } }; template struct Dynamic { typedef typename PM::key_type key_type; typedef typename PM::value_type value_type; typedef typename PM::reference reference; typedef typename PM::category category; typedef Dynamic_property_map_deleter Deleter; Dynamic() : map_() {} Dynamic(const Mesh& mesh, PM* pm) : map_(pm, Deleter(mesh)) {} friend reference get(const Dynamic& m, const key_type& k) { return get(*(m.map_), k); } friend void put(const Dynamic& m, const key_type& k, const value_type& v) { put(*(m.map_), k, v); } boost::shared_ptr map_; }; template struct Dynamic_with_index { typedef Key key_type; typedef Value value_type; typedef typename boost::mpl::if_< boost::is_same, value_type, value_type&>::type reference; typedef typename boost::mpl::if_< boost::is_same, boost::read_write_property_map_tag, boost::lvalue_property_map_tag>::type category; Dynamic_with_index() : m_values() {} Dynamic_with_index(std::size_t num_features) : m_values( new std::vector(num_features) ) {} friend reference get(const Dynamic_with_index& m, const key_type& k) { return (*m.m_values)[k.idx()]; } friend void put(const Dynamic_with_index& m, const key_type& k, const value_type& v) { (*m.m_values)[k.idx()]=v; } boost::shared_ptr > m_values; }; } // namespace internal template struct dynamic_vertex_property_t { dynamic_vertex_property_t() {} }; template struct dynamic_halfedge_property_t { dynamic_halfedge_property_t() {} }; template struct dynamic_edge_property_t { dynamic_edge_property_t() {} }; template struct dynamic_face_property_t { dynamic_face_property_t() {} }; } // namespace CGAL namespace boost { template struct property_map > { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; template struct property_map > { typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef CGAL::internal::Dynamic_property_map type; typedef type const_type; }; } // namespace boost namespace CGAL { template typename boost::property_map >::const_type get(const CGAL::dynamic_vertex_property_t&, const G&) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; return internal::Dynamic_property_map(); } template typename boost::property_map >::const_type get(const CGAL::dynamic_halfedge_property_t&, const G&) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; return internal::Dynamic_property_map(); } template typename boost::property_map >::const_type get(const CGAL::dynamic_edge_property_t&, const G&) { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; return internal::Dynamic_property_map(); } template typename boost::property_map >::const_type get(const CGAL::dynamic_face_property_t&, const G&) { typedef typename boost::graph_traits::face_descriptor face_descriptor; return internal::Dynamic_property_map(); } template void remove_property( internal::Dynamic_property_map pm, const G&) { pm.clear(); } } // namespace CGAL #endif // CGAL_DYNAMIC_PROPERTY_MAP_H