// Copyright (c) 2008-2009 GeometryFactory and INRIA // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // Author(s) : Andreas Fabri and Laurent Saboret #ifndef CGAL_POINT_SET_PROPERTY_MAP_H #define CGAL_POINT_SET_PROPERTY_MAP_H #include #include #if BOOST_VERSION >= 104000 #include #else #include #endif #include #include // defines std::pair namespace CGAL { #ifndef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \cond SKIP_IN_MANUAL /// An alternative to boost::put_get_helper for pmaps where key itself or a part of it returned as mapped value. /// - Two `get` functions exist. /// + One of them passes key by reference and returns mapped value as reference /// + The other passes key by const reference, and returns mapped value as const reference /// - `key` is passed by reference in `put` function template struct put_get_helper_pass_key_by_reference { }; // this is required since LValuePM should have get which returns reference template inline Reference get(const put_get_helper_pass_key_by_reference& pa, K& k) { return static_cast(pa)[k]; } // this is also required because some of the functions pass const ref parameters template inline const typename PropertyMap::value_type& get(const put_get_helper_pass_key_by_reference& pa, const K& k) { return static_cast(pa)[k]; } template inline void put(const put_get_helper_pass_key_by_reference& pa, K& k, const V& v) { static_cast(pa)[k] = v; } /// \endcond #endif #ifdef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \ingroup PkgProperty_map /// Property map that converts a `T*` pointer (or in general an iterator /// over `T` elements) to the `T` object. /// /// \cgalModels `LvaluePropertyMap` template struct Dereference_property_map : public boost::put_get_helper > { typedef T* key_type; ///< typedef to 'T*' typedef T value_type; ///< typedef to 'T' typedef value_type& reference; ///< typedef to 'T&' typedef boost::lvalue_property_map_tag category; ///< `boost::lvalue_property_map_tag` /// Access a property map element. /// /// @tparam Iter Type convertible to `key_type`. template reference operator[](Iter it) const { return reference(*it); } }; /// Free function to create a `Dereference_property_map` property map. /// /// \relates Dereference_property_map template // Type convertible to `key_type` Dereference_property_map::type> make_dereference_property_map(Iter) { // value_type_traits is a workaround as back_insert_iterator's `value_type` is void return Dereference_property_map::type>(); } #endif #ifndef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \ingroup PkgProperty_map /// Property map that maps a key to itself. /// /// \cgalModels `LvaluePropertyMap` template struct Typed_identity_property_map_by_reference : put_get_helper_pass_key_by_reference > { typedef T key_type; ///< typedef to `T` typedef T value_type; ///< typedef to `T` typedef T& reference; ///< typedef to `T&` typedef boost::lvalue_property_map_tag category; ///< `boost::lvalue_property_map_tag` /// Access a property map element. /// @param v a key which is returned as mapped value. reference operator[](key_type& v) const { return v; } /// Const version. const value_type& operator[](const key_type& v) const { return v; } }; /// Free function to create a `Typed_identity_property_map_by_reference` property map. /// /// \relates Typed_identity_property_map_by_reference template // Key and value type Typed_identity_property_map_by_reference make_typed_identity_property_map_by_reference(T) { return Typed_identity_property_map_by_reference(); } #endif //========================================================================= #ifdef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \ingroup PkgProperty_map /// Property map that accesses the first item of a `std::pair`. /// \tparam Pair Instance of `std::pair`. /// \cgalModels `LvaluePropertyMap` /// /// \sa `CGAL::Second_of_pair_property_map` template struct First_of_pair_property_map : public boost::put_get_helper > { typedef Pair* key_type; ///< typedef to `Pair*` typedef typename Pair::first_type value_type; ///< typedef to `Pair::first_type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< boost::lvalue_property_map_tag /// Access a property map element. /// /// @tparam Iter Type convertible to `key_type`. template reference operator[](Iter pair) const { return reference(pair->first); } }; /// Free function to create a `First_of_pair_property_map` property map. /// /// \relates First_of_pair_property_map template // Type convertible to key_type First_of_pair_property_map::type> make_first_of_pair_property_map(Iter) { // value_type_traits is a workaround as back_insert_iterator's value_type is void return First_of_pair_property_map::type>(); } #else /// \ingroup PkgProperty_map /// Property map that accesses the first item of a `std::pair`. /// \tparam Pair Instance of `std::pair`. /// \cgalModels `LvaluePropertyMap` /// /// \sa `CGAL::Second_of_pair_property_map` template struct First_of_pair_property_map : put_get_helper_pass_key_by_reference > { typedef Pair key_type; ///< typedef to `Pair` typedef typename Pair::first_type value_type; ///< typedef to `Pair::first_type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< boost::lvalue_property_map_tag /// Access a property map element. /// @param pair a key whose first item is accessed reference operator[](key_type& pair) const { return pair.first; } /// Const version. const value_type& operator[](const key_type& pair) const { return pair.first; } }; /// Free function to create a `First_of_pair_property_map` property map. /// /// \relates First_of_pair_property_map template // Pair type First_of_pair_property_map make_first_of_pair_property_map(Pair) { return First_of_pair_property_map(); } #endif #ifdef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \ingroup PkgProperty_map /// /// Property map that accesses the second item of a `std::pair`. /// /// \tparam Pair Instance of `std::pair`. /// /// \cgalModels `LvaluePropertyMap` /// /// \sa `CGAL::First_of_pair_property_map` template struct Second_of_pair_property_map : public boost::put_get_helper > { typedef Pair* key_type; ///< typedef to `Pair*` typedef typename Pair::second_type value_type; ///< typedef to `Pair::second_type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< `boost::lvalue_property_map_tag` /// Access a property map element. /// /// @tparam Iter Type convertible to `key_type`. template reference operator[](Iter pair) const { return reference(pair->second); } }; /// Free function to create a Second_of_pair_property_map property map. /// /// \relates Second_of_pair_property_map template // Type convertible to key_type Second_of_pair_property_map::type> make_second_of_pair_property_map(Iter) { // value_type_traits is a workaround as back_insert_iterator's value_type is void return Second_of_pair_property_map::type>(); } #else /// \ingroup PkgProperty_map /// /// Property map that accesses the second item of a `std::pair`. /// /// \tparam Pair Instance of `std::pair`. /// /// \cgalModels `LvaluePropertyMap` /// /// \sa `CGAL::First_of_pair_property_map` template struct Second_of_pair_property_map : put_get_helper_pass_key_by_reference > { typedef Pair key_type; ///< typedef to `Pair` typedef typename Pair::second_type value_type; ///< typedef to `Pair::first_type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< boost::lvalue_property_map_tag /// Access a property map element. /// @param pair a key whose second item is accessed reference operator[](key_type& pair) const { return pair.second; } /// Const version. const value_type& operator[](const key_type& pair) const { return pair.second; } }; /// Free function to create a Second_of_pair_property_map property map. /// /// \relates Second_of_pair_property_map template // Pair type Second_of_pair_property_map make_second_of_pair_property_map(Pair) { return Second_of_pair_property_map(); } #endif //========================================================================= #ifdef CGAL_USE_OLD_PAIR_PROPERTY_MAPS /// \ingroup PkgProperty_map /// /// Property map that accesses the Nth item of a `boost::tuple`. /// /// \tparam N Index of the item to access. /// \tparam Tuple Instance of `boost::tuple`. /// /// \cgalModels `LvaluePropertyMap` template struct Nth_of_tuple_property_map : public boost::put_get_helper::type&, Nth_of_tuple_property_map > { typedef Tuple* key_type; ///< typedef to `Tuple*` typedef typename boost::tuples::element::type value_type; ///< typedef to `boost::tuples::element::%type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< `boost::lvalue_property_map_tag` /// Access a property map element. /// /// @tparam Iter Type convertible to `key_type`. template reference operator[](Iter tuple) const { return (reference) tuple->template get(); } }; /// Free function to create a Nth_of_tuple_property_map property map. /// /// \relates Nth_of_tuple_property_map template // Type convertible to key_type Nth_of_tuple_property_map::type> make_nth_of_tuple_property_map(Iter) { // value_type_traits is a workaround as back_insert_iterator's `value_type` is void return Nth_of_tuple_property_map::type>(); } #else /// \ingroup PkgProperty_map /// /// Property map that accesses the Nth item of a `boost::tuple`. /// /// \tparam N Index of the item to access. /// \tparam Tuple Instance of `boost::tuple`. /// /// \cgalModels `LvaluePropertyMap` template struct Nth_of_tuple_property_map : put_get_helper_pass_key_by_reference::type&, Nth_of_tuple_property_map > { typedef Tuple key_type; ///< typedef to `Tuple` typedef typename boost::tuples::element::type value_type; ///< typedef to `boost::tuples::element::%type` typedef value_type& reference; ///< typedef to `value_type&` typedef boost::lvalue_property_map_tag category; ///< `boost::lvalue_property_map_tag` /// Access a property map element. /// @param tuple a key whose Nth item is accessed reference operator[](key_type& tuple) const { return tuple.template get(); } /// Const version. const value_type& operator[](const key_type& tuple) const { return tuple.template get(); } }; /// Free function to create a Nth_of_tuple_property_map property map. /// /// \relates Nth_of_tuple_property_map template // Tuple type Nth_of_tuple_property_map make_nth_of_tuple_property_map(Tuple) { return Nth_of_tuple_property_map(); } #endif } // namespace CGAL #endif // CGAL_POINT_SET_PROPERTY_MAP_H