// Copyright (c) 2002,2011 Utrecht University (The Netherlands). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL: https://github.com/CGAL/cgal/blob/v5.1/Spatial_searching/include/CGAL/internal/Search_helpers.h $ // $Id: Search_helpers.h 8bb22d5 2020-03-26T14:23:37+01:00 Sébastien Loriot // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Clement Jamin (clement.jamin.pro@gmail.com) #ifndef CGAL_INTERNAL_SEARCH_HELPERS_H #define CGAL_INTERNAL_SEARCH_HELPERS_H #include #include #include namespace CGAL { namespace internal { // Helper struct to know at compile-time if there is a cache of the points // stored in the tree template struct Has_points_cache; template struct Has_points_cache { typedef typename Tree::Enable_points_cache type; static const bool value = type::value; }; template struct Has_points_cache { typedef Tag_false type; static const bool value = false; }; CGAL_GENERATE_MEMBER_DETECTOR(transformed_distance_from_coordinates); CGAL_GENERATE_MEMBER_DETECTOR(interruptible_transformed_distance); BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Enable_points_cache, Enable_points_cache, false) // If transformed_distance_from_coordinates does not exist in `Distance` template class Transformed_distance_from_coordinates { typedef typename Distance::FT FT; typedef typename Distance::Point_d Point; typedef typename Distance::Query_item Query_item; public: Transformed_distance_from_coordinates(Distance const& distance) : m_distance(distance) {} FT operator() ( const Query_item& q, Point const& p, typename std::vector::const_iterator /*it_coord_begin*/, typename std::vector::const_iterator /*it_coord_end*/) const { return m_distance.transformed_distance(q, p); } private: Distance const& m_distance; }; // ... or if it exists template class Transformed_distance_from_coordinates { typedef typename Distance::FT FT; typedef typename Distance::Point_d Point; typedef typename Distance::Query_item Query_item; public: Transformed_distance_from_coordinates(Distance const& distance) : m_distance(distance) {} FT operator() ( const Query_item& q, Point const& /*p*/, typename std::vector::const_iterator it_coord_begin, typename std::vector::const_iterator it_coord_end) const { return m_distance.transformed_distance_from_coordinates(q, it_coord_begin, it_coord_end); } private: Distance const& m_distance; }; // If interruptible_transformed_distance does not exist in `Distance` template class Interruptible_transformed_distance { typedef typename Distance::FT FT; typedef typename Distance::Point_d Point; typedef typename Distance::Query_item Query_item; public: typedef Transformed_distance_from_coordinates::value> Tdfc; Interruptible_transformed_distance( SearchTraits const&, Distance const& distance, Tdfc const& tdfc) : m_distance(distance), m_ref_to_tdfc(tdfc) {} FT operator() ( const Query_item& q, Point const& p, FT) const { return m_distance.transformed_distance(q, p); } FT operator() ( const Query_item& q, Point const& p, typename std::vector::const_iterator it_coord_begin, typename std::vector::const_iterator it_coord_end, FT) const { return m_ref_to_tdfc(q, p, it_coord_begin, it_coord_end); } private: Distance const& m_distance; Tdfc const& m_ref_to_tdfc; }; // ... or if it exists template class Interruptible_transformed_distance { typedef typename Distance::FT FT; typedef typename Distance::Point_d Point; typedef typename Distance::Query_item Query_item; public: typedef Transformed_distance_from_coordinates::value> Tdfc; Interruptible_transformed_distance( SearchTraits const& traits, Distance const& distance, Tdfc const&) : m_traits(traits), m_distance(distance) {} FT operator() ( const Query_item& q, Point const& p, FT stop_if_geq_to_this) const { typename SearchTraits::Construct_cartesian_const_iterator_d construct_it = m_traits.construct_cartesian_const_iterator_d_object(); return m_distance.interruptible_transformed_distance( q, construct_it(p), construct_it(p, 0), stop_if_geq_to_this); } FT operator() ( const Query_item& q, Point const& /*p*/, typename std::vector::const_iterator it_coord_begin, typename std::vector::const_iterator it_coord_end, FT stop_if_geq_to_this) const { return m_distance.interruptible_transformed_distance( q, it_coord_begin, it_coord_end, stop_if_geq_to_this); } private: SearchTraits const& m_traits; Distance const& m_distance; }; template class Distance_helper { typedef typename Distance::FT FT; typedef typename Distance::Point_d Point; typedef typename Distance::Query_item Query_item; public: Distance_helper(Distance const& distance, SearchTraits const& traits) : m_distance(distance), m_tdfc(m_distance), m_itd(traits, distance, m_tdfc) {} FT transformed_distance_from_coordinates( const Query_item& q, Point const& p, typename std::vector::const_iterator it_coord_begin, typename std::vector::const_iterator it_coord_end) { return m_tdfc(q, p, it_coord_begin, it_coord_end); } FT interruptible_transformed_distance( const Query_item& q, Point const& p, FT stop_if_geq_to_this) { return m_itd(q, p, stop_if_geq_to_this); } FT interruptible_transformed_distance( const Query_item& q, Point const& p, typename std::vector::const_iterator it_coord_begin, typename std::vector::const_iterator it_coord_end, FT stop_if_geq_to_this) { return m_itd(q, p, it_coord_begin, it_coord_end, stop_if_geq_to_this); } private: Distance const& m_distance; Transformed_distance_from_coordinates::value> m_tdfc; Interruptible_transformed_distance::value> m_itd; }; // Distance_helper }} // namespace CGAL::internal #endif // CGAL_INTERNAL_SEARCH_HELPERSS_H