update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,11 +15,18 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
#include <boost/geometry/algorithms/detail/envelope/interface.hpp>
#include <boost/geometry/algorithms/detail/expand/interface.hpp>
#include <boost/geometry/index/detail/bounded_view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace boost { namespace geometry { namespace index { namespace detail
{
namespace dispatch {
namespace dispatch
{
template <typename Geometry,
typename Bounds,
@@ -23,7 +34,8 @@ template <typename Geometry,
typename TagBounds = typename geometry::tag<Bounds>::type>
struct bounds
{
static inline void apply(Geometry const& g, Bounds & b)
template <typename Strategy>
static inline void apply(Geometry const& g, Bounds & b, Strategy const& )
{
geometry::convert(g, b);
}
@@ -32,59 +44,184 @@ struct bounds
template <typename Geometry, typename Bounds>
struct bounds<Geometry, Bounds, segment_tag, box_tag>
{
static inline void apply(Geometry const& g, Bounds & b)
template <typename Strategy>
static inline void apply(Geometry const& g, Bounds & b, Strategy const& s)
{
index::detail::bounded_view<Geometry, Bounds> v(g);
index::detail::bounded_view<Geometry, Bounds, Strategy> v(g, s);
geometry::convert(v, b);
}
};
} // namespace dispatch
template <typename Geometry, typename Bounds>
inline void bounds(Geometry const& g, Bounds & b)
template <typename Geometry, typename Bounds, typename Strategy>
inline void bounds(Geometry const& g, Bounds & b, Strategy const& s)
{
concepts::check_concepts_and_equal_dimensions<Geometry const, Bounds>();
dispatch::bounds<Geometry, Bounds>::apply(g, b);
dispatch::bounds<Geometry, Bounds>::apply(g, b, s);
}
namespace dispatch {
template <typename Geometry,
namespace dispatch
{
template <typename Bounds,
typename Geometry,
typename TagBounds = typename geometry::tag<Bounds>::type,
typename TagGeometry = typename geometry::tag<Geometry>::type>
struct return_ref_or_bounds
struct expand
{
typedef Geometry const& result_type;
// STATIC ASSERT
};
static inline result_type apply(Geometry const& g)
template <typename Bounds, typename Geometry>
struct expand<Bounds, Geometry, box_tag, point_tag>
{
static inline void apply(Bounds & b, Geometry const& g)
{
return g;
geometry::expand(b, g);
}
template <typename Strategy>
static inline void apply(Bounds & b, Geometry const& g, Strategy const& s)
{
geometry::expand(b, g, s);
}
};
template <typename Geometry>
struct return_ref_or_bounds<Geometry, segment_tag>
template <typename Bounds, typename Geometry>
struct expand<Bounds, Geometry, box_tag, box_tag>
{
typedef typename point_type<Geometry>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<Geometry, bounds_type> result_type;
static inline result_type apply(Geometry const& g)
static inline void apply(Bounds & b, Geometry const& g)
{
return result_type(g);
geometry::expand(b, g);
}
template <typename Strategy>
static inline void apply(Bounds & b, Geometry const& g, Strategy const& s)
{
geometry::expand(b, g, s);
}
};
template <typename Bounds, typename Geometry>
struct expand<Bounds, Geometry, box_tag, segment_tag>
{
static inline void apply(Bounds & b, Geometry const& g)
{
geometry::expand(b, g);
}
template <typename Strategy>
static inline void apply(Bounds & b, Geometry const& g, Strategy const& s)
{
geometry::expand(b, geometry::return_envelope<Bounds>(g, s), s);
// requires additional strategy
//geometry::expand(b, g, s);
}
};
} // namespace dispatch
template <typename Geometry>
inline
typename dispatch::return_ref_or_bounds<Geometry>::result_type
return_ref_or_bounds(Geometry const& g)
template <typename Bounds, typename Geometry, typename Strategy>
inline void expand(Bounds & b, Geometry const& g, Strategy const& s)
{
return dispatch::return_ref_or_bounds<Geometry>::apply(g);
dispatch::expand<Bounds, Geometry>::apply(b, g, s);
}
template <typename Bounds, typename Geometry>
inline void expand(Bounds & b, Geometry const& g, default_strategy const& )
{
dispatch::expand<Bounds, Geometry>::apply(b, g);
}
namespace dispatch
{
template <typename Geometry,
typename Bounds,
typename TagGeometry = typename geometry::tag<Geometry>::type,
typename TagBounds = typename geometry::tag<Bounds>::type>
struct covered_by_bounds
{};
template <typename Geometry, typename Bounds>
struct covered_by_bounds<Geometry, Bounds, point_tag, box_tag>
{
static inline bool apply(Geometry const& g, Bounds & b)
{
return geometry::covered_by(g, b);
}
template <typename Strategy>
static inline bool apply(Geometry const& g, Bounds & b, Strategy const& s)
{
return geometry::covered_by(g, b, s);
}
};
template <typename Geometry, typename Bounds>
struct covered_by_bounds<Geometry, Bounds, box_tag, box_tag>
{
static inline bool apply(Geometry const& g, Bounds & b)
{
return geometry::covered_by(g, b);
}
template <typename Strategy>
static inline bool apply(Geometry const& g, Bounds & b, Strategy const& s)
{
return geometry::covered_by(g, b, s);
}
};
template <typename Geometry, typename Bounds>
struct covered_by_bounds<Geometry, Bounds, segment_tag, box_tag>
{
static inline bool apply(Geometry const& g, Bounds & b)
{
typedef typename point_type<Geometry>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<Geometry, bounds_type, default_strategy> view_type;
return geometry::covered_by(view_type(g, default_strategy()), b);
}
template <typename Strategy>
static inline bool apply(Geometry const& g, Bounds & b, Strategy const& strategy)
{
typedef typename point_type<Geometry>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<Geometry, bounds_type, Strategy> view_type;
return geometry::covered_by(view_type(g, strategy), b, strategy);
}
};
} // namespace dispatch
template <typename Geometry, typename Bounds, typename Strategy>
inline bool covered_by_bounds(Geometry const& g, Bounds & b, Strategy const& s)
{
return dispatch::covered_by_bounds<Geometry, Bounds>::apply(g, b, s);
}
template <typename Geometry, typename Bounds>
inline bool covered_by_bounds(Geometry const& g, Bounds & b, default_strategy const& )
{
return dispatch::covered_by_bounds<Geometry, Bounds>::apply(g, b);
}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_BOUNDS_HPP

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_CENTROID_HPP
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/index/detail/algorithms/sum_for_indexable.hpp>
#include <boost/geometry/index/detail/algorithms/diff_abs.hpp>
@@ -48,7 +55,7 @@ struct sum_for_indexable_dimension<Point, BoxIndexable, box_tag, comparable_dist
point_coord_t pt_c = geometry::get<DimensionIndex>(pt);
indexable_coord_t ind_c_min = geometry::get<geometry::min_corner, DimensionIndex>(i);
indexable_coord_t ind_c_max = geometry::get<geometry::max_corner, DimensionIndex>(i);
indexable_coord_t ind_c_avg = ind_c_min + (ind_c_max - ind_c_min) / 2;
// TODO: awulkiew - is (ind_c_min + ind_c_max) / 2 safe?

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_FAR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_FAR_HPP
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/index/detail/algorithms/diff_abs.hpp>
#include <boost/geometry/index/detail/algorithms/sum_for_indexable.hpp>

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_COMPARABLE_DISTANCE_NEAR_HPP
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/index/detail/algorithms/sum_for_indexable.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2023.
// Modifications copyright (c) 2020-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,15 +16,24 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Indexable>
struct default_content_result
{
typedef typename select_most_precise<
typename coordinate_type<Indexable>::type,
long double
>::type type;
using type = typename select_most_precise
<
typename coordinate_type<Indexable>::type,
double
>::type;
};
namespace dispatch {
@@ -49,7 +63,9 @@ struct content_box<Box, 1>
template <typename Indexable, typename Tag>
struct content
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_AND_TAG, (Indexable, Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable and Tag.",
Indexable, Tag);
};
template <typename Indexable>

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2023.
// Modifications copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,27 +16,30 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_DIFF_ABS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_DIFF_ABS_HPP
namespace boost { namespace geometry { namespace index { namespace detail {
#include <cmath>
#include <type_traits>
template <typename T>
inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<true> const& /*is_integral*/)
namespace boost { namespace geometry { namespace index { namespace detail
{
template
<
typename T,
std::enable_if_t<std::is_integral<T>::value, int> = 0
>
inline T diff_abs(T const& v1, T const& v2)
{
return v1 < v2 ? v2 - v1 : v1 - v2;
}
template <typename T>
inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_<false> const& /*is_integral*/)
{
return ::fabs(v1 - v2);
}
template <typename T>
template
<
typename T,
std::enable_if_t<! std::is_integral<T>::value, int> = 0
>
inline T diff_abs(T const& v1, T const& v2)
{
typedef boost::mpl::bool_<
boost::is_integral<T>::value
> is_integral;
return diff_abs_dispatch(v1, v2, is_integral());
return ::fabs(v1 - v2);
}
}}}} // namespace boost::geometry::index::detail

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -16,20 +20,36 @@
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
/**
* \brief Compute the area of the intersection of b1 and b2
*/
template <typename Box>
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2)
// Util to distinguish between default and non-default index strategy
template <typename Box, typename Strategy>
inline bool disjoint_box_box(Box const& box1, Box const& box2, Strategy const& s)
{
typedef typename strategy::disjoint::services::default_strategy
<
Box, Box
>::type strategy_type;
return geometry::detail::disjoint::disjoint_box_box(box1, box2, s);
}
bool const intersects = ! geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type());
template <typename Box>
inline bool disjoint_box_box(Box const& box1, Box const& box2, default_strategy const& )
{
typedef typename strategy::disjoint::services::default_strategy<Box, Box>::type strategy_type;
return geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type());
}
/**
* \brief Compute the area, volume, ... of the intersection of b1 and b2
*/
template <typename Box, typename Strategy>
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2, Strategy const& strategy)
{
bool const intersects = ! index::detail::disjoint_box_box(box1, box2, strategy);
// NOTE: the code below may be inconsistent with the disjoint_box_box()
// however intersection_box_box checks if the boxes intersect on the fly so it should be ok
// but this also means that disjoint_box_box() is probably not needed
if ( intersects )
{
@@ -46,6 +66,12 @@ inline typename default_content_result<Box>::type intersection_content(Box const
return 0;
}
template <typename Box>
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2)
{
return intersection_content(box1, box2, default_strategy());
}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_INTERSECTION_CONTENT_HPP

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2021.
// Modifications copyright (c) 2020-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,7 +16,10 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -42,10 +49,9 @@ template <typename Indexable,
typename Tag = typename geometry::tag<Indexable>::type>
struct is_valid
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_INDEXABLE,
(is_valid));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Tag);
};
template <typename Indexable>

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2023.
// Modifications copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +16,14 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
// WARNING! comparable_margin() will work only if the same Geometries are compared
// so it shouldn't be used in the case of Variants!
@@ -19,10 +32,11 @@ namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Box>
struct default_margin_result
{
typedef typename select_most_precise<
typename coordinate_type<Box>::type,
long double
>::type type;
using type = typename select_most_precise
<
typename coordinate_type<Box>::type,
double
>::type;
};
//template <typename Box,
@@ -124,7 +138,9 @@ namespace dispatch {
template <typename Geometry, typename Tag>
struct comparable_margin
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry type.",
Geometry, Tag);
};
template <typename Geometry>

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -14,6 +18,8 @@
#include <boost/geometry/algorithms/distance.hpp>
#include <boost/geometry/algorithms/comparable_distance.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/diff_abs.hpp>
#include <boost/geometry/index/detail/algorithms/sum_for_indexable.hpp>
#include <boost/geometry/index/detail/algorithms/smallest_for_indexable.hpp>
@@ -50,7 +56,7 @@ struct smallest_for_indexable_dimension<Point, BoxIndexable, box_tag, minmaxdist
closer_comp = detail::diff_abs(pt_c, ind_c_min); // unsigned values protection
else
closer_comp = ind_c_max - pt_c;
result_type further_comp = 0;
if ( ind_c_avg <= pt_c )
further_comp = pt_c - ind_c_min;
@@ -64,10 +70,9 @@ struct smallest_for_indexable_dimension<Point, BoxIndexable, box_tag, minmaxdist
template <typename Point, typename Indexable, typename IndexableTag>
struct minmaxdist_impl
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_TAG_TYPE,
(minmaxdist_impl));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Point, Indexable, IndexableTag);
};
template <typename Point, typename Indexable>

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2023.
// Modifications copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,8 +17,14 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_PATH_INTERSECTION_HPP
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/distance/interface.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/segment_intersection.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/default_length_result.hpp>
@@ -24,7 +35,9 @@ namespace dispatch {
template <typename Indexable, typename Geometry, typename IndexableTag, typename GeometryTag>
struct path_intersection
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_GEOMETRY_OR_INDEXABLE, (path_intersection));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry or Indexable.",
Indexable, Geometry, IndexableTag, GeometryTag);
};
// TODO: FP type must be used as a relative distance type!
@@ -55,9 +68,9 @@ struct path_intersection<Indexable, Linestring, box_tag, linestring_tag>
static inline bool apply(Indexable const& b, Linestring const& path, comparable_distance_type & comparable_distance)
{
typedef typename ::boost::range_value<Linestring>::type point_type;
typedef typename ::boost::range_const_iterator<Linestring>::type const_iterator;
typedef typename ::boost::range_const_iterator<Linestring>::type const_iterator;
typedef typename ::boost::range_size<Linestring>::type size_type;
const size_type count = ::boost::size(path);
if ( count == 2 )

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020-2021.
// Modifications copyright (c) 2020-2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,15 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP
#include <limits>
#include <type_traits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
//template <typename Indexable, typename Point>
@@ -25,8 +38,8 @@ namespace boost { namespace geometry { namespace index { namespace detail {
// >::type type;
//
//
// BOOST_MPL_ASSERT_MSG((!::boost::is_unsigned<type>::value),
// THIS_TYPE_SHOULDNT_BE_UNSIGNED, (type));
// BOOST_GEOMETRY_STATIC_ASSERT((!std::is_unsigned<type>::value),
// "Distance type can not be unsigned.", type);
//};
namespace dispatch {
@@ -93,13 +106,17 @@ struct box_segment_intersection<Box, Point, 1>
template <typename Indexable, typename Point, typename Tag>
struct segment_intersection
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (segment_intersection));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Point, Tag);
};
template <typename Indexable, typename Point>
struct segment_intersection<Indexable, Point, point_tag>
{
BOOST_MPL_ASSERT_MSG((false), SEGMENT_POINT_INTERSECTION_UNAVAILABLE, (segment_intersection));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Segment-Point intersection unavailable.",
Indexable, Point);
};
template <typename Indexable, typename Point>
@@ -113,8 +130,10 @@ struct segment_intersection<Indexable, Point, box_tag>
// TODO: this ASSERT CHECK is wrong for user-defined CoordinateTypes!
static const bool check = !::boost::is_integral<RelativeDistance>::value;
BOOST_MPL_ASSERT_MSG(check, RELATIVE_DISTANCE_MUST_BE_FLOATING_POINT_TYPE, (RelativeDistance));
static const bool check = !std::is_integral<RelativeDistance>::value;
BOOST_GEOMETRY_STATIC_ASSERT(check,
"RelativeDistance must be a floating point type.",
RelativeDistance);
RelativeDistance t_near = -(::std::numeric_limits<RelativeDistance>::max)();
RelativeDistance t_far = (::std::numeric_limits<RelativeDistance>::max)();

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SMALLEST_FOR_INDEXABLE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SMALLEST_FOR_INDEXABLE_HPP
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <
@@ -21,10 +27,9 @@ template <
size_t DimensionIndex>
struct smallest_for_indexable_dimension
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_TAG_TYPE,
(smallest_for_indexable_dimension));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Geometry, Indexable, IndexableTag, AlgoTag);
};
template <

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <
@@ -21,10 +27,9 @@ template <
size_t DimensionIndex>
struct sum_for_indexable_dimension
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_TAG_TYPE,
(sum_for_indexable_dimension));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Geometry, Indexable, IndexableTag, AlgoTag);
};
template <

View File

@@ -5,6 +5,10 @@
//
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,38 +16,62 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/index/services.hpp>
namespace boost { namespace geometry {
namespace index { namespace detail {
template <typename Geometry,
typename BoundingGeometry,
typename Tag = typename geometry::tag<Geometry>::type,
typename BoundingTag = typename geometry::tag<BoundingGeometry>::type,
typename CSystem = typename geometry::coordinate_system<Geometry>::type>
struct bounded_view
template <typename Geometry, typename BoundingGeometry, typename Strategy>
struct bounded_view_base_cs_tag
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THOSE_GEOMETRIES,
(BoundingTag, Tag));
typedef typename Strategy::cs_tag type;
};
template <typename Geometry, typename BoundingGeometry>
struct bounded_view_base_cs_tag<Geometry, BoundingGeometry, default_strategy>
: geometry::cs_tag<Geometry>
{};
template
<
typename Geometry,
typename BoundingGeometry,
typename Strategy,
typename Tag = typename geometry::tag<Geometry>::type,
typename BoundingTag = typename geometry::tag<BoundingGeometry>::type,
typename CSTag = typename bounded_view_base_cs_tag
<
Geometry, BoundingGeometry, Strategy
>::type
>
struct bounded_view_base
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for these Geometries.",
Geometry, BoundingGeometry, Strategy, Tag, BoundingTag, CSTag);
};
// Segment -> Box
template <typename Segment, typename Box>
struct bounded_view<Segment, Box, segment_tag, box_tag, cs::cartesian>
template <typename Segment, typename Box, typename Strategy>
struct bounded_view_base<Segment, Box, Strategy, segment_tag, box_tag, cartesian_tag>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
explicit bounded_view(Segment const& segment)
bounded_view_base(Segment const& segment, Strategy const& )
: m_segment(segment)
{}
template <std::size_t Dimension>
inline coordinate_type get_min() const
{
@@ -64,15 +92,14 @@ private:
Segment const& m_segment;
};
template <typename Segment, typename Box, typename CSystem>
struct bounded_view<Segment, Box, segment_tag, box_tag, CSystem>
template <typename Segment, typename Box, typename Strategy, typename CSTag>
struct bounded_view_base<Segment, Box, Strategy, segment_tag, box_tag, CSTag>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
explicit bounded_view(Segment const& segment)
bounded_view_base(Segment const& segment, Strategy const& strategy)
{
geometry::envelope(segment, m_box);
geometry::envelope(segment, m_box, strategy);
}
template <std::size_t Dimension>
@@ -93,13 +120,13 @@ private:
// Box -> Box
template <typename BoxIn, typename Box, typename CSystem>
struct bounded_view<BoxIn, Box, box_tag, box_tag, CSystem>
template <typename BoxIn, typename Box, typename Strategy, typename CSTag>
struct bounded_view_base<BoxIn, Box, Strategy, box_tag, box_tag, CSTag>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
explicit bounded_view(BoxIn const& box)
bounded_view_base(BoxIn const& box, Strategy const& )
: m_box(box)
{}
@@ -123,13 +150,13 @@ private:
// Point -> Box
template <typename Point, typename Box, typename CSystem>
struct bounded_view<Point, Box, point_tag, box_tag, CSystem>
template <typename Point, typename Box, typename Strategy, typename CSTag>
struct bounded_view_base<Point, Box, Strategy, point_tag, box_tag, CSTag>
{
public:
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
explicit bounded_view(Point const& point)
bounded_view_base(Point const& point, Strategy const& )
: m_point(point)
{}
@@ -151,6 +178,52 @@ private:
Point const& m_point;
};
template <typename Geometry,
typename BoundingGeometry,
typename Strategy,
typename Tag = typename geometry::tag<Geometry>::type,
typename BoundingTag = typename geometry::tag<BoundingGeometry>::type>
struct bounded_view
: bounded_view_base<Geometry, BoundingGeometry, Strategy>
{
typedef bounded_view_base<Geometry, BoundingGeometry, Strategy> base_type;
bounded_view(Geometry const& geometry, Strategy const& strategy)
: base_type(geometry, strategy)
{}
};
template <typename Geometry,
typename BoundingGeometry,
typename Tag,
typename BoundingTag>
struct bounded_view<Geometry, BoundingGeometry, default_strategy, Tag, BoundingTag>
: bounded_view_base
<
Geometry,
BoundingGeometry,
typename strategies::index::services::default_strategy<Geometry>::type
>
{
typedef typename strategies::index::services::default_strategy
<
Geometry
>::type strategy_type;
typedef bounded_view_base
<
Geometry,
BoundingGeometry,
strategy_type
> base_type;
explicit bounded_view(Geometry const& geometry, default_strategy const& )
: base_type(geometry, strategy_type())
{}
};
}} // namespace index::detail
// XXX -> Box
@@ -159,23 +232,23 @@ private:
namespace traits
{
template <typename Geometry, typename Box, typename Tag, typename CSystem>
struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
template <typename Geometry, typename Box, typename Strategy, typename Tag>
struct tag< index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> >
{
typedef box_tag type;
};
template <typename Geometry, typename Box, typename Tag, typename CSystem>
struct point_type< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
template <typename Geometry, typename Box, typename Strategy, typename Tag>
struct point_type< index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> >
{
typedef typename point_type<Box>::type type;
};
template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
template <typename Geometry, typename Box, typename Strategy, typename Tag, std::size_t Dimension>
struct indexed_access<index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag>,
min_corner, Dimension>
{
typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)
@@ -189,11 +262,11 @@ struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, C
//}
};
template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
template <typename Geometry, typename Box, typename Strategy, typename Tag, std::size_t Dimension>
struct indexed_access<index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag>,
max_corner, Dimension>
{
typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
typedef index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> box_type;
typedef typename geometry::coordinate_type<Box>::type coordinate_type;
static inline coordinate_type get(box_type const& b)

View File

@@ -5,6 +5,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,11 +17,20 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_DISTANCE_PREDICATES_HPP
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
#include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
#include <boost/geometry/algorithms/detail/touches/interface.hpp>
#include <boost/geometry/algorithms/detail/within/interface.hpp>
#include <boost/geometry/index/detail/algorithms/comparable_distance_near.hpp>
#include <boost/geometry/index/detail/algorithms/comparable_distance_far.hpp>
#include <boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp>
#include <boost/geometry/index/detail/algorithms/path_intersection.hpp>
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/detail/tags.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -92,65 +106,118 @@ struct relation< to_furthest<T> >
static inline T & value(to_furthest<T> & r) { return r.value; }
};
// ------------------------------------------------------------------ //
template
<
typename G1, typename G2, typename Strategy
>
struct comparable_distance_call
{
typedef typename geometry::comparable_distance_result
<
G1, G2, Strategy
>::type result_type;
static inline result_type apply(G1 const& g1, G2 const& g2, Strategy const& s)
{
return geometry::comparable_distance(g1, g2, s);
}
};
template
<
typename G1, typename G2
>
struct comparable_distance_call<G1, G2, default_strategy>
{
typedef typename geometry::default_comparable_distance_result
<
G1, G2
>::type result_type;
static inline result_type apply(G1 const& g1, G2 const& g2, default_strategy const&)
{
return geometry::comparable_distance(g1, g2);
}
};
// ------------------------------------------------------------------ //
// calculate_distance
// ------------------------------------------------------------------ //
template <typename Predicate, typename Indexable, typename Tag>
template <typename Predicate, typename Indexable, typename Strategy, typename Tag>
struct calculate_distance
{
BOOST_MPL_ASSERT_MSG((false), INVALID_PREDICATE_OR_TAG, (calculate_distance));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Invalid Predicate or Tag.",
Predicate, Indexable, Strategy, Tag);
};
// this handles nearest() with default Point parameter, to_nearest() and bounds
template <typename PointRelation, typename Indexable, typename Tag>
struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Tag >
template <typename PointRelation, typename Indexable, typename Strategy, typename Tag>
struct calculate_distance< predicates::nearest<PointRelation>, Indexable, Strategy, Tag>
{
typedef detail::relation<PointRelation> relation;
typedef typename relation::value_type point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
typedef comparable_distance_call
<
typename relation::value_type,
Indexable,
Strategy
> call_type;
typedef typename call_type::result_type result_type;
static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest<PointRelation> const& p, Indexable const& i,
Strategy const& s, result_type & result)
{
result = geometry::comparable_distance(relation::value(p.point_or_relation), i);
result = call_type::apply(relation::value(p.point_or_relation), i, s);
return true;
}
};
template <typename Point, typename Indexable>
struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, value_tag>
template <typename Point, typename Indexable, typename Strategy>
struct calculate_distance< predicates::nearest< to_centroid<Point> >, Indexable, Strategy, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
typedef typename geometry::default_comparable_distance_result
<
point_type, Indexable
>::type result_type;
static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest< to_centroid<Point> > const& p, Indexable const& i,
Strategy const& , result_type & result)
{
result = index::detail::comparable_distance_centroid(p.point_or_relation.value, i);
return true;
}
};
template <typename Point, typename Indexable>
struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, value_tag>
template <typename Point, typename Indexable, typename Strategy>
struct calculate_distance< predicates::nearest< to_furthest<Point> >, Indexable, Strategy, value_tag>
{
typedef Point point_type;
typedef typename geometry::default_comparable_distance_result<point_type, Indexable>::type result_type;
typedef typename geometry::default_comparable_distance_result
<
point_type, Indexable
>::type result_type;
static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::nearest< to_furthest<Point> > const& p, Indexable const& i,
Strategy const& , result_type & result)
{
result = index::detail::comparable_distance_far(p.point_or_relation.value, i);
return true;
}
};
template <typename SegmentOrLinestring, typename Indexable, typename Tag>
struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Tag>
template <typename SegmentOrLinestring, typename Indexable, typename Strategy, typename Tag>
struct calculate_distance< predicates::path<SegmentOrLinestring>, Indexable, Strategy, Tag>
{
typedef typename index::detail::default_path_intersection_distance_type<
Indexable, SegmentOrLinestring
>::type result_type;
static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i, result_type & result)
static inline bool apply(predicates::path<SegmentOrLinestring> const& p, Indexable const& i,
Strategy const& , result_type & result)
{
return index::detail::path_intersection(i, p.geometry, result);
}

View File

@@ -0,0 +1,107 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP
#include <boost/geometry/index/detail/minmax_heap.hpp>
namespace boost { namespace geometry { namespace index { namespace detail
{
template <typename It, typename Compare>
inline void push_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
minmax_heap_detail::push_heap<max_call, min_call>(first, last, comp);
}
template <typename It>
inline void push_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
minmax_heap_detail::push_heap<max_call, min_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline void pop_top_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
pop_heap<max_call, min_call>(first, first, last, comp);
}
template <typename It>
inline void pop_top_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
pop_heap<max_call, min_call>(first, first, last, std::less<>());
}
template <typename It, typename Compare>
inline void pop_bottom_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
It bottom = minmax_heap_detail::bottom_heap<max_call>(first, last, comp);
pop_heap<max_call, min_call>(first, bottom, last, comp);
}
template <typename It>
inline void pop_bottom_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
auto&& comp = std::less<>();
It bottom = minmax_heap_detail::bottom_heap<max_call>(first, last, comp);
pop_heap<max_call, min_call>(first, bottom, last, comp);
}
template <typename It, typename Compare>
inline void make_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::make_heap<max_call, min_call>(first, last, comp);
}
template <typename It>
inline void make_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::make_heap<max_call, min_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline bool is_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::is_heap<max_call>(first, last, comp);
}
template <typename It>
inline bool is_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::is_heap<max_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline decltype(auto) bottom_maxmin_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return *minmax_heap_detail::bottom_heap<max_call>(first, last, comp);
}
template <typename It>
inline decltype(auto) bottom_maxmin_heap(It first, It last)
{
using namespace minmax_heap_detail;
return *minmax_heap_detail::bottom_heap<max_call>(first, last, std::less<>());
}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_MAXMIN_HEAP_HPP

View File

@@ -2,40 +2,36 @@
//
// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/range.hpp>
#include <boost/mpl/aux_/has_type.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_META_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_META_HPP
#include <type_traits>
//#include <boost/range/value_type.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename T>
struct is_range
: ::boost::mpl::aux::has_type< ::boost::range_iterator<T> >
{};
//template <typename T, typename V, bool IsRange>
//template <typename T, typename V, bool IsRange = range::detail::is_range<T>::value>
//struct is_range_of_convertible_values_impl
// : ::boost::is_convertible<typename ::boost::range_value<T>::type, V>
// : std::is_convertible<typename ::boost::range_value<T>::type, V>
//{};
//
//template <typename T, typename V>
//struct is_range_of_convertible_values_impl<T, V, false>
// : ::boost::mpl::bool_<false>
// : std::integral_constant<bool, false>
//{};
//
//template <typename T, typename V>
//struct is_range_of_convertible_values
// : is_range_of_convertible_values_impl<T, V, is_range<T>::value>
// : is_range_of_convertible_values_impl<T, V>
//{};
// Implemented this way in order to prevent instantiation of all type traits at
@@ -55,12 +51,12 @@ struct convertible_type_impl
template <typename T, typename Value, typename Indexable>
struct convertible_type_impl<T, Value, Indexable, void, 0>
{
typedef typename boost::mpl::if_c
typedef std::conditional_t
<
boost::is_convertible<T, Indexable>::value,
std::is_convertible<T, Indexable>::value,
Indexable,
void
>::type result_type;
> result_type;
typedef typename convertible_type_impl
<
@@ -71,28 +67,28 @@ struct convertible_type_impl<T, Value, Indexable, void, 0>
template <typename T, typename Value, typename Indexable>
struct convertible_type_impl<T, Value, Indexable, void, 1>
{
typedef typename boost::mpl::if_c
typedef std::conditional_t
<
boost::is_convertible<T, Value>::value,
std::is_convertible<T, Value>::value,
Value,
void
>::type type;
> type;
};
template <typename T, typename Value, typename Indexable>
struct convertible_type
{
typedef typename boost::mpl::if_c
typedef std::conditional_t
<
boost::is_same<T, Value>::value,
std::is_same<T, Value>::value,
Value,
typename boost::mpl::if_c
std::conditional_t
<
boost::is_same<T, Indexable>::value,
std::is_same<T, Indexable>::value,
Indexable,
void
>::type
>::type result_type;
>
> result_type;
typedef typename convertible_type_impl
<

View File

@@ -0,0 +1,521 @@
// Boost.Geometry
// Copyright (c) 2021-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP
#include <iterator>
#include <limits.h>
#include <type_traits>
#include <utility>
#ifdef _MSC_VER // msvc and clang-win
#include <intrin.h>
#endif
namespace boost { namespace geometry { namespace index { namespace detail
{
// Resources:
// https://en.wikipedia.org/wiki/Min-max_heap
// http://akira.ruc.dk/~keld/teaching/algoritmedesign_f03/Artikler/02/Atkinson86.pdf
// https://probablydance.com/2020/08/31/on-modern-hardware-the-min-max-heap-beats-a-binary-heap/
// https://stackoverflow.com/questions/6531543/efficient-implementation-of-binary-heaps
// https://stackoverflow.com/questions/994593/how-to-do-an-integer-log2-in-c
namespace minmax_heap_detail
{
template <typename T>
using bitsize = std::integral_constant<std::size_t, sizeof(T) * CHAR_BIT>;
template <typename It>
using diff_t = typename std::iterator_traits<It>::difference_type;
template <typename It>
using val_t = typename std::iterator_traits<It>::value_type;
// TODO: In C++20 use std::bit_width()
template <typename T, std::enable_if_t<!std::is_integral<T>::value || (bitsize<T>::value != 32 && bitsize<T>::value != 64), int> = 0>
inline int level(T i)
{
++i;
int r = 0;
while (i >>= 1) { ++r; }
return r;
}
//template <typename T>
//inline int level(T i)
//{
// using std::log2;
// return int(log2(i + 1));
//}
#ifdef _MSC_VER // msvc and clang-win
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 32, int> = 0>
inline int level(T i)
{
unsigned long r = 0;
_BitScanReverse(&r, (unsigned long)(i + 1));
return int(r);
}
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 64, int> = 0>
inline int level(T i)
{
unsigned long r = 0;
#ifdef _WIN64
_BitScanReverse64(&r, (unsigned long long)(i + 1));
#else
if (_BitScanReverse(&r, (unsigned long)((i + 1) >> 32))) { r += 32; }
else { _BitScanReverse(&r, (unsigned long)(i + 1)); }
#endif
return int(r);
}
#elif defined(__clang__) || defined(__GNUC__)
// Only available in gcc-10 and clang-10
//#elif defined(__has_builtin) && __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll)
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 32, int> = 0>
inline int level(T i)
{
return 31 - __builtin_clzl((unsigned long)(i + 1));
}
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 64, int> = 0>
inline int level(T i)
{
return 63 - __builtin_clzll((unsigned long long)(i + 1));
}
#else
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 32, int> = 0>
inline int level(T i)
{
++i;
int r = 0;
if (i >= 65536) { r += 16; i >>= 16; }
if (i >= 256) { r += 8; i >>= 8; }
if (i >= 16) { r += 4; i >>= 4; }
if (i >= 4) { r += 2; i >>= 2; }
if (i >= 2) { r += 1; i >>= 1; }
return r;
}
template <typename T, std::enable_if_t<std::is_integral<T>::value && bitsize<T>::value == 64, int> = 0>
inline int level(T i)
{
++i;
int r = 0;
if (i >= 4294967296ll) { r += 32; i >>= 32; }
if (i >= 65536ll) { r += 16; i >>= 16; }
if (i >= 256ll) { r += 8; i >>= 8; }
if (i >= 16ll) { r += 4; i >>= 4; }
if (i >= 4ll) { r += 2; i >>= 2; }
if (i >= 2ll) { r += 1; i >>= 1; }
return r;
}
#endif
// min/max functions only differ in the order of arguments in comp
struct min_call
{
template <typename Compare, typename T1, typename T2>
bool operator()(Compare&& comp, T1 const& v1, T2 const& v2) const
{
return comp(v1, v2);
}
};
struct max_call
{
template <typename Compare, typename T1, typename T2>
bool operator()(Compare&& comp, T1 const& v1, T2 const& v2) const
{
return comp(v2, v1);
}
};
template <typename Call, typename It, typename Compare>
inline void push_heap2(It first, diff_t<It> c, val_t<It> val, Compare comp)
{
while (c > 2)
{
diff_t<It> const g = (c - 3) >> 2; // grandparent index
if (! Call()(comp, val, *(first + g)))
{
break;
}
*(first + c) = std::move(*(first + g));
c = g;
}
*(first + c) = std::move(val);
}
template <typename MinCall, typename MaxCall, typename It, typename Compare>
inline void push_heap1(It first, diff_t<It> c, val_t<It> val, Compare comp)
{
diff_t<It> const p = (c - 1) >> 1; // parent index
if (MinCall()(comp, *(first + p), val))
{
*(first + c) = std::move(*(first + p));
return push_heap2<MaxCall>(first, p, std::move(val), comp);
}
else
{
return push_heap2<MinCall>(first, c, std::move(val), comp);
}
}
template <typename MinCall, typename MaxCall, typename It, typename Compare>
inline void push_heap(It first, It last, Compare comp)
{
diff_t<It> const size = last - first;
if (size < 2)
{
return;
}
diff_t<It> c = size - 1; // back index
val_t<It> val = std::move(*(first + c));
if (level(c) % 2 == 0) // is min level
{
push_heap1<MinCall, MaxCall>(first, c, std::move(val), comp);
}
else
{
push_heap1<MaxCall, MinCall>(first, c, std::move(val), comp);
}
}
template <typename Call, typename It, typename Compare>
inline diff_t<It> pick_grandchild4(It first, diff_t<It> f, Compare comp)
{
It it = first + f;
diff_t<It> m1 = Call()(comp, *(it), *(it + 1)) ? f : f + 1;
diff_t<It> m2 = Call()(comp, *(it + 2), *(it + 3)) ? f + 2 : f + 3;
return Call()(comp, *(first + m1), *(first + m2)) ? m1 : m2;
}
//template <typename Call, typename It, typename Compare>
//inline diff_t<It> pick_descendant(It first, diff_t<It> f, diff_t<It> l, Compare comp)
//{
// diff_t<It> m = f;
// for (++f; f != l; ++f)
// {
// if (Call()(comp, *(first + f), *(first + m)))
// {
// m = f;
// }
// }
// return m;
//}
template <typename Call, typename It, typename Compare>
inline void pop_heap1(It first, diff_t<It> p, diff_t<It> size, val_t<It> val, Compare comp)
{
if (size >= 7) // grandparent of 4 grandchildren is possible
{
diff_t<It> const last_g = (size - 3) >> 2; // grandparent of the element behind back
while (p < last_g) // p is grandparent of 4 grandchildren
{
diff_t<It> const ll = 4 * p + 3;
diff_t<It> const m = pick_grandchild4<Call>(first, ll, comp);
if (! Call()(comp, *(first + m), val))
{
break;
}
*(first + p) = std::move(*(first + m));
diff_t<It> par = (m - 1) >> 1;
if (Call()(comp, *(first + par), val))
{
using std::swap;
swap(*(first + par), val);
}
p = m;
}
}
if (size >= 2 && p <= ((size - 2) >> 1)) // at least one child
{
diff_t<It> const l = 2 * p + 1;
diff_t<It> m = l; // left child
if (size >= 3 && p <= ((size - 3) >> 1)) // at least two children
{
// m = left child
diff_t<It> m2 = l + 1; // right child
if (size >= 4 && p <= ((size - 4) >> 2)) // at least two children and one grandchild
{
diff_t<It> const ll = 2 * l + 1;
m = ll; // left most grandchild
// m2 = right child
if (size >= 5 && p <= ((size - 5) >> 2)) // at least two children and two grandchildren
{
m = Call()(comp, *(first + ll), *(first + ll + 1)) ? ll : (ll + 1); // greater of the left grandchildren
// m2 = right child
if (size >= 6 && p <= ((size - 6) >> 2)) // at least two children and three grandchildren
{
// m = greater of the left grandchildren
m2 = ll + 2; // third grandchild
}
}
}
m = Call()(comp, *(first + m), *(first + m2)) ? m : m2;
}
if (Call()(comp, *(first + m), val))
{
*(first + p) = std::move(*(first + m));
if (m >= 3 && p <= ((m - 3) >> 2)) // is p grandparent of m
{
diff_t<It> par = (m - 1) >> 1;
if (Call()(comp, *(first + par), val))
{
using std::swap;
swap(*(first + par), val);
}
}
p = m;
}
}
*(first + p) = std::move(val);
}
template <typename MinCall, typename MaxCall, typename It, typename Compare>
inline void pop_heap(It first, It el, It last, Compare comp)
{
diff_t<It> size = last - first;
if (size < 2)
{
return;
}
--last;
val_t<It> val = std::move(*last);
*last = std::move(*el);
// Ignore the last element
--size;
diff_t<It> p = el - first;
if (level(p) % 2 == 0) // is min level
{
pop_heap1<MinCall>(first, p, size, std::move(val), comp);
}
else
{
pop_heap1<MaxCall>(first, p, size, std::move(val), comp);
}
}
template <typename MinCall, typename MaxCall, typename It, typename Compare>
inline void make_heap(It first, It last, Compare comp)
{
diff_t<It> size = last - first;
diff_t<It> p = size / 2;
if (p <= 0)
{
return;
}
int level_p = level(p - 1);
diff_t<It> level_f = (diff_t<It>(1) << level_p) - 1;
while (p > 0)
{
--p;
val_t<It> val = std::move(*(first + p));
if (level_p % 2 == 0) // is min level
{
pop_heap1<MinCall>(first, p, size, std::move(val), comp);
}
else
{
pop_heap1<MaxCall>(first, p, size, std::move(val), comp);
}
if (p == level_f)
{
--level_p;
level_f >>= 1;
}
}
}
template <typename Call, typename It, typename Compare>
inline bool is_heap(It first, It last, Compare comp)
{
diff_t<It> const size = last - first;
diff_t<It> pow2 = 4;
bool is_min_level = false;
for (diff_t<It> i = 1; i < size; ++i)
{
if (i == pow2 - 1)
{
pow2 *= 2;
is_min_level = ! is_min_level;
}
diff_t<It> const p = (i - 1) >> 1;
if (is_min_level)
{
if (Call()(comp, *(first + p), *(first + i)))
{
return false;
}
}
else
{
if (Call()(comp, *(first + i), *(first + p)))
{
return false;
}
}
if (i >= 3)
{
diff_t<It> const g = (p - 1) >> 1;
if (is_min_level)
{
if (Call()(comp, *(first + i), *(first + g)))
{
return false;
}
}
else
{
if (Call()(comp, *(first + g), *(first + i)))
{
return false;
}
}
}
}
return true;
}
template <typename Call, typename It, typename Compare>
inline It bottom_heap(It first, It last, Compare comp)
{
diff_t<It> const size = last - first;
return size <= 1 ? first :
size == 2 ? (first + 1) :
Call()(comp, *(first + 1), *(first + 2)) ? (first + 2) : (first + 1);
}
} // namespace minmax_heap_detail
template <typename It, typename Compare>
inline void push_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
minmax_heap_detail::push_heap<min_call, max_call>(first, last, comp);
}
template <typename It>
inline void push_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
minmax_heap_detail::push_heap<min_call, max_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline void pop_top_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
pop_heap<min_call, max_call>(first, first, last, comp);
}
template <typename It>
inline void pop_top_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
pop_heap<min_call, max_call>(first, first, last, std::less<>());
}
template <typename It, typename Compare>
inline void pop_bottom_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
It bottom = minmax_heap_detail::bottom_heap<min_call>(first, last, comp);
pop_heap<min_call, max_call>(first, bottom, last, comp);
}
template <typename It>
inline void pop_bottom_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
auto&& comp = std::less<>();
It bottom = minmax_heap_detail::bottom_heap<min_call>(first, last, comp);
pop_heap<min_call, max_call>(first, bottom, last, comp);
}
template <typename It, typename Compare>
inline void make_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::make_heap<min_call, max_call>(first, last, comp);
}
template <typename It>
inline void make_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::make_heap<min_call, max_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline bool is_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::is_heap<min_call>(first, last, comp);
}
template <typename It>
inline bool is_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
return minmax_heap_detail::is_heap<min_call>(first, last, std::less<>());
}
template <typename It, typename Compare>
inline decltype(auto) bottom_minmax_heap(It first, It last, Compare comp)
{
using namespace minmax_heap_detail;
return *minmax_heap_detail::bottom_heap<min_call>(first, last, comp);
}
template <typename It>
inline decltype(auto) bottom_minmax_heap(It first, It last)
{
using namespace minmax_heap_detail;
return *minmax_heap_detail::bottom_heap<min_call>(first, last, std::less<>());
}
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_MINMAX_HEAP_HPP

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,13 +16,25 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_PREDICATES_HPP
#include <tuple>
#include <type_traits>
//#include <utility>
#include <boost/mpl/assert.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
#include <boost/geometry/algorithms/detail/overlaps/interface.hpp>
#include <boost/geometry/algorithms/detail/touches/interface.hpp>
#include <boost/geometry/algorithms/detail/within/interface.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/index/detail/tags.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace predicates {
@@ -26,10 +43,10 @@ namespace predicates {
// predicates
// ------------------------------------------------------------------ //
template <typename Fun, bool IsFunction>
template <typename Fun, bool IsFunction = std::is_function<Fun>::value>
struct satisfies_impl
{
satisfies_impl() : fun(NULL) {}
satisfies_impl() : fun(nullptr) {}
satisfies_impl(Fun f) : fun(f) {}
Fun * fun;
};
@@ -37,20 +54,19 @@ struct satisfies_impl
template <typename Fun>
struct satisfies_impl<Fun, false>
{
satisfies_impl() {}
satisfies_impl() = default;
satisfies_impl(Fun const& f) : fun(f) {}
Fun fun;
};
template <typename Fun, bool Negated>
struct satisfies
: satisfies_impl<Fun, ::boost::is_function<Fun>::value>
struct satisfies : satisfies_impl<Fun>
{
typedef satisfies_impl<Fun, ::boost::is_function<Fun>::value> base;
using base_t = satisfies_impl<Fun>;
satisfies() {}
satisfies(Fun const& f) : base(f) {}
satisfies(base const& b) : base(b) {}
satisfies() = default;
satisfies(Fun const& f) : base_t(f) {}
satisfies(base_t const& b) : base_t(b) {}
};
// ------------------------------------------------------------------ //
@@ -86,12 +102,12 @@ struct nearest
nearest()
// : count(0)
{}
nearest(PointOrRelation const& por, unsigned k)
nearest(PointOrRelation const& por, std::size_t k)
: point_or_relation(por)
, count(k)
{}
PointOrRelation point_or_relation;
unsigned count;
std::size_t count;
};
template <typename SegmentOrLinestring>
@@ -100,12 +116,12 @@ struct path
path()
// : count(0)
{}
path(SegmentOrLinestring const& g, unsigned k)
path(SegmentOrLinestring const& g, std::size_t k)
: geometry(g)
, count(k)
{}
SegmentOrLinestring geometry;
unsigned count;
std::size_t count;
};
} // namespace predicates
@@ -117,10 +133,9 @@ struct path
template <typename Predicate, typename Tag>
struct predicate_check
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_PREDICATE_OR_TAG,
(predicate_check));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Predicate or Tag.",
Predicate, Tag);
};
// ------------------------------------------------------------------ //
@@ -128,8 +143,8 @@ struct predicate_check
template <typename Fun>
struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
{
template <typename Value, typename Indexable>
static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const&)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(predicates::satisfies<Fun, false> const& p, Value const& v, Indexable const& , Strategy const&)
{
return p.fun(v);
}
@@ -138,8 +153,8 @@ struct predicate_check<predicates::satisfies<Fun, false>, value_tag>
template <typename Fun>
struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
{
template <typename Value, typename Indexable>
static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const&)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(predicates::satisfies<Fun, true> const& p, Value const& v, Indexable const& , Strategy const&)
{
return !p.fun(v);
}
@@ -150,14 +165,16 @@ struct predicate_check<predicates::satisfies<Fun, true>, value_tag>
template <typename Tag>
struct spatial_predicate_call
{
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag.",
Tag);
};
template <>
struct spatial_predicate_call<predicates::contains_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::within(g2, g1);
}
@@ -166,8 +183,8 @@ struct spatial_predicate_call<predicates::contains_tag>
template <>
struct spatial_predicate_call<predicates::covered_by_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::covered_by(g1, g2);
}
@@ -176,8 +193,8 @@ struct spatial_predicate_call<predicates::covered_by_tag>
template <>
struct spatial_predicate_call<predicates::covers_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::covered_by(g2, g1);
}
@@ -186,28 +203,60 @@ struct spatial_predicate_call<predicates::covers_tag>
template <>
struct spatial_predicate_call<predicates::disjoint_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::disjoint(g1, g2);
}
};
// TEMP: used to implement CS-specific intersects predicate for certain
// combinations of geometries until umbrella strategies are implemented
template
<
typename G1, typename G2,
typename Tag1 = typename tag<G1>::type,
typename Tag2 = typename tag<G2>::type
>
struct spatial_predicate_intersects
{
template <typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::intersects(g1, g2);
}
};
// TEMP: used in within and relate
template <typename G1, typename G2>
struct spatial_predicate_intersects<G1, G2, box_tag, point_tag>
{
static inline bool apply(G1 const& g1, G2 const& g2, default_strategy const&)
{
return geometry::intersects(g1, g2);
}
template <typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
{
return geometry::intersects(g1, g2, s);
}
};
template <>
struct spatial_predicate_call<predicates::intersects_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const& s)
{
return geometry::intersects(g1, g2);
return spatial_predicate_intersects<G1, G2>::apply(g1, g2, s);
}
};
template <>
struct spatial_predicate_call<predicates::overlaps_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::overlaps(g1, g2);
}
@@ -216,8 +265,8 @@ struct spatial_predicate_call<predicates::overlaps_tag>
template <>
struct spatial_predicate_call<predicates::touches_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::touches(g1, g2);
}
@@ -226,8 +275,8 @@ struct spatial_predicate_call<predicates::touches_tag>
template <>
struct spatial_predicate_call<predicates::within_tag>
{
template <typename G1, typename G2>
static inline bool apply(G1 const& g1, G2 const& g2)
template <typename G1, typename G2, typename S>
static inline bool apply(G1 const& g1, G2 const& g2, S const&)
{
return geometry::within(g1, g2);
}
@@ -241,10 +290,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, valu
{
typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return spatial_predicate_call<Tag>::apply(i, p.geometry);
return spatial_predicate_call<Tag>::apply(i, p.geometry, s);
}
};
@@ -254,10 +303,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value
{
typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return !spatial_predicate_call<Tag>::apply(i, p.geometry);
return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
}
};
@@ -266,8 +315,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, value
template <typename DistancePredicates>
struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
{
template <typename Value, typename Box>
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
template <typename Value, typename Box, typename Strategy>
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
{
return true;
}
@@ -276,8 +325,8 @@ struct predicate_check<predicates::nearest<DistancePredicates>, value_tag>
template <typename Linestring>
struct predicate_check<predicates::path<Linestring>, value_tag>
{
template <typename Value, typename Box>
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
template <typename Value, typename Box, typename Strategy>
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
{
return true;
}
@@ -290,8 +339,8 @@ struct predicate_check<predicates::path<Linestring>, value_tag>
template <typename Fun, bool Negated>
struct predicate_check<predicates::satisfies<Fun, Negated>, bounds_tag>
{
template <typename Value, typename Box>
static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&)
template <typename Value, typename Box, typename Strategy>
static bool apply(predicates::satisfies<Fun, Negated> const&, Value const&, Box const&, Strategy const&)
{
return true;
}
@@ -317,10 +366,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, Tag, false>, boun
{
typedef predicates::spatial_predicate<Geometry, Tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry, s);
}
};
@@ -330,10 +379,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::conta
{
typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
}
};
@@ -343,10 +392,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::cover
{
typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry);
return spatial_predicate_call<predicates::covers_tag>::apply(i, p.geometry, s);
}
};
@@ -356,10 +405,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::disjo
{
typedef predicates::spatial_predicate<Geometry, predicates::disjoint_tag, false> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
}
};
@@ -381,10 +430,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, Tag, true>, bound
{
typedef predicates::spatial_predicate<Geometry, Tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return !spatial_predicate_call<Tag>::apply(i, p.geometry);
return !spatial_predicate_call<Tag>::apply(i, p.geometry, s);
}
};
@@ -394,8 +443,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::conta
{
typedef predicates::spatial_predicate<Geometry, predicates::contains_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
{
return true;
}
@@ -407,8 +456,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::cover
{
typedef predicates::spatial_predicate<Geometry, predicates::covers_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
{
return true;
}
@@ -420,10 +469,10 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::inter
{
typedef predicates::spatial_predicate<Geometry, predicates::intersects_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const& s)
{
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry);
return !spatial_predicate_call<predicates::covered_by_tag>::apply(i, p.geometry, s);
}
};
@@ -433,8 +482,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::overl
{
typedef predicates::spatial_predicate<Geometry, predicates::overlaps_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& , Value const&, Indexable const& )
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& , Value const&, Indexable const&, Strategy const&)
{
return true;
}
@@ -446,8 +495,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touch
{
typedef predicates::spatial_predicate<Geometry, predicates::touches_tag, true> Pred;
template <typename Value, typename Indexable>
static inline bool apply(Pred const& p, Value const&, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Pred const& p, Value const&, Indexable const& i, Strategy const&)
{
return !spatial_predicate_call<predicates::intersects_tag>::apply(i, p.geometry);
}
@@ -458,8 +507,8 @@ struct predicate_check<predicates::spatial_predicate<Geometry, predicates::touch
template <typename DistancePredicates>
struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
{
template <typename Value, typename Box>
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&)
template <typename Value, typename Box, typename Strategy>
static inline bool apply(predicates::nearest<DistancePredicates> const&, Value const&, Box const&, Strategy const&)
{
return true;
}
@@ -468,8 +517,8 @@ struct predicate_check<predicates::nearest<DistancePredicates>, bounds_tag>
template <typename Linestring>
struct predicate_check<predicates::path<Linestring>, bounds_tag>
{
template <typename Value, typename Box>
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&)
template <typename Value, typename Box, typename Strategy>
static inline bool apply(predicates::path<Linestring> const&, Value const&, Box const&, Strategy const&)
{
return true;
}
@@ -482,224 +531,112 @@ struct predicate_check<predicates::path<Linestring>, bounds_tag>
template <typename T>
struct predicates_length
{
static const unsigned value = 1;
static const std::size_t value = 1;
};
//template <typename F, typename S>
//struct predicates_length< std::pair<F, S> >
//{
// static const unsigned value = 2;
//};
//template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
//struct predicates_length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
//{
// static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value;
//};
template <typename Head, typename Tail>
struct predicates_length< boost::tuples::cons<Head, Tail> >
template <typename ...Ts>
struct predicates_length<std::tuple<Ts...>>
{
static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value;
static const std::size_t value = std::tuple_size<std::tuple<Ts...>>::value;
};
// ------------------------------------------------------------------ //
// predicates_element
// ------------------------------------------------------------------ //
template <unsigned I, typename T>
template <std::size_t I, typename T>
struct predicates_element
{
BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element));
BOOST_GEOMETRY_STATIC_ASSERT((I < 1),
"Invalid I index.",
std::integral_constant<std::size_t, I>);
typedef T type;
static type const& get(T const& p) { return p; }
};
//template <unsigned I, typename F, typename S>
//struct predicates_element< I, std::pair<F, S> >
//{
// BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element));
//
// typedef F type;
// static type const& get(std::pair<F, S> const& p) { return p.first; }
//};
//
//template <typename F, typename S>
//struct predicates_element< 1, std::pair<F, S> >
//{
// typedef S type;
// static type const& get(std::pair<F, S> const& p) { return p.second; }
//};
//
//template <unsigned I, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
//struct predicates_element< I, boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
//{
// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type;
//
// typedef typename boost::tuples::element<I, predicate_type>::type type;
// static type const& get(predicate_type const& p) { return boost::get<I>(p); }
//};
template <unsigned I, typename Head, typename Tail>
struct predicates_element< I, boost::tuples::cons<Head, Tail> >
template <std::size_t I, typename ...Ts>
struct predicates_element<I, std::tuple<Ts...>>
{
typedef boost::tuples::cons<Head, Tail> predicate_type;
typedef std::tuple<Ts...> predicate_type;
typedef typename boost::tuples::element<I, predicate_type>::type type;
static type const& get(predicate_type const& p) { return boost::get<I>(p); }
typedef typename std::tuple_element<I, predicate_type>::type type;
static type const& get(predicate_type const& p) { return std::get<I>(p); }
};
// ------------------------------------------------------------------ //
// predicates_check
// ------------------------------------------------------------------ //
//template <typename PairPredicates, typename Tag, unsigned First, unsigned Last>
//struct predicates_check_pair {};
//
//template <typename PairPredicates, typename Tag, unsigned I>
//struct predicates_check_pair<PairPredicates, Tag, I, I>
//{
// template <typename Value, typename Indexable>
// static inline bool apply(PairPredicates const& , Value const& , Indexable const& )
// {
// return true;
// }
//};
//
//template <typename PairPredicates, typename Tag>
//struct predicates_check_pair<PairPredicates, Tag, 0, 1>
//{
// template <typename Value, typename Indexable>
// static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
// {
// return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i);
// }
//};
//
//template <typename PairPredicates, typename Tag>
//struct predicates_check_pair<PairPredicates, Tag, 1, 2>
//{
// template <typename Value, typename Indexable>
// static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
// {
// return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
// }
//};
//
//template <typename PairPredicates, typename Tag>
//struct predicates_check_pair<PairPredicates, Tag, 0, 2>
//{
// template <typename Value, typename Indexable>
// static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
// {
// return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i)
// && predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
// }
//};
template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last>
template <typename TuplePredicates, typename Tag, std::size_t First, std::size_t Last>
struct predicates_check_tuple
{
template <typename Value, typename Indexable>
static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i, Strategy const& s)
{
return
predicate_check<
typename boost::tuples::element<First, TuplePredicates>::type,
Tag
>::apply(boost::get<First>(p), v, i) &&
predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i);
return predicate_check
<
typename std::tuple_element<First, TuplePredicates>::type,
Tag
>::apply(std::get<First>(p), v, i, s)
&& predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i, s);
}
};
template <typename TuplePredicates, typename Tag, unsigned First>
template <typename TuplePredicates, typename Tag, std::size_t First>
struct predicates_check_tuple<TuplePredicates, Tag, First, First>
{
template <typename Value, typename Indexable>
static inline bool apply(TuplePredicates const& , Value const& , Indexable const& )
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(TuplePredicates const& , Value const& , Indexable const& , Strategy const& )
{
return true;
}
};
template <typename Predicate, typename Tag, unsigned First, unsigned Last>
template <typename Predicate, typename Tag, std::size_t First, std::size_t Last>
struct predicates_check_impl
{
static const bool check = First < 1 && Last <= 1 && First <= Last;
BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
BOOST_GEOMETRY_STATIC_ASSERT((check),
"Invalid First or Last index.",
std::integer_sequence<std::size_t, First, Last>);
template <typename Value, typename Indexable>
static inline bool apply(Predicate const& p, Value const& v, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(Predicate const& p, Value const& v, Indexable const& i, Strategy const& s)
{
return predicate_check<Predicate, Tag>::apply(p, v, i);
return predicate_check<Predicate, Tag>::apply(p, v, i, s);
}
};
//template <typename Predicate1, typename Predicate2, typename Tag, size_t First, size_t Last>
//struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag, First, Last>
//{
// BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
//
// template <typename Value, typename Indexable>
// static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i)
// {
// return predicate_check<Predicate1, Tag>::apply(p.first, v, i)
// && predicate_check<Predicate2, Tag>::apply(p.second, v, i);
// }
//};
//
//template <
// typename T0, typename T1, typename T2, typename T3, typename T4,
// typename T5, typename T6, typename T7, typename T8, typename T9,
// typename Tag, unsigned First, unsigned Last
//>
//struct predicates_check_impl<
// boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
// Tag, First, Last
//>
//{
// typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type;
//
// static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
// BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl));
//
// template <typename Value, typename Indexable>
// static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
// {
// return predicates_check_tuple<
// predicates_type,
// Tag, First, Last
// >::apply(p, v, i);
// }
//};
template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last>
struct predicates_check_impl<
boost::tuples::cons<Head, Tail>,
Tag, First, Last
>
template <typename ...Ts, typename Tag, std::size_t First, std::size_t Last>
struct predicates_check_impl<std::tuple<Ts...>, Tag, First, Last>
{
typedef boost::tuples::cons<Head, Tail> predicates_type;
typedef std::tuple<Ts...> predicates_type;
static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
static const std::size_t pred_len = std::tuple_size<predicates_type>::value;
static const bool check = First < pred_len && Last <= pred_len && First <= Last;
BOOST_MPL_ASSERT_MSG((check), INVALID_INDEXES, (predicates_check_impl));
BOOST_GEOMETRY_STATIC_ASSERT((check),
"Invalid First or Last index.",
std::integer_sequence<std::size_t, First, Last>);
template <typename Value, typename Indexable>
static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
template <typename Value, typename Indexable, typename Strategy>
static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i, Strategy const& s)
{
return predicates_check_tuple<
predicates_type,
Tag, First, Last
>::apply(p, v, i);
return predicates_check_tuple
<
predicates_type,
Tag, First, Last
>::apply(p, v, i, s);
}
};
template <typename Tag, unsigned First, unsigned Last, typename Predicates, typename Value, typename Indexable>
inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i)
template <typename Tag, typename Predicates, typename Value, typename Indexable, typename Strategy>
inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i, Strategy const& s)
{
return detail::predicates_check_impl<Predicates, Tag, First, Last>
::apply(p, v, i);
return detail::predicates_check_impl
<
Predicates, Tag, 0, predicates_length<Predicates>::value
>::apply(p, v, i, s);
}
// ------------------------------------------------------------------ //
@@ -711,19 +648,19 @@ inline bool predicates_check(Predicates const& p, Value const& v, Indexable cons
template <typename P>
struct predicates_is_distance
{
static const unsigned value = 0;
static const std::size_t value = 0;
};
template <typename DistancePredicates>
struct predicates_is_distance< predicates::nearest<DistancePredicates> >
{
static const unsigned value = 1;
static const std::size_t value = 1;
};
template <typename Linestring>
struct predicates_is_distance< predicates::path<Linestring> >
{
static const unsigned value = 1;
static const std::size_t value = 1;
};
// predicates_count_nearest
@@ -731,46 +668,30 @@ struct predicates_is_distance< predicates::path<Linestring> >
template <typename T>
struct predicates_count_distance
{
static const unsigned value = predicates_is_distance<T>::value;
static const std::size_t value = predicates_is_distance<T>::value;
};
//template <typename F, typename S>
//struct predicates_count_distance< std::pair<F, S> >
//{
// static const unsigned value = predicates_is_distance<F>::value
// + predicates_is_distance<S>::value;
//};
template <typename Tuple, unsigned N>
template <typename Tuple, std::size_t N>
struct predicates_count_distance_tuple
{
static const unsigned value =
predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value
static const std::size_t value =
predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value
+ predicates_count_distance_tuple<Tuple, N-1>::value;
};
template <typename Tuple>
struct predicates_count_distance_tuple<Tuple, 1>
{
static const unsigned value =
predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
static const std::size_t value =
predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
};
//template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
//struct predicates_count_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
//{
// static const unsigned value = predicates_count_distance_tuple<
// boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
// boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
// >::value;
//};
template <typename Head, typename Tail>
struct predicates_count_distance< boost::tuples::cons<Head, Tail> >
template <typename ...Ts>
struct predicates_count_distance<std::tuple<Ts...>>
{
static const unsigned value = predicates_count_distance_tuple<
boost::tuples::cons<Head, Tail>,
boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
static const std::size_t value = predicates_count_distance_tuple<
std::tuple<Ts...>,
std::tuple_size<std::tuple<Ts...>>::value
>::value;
};
@@ -779,50 +700,34 @@ struct predicates_count_distance< boost::tuples::cons<Head, Tail> >
template <typename T>
struct predicates_find_distance
{
static const unsigned value = predicates_is_distance<T>::value ? 0 : 1;
static const std::size_t value = predicates_is_distance<T>::value ? 0 : 1;
};
//template <typename F, typename S>
//struct predicates_find_distance< std::pair<F, S> >
//{
// static const unsigned value = predicates_is_distance<F>::value ? 0 :
// (predicates_is_distance<S>::value ? 1 : 2);
//};
template <typename Tuple, unsigned N>
template <typename Tuple, std::size_t N>
struct predicates_find_distance_tuple
{
static const bool is_found = predicates_find_distance_tuple<Tuple, N-1>::is_found
|| predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value;
|| predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value;
static const unsigned value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
static const std::size_t value = predicates_find_distance_tuple<Tuple, N-1>::is_found ?
predicates_find_distance_tuple<Tuple, N-1>::value :
(predicates_is_distance<typename boost::tuples::element<N-1, Tuple>::type>::value ?
N-1 : boost::tuples::length<Tuple>::value);
(predicates_is_distance<typename std::tuple_element<N-1, Tuple>::type>::value ?
N-1 : std::tuple_size<Tuple>::value);
};
template <typename Tuple>
struct predicates_find_distance_tuple<Tuple, 1>
{
static const bool is_found = predicates_is_distance<typename boost::tuples::element<0, Tuple>::type>::value;
static const unsigned value = is_found ? 0 : boost::tuples::length<Tuple>::value;
static const bool is_found = predicates_is_distance<typename std::tuple_element<0, Tuple>::type>::value;
static const std::size_t value = is_found ? 0 : std::tuple_size<Tuple>::value;
};
//template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
//struct predicates_find_distance< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
//{
// static const unsigned value = predicates_find_distance_tuple<
// boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
// boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
// >::value;
//};
template <typename Head, typename Tail>
struct predicates_find_distance< boost::tuples::cons<Head, Tail> >
template <typename ...Ts>
struct predicates_find_distance<std::tuple<Ts...>>
{
static const unsigned value = predicates_find_distance_tuple<
boost::tuples::cons<Head, Tail>,
boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
static const std::size_t value = predicates_find_distance_tuple<
std::tuple<Ts...>,
std::tuple_size<std::tuple<Ts...>>::value
>::value;
};

View File

@@ -0,0 +1,150 @@
// Boost.Geometry
// Copyright (c) 2021, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP
#include <vector>
#include <boost/geometry/index/detail/maxmin_heap.hpp>
namespace boost { namespace geometry { namespace index { namespace detail
{
template
<
typename T,
typename Container = std::vector<T>,
typename Compare = std::less<typename Container::value_type>
>
class priority_dequeue
{
public:
using container_type = Container;
using value_compare = Compare;
using value_type = typename Container::value_type;
using size_type = typename Container::size_type;
using reference = typename Container::reference;
using const_reference = typename Container::const_reference;
priority_dequeue()
: c(), comp()
{}
explicit priority_dequeue(Compare const& compare)
: c(), comp(compare)
{}
priority_dequeue(Compare const& compare, Container const& cont)
: c(cont), comp(compare)
{
make_maxmin_heap(c.begin(), c.end(), comp);
}
priority_dequeue(Compare const& compare, Container&& cont)
: c(std::move(cont)), comp(compare)
{
make_maxmin_heap(c.begin(), c.end(), comp);
}
template <typename It>
priority_dequeue(It first, It last)
: c(first, last), comp()
{
make_maxmin_heap(c.begin(), c.end(), comp);
}
template <typename It>
priority_dequeue(It first, It last, Compare const& compare)
: c(first, last), comp(compare)
{
make_maxmin_heap(c.begin(), c.end(), comp);
}
template <typename It>
priority_dequeue(It first, It last, Compare const& compare, Container const& cont)
: c(cont), comp(compare)
{
c.insert(first, last);
make_maxmin_heap(c.begin(), c.end(), comp);
}
template <typename It>
priority_dequeue(It first, It last, Compare const& compare, Container&& cont)
: c(std::move(cont)), comp(compare)
{
c.insert(first, last);
make_maxmin_heap(c.begin(), c.end(), comp);
}
const_reference top() const
{
return *c.begin();
}
const_reference bottom() const
{
return bottom_maxmin_heap(c.begin(), c.end(), comp);
}
void push(const value_type& value)
{
c.push_back(value);
push_maxmin_heap(c.begin(), c.end(), comp);
}
void push(value_type&& value)
{
c.push_back(std::move(value));
push_maxmin_heap(c.begin(), c.end(), comp);
}
template <typename ...Args>
void emplace(Args&& ...args)
{
c.emplace_back(std::forward<Args>(args)...);
push_maxmin_heap(c.begin(), c.end(), comp);
}
void pop_top()
{
pop_top_maxmin_heap(c.begin(), c.end(), comp);
c.pop_back();
}
void pop_bottom()
{
pop_bottom_maxmin_heap(c.begin(), c.end(), comp);
c.pop_back();
}
bool empty() const
{
return c.empty();
}
size_t size() const
{
return c.size();
}
void swap(priority_dequeue& other)
{
using std::swap;
std::swap(c, other.c);
std::swap(comp, other.comp);
}
protected:
Container c;
Compare comp;
};
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_PRIORITY_DEQUEUE_HPP

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,13 +15,13 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ADAPTORS_HPP
#include <deque>
#include <boost/static_assert.hpp>
#include <vector>
#include <boost/geometry/index/adaptors/query.hpp>
namespace boost { namespace geometry { namespace index {
// Forward declaration
template <typename Value, typename Options, typename IndexableGetter, typename EqualTo, typename Allocator>
class rtree;

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,10 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_ITERATORS_HPP
#include <iterator>
#include <boost/geometry/index/detail/rtree/visitors/iterator.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
template <typename Value, typename Allocators>
@@ -112,7 +120,7 @@ public:
{
return r.m_visitor.is_end();
}
private:
visitor_type m_visitor;
};

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP
#include <boost/geometry/index/rtree/kmeans/split.hpp>
#include <boost/geometry/index/detail/rtree/kmeans/split.hpp>
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_KMEANS_HPP

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,13 +15,17 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_KMEANS_SPLIT_HPP
#include <boost/geometry/index/rtree/node/node.hpp>
#include <boost/geometry/index/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// TODO: This should be defined in options.hpp
// For now it's defined here to satisfy Boost header policy
struct split_kmeans_tag {};
namespace kmeans {
// some details
@@ -56,25 +64,34 @@ namespace kmeans {
// 4. Pamietac o parametryzacji kontenera z nadmiarowymi elementami
// PS. Z R* reinsertami moze byc masakra
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class split<Value, Options, Translator, Box, Allocators, split_kmeans_tag>
template <typename MembersHolder>
class split<MembersHolder, split_kmeans_tag>
{
protected:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::size_type size_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
typedef index::detail::varray
<
typename rtree::elements_type<internal_node>::type::value_type,
1
> nodes_container_type;
template <typename Node>
static inline void apply(node* & root_node,
size_t & leafs_level,
static inline void apply(nodes_container_type & additional_nodes,
Node & n,
internal_node *parent_node,
size_t current_child_index,
Translator const& tr,
Allocators & allocators)
box_type & n_box,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
}

View File

@@ -3,7 +3,11 @@
// R-tree linear split algorithm implementation
//
// Copyright (c) 2008 Federico J. Fernandez.
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,9 +16,13 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_LINEAR_REDISTRIBUTE_ELEMENTS_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <type_traits>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/bounded_view.hpp>
@@ -29,13 +37,13 @@ namespace detail { namespace rtree {
namespace linear {
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<false> const& /*is_unsigned*/)
inline R difference_dispatch(T const& from, T const& to, std::false_type /*is_unsigned*/)
{
return to - from;
}
template <typename R, typename T>
inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<true> const& /*is_unsigned*/)
inline R difference_dispatch(T const& from, T const& to, std::true_type /*is_unsigned*/)
{
return from <= to ? R(to - from) : -R(from - to);
}
@@ -43,13 +51,11 @@ inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_<tru
template <typename R, typename T>
inline R difference(T const& from, T const& to)
{
BOOST_MPL_ASSERT_MSG(!boost::is_unsigned<R>::value, RESULT_CANT_BE_UNSIGNED, (R));
BOOST_GEOMETRY_STATIC_ASSERT((! std::is_unsigned<R>::value),
"Result can not be an unsigned type.",
R);
typedef ::boost::mpl::bool_<
boost::is_unsigned<T>::value
> is_unsigned;
return difference_dispatch<R>(from, to, is_unsigned());
return difference_dispatch<R>(from, to, std::is_unsigned<T>());
}
// TODO: awulkiew
@@ -82,15 +88,20 @@ struct find_greatest_normalized_separation
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename coordinate_type<indexable_type>::type coordinate_type;
typedef typename boost::mpl::if_c<
boost::is_integral<coordinate_type>::value,
double,
coordinate_type
>::type separation_type;
typedef std::conditional_t
<
std::is_integral<coordinate_type>::value,
double,
coordinate_type
> separation_type;
typedef typename geometry::point_type<indexable_type>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
typedef index::detail::bounded_view
<
indexable_type, bounds_type,
typename index::detail::strategy_type<Parameters>::type
> bounded_view_type;
static inline void apply(Elements const& elements,
Parameters const& parameters,
@@ -103,43 +114,52 @@ struct find_greatest_normalized_separation
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
auto const& strategy = index::detail::get_strategy(parameters);
// find the lowest low, highest high
bounded_view_type bounded_indexable_0(rtree::element_indexable(elements[0], translator));
indexable_type const& indexable_0 = rtree::element_indexable(elements[0], translator);
bounded_view_type const bounded_indexable_0(indexable_0, strategy);
coordinate_type lowest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_0);
coordinate_type highest_high = geometry::get<max_corner, DimensionIndex>(bounded_indexable_0);
// and the lowest high
coordinate_type lowest_high = highest_high;
size_t lowest_high_index = 0;
for ( size_t i = 1 ; i < elements_count ; ++i )
for (size_t i = 1 ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
indexable_type const& indexable_i = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable_i, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
coordinate_type max_coord = geometry::get<max_corner, DimensionIndex>(bounded_indexable);
if ( max_coord < lowest_high )
if (max_coord < lowest_high)
{
lowest_high = max_coord;
lowest_high_index = i;
}
if ( min_coord < lowest_low )
if (min_coord < lowest_low)
{
lowest_low = min_coord;
}
if ( highest_high < max_coord )
if (highest_high < max_coord)
{
highest_high = max_coord;
}
}
// find the highest low
size_t highest_low_index = lowest_high_index == 0 ? 1 : 0;
bounded_view_type bounded_indexable_hl(rtree::element_indexable(elements[highest_low_index], translator));
indexable_type const& indexable_hl = rtree::element_indexable(elements[highest_low_index], translator);
bounded_view_type const bounded_indexable_hl(indexable_hl, strategy);
coordinate_type highest_low = geometry::get<min_corner, DimensionIndex>(bounded_indexable_hl);
for ( size_t i = highest_low_index ; i < elements_count ; ++i )
for (size_t i = highest_low_index ; i < elements_count ; ++i)
{
bounded_view_type bounded_indexable(rtree::element_indexable(elements[i], translator));
indexable_type const& indexable = rtree::element_indexable(elements[i], translator);
bounded_view_type const bounded_indexable(indexable, strategy);
coordinate_type min_coord = geometry::get<min_corner, DimensionIndex>(bounded_indexable);
if ( highest_low < min_coord &&
i != lowest_high_index )
if (highest_low < min_coord && i != lowest_high_index)
{
highest_low = min_coord;
highest_low_index = i;
@@ -147,12 +167,14 @@ struct find_greatest_normalized_separation
}
coordinate_type const width = highest_high - lowest_low;
// highest_low - lowest_high
separation = difference<separation_type>(lowest_high, highest_low);
// BOOST_GEOMETRY_INDEX_ASSERT(0 <= width);
if ( std::numeric_limits<coordinate_type>::epsilon() < width )
if (std::numeric_limits<coordinate_type>::epsilon() < width)
{
separation /= width;
}
seed1 = highest_low_index;
seed2 = lowest_high_index;
@@ -306,28 +328,34 @@ inline void pick_seeds(Elements const& elements,
// from void split_node(node_pointer const& n, node_pointer& n1, node_pointer& n2) const
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, linear_tag>
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
template <typename Node>
static inline void apply(Node & n,
Node & second_node,
Box & box1,
Box & box2,
box_type & box1,
box_type & box2,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -357,8 +385,10 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator),
box1, strategy);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator),
box2, strategy);
// initialize areas
content_type content1 = index::detail::content(box1);
@@ -380,23 +410,23 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
if ( elements1.size() + remaining <= parameters.get_min_elements() )
{
elements1.push_back(elem); // MAY THROW, STRONG (copy)
geometry::expand(box1, indexable);
index::detail::expand(box1, indexable, strategy);
content1 = index::detail::content(box1);
}
else if ( elements2.size() + remaining <= parameters.get_min_elements() )
{
elements2.push_back(elem); // MAY THROW, STRONG (alloc, copy)
geometry::expand(box2, indexable);
index::detail::expand(box2, indexable, strategy);
content2 = index::detail::content(box2);
}
// choose better node and insert element
else
{
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
geometry::expand(enlarged_box1, indexable);
geometry::expand(enlarged_box2, indexable);
box_type enlarged_box1(box1);
box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1);
content_type enlarged_content2 = index::detail::content(enlarged_box2);
@@ -420,7 +450,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
content2 = enlarged_content2;
}
}
BOOST_GEOMETRY_INDEX_ASSERT(0 < remaining, "unexpected value");
--remaining;
}
@@ -431,7 +461,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, linear
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_copy, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_copy, allocators);
//elements_copy.clear();
BOOST_RETHROW // RETHROW, BASIC

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_CONCEPT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_CONCEPT_HPP
#include <boost/geometry/core/static_assert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -18,64 +24,57 @@ namespace detail { namespace rtree {
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct internal_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(internal_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct leaf
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(leaf));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag, bool IsVisitableConst>
struct visitor
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(visitor));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Value, Parameters, Box, Allocators, Tag);
};
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
class allocators
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TAG_TYPE,
(allocators));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Tag type.",
Allocator, Value, Parameters, Box, Tag);
};
template <typename Allocators, typename Node>
struct create_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE,
(create_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Node type.",
Allocators, Node);
};
template <typename Allocators, typename Node>
struct destroy_node
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_NODE_TYPE,
(destroy_node));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Node type.",
Allocators, Node);
};
}} // namespace detail::rtree

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,7 +15,12 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
#include <type_traits>
#include <boost/container/vector.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
@@ -27,10 +36,9 @@
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
@@ -42,11 +50,12 @@ namespace detail { namespace rtree {
// elements box
template <typename Box, typename FwdIter, typename Translator>
inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
template <typename Box, typename FwdIter, typename Translator, typename Strategy>
inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr,
Strategy const& strategy)
{
Box result;
// Only here to suppress 'uninitialized local variable used' warning
// until the suggestion below is not implemented
geometry::assign_inverse(result);
@@ -57,11 +66,11 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
if ( first == last )
return result;
detail::bounds(element_indexable(*first, tr), result);
detail::bounds(element_indexable(*first, tr), result, strategy);
++first;
for ( ; first != last ; ++first )
geometry::expand(result, element_indexable(*first, tr));
detail::expand(result, element_indexable(*first, tr), strategy);
return result;
}
@@ -71,15 +80,16 @@ inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
// This ensures that leafs bounds correspond to the stored elements.
// NOTE: this is done only if the Indexable is not a Box
// in the future don't do it also for NSphere
template <typename Box, typename FwdIter, typename Translator>
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr)
template <typename Box, typename FwdIter, typename Translator, typename Strategy>
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr,
Strategy const& strategy)
{
typedef typename std::iterator_traits<FwdIter>::value_type element_type;
BOOST_MPL_ASSERT_MSG((is_leaf_element<element_type>::value),
SHOULD_BE_CALLED_ONLY_FOR_LEAF_ELEMENTS,
(element_type));
BOOST_GEOMETRY_STATIC_ASSERT((is_leaf_element<element_type>::value),
"This function should be called only for elements of leaf nodes.",
element_type);
Box result = elements_box<Box>(first, last, tr);
Box result = elements_box<Box>(first, last, tr, strategy);
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
if (BOOST_GEOMETRY_CONDITION((
@@ -96,80 +106,86 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr)
}
// destroys subtree if the element is internal node's element
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_element
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
inline static void apply(typename internal_node::elements_type::value_type & element, Allocators & allocators)
inline static void apply(typename internal_node::elements_type::value_type & element,
allocators_type & allocators)
{
subtree_destroyer dummy(element.second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::apply(element.second, allocators);
element.second = 0;
}
inline static void apply(typename leaf::elements_type::value_type &, Allocators &) {}
inline static void apply(typename leaf::elements_type::value_type &,
allocators_type &)
{}
};
// destroys stored subtrees if internal node's elements are passed
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
struct destroy_elements
{
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::allocators_type allocators_type;
template <typename Range>
inline static void apply(Range & elements, Allocators & allocators)
inline static void apply(Range & elements, allocators_type & allocators)
{
apply(boost::begin(elements), boost::end(elements), allocators);
}
template <typename It>
inline static void apply(It first, It last, Allocators & allocators)
inline static void apply(It first, It last, allocators_type & allocators)
{
typedef boost::mpl::bool_<
boost::is_same<
Value, typename std::iterator_traits<It>::value_type
>::value
> is_range_of_values;
typedef std::is_same
<
value_type, typename std::iterator_traits<It>::value_type
> is_range_of_values;
apply_dispatch(first, last, allocators, is_range_of_values());
}
private:
template <typename It>
inline static void apply_dispatch(It first, It last, Allocators & allocators,
boost::mpl::bool_<false> const& /*is_range_of_values*/)
inline static void apply_dispatch(It first, It last, allocators_type & allocators,
std::false_type /*is_range_of_values*/)
{
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
for ( ; first != last ; ++first )
{
subtree_destroyer dummy(first->second, allocators);
detail::rtree::visitors::destroy<MembersHolder>::apply(first->second, allocators);
first->second = 0;
}
}
template <typename It>
inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/,
boost::mpl::bool_<true> const& /*is_range_of_values*/)
inline static void apply_dispatch(It /*first*/, It /*last*/, allocators_type & /*allocators*/,
std::true_type /*is_range_of_values*/)
{}
};
// clears node, deletes all subtrees stored in node
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
/*
template <typename MembersHolder>
struct clear_node
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline static void apply(node & node, Allocators & allocators)
inline static void apply(node & node, allocators_type & allocators)
{
rtree::visitors::is_leaf<Value, Options, Box, Allocators> ilv;
rtree::visitors::is_leaf<MembersHolder> ilv;
rtree::apply_visitor(ilv, node);
if ( ilv.result )
{
@@ -181,17 +197,18 @@ struct clear_node
}
}
inline static void apply(internal_node & internal_node, Allocators & allocators)
inline static void apply(internal_node & internal_node, allocators_type & allocators)
{
destroy_elements<Value, Options, Translator, Box, Allocators>::apply(rtree::elements(internal_node), allocators);
destroy_elements<MembersHolder>::apply(rtree::elements(internal_node), allocators);
rtree::elements(internal_node).clear();
}
inline static void apply(leaf & leaf, Allocators &)
inline static void apply(leaf & leaf, allocators_type &)
{
rtree::elements(leaf).clear();
}
};
*/
template <typename Container, typename Iterator>
void move_from_back(Container & container, Iterator it)
@@ -201,7 +218,7 @@ void move_from_back(Container & container, Iterator it)
--back_it;
if ( it != back_it )
{
*it = boost::move(*back_it); // MAY THROW (copy)
*it = std::move(*back_it); // MAY THROW (copy)
}
}

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -15,6 +19,7 @@
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/translator.hpp>
namespace boost { namespace geometry { namespace index {

View File

@@ -2,7 +2,7 @@
//
// Pairs intended to be used internally in nodes.
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,8 +11,6 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_PAIRS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_PAIRS_HPP
#include <boost/move/move.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -24,46 +22,17 @@ public:
typedef First first_type;
typedef Pointer second_type;
ptr_pair(First const& f, Pointer s) : first(f), second(s) {}
//ptr_pair(ptr_pair const& p) : first(p.first), second(p.second) {}
//ptr_pair & operator=(ptr_pair const& p) { first = p.first; second = p.second; return *this; }
first_type first;
second_type second;
};
template <typename First, typename Pointer> inline
ptr_pair<First, Pointer>
make_ptr_pair(First const& f, Pointer s)
ptr_pair<First, Pointer> make_ptr_pair(First const& f, Pointer s)
{
return ptr_pair<First, Pointer>(f, s);
}
// TODO: It this will be used, rename it to unique_ptr_pair and possibly use unique_ptr.
template <typename First, typename Pointer>
class exclusive_ptr_pair
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(exclusive_ptr_pair)
public:
typedef First first_type;
typedef Pointer second_type;
exclusive_ptr_pair(First const& f, Pointer s) : first(f), second(s) {}
// INFO - members aren't really moved!
exclusive_ptr_pair(BOOST_RV_REF(exclusive_ptr_pair) p) : first(p.first), second(p.second) { p.second = 0; }
exclusive_ptr_pair & operator=(BOOST_RV_REF(exclusive_ptr_pair) p) { first = p.first; second = p.second; p.second = 0; return *this; }
first_type first;
second_type second;
};
template <typename First, typename Pointer> inline
exclusive_ptr_pair<First, Pointer>
make_exclusive_ptr_pair(First const& f, Pointer s)
{
return exclusive_ptr_pair<First, Pointer>(f, s);
}
}} // namespace detail::rtree
}}} // namespace boost::geometry::index

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_SCOPED_DEALLOCATOR_HPP
#include <boost/container/allocator_traits.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -17,17 +21,19 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class subtree_destroyer
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename Allocators::node_pointer pointer;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::node_pointer pointer;
subtree_destroyer(subtree_destroyer const&);
subtree_destroyer & operator=(subtree_destroyer const&);
public:
subtree_destroyer(pointer ptr, Allocators & allocators)
subtree_destroyer(pointer ptr, allocators_type & allocators)
: m_ptr(ptr)
, m_allocators(allocators)
{}
@@ -41,8 +47,7 @@ public:
{
if ( m_ptr && m_ptr != ptr )
{
detail::rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(m_ptr, m_allocators);
detail::rtree::apply_visitor(del_v, *m_ptr);
detail::rtree::visitors::destroy<MembersHolder>::apply(m_ptr, m_allocators);
}
m_ptr = ptr;
}
@@ -69,7 +74,7 @@ public:
private:
pointer m_ptr;
Allocators & m_allocators;
allocators_type & m_allocators;
};
}} // namespace detail::rtree

View File

@@ -2,7 +2,12 @@
//
// R-tree nodes based on Boost.Variant, storing dynamic-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,7 +16,16 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP
#include <boost/container/allocator_traits.hpp>
#include <boost/container/vector.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
namespace boost { namespace geometry { namespace index {
@@ -130,7 +144,7 @@ private:
node_allocator_type // node_allocator_type for consistency with variant_leaf
>::template rebind_alloc<Value> value_allocator_type;
typedef boost::container::allocator_traits<value_allocator_type> value_allocator_traits;
public:
typedef Allocator allocator_type;
@@ -152,23 +166,21 @@ public:
: node_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: node_allocator_type(boost::move(a.node_allocator()))
inline allocators(allocators&& a)
: node_allocator_type(std::move(a.node_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
node_allocator() = boost::move(a.node_allocator());
node_allocator() = std::move(a.node_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
node_allocator() = a.node_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes based on Boost.Variant, storing static-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/varray.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -121,23 +128,21 @@ public:
: node_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: node_allocator_type(boost::move(a.node_allocator()))
inline allocators(allocators&& a)
: node_allocator_type(std::move(a.node_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
node_allocator() = boost::move(a.node_allocator());
node_allocator() = std::move(a.node_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
node_allocator() = a.node_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,12 @@
//
// R-tree nodes based on static conversion, storing dynamic-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,10 +16,26 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP
#include <boost/container/allocator_traits.hpp>
#include <boost/container/vector.hpp>
#include <boost/core/pointer_traits.hpp>
#include <boost/core/swap.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/pairs.hpp>
#include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// TODO: This should be defined in options.hpp
// For now it's defined here to satisfy Boost header policy
struct node_weak_dynamic_tag {};
struct node_weak_static_tag {};
template <typename Value, typename Parameters, typename Box, typename Allocators, typename Tag>
struct weak_internal_node
: public weak_node<Value, Parameters, Box, Allocators, Tag>
@@ -87,7 +108,7 @@ struct visitor<Value, Parameters, Box, Allocators, node_weak_dynamic_tag, IsVisi
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
struct internal_node_alloc
{
typedef typename internal_nod
typedef typename internal_node
<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, Tag>,
@@ -116,6 +137,22 @@ struct leaf_alloc
>::template rebind_alloc<node_type> type;
};
template <typename Allocator, typename Value, typename Parameters, typename Box, typename Tag>
struct node_alloc
{
typedef typename weak_node
<
Value, Parameters, Box,
allocators<Allocator, Value, Parameters, Box, Tag>,
Tag
>::type node_type;
typedef typename ::boost::container::allocator_traits
<
Allocator
>::template rebind_alloc<node_type> type;
};
template <typename Allocator, typename Value, typename Parameters, typename Box>
class allocators<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>
: public internal_node_alloc<Allocator, Value, Parameters, Box, node_weak_dynamic_tag>::type
@@ -147,10 +184,10 @@ private:
leaf_allocator_type // leaf_allocator_type for consistency with weak_leaf
>::template rebind_alloc<Value> value_allocator_type;
typedef boost::container::allocator_traits<value_allocator_type> value_allocator_traits;
public:
typedef Allocator allocator_type;
typedef Value value_type;
typedef typename value_allocator_traits::reference reference;
typedef typename value_allocator_traits::const_reference const_reference;
@@ -170,26 +207,24 @@ public:
, leaf_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: internal_node_allocator_type(boost::move(a.internal_node_allocator()))
, leaf_allocator_type(boost::move(a.leaf_allocator()))
inline allocators(allocators&& a)
: internal_node_allocator_type(std::move(a.internal_node_allocator()))
, leaf_allocator_type(std::move(a.leaf_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
internal_node_allocator() = ::boost::move(a.internal_node_allocator());
leaf_allocator() = ::boost::move(a.leaf_allocator());
internal_node_allocator() = std::move(a.internal_node_allocator());
leaf_allocator() = std::move(a.leaf_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
internal_node_allocator() = a.internal_node_allocator();
leaf_allocator() = a.leaf_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -2,7 +2,11 @@
//
// R-tree nodes based on static conversion, storing static-size containers
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,6 +15,9 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP
#include <boost/geometry/index/detail/rtree/node/weak_dynamic.hpp>
#include <boost/geometry/index/detail/varray.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
@@ -127,26 +134,24 @@ public:
, leaf_allocator_type(alloc)
{}
inline allocators(BOOST_FWD_REF(allocators) a)
: internal_node_allocator_type(boost::move(a.internal_node_allocator()))
, leaf_allocator_type(boost::move(a.leaf_allocator()))
inline allocators(allocators&& a)
: internal_node_allocator_type(std::move(a.internal_node_allocator()))
, leaf_allocator_type(std::move(a.leaf_allocator()))
{}
inline allocators & operator=(BOOST_FWD_REF(allocators) a)
inline allocators & operator=(allocators&& a)
{
internal_node_allocator() = ::boost::move(a.internal_node_allocator());
leaf_allocator() = ::boost::move(a.leaf_allocator());
internal_node_allocator() = std::move(a.internal_node_allocator());
leaf_allocator() = std::move(a.leaf_allocator());
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline allocators & operator=(allocators const& a)
{
internal_node_allocator() = a.internal_node_allocator();
leaf_allocator() = a.leaf_allocator();
return *this;
}
#endif
void swap(allocators & a)
{

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021.
// Modifications copyright (c) 2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +15,8 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP
#include <boost/geometry/index/detail/assert.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -148,6 +152,21 @@ struct options_type< index::dynamic_rstar >
> type;
};
template <typename Parameters, typename Strategy>
struct options_type< index::parameters<Parameters, Strategy> >
: options_type<Parameters>
{
typedef typename options_type<Parameters>::type opt;
typedef options<
index::parameters<Parameters, Strategy>,
typename opt::insert_tag,
typename opt::choose_next_node_tag,
typename opt::split_tag,
typename opt::redistribute_tag,
typename opt::node_tag
> type;
};
}} // namespace detail::rtree
}}} // namespace boost::geometry::index

View File

@@ -2,7 +2,13 @@
//
// R-tree initial packing
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2020 Caian Benedicto, Campinas, Brazil.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,11 +19,17 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/parameters.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
@@ -66,23 +78,28 @@ template <std::size_t I, std::size_t Dimension>
struct nth_element_and_half_boxes
{
template <typename EIt, typename Box>
static inline void apply(EIt first, EIt median, EIt last, Box const& box, Box & left, Box & right, std::size_t dim_index)
static inline void apply(EIt first, EIt median, EIt last, Box const& box,
Box & left, Box & right, std::size_t dim_index)
{
if ( I == dim_index )
if (I == dim_index)
{
index::detail::nth_element(first, median, last, point_entries_comparer<I>());
geometry::convert(box, left);
geometry::convert(box, right);
typename coordinate_type<Box>::type edge_len
= geometry::get<max_corner, I>(box) - geometry::get<min_corner, I>(box);
typename coordinate_type<Box>::type median
= geometry::get<min_corner, I>(box) + edge_len / 2;
geometry::set<max_corner, I>(left, median);
geometry::set<min_corner, I>(right, median);
auto const mi = geometry::get<min_corner, I>(box);
auto const ma = geometry::get<max_corner, I>(box);
auto const center = mi + (ma - mi) / 2;
geometry::set<max_corner, I>(left, center);
geometry::set<min_corner, I>(right, center);
}
else
nth_element_and_half_boxes<I+1, Dimension>::apply(first, median, last, box, left, right, dim_index);
{
nth_element_and_half_boxes
<
I + 1, Dimension
>::apply(first, median, last, box, left, right, dim_index);
}
}
};
@@ -122,50 +139,78 @@ struct nth_element_and_half_boxes<Dimension, Dimension>
// L2 25 25 25 25 25 25 17 10
// L3 5x5 5x5 5x5 5x5 5x5 5x5 3x5+2 2x5
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class pack
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
typedef typename MembersHolder::node_pointer node_pointer;
typedef typename MembersHolder::size_type size_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename geometry::point_type<Box>::type point_type;
typedef typename MembersHolder::box_type box_type;
typedef typename geometry::point_type<box_type>::type point_type;
typedef typename geometry::coordinate_type<point_type>::type coordinate_type;
typedef typename detail::default_content_result<Box>::type content_type;
typedef typename Options::parameters_type parameters_type;
typedef typename detail::default_content_result<box_type>::type content_type;
typedef typename detail::strategy_type<parameters_type>::type strategy_type;
static const std::size_t dimension = geometry::dimension<point_type>::value;
typedef typename rtree::container_from_elements_type<
typename rtree::elements_type<leaf>::type,
std::size_t
size_type
>::type values_counts_container;
typedef typename rtree::elements_type<internal_node>::type internal_elements;
typedef typename internal_elements::value_type internal_element;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
public:
// Arbitrary iterators
template <typename InIt> inline static
node_pointer apply(InIt first, InIt last, size_type & values_count, size_type & leafs_level,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
node_pointer apply(InIt first, InIt last,
size_type & values_count,
size_type & leafs_level,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
return apply(first, last, values_count, leafs_level, parameters, translator,
allocators, boost::container::new_allocator<void>());
}
template <typename InIt, typename TmpAlloc> inline static
node_pointer apply(InIt first, InIt last,
size_type & values_count,
size_type & leafs_level,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators,
TmpAlloc const& temp_allocator)
{
typedef typename std::iterator_traits<InIt>::difference_type diff_type;
diff_type diff = std::distance(first, last);
if ( diff <= 0 )
return node_pointer(0);
typedef std::pair<point_type, InIt> entry_type;
std::vector<entry_type> entries;
typedef typename boost::container::allocator_traits<TmpAlloc>::
template rebind_alloc<entry_type> temp_entry_allocator_type;
temp_entry_allocator_type temp_entry_allocator(temp_allocator);
boost::container::vector<entry_type, temp_entry_allocator_type> entries(temp_entry_allocator);
values_count = static_cast<size_type>(diff);
entries.reserve(values_count);
expandable_box<Box> hint_box;
auto const& strategy = index::detail::get_strategy(parameters);
expandable_box<box_type, strategy_type> hint_box(strategy);
for ( ; first != last ; ++first )
{
// NOTE: support for iterators not returning true references adapted
@@ -173,7 +218,7 @@ public:
// An alternative would be to dereference the iterator and translate
// in one expression each time the indexable was needed.
typename std::iterator_traits<InIt>::reference in_ref = *first;
typename Translator::result_type indexable = translator(in_ref);
typename translator_type::result_type indexable = translator(in_ref);
// NOTE: added for consistency with insert()
// CONSIDER: alternative - ignore invalid indexable or throw an exception
@@ -182,7 +227,7 @@ public:
hint_box.expand(indexable);
point_type pt;
geometry::centroid(indexable, pt);
geometry::centroid(indexable, pt, strategy);
entries.push_back(std::make_pair(pt, first));
}
@@ -194,19 +239,19 @@ public:
}
private:
template <typename BoxType>
template <typename BoxType, typename Strategy>
class expandable_box
{
public:
expandable_box()
: m_initialized(false)
explicit expandable_box(Strategy const& strategy)
: m_strategy(strategy), m_initialized(false)
{}
template <typename Indexable>
explicit expandable_box(Indexable const& indexable)
: m_initialized(true)
explicit expandable_box(Indexable const& indexable, Strategy const& strategy)
: m_strategy(strategy), m_initialized(true)
{
detail::bounds(indexable, m_box);
detail::bounds(indexable, m_box, m_strategy);
}
template <typename Indexable>
@@ -217,12 +262,12 @@ private:
// it's guaranteed that the Box will be initialized
// only for Points, Boxes and Segments but that's ok
// since only those Geometries can be stored
detail::bounds(indexable, m_box);
detail::bounds(indexable, m_box, m_strategy);
m_initialized = true;
}
else
{
geometry::expand(m_box, indexable);
detail::expand(m_box, indexable, m_strategy);
}
}
@@ -238,22 +283,28 @@ private:
}
private:
bool m_initialized;
BoxType m_box;
Strategy m_strategy;
bool m_initialized;
};
struct subtree_elements_counts
{
subtree_elements_counts(std::size_t ma, std::size_t mi) : maxc(ma), minc(mi) {}
std::size_t maxc;
std::size_t minc;
subtree_elements_counts(size_type ma, size_type mi) : maxc(ma), minc(mi) {}
size_type maxc;
size_type minc;
};
template <typename EIt> inline static
internal_element per_level(EIt first, EIt last, Box const& hint_box, std::size_t values_count, subtree_elements_counts const& subtree_counts,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
internal_element per_level(EIt first, EIt last,
box_type const& hint_box,
size_type values_count,
subtree_elements_counts const& subtree_counts,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<size_type>(std::distance(first, last)) == values_count,
"unexpected parameters");
if ( subtree_counts.maxc <= 1 )
@@ -264,7 +315,7 @@ private:
// if !root check m_parameters.get_min_elements() <= count
// create new leaf node
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
node_pointer n = rtree::create_node<allocators_type, leaf>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
@@ -273,13 +324,14 @@ private:
// calculate values box and copy values
// initialize the box explicitly to avoid GCC-4.4 uninitialized variable warnings with O2
expandable_box<Box> elements_box(translator(*(first->second)));
expandable_box<box_type, strategy_type> elements_box(translator(*(first->second)),
detail::get_strategy(parameters));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
for ( ++first ; first != last ; ++first )
{
// NOTE: push_back() must be called at the end in order to support move_iterator.
// The iterator is dereferenced 2x (no temporary reference) to support
// non-true reference types and move_iterator without boost::forward<>.
// non-true reference types and move_iterator without std::forward<>.
elements_box.expand(translator(*(first->second)));
rtree::elements(l).push_back(*(first->second)); // MAY THROW (A?,C)
}
@@ -294,7 +346,7 @@ private:
if ( BOOST_GEOMETRY_CONDITION((
! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )) )
{
elements_box.expand_by_epsilon();
@@ -311,16 +363,16 @@ private:
next_subtree_counts.minc /= parameters.get_max_elements();
// create new internal node
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
node_pointer n = rtree::create_node<allocators_type, internal_node>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
// reserve space for values
std::size_t nodes_count = calculate_nodes_count(values_count, subtree_counts);
size_type nodes_count = calculate_nodes_count(values_count, subtree_counts);
rtree::elements(in).reserve(nodes_count); // MAY THROW (A)
// calculate values box and copy values
expandable_box<Box> elements_box;
expandable_box<box_type, strategy_type> elements_box(detail::get_strategy(parameters));
per_level_packets(first, last, hint_box, values_count, subtree_counts, next_subtree_counts,
rtree::elements(in), elements_box,
parameters, translator, allocators);
@@ -330,14 +382,18 @@ private:
}
template <typename EIt, typename ExpandableBox> inline static
void per_level_packets(EIt first, EIt last, Box const& hint_box,
std::size_t values_count,
void per_level_packets(EIt first, EIt last,
box_type const& hint_box,
size_type values_count,
subtree_elements_counts const& subtree_counts,
subtree_elements_counts const& next_subtree_counts,
internal_elements & elements, ExpandableBox & elements_box,
parameters_type const& parameters, Translator const& translator, Allocators & allocators)
internal_elements & elements,
ExpandableBox & elements_box,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<std::size_t>(std::distance(first, last)) == values_count,
BOOST_GEOMETRY_INDEX_ASSERT(0 < std::distance(first, last) && static_cast<size_type>(std::distance(first, last)) == values_count,
"unexpected parameters");
BOOST_GEOMETRY_INDEX_ASSERT(subtree_counts.minc <= values_count,
@@ -361,17 +417,17 @@ private:
elements_box.expand(el.first);
return;
}
std::size_t median_count = calculate_median_count(values_count, subtree_counts);
size_type median_count = calculate_median_count(values_count, subtree_counts);
EIt median = first + median_count;
coordinate_type greatest_length;
std::size_t greatest_dim_index = 0;
pack_utils::biggest_edge<dimension>::apply(hint_box, greatest_length, greatest_dim_index);
Box left, right;
box_type left, right;
pack_utils::nth_element_and_half_boxes<0, dimension>
::apply(first, median, last, hint_box, left, right, greatest_dim_index);
per_level_packets(first, median, left,
median_count, subtree_counts, next_subtree_counts,
elements, elements_box,
@@ -383,14 +439,14 @@ private:
}
inline static
subtree_elements_counts calculate_subtree_elements_counts(std::size_t elements_count, parameters_type const& parameters, size_type & leafs_level)
subtree_elements_counts calculate_subtree_elements_counts(size_type elements_count, parameters_type const& parameters, size_type & leafs_level)
{
boost::ignore_unused(parameters);
subtree_elements_counts res(1, 1);
leafs_level = 0;
std::size_t smax = parameters.get_max_elements();
size_type smax = parameters.get_max_elements();
for ( ; smax < elements_count ; smax *= parameters.get_max_elements(), ++leafs_level )
res.maxc = smax;
@@ -400,15 +456,15 @@ private:
}
inline static
std::size_t calculate_nodes_count(std::size_t count,
subtree_elements_counts const& subtree_counts)
size_type calculate_nodes_count(size_type count,
subtree_elements_counts const& subtree_counts)
{
std::size_t n = count / subtree_counts.maxc;
std::size_t r = count % subtree_counts.maxc;
size_type n = count / subtree_counts.maxc;
size_type r = count % subtree_counts.maxc;
if ( 0 < r && r < subtree_counts.minc )
{
std::size_t count_minus_min = count - subtree_counts.minc;
size_type count_minus_min = count - subtree_counts.minc;
n = count_minus_min / subtree_counts.maxc;
r = count_minus_min % subtree_counts.maxc;
++n;
@@ -421,14 +477,14 @@ private:
}
inline static
std::size_t calculate_median_count(std::size_t count,
subtree_elements_counts const& subtree_counts)
size_type calculate_median_count(size_type count,
subtree_elements_counts const& subtree_counts)
{
// e.g. for max = 5, min = 2, count = 52, subtree_max = 25, subtree_min = 10
std::size_t n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2
std::size_t r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2
std::size_t median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25
size_type n = count / subtree_counts.maxc; // e.g. 52 / 25 = 2
size_type r = count % subtree_counts.maxc; // e.g. 52 % 25 = 2
size_type median_count = (n / 2) * subtree_counts.maxc; // e.g. 2 / 2 * 25 = 25
if ( 0 != r ) // e.g. 0 != 2
{
@@ -439,7 +495,7 @@ private:
}
else // r < subtree_counts.second // e.g. 2 < 10 == true
{
std::size_t count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42
size_type count_minus_min = count - subtree_counts.minc; // e.g. 52 - 10 = 42
n = count_minus_min / subtree_counts.maxc; // e.g. 42 / 25 = 1
r = count_minus_min % subtree_counts.maxc; // e.g. 42 % 25 = 17
if ( r == 0 ) // e.g. false

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -41,12 +45,18 @@ inline void pick_seeds(Elements const& elements,
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef Box box_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
typedef index::detail::bounded_view<indexable_type, box_type> bounded_indexable_view;
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
typedef index::detail::bounded_view
<
indexable_type, box_type, strategy_type
> bounded_indexable_view;
const size_t elements_count = parameters.get_max_elements() + 1;
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements");
strategy_type const& strategy = index::detail::get_strategy(parameters);
content_type greatest_free_content = 0;
seed1 = 0;
seed2 = 1;
@@ -59,15 +69,15 @@ inline void pick_seeds(Elements const& elements,
indexable_type const& ind2 = rtree::element_indexable(elements[j], tr);
box_type enlarged_box;
detail::bounds(ind1, enlarged_box);
geometry::expand(enlarged_box, ind2);
index::detail::bounds(ind1, enlarged_box, strategy);
index::detail::expand(enlarged_box, ind2, strategy);
bounded_indexable_view bounded_ind1(ind1);
bounded_indexable_view bounded_ind2(ind2);
bounded_indexable_view bounded_ind1(ind1, strategy);
bounded_indexable_view bounded_ind2(ind2, strategy);
content_type free_content = ( index::detail::content(enlarged_box)
- index::detail::content(bounded_ind1) )
- index::detail::content(bounded_ind2);
if ( greatest_free_content < free_content )
{
greatest_free_content = free_content;
@@ -82,33 +92,36 @@ inline void pick_seeds(Elements const& elements,
} // namespace quadratic
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadratic_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, quadratic_tag>
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Node>
static inline void apply(Node & n,
Node & second_node,
Box & box1,
Box & box2,
box_type & box1,
box_type & box2,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
BOOST_GEOMETRY_INDEX_ASSERT(elements1.size() == parameters.get_max_elements() + 1, "unexpected elements number");
// copy original elements - use in-memory storage (std::allocator)
@@ -117,11 +130,11 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
container_type;
container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy)
// calculate initial seeds
size_t seed1 = 0;
size_t seed2 = 0;
quadratic::pick_seeds<Box>(elements_copy, parameters, translator, seed1, seed2);
quadratic::pick_seeds<box_type>(elements_copy, parameters, translator, seed1, seed2);
// prepare nodes' elements containers
elements1.clear();
@@ -129,13 +142,18 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
BOOST_TRY
{
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
// add seeds
elements1.push_back(elements_copy[seed1]); // MAY THROW, STRONG (copy)
elements2.push_back(elements_copy[seed2]); // MAY THROW, STRONG (alloc, copy)
// calculate boxes
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator), box1);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator), box2);
detail::bounds(rtree::element_indexable(elements_copy[seed1], translator),
box1, strategy);
detail::bounds(rtree::element_indexable(elements_copy[seed2], translator),
box2, strategy);
// remove seeds
if (seed1 < seed2)
@@ -185,7 +203,8 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
content_type content_increase1 = 0;
content_type content_increase2 = 0;
el_it = pick_next(elements_copy.rbegin(), elements_copy.rend(),
box1, box2, content1, content2, translator,
box1, box2, content1, content2,
translator, strategy,
content_increase1, content_increase2);
if ( content_increase1 < content_increase2 ||
@@ -208,13 +227,13 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
if ( insert_into_group1 )
{
elements1.push_back(elem); // MAY THROW, STRONG (copy)
geometry::expand(box1, indexable);
index::detail::expand(box1, indexable, strategy);
content1 = index::detail::content(box1);
}
else
{
elements2.push_back(elem); // MAY THROW, STRONG (alloc, copy)
geometry::expand(box2, indexable);
index::detail::expand(box2, indexable, strategy);
content2 = index::detail::content(box2);
}
@@ -233,7 +252,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_backup, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_backup, allocators);
//elements_backup.clear();
BOOST_RETHROW // RETHROW, BASIC
@@ -245,29 +264,30 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, quadra
template <typename It>
static inline It pick_next(It first, It last,
Box const& box1, Box const& box2,
box_type const& box1, box_type const& box2,
content_type const& content1, content_type const& content2,
Translator const& translator,
translator_type const& translator,
typename index::detail::strategy_type<parameters_type>::type const& strategy,
content_type & out_content_increase1, content_type & out_content_increase2)
{
typedef typename boost::iterator_value<It>::type element_type;
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename rtree::element_indexable_type<element_type, translator_type>::type indexable_type;
content_type greatest_content_incrase_diff = 0;
It out_it = first;
out_content_increase1 = 0;
out_content_increase2 = 0;
// find element with greatest difference between increased group's boxes areas
for ( It el_it = first ; el_it != last ; ++el_it )
{
indexable_type const& indexable = rtree::element_indexable(*el_it, translator);
// calculate enlarged boxes and areas
Box enlarged_box1(box1);
Box enlarged_box2(box2);
geometry::expand(enlarged_box1, indexable);
geometry::expand(enlarged_box2, indexable);
box_type enlarged_box1(box1);
box_type enlarged_box2(box2);
index::detail::expand(enlarged_box1, indexable, strategy);
index::detail::expand(enlarged_box2, indexable, strategy);
content_type enlarged_content1 = index::detail::content(enlarged_box1);
content_type enlarged_content2 = index::detail::content(enlarged_box2);

View File

@@ -2,7 +2,11 @@
//
// R-tree query iterators
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,9 +15,11 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_QUERY_ITERATORS_HPP
#include <boost/scoped_ptr.hpp>
#include <memory>
//#define BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
#include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace iterators {
@@ -58,45 +64,43 @@ struct end_query_iterator
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates>
template <typename MembersHolder, typename Predicates>
class spatial_query_iterator
{
typedef visitors::spatial_query_incremental<Value, Options, Translator, Box, Allocators, Predicates> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
typedef typename MembersHolder::allocators_type allocators_type;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
typedef typename MembersHolder::value_type value_type;
typedef typename allocators_type::const_reference reference;
typedef typename allocators_type::difference_type difference_type;
typedef typename allocators_type::const_pointer pointer;
inline spatial_query_iterator()
spatial_query_iterator() = default;
explicit spatial_query_iterator(Predicates const& pred)
: m_impl(pred)
{}
inline spatial_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
inline spatial_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
: m_visitor(t, p)
spatial_query_iterator(MembersHolder const& members, Predicates const& pred)
: m_impl(members, pred)
{
m_visitor.initialize(root);
m_impl.initialize(members);
}
reference operator*() const
{
return m_visitor.dereference();
return m_impl.dereference();
}
const value_type * operator->() const
{
return boost::addressof(m_visitor.dereference());
return boost::addressof(m_impl.dereference());
}
spatial_query_iterator & operator++()
{
m_visitor.increment();
m_impl.increment();
return *this;
}
@@ -109,62 +113,60 @@ public:
friend bool operator==(spatial_query_iterator const& l, spatial_query_iterator const& r)
{
return l.m_visitor == r.m_visitor;
return l.m_impl == r.m_impl;
}
friend bool operator==(spatial_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
friend bool operator==(spatial_query_iterator const& l, end_query_iterator<value_type, allocators_type> const& /*r*/)
{
return l.m_visitor.is_end();
return l.m_impl.is_end();
}
friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, spatial_query_iterator const& r)
friend bool operator==(end_query_iterator<value_type, allocators_type> const& /*l*/, spatial_query_iterator const& r)
{
return r.m_visitor.is_end();
return r.m_impl.is_end();
}
private:
visitor_type m_visitor;
visitors::spatial_query_incremental<MembersHolder, Predicates> m_impl;
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, unsigned NearestPredicateIndex>
template <typename MembersHolder, typename Predicates>
class distance_query_iterator
{
typedef visitors::distance_query_incremental<Value, Options, Translator, Box, Allocators, Predicates, NearestPredicateIndex> visitor_type;
typedef typename visitor_type::node_pointer node_pointer;
typedef typename MembersHolder::allocators_type allocators_type;
public:
typedef std::forward_iterator_tag iterator_category;
typedef Value value_type;
typedef typename Allocators::const_reference reference;
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
typedef typename MembersHolder::value_type value_type;
typedef typename allocators_type::const_reference reference;
typedef typename allocators_type::difference_type difference_type;
typedef typename allocators_type::const_pointer pointer;
inline distance_query_iterator()
distance_query_iterator() = default;
explicit distance_query_iterator(Predicates const& pred)
: m_impl(pred)
{}
inline distance_query_iterator(Translator const& t, Predicates const& p)
: m_visitor(t, p)
{}
inline distance_query_iterator(node_pointer root, Translator const& t, Predicates const& p)
: m_visitor(t, p)
distance_query_iterator(MembersHolder const& members, Predicates const& pred)
: m_impl(members, pred)
{
m_visitor.initialize(root);
m_impl.initialize(members);
}
reference operator*() const
{
return m_visitor.dereference();
return m_impl.dereference();
}
const value_type * operator->() const
{
return boost::addressof(m_visitor.dereference());
return boost::addressof(m_impl.dereference());
}
distance_query_iterator & operator++()
{
m_visitor.increment();
m_impl.increment();
return *this;
}
@@ -177,21 +179,21 @@ public:
friend bool operator==(distance_query_iterator const& l, distance_query_iterator const& r)
{
return l.m_visitor == r.m_visitor;
return l.m_impl == r.m_impl;
}
friend bool operator==(distance_query_iterator const& l, end_query_iterator<Value, Allocators> const& /*r*/)
friend bool operator==(distance_query_iterator const& l, end_query_iterator<value_type, allocators_type> const& /*r*/)
{
return l.m_visitor.is_end();
return l.m_impl.is_end();
}
friend bool operator==(end_query_iterator<Value, Allocators> const& /*l*/, distance_query_iterator const& r)
friend bool operator==(end_query_iterator<value_type, allocators_type> const& /*l*/, distance_query_iterator const& r)
{
return r.m_visitor.is_end();
return r.m_impl.is_end();
}
private:
visitor_type m_visitor;
visitors::distance_query_incremental<MembersHolder, Predicates> m_impl;
};
@@ -215,7 +217,7 @@ public:
virtual ~query_iterator_base() {}
virtual query_iterator_base * clone() const = 0;
virtual bool is_end() const = 0;
virtual reference dereference() const = 0;
virtual void increment() = 0;
@@ -259,7 +261,7 @@ template <typename Value, typename Allocators>
class query_iterator
{
typedef query_iterator_base<Value, Allocators> iterator_base;
typedef boost::scoped_ptr<iterator_base> iterator_ptr;
typedef std::unique_ptr<iterator_base> iterator_ptr;
public:
typedef std::forward_iterator_tag iterator_category;
@@ -268,8 +270,7 @@ public:
typedef typename Allocators::difference_type difference_type;
typedef typename Allocators::const_pointer pointer;
query_iterator()
{}
query_iterator() = default;
template <typename It>
query_iterator(It const& it)
@@ -284,7 +285,8 @@ public:
: m_ptr(o.m_ptr.get() ? o.m_ptr->clone() : 0)
{}
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator(query_iterator&&) = default;
query_iterator & operator=(query_iterator const& o)
{
if ( this != boost::addressof(o) )
@@ -293,49 +295,8 @@ public:
}
return *this;
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
query_iterator(query_iterator && o)
: m_ptr(0)
{
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(query_iterator && o)
{
if ( this != boost::addressof(o) )
{
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}
#endif
#else // !BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
private:
BOOST_COPYABLE_AND_MOVABLE(query_iterator)
public:
query_iterator & operator=(BOOST_COPY_ASSIGN_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
m_ptr.reset(o.m_ptr.get() ? o.m_ptr->clone() : 0);
}
return *this;
}
query_iterator(BOOST_RV_REF(query_iterator) o)
: m_ptr(0)
{
m_ptr.swap(o.m_ptr);
}
query_iterator & operator=(BOOST_RV_REF(query_iterator) o)
{
if ( this != boost::addressof(o) )
{
m_ptr.swap(o.m_ptr);
o.m_ptr.reset();
}
return *this;
}
#endif // BOOST_GEOMETRY_INDEX_DETAIL_QUERY_ITERATORS_USE_MOVE
query_iterator& operator=(query_iterator &&) = default;
reference operator*() const
{

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -23,25 +27,28 @@
#include <boost/geometry/index/detail/algorithms/union_content.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
template <typename Value, typename Options, typename Box, typename Allocators>
class choose_next_node<Value, Options, Box, Allocators, choose_by_overlap_diff_tag>
template <typename MembersHolder>
class choose_next_node<MembersHolder, choose_by_overlap_diff_tag>
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename rtree::elements_type<internal_node>::type children_type;
typedef typename children_type::value_type child_type;
typedef typename Options::parameters_type parameters_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
public:
template <typename Indexable>
@@ -53,15 +60,20 @@ public:
::boost::ignore_unused(parameters);
children_type & children = rtree::elements(n);
// children are leafs
if ( node_relative_level <= 1 )
{
return choose_by_minimum_overlap_cost(children, indexable, parameters.get_overlap_cost_threshold());
return choose_by_minimum_overlap_cost(children, indexable,
parameters.get_overlap_cost_threshold(),
index::detail::get_strategy(parameters));
}
// children are internal nodes
else
return choose_by_minimum_content_cost(children, indexable);
{
return choose_by_minimum_content_cost(children, indexable,
index::detail::get_strategy(parameters));
}
}
private:
@@ -79,10 +91,11 @@ private:
}
};
template <typename Indexable>
template <typename Indexable, typename Strategy>
static inline size_t choose_by_minimum_overlap_cost(children_type const& children,
Indexable const& indexable,
size_t overlap_cost_threshold)
size_t overlap_cost_threshold,
Strategy const& strategy)
{
const size_t children_count = children.size();
@@ -99,8 +112,8 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference
content_type content = index::detail::content(box_exp);
@@ -131,7 +144,11 @@ private:
}
// calculate minimum or nearly minimum overlap cost
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable, first_n_children_count, children_count, children_contents);
choosen_index = choose_by_minimum_overlap_cost_first_n(children, indexable,
first_n_children_count,
children_count,
children_contents,
strategy);
}
return choosen_index;
@@ -143,12 +160,13 @@ private:
|| (p1.content_diff == p2.content_diff && (p1.content) < (p2.content));
}
template <typename Indexable, typename ChildrenContents>
template <typename Indexable, typename ChildrenContents, typename Strategy>
static inline size_t choose_by_minimum_overlap_cost_first_n(children_type const& children,
Indexable const& indexable,
size_t const first_n_children_count,
size_t const children_count,
ChildrenContents const& children_contents)
ChildrenContents const& children_contents,
Strategy const& strategy)
{
BOOST_GEOMETRY_INDEX_ASSERT(first_n_children_count <= children_count, "unexpected value");
BOOST_GEOMETRY_INDEX_ASSERT(children_contents.size() == children_count, "unexpected number of elements");
@@ -168,9 +186,9 @@ private:
child_type const& ch_i = children[i];
Box box_exp(ch_i.first);
box_type box_exp(ch_i.first);
// calculate expanded box of child node ch_i
geometry::expand(box_exp, indexable);
index::detail::expand(box_exp, indexable, strategy);
content_type overlap_diff = 0;
@@ -181,10 +199,10 @@ private:
{
child_type const& ch_j = children[j];
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first);
content_type overlap_exp = index::detail::intersection_content(box_exp, ch_j.first, strategy);
if ( overlap_exp < -std::numeric_limits<content_type>::epsilon() || std::numeric_limits<content_type>::epsilon() < overlap_exp )
{
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first);
overlap_diff += overlap_exp - index::detail::intersection_content(ch_i.first, ch_j.first, strategy);
}
}
}
@@ -205,8 +223,10 @@ private:
return choosen_index;
}
template <typename Indexable>
static inline size_t choose_by_minimum_content_cost(children_type const& children, Indexable const& indexable)
template <typename Indexable, typename Strategy>
static inline size_t choose_by_minimum_content_cost(children_type const& children,
Indexable const& indexable,
Strategy const& strategy)
{
size_t children_count = children.size();
@@ -221,8 +241,8 @@ private:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable, strategy);
// areas difference
content_type content = index::detail::content(box_exp);

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,9 +16,17 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_RSTAR_INSERT_HPP
#include <type_traits>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/centroid.hpp>
#include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
namespace boost { namespace geometry { namespace index {
@@ -21,15 +34,47 @@ namespace detail { namespace rtree { namespace visitors {
namespace rstar {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
// Utility to distinguish between default and non-default index strategy
template <typename Point1, typename Point2, typename Strategy>
struct comparable_distance
{
typedef typename geometry::comparable_distance_result
<
Point1, Point2, Strategy
>::type result_type;
static inline result_type call(Point1 const& p1, Point2 const& p2, Strategy const& s)
{
return geometry::comparable_distance(p1, p2, s);
}
};
template <typename Point1, typename Point2>
struct comparable_distance<Point1, Point2, default_strategy>
{
typedef typename geometry::default_comparable_distance_result
<
Point1, Point2
>::type result_type;
static inline result_type call(Point1 const& p1, Point2 const& p2, default_strategy const& )
{
return geometry::comparable_distance(p1, p2);
}
};
template <typename MembersHolder>
class remove_elements_to_reinsert
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
typedef internal_node * internal_node_pointer;
@@ -40,16 +85,19 @@ public:
internal_node_pointer parent,
size_t current_child_index,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
typedef typename geometry::point_type<Box>::type point_type;
typedef typename geometry::point_type<box_type>::type point_type;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
// TODO: awulkiew - change second point_type to the point type of the Indexable?
typedef typename
geometry::default_comparable_distance_result<point_type>::type
comparable_distance_type;
typedef rstar::comparable_distance
<
point_type, point_type, strategy_type
> comparable_distance_pp;
typedef typename comparable_distance_pp::result_type comparable_distance_type;
elements_type & elements = rtree::elements(n);
@@ -60,9 +108,12 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected elements number");
BOOST_GEOMETRY_INDEX_ASSERT(0 < reinserted_elements_count, "wrong value of elements to reinsert");
auto const& strategy = index::detail::get_strategy(parameters);
// calculate current node's center
point_type node_center;
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center);
geometry::centroid(rtree::elements(*parent)[current_child_index].first, node_center,
strategy);
// fill the container of centers' distances of children from current node's center
typedef typename index::detail::rtree::container_from_elements_type<
@@ -73,14 +124,15 @@ public:
sorted_elements_type sorted_elements;
// If constructor is used instead of resize() MS implementation leaks here
sorted_elements.reserve(elements_count); // MAY THROW, STRONG (V, E: alloc, copy)
for ( typename elements_type::const_iterator it = elements.begin() ;
it != elements.end() ; ++it )
{
point_type element_center;
geometry::centroid( rtree::element_indexable(*it, translator), element_center);
geometry::centroid(rtree::element_indexable(*it, translator), element_center,
strategy);
sorted_elements.push_back(std::make_pair(
geometry::comparable_distance(node_center, element_center),
comparable_distance_pp::call(node_center, element_center, strategy),
*it)); // MAY THROW (V, E: copy)
}
@@ -118,7 +170,7 @@ public:
for ( typename sorted_elements_type::iterator it = sorted_elements.begin() ;
it != sorted_elements.end() ; ++it )
{
destroy_element<Value, Options, Translator, Box, Allocators>::apply(it->second, allocators);
destroy_element<MembersHolder>::apply(it->second, allocators);
}
BOOST_RETHROW // RETHROW
@@ -136,7 +188,7 @@ private:
{
return d1.first < d2.first;
}
template <typename Distance, typename El>
static inline bool distances_dsc(
std::pair<Distance, El> const& d1,
@@ -146,48 +198,69 @@ private:
}
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Box, typename Allocators>
template
<
size_t InsertIndex,
typename Element,
typename MembersHolder,
bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
>
struct level_insert_elements_type
{
typedef typename rtree::elements_type<
typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
typename rtree::internal_node<
typename MembersHolder::value_type,
typename MembersHolder::parameters_type,
typename MembersHolder::box_type,
typename MembersHolder::allocators_type,
typename MembersHolder::node_tag
>::type
>::type type;
};
template <typename Value, typename Options, typename Box, typename Allocators>
struct level_insert_elements_type<0, Value, Value, Options, Box, Allocators>
template <typename Value, typename MembersHolder>
struct level_insert_elements_type<0, Value, MembersHolder, true>
{
typedef typename rtree::elements_type<
typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type
typename rtree::leaf<
typename MembersHolder::value_type,
typename MembersHolder::parameters_type,
typename MembersHolder::box_type,
typename MembersHolder::allocators_type,
typename MembersHolder::node_tag
>::type
>::type type;
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <size_t InsertIndex, typename Element, typename MembersHolder>
struct level_insert_base
: public detail::insert<Element, Value, Options, Translator, Box, Allocators>
: public detail::insert<Element, MembersHolder>
{
typedef detail::insert<Element, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<Element, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename level_insert_elements_type<InsertIndex, Element, Value, Options, Box, Allocators>::type elements_type;
typedef typename level_insert_elements_type<InsertIndex, Element, MembersHolder>::type elements_type;
typedef typename index::detail::rtree::container_from_elements_type<
elements_type,
typename elements_type::value_type
>::type result_elements_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
inline level_insert_base(node_pointer & root,
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
, result_relative_level(0)
@@ -208,7 +281,7 @@ struct level_insert_base
{
// NOTE: exception-safety
// After an exception result_elements may contain garbage, don't use it
rstar::remove_elements_to_reinsert<Value, Options, Translator, Box, Allocators>::apply(
rstar::remove_elements_to_reinsert<MembersHolder>::apply(
result_elements, n,
base::m_traverse_data.parent, base::m_traverse_data.current_child_index,
base::m_parameters, base::m_translator, base::m_allocators); // MAY THROW, BASIC (V, E: alloc, copy)
@@ -246,39 +319,51 @@ struct level_insert_base
inline void recalculate_aabb(Node const& n) const
{
base::m_traverse_data.current_element().first =
elements_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
elements_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
}
inline void recalculate_aabb(leaf const& n) const
{
base::m_traverse_data.current_element().first =
values_box<Box>(rtree::elements(n).begin(), rtree::elements(n).end(), base::m_translator);
values_box<box_type>(rtree::elements(n).begin(), rtree::elements(n).end(),
base::m_translator,
index::detail::get_strategy(base::m_parameters));
}
size_type result_relative_level;
result_elements_type result_elements;
};
template <size_t InsertIndex, typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template
<
size_t InsertIndex,
typename Element,
typename MembersHolder,
bool IsValue = std::is_same<Element, typename MembersHolder::value_type>::value
>
struct level_insert
: public level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators>
: public level_insert_base<InsertIndex, Element, MembersHolder>
{
typedef level_insert_base<InsertIndex, Element, Value, Options, Translator, Box, Allocators> base;
typedef level_insert_base<InsertIndex, Element, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename base::parameters_type parameters_type;
typedef typename base::translator_type translator_type;
typedef typename base::allocators_type allocators_type;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename base::node_pointer node_pointer;
typedef typename base::size_type size_type;
inline level_insert(node_pointer & root,
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
{}
@@ -317,8 +402,7 @@ struct level_insert
// NOTE: exception-safety
// if the insert fails above, the element won't be stored in the tree, so delete it
rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(base::m_element.second, base::m_allocators);
rtree::apply_visitor(del_v, *base::m_element.second);
rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
BOOST_RETHROW // RETHROW
}
@@ -345,26 +429,29 @@ struct level_insert
}
};
template <size_t InsertIndex, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
: public level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators>
template <size_t InsertIndex, typename Value, typename MembersHolder>
struct level_insert<InsertIndex, Value, MembersHolder, true>
: public level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder>
{
typedef level_insert_base<InsertIndex, Value, Value, Options, Translator, Box, Allocators> base;
typedef level_insert_base<InsertIndex, typename MembersHolder::value_type, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::value_type value_type;
typedef typename base::parameters_type parameters_type;
typedef typename base::translator_type translator_type;
typedef typename base::allocators_type allocators_type;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename base::node_pointer node_pointer;
typedef typename base::size_type size_type;
inline level_insert(node_pointer & root,
size_type & leafs_level,
Value const& v,
value_type const& v,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level)
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
{}
@@ -378,7 +465,7 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
base::traverse(*this, n); // MAY THROW (V, E: alloc, copy, N: alloc)
BOOST_GEOMETRY_INDEX_ASSERT(0 < base::m_level, "illegal level value, level shouldn't be the root level for 0 < InsertIndex");
if ( base::m_traverse_data.current_level == base::m_level - 1 )
{
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (E: alloc, copy, N: alloc)
@@ -394,33 +481,36 @@ struct level_insert<InsertIndex, Value, Value, Options, Translator, Box, Allocat
BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
base::m_level == (std::numeric_limits<size_t>::max)(),
"unexpected level");
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::handle_possible_split(n); // MAY THROW (V: alloc, copy, N: alloc)
}
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
: public level_insert_base<0, Value, Value, Options, Translator, Box, Allocators>
template <typename Value, typename MembersHolder>
struct level_insert<0, Value, MembersHolder, true>
: public level_insert_base<0, typename MembersHolder::value_type, MembersHolder>
{
typedef level_insert_base<0, Value, Value, Options, Translator, Box, Allocators> base;
typedef level_insert_base<0, typename MembersHolder::value_type, MembersHolder> base;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::value_type value_type;
typedef typename base::parameters_type parameters_type;
typedef typename base::translator_type translator_type;
typedef typename base::allocators_type allocators_type;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename base::node_pointer node_pointer;
typedef typename base::size_type size_type;
inline level_insert(node_pointer & root,
size_type & leafs_level,
Value const& v,
value_type const& v,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level)
: base(root, leafs_level, v, parameters, translator, allocators, relative_level)
{}
@@ -449,7 +539,7 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::handle_possible_reinsert_or_split_of_root(n); // MAY THROW (V: alloc, copy, N: alloc)
base::recalculate_aabb_if_necessary(n);
}
};
@@ -460,26 +550,28 @@ struct level_insert<0, Value, Value, Options, Translator, Box, Allocators>
// After passing the Element to insert visitor the Element is managed by the tree
// I.e. one should not delete the node passed to the insert visitor after exception is thrown
// because this visitor may delete it
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Element, Value, Options, Translator, Box, Allocators, insert_reinsert_tag>
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
template <typename Element, typename MembersHolder>
class insert<Element, MembersHolder, insert_reinsert_tag>
: public MembersHolder::visitor
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
public:
inline insert(node_pointer & root,
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level = 0)
: m_root(root), m_leafs_level(leafs_level), m_element(element)
, m_parameters(parameters), m_translator(translator)
@@ -494,7 +586,7 @@ public:
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
if ( m_parameters.get_reinserted_elements() > 0 )
{
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<0, Element, MembersHolder> lins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
@@ -506,10 +598,10 @@ public:
}
else
{
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(ins_v, *m_root);
rtree::apply_visitor(ins_v, *m_root);
}
}
@@ -521,7 +613,7 @@ public:
// Distinguish between situation when reinserts are required and use adequate visitor, otherwise use default one
if ( m_parameters.get_reinserted_elements() > 0 )
{
rstar::level_insert<0, Element, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<0, Element, MembersHolder> lins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(lins_v, *m_root); // MAY THROW (V, E: alloc, copy, N: alloc)
@@ -531,10 +623,10 @@ public:
}
else
{
visitors::insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag> ins_v(
visitors::insert<Element, MembersHolder, insert_default_tag> ins_v(
m_root, m_leafs_level, m_element, m_parameters, m_translator, m_allocators, m_relative_level);
rtree::apply_visitor(ins_v, *m_root);
rtree::apply_visitor(ins_v, *m_root);
}
}
@@ -548,7 +640,7 @@ private:
typename Elements::reverse_iterator it = elements.rbegin();
for ( ; it != elements.rend() ; ++it)
{
rstar::level_insert<1, element_type, Value, Options, Translator, Box, Allocators> lins_v(
rstar::level_insert<1, element_type, MembersHolder> lins_v(
m_root, m_leafs_level, *it, m_parameters, m_translator, m_allocators, relative_level);
BOOST_TRY
@@ -559,7 +651,7 @@ private:
{
++it;
for ( ; it != elements.rend() ; ++it)
rtree::destroy_element<Value, Options, Translator, Box, Allocators>::apply(*it, m_allocators);
rtree::destroy_element<MembersHolder>::apply(*it, m_allocators);
BOOST_RETHROW // RETHROW
}
BOOST_CATCH_END
@@ -579,11 +671,11 @@ private:
Element const& m_element;
parameters_type const& m_parameters;
Translator const& m_translator;
translator_type const& m_translator;
size_type m_relative_level;
Allocators & m_allocators;
allocators_type & m_allocators;
};
}}} // namespace detail::rtree::visitors

View File

@@ -2,7 +2,11 @@
//
// R-tree R*-tree split algorithm implementation
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2020.
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +17,8 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/intersection_content.hpp>
#include <boost/geometry/index/detail/algorithms/margin.hpp>
#include <boost/geometry/index/detail/algorithms/nth_element.hpp>
@@ -30,37 +36,43 @@ namespace detail { namespace rtree {
namespace rstar {
template <typename Element, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
template <typename Element, typename Parameters, typename Translator, typename Tag, size_t Corner, size_t AxisIndex>
class element_axis_corner_less
{
typedef typename rtree::element_indexable_type<Element, Translator>::type indexable_type;
typedef typename geometry::point_type<indexable_type>::type point_type;
typedef geometry::model::box<point_type> bounds_type;
typedef index::detail::bounded_view<indexable_type, bounds_type> bounded_view_type;
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
typedef index::detail::bounded_view
<
indexable_type, bounds_type, strategy_type
> bounded_view_type;
public:
element_axis_corner_less(Translator const& tr)
: m_tr(tr)
element_axis_corner_less(Translator const& tr, strategy_type const& strategy)
: m_tr(tr), m_strategy(strategy)
{}
bool operator()(Element const& e1, Element const& e2) const
{
bounded_view_type bounded_ind1(rtree::element_indexable(e1, m_tr));
bounded_view_type bounded_ind2(rtree::element_indexable(e2, m_tr));
return geometry::get<Corner, AxisIndex>(bounded_ind1)
< geometry::get<Corner, AxisIndex>(bounded_ind2);
indexable_type const& ind1 = rtree::element_indexable(e1, m_tr);
indexable_type const& ind2 = rtree::element_indexable(e2, m_tr);
return geometry::get<Corner, AxisIndex>(bounded_view_type(ind1, m_strategy))
< geometry::get<Corner, AxisIndex>(bounded_view_type(ind2, m_strategy));
}
private:
Translator const& m_tr;
strategy_type const& m_strategy;
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, box_tag, Corner, AxisIndex>
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Parameters, Translator, box_tag, Corner, AxisIndex>
{
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
public:
element_axis_corner_less(Translator const& tr)
element_axis_corner_less(Translator const& tr, strategy_type const&)
: m_tr(tr)
{}
@@ -74,11 +86,13 @@ private:
Translator const& m_tr;
};
template <typename Element, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Translator, point_tag, Corner, AxisIndex>
template <typename Element, typename Parameters, typename Translator, size_t Corner, size_t AxisIndex>
class element_axis_corner_less<Element, Parameters, Translator, point_tag, Corner, AxisIndex>
{
typedef typename index::detail::strategy_type<Parameters>::type strategy_type;
public:
element_axis_corner_less(Translator const& tr)
element_axis_corner_less(Translator const& tr, strategy_type const& )
: m_tr(tr)
{}
@@ -113,14 +127,20 @@ struct choose_split_axis_and_index_for_corner
BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements");
typename index::detail::strategy_type<Parameters>::type const&
strategy = index::detail::get_strategy(parameters);
// copy elements
Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy)
size_t const index_first = parameters.get_min_elements();
size_t const index_last = parameters.get_max_elements() - parameters.get_min_elements() + 2;
// sort elements
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, AxisIndex> elements_less(translator);
element_axis_corner_less
<
element_type, Parameters, Translator, indexable_tag, Corner, AxisIndex
> elements_less(translator, strategy);
std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy)
// {
// typename Elements::iterator f = elements_copy.begin() + index_first;
@@ -143,12 +163,14 @@ struct choose_split_axis_and_index_for_corner
// TODO - awulkiew: may be optimized - box of group 1 may be initialized with
// box of min_elems number of elements and expanded for each iteration by another element
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i, translator);
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(), translator);
Box box1 = rtree::elements_box<Box>(elements_copy.begin(), elements_copy.begin() + i,
translator, strategy);
Box box2 = rtree::elements_box<Box>(elements_copy.begin() + i, elements_copy.end(),
translator, strategy);
sum_of_margins += index::detail::comparable_margin(box1) + index::detail::comparable_margin(box2);
content_type ovl = index::detail::intersection_content(box1, box2);
content_type ovl = index::detail::intersection_content(box1, box2, strategy);
content_type con = index::detail::content(box1) + index::detail::content(box2);
// TODO - shouldn't here be < instead of <= ?
@@ -167,7 +189,7 @@ struct choose_split_axis_and_index_for_corner
//template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
//struct choose_split_axis_and_index_for_axis
//{
// BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag));
// BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Not implemented for this Tag type.", ElementIndexableTag);
//};
template <typename Box, size_t AxisIndex, typename ElementIndexableTag>
@@ -337,14 +359,15 @@ struct nth_element
BOOST_STATIC_ASSERT(0 < Dimension);
BOOST_STATIC_ASSERT(I < Dimension);
template <typename Elements, typename Translator>
static inline void apply(Elements & elements, const size_t axis, const size_t index, Translator const& tr)
template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements & elements, Parameters const& parameters,
const size_t axis, const size_t index, Translator const& tr)
{
//BOOST_GEOMETRY_INDEX_ASSERT(axis < Dimension, "unexpected axis value");
if ( axis != I )
{
nth_element<Corner, Dimension, I + 1>::apply(elements, axis, index, tr); // MAY THROW, BASIC (copy)
nth_element<Corner, Dimension, I + 1>::apply(elements, parameters, axis, index, tr); // MAY THROW, BASIC (copy)
}
else
{
@@ -352,7 +375,13 @@ struct nth_element
typedef typename rtree::element_indexable_type<element_type, Translator>::type indexable_type;
typedef typename tag<indexable_type>::type indexable_tag;
element_axis_corner_less<element_type, Translator, indexable_tag, Corner, I> less(tr);
typename index::detail::strategy_type<Parameters>::type
strategy = index::detail::get_strategy(parameters);
element_axis_corner_less
<
element_type, Parameters, Translator, indexable_tag, Corner, I
> less(tr, strategy);
index::detail::nth_element(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy)
}
}
@@ -361,40 +390,44 @@ struct nth_element
template <size_t Corner, size_t Dimension>
struct nth_element<Corner, Dimension, Dimension>
{
template <typename Elements, typename Translator>
static inline void apply(Elements & /*elements*/, const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
template <typename Elements, typename Parameters, typename Translator>
static inline void apply(Elements & /*elements*/, Parameters const& /*parameters*/,
const size_t /*axis*/, const size_t /*index*/, Translator const& /*tr*/)
{}
};
} // namespace rstar
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_tag>
template <typename MembersHolder>
struct redistribute_elements<MembersHolder, rstar_tag>
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
static const size_t dimension = geometry::dimension<Box>::value;
static const size_t dimension = geometry::dimension<box_type>::value;
typedef typename index::detail::default_margin_result<Box>::type margin_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_margin_result<box_type>::type margin_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Node>
static inline void apply(
Node & n,
Node & second_node,
Box & box1,
Box & box2,
box_type & box1,
box_type & box2,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
typedef typename rtree::elements_type<Node>::type elements_type;
typedef typename elements_type::value_type element_type;
elements_type & elements1 = rtree::elements(n);
elements_type & elements2 = rtree::elements(second_node);
@@ -417,7 +450,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
// and again, the same below calling partial_sort/nth_element
// It would be even possible to not re-sort/find nth_element if the axis/corner
// was found for the last sorting - last combination of axis/corner
rstar::choose_split_axis_and_index<Box, dimension>
rstar::choose_split_axis_and_index<box_type, dimension>
::apply(elements_copy,
split_axis, split_corner, split_index,
smallest_sum_of_margins, smallest_overlap, smallest_content,
@@ -432,23 +465,28 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
if ( split_corner == static_cast<size_t>(min_corner) )
{
rstar::nth_element<min_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
else
{
rstar::nth_element<max_corner, dimension>
::apply(elements_copy, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
::apply(elements_copy, parameters, split_axis, split_index, translator); // MAY THROW, BASIC (copy)
}
BOOST_TRY
{
typename index::detail::strategy_type<parameters_type>::type const&
strategy = index::detail::get_strategy(parameters);
// copy elements to nodes
elements1.assign(elements_copy.begin(), elements_copy.begin() + split_index); // MAY THROW, BASIC
elements2.assign(elements_copy.begin() + split_index, elements_copy.end()); // MAY THROW, BASIC
// calculate boxes
box1 = rtree::elements_box<Box>(elements1.begin(), elements1.end(), translator);
box2 = rtree::elements_box<Box>(elements2.begin(), elements2.end(), translator);
box1 = rtree::elements_box<box_type>(elements1.begin(), elements1.end(),
translator, strategy);
box2 = rtree::elements_box<box_type>(elements2.begin(), elements2.end(),
translator, strategy);
}
BOOST_CATCH(...)
{
@@ -456,7 +494,7 @@ struct redistribute_elements<Value, Options, Translator, Box, Allocators, rstar_
elements1.clear();
elements2.clear();
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>::apply(elements_backup, allocators);
rtree::destroy_elements<MembersHolder>::apply(elements_backup, allocators);
//elements_backup.clear();
BOOST_RETHROW // RETHROW, BASIC

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -18,16 +22,20 @@ namespace boost { namespace geometry { namespace index { namespace detail { name
namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class are_boxes_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
are_boxes_ok(Translator const& tr, bool exact_match)
: result(false), m_tr(tr), m_is_root(true), m_exact_match(exact_match)
are_boxes_ok(parameters_type const& parameters, translator_type const& tr, bool exact_match)
: result(false), m_parameters(parameters), m_tr(tr), m_is_root(true), m_exact_match(exact_match)
{}
void operator()(internal_node const& n)
@@ -41,7 +49,7 @@ public:
return;
}
Box box_bckup = m_box;
box_type box_bckup = m_box;
bool is_root_bckup = m_is_root;
m_is_root = false;
@@ -60,8 +68,9 @@ public:
m_box = box_bckup;
m_is_root = is_root_bckup;
Box box_exp = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr);
box_type box_exp = rtree::elements_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
if ( m_exact_match )
result = m_is_root || geometry::equals(box_exp, m_box);
else
@@ -81,8 +90,9 @@ public:
result = false;
return;
}
Box box_exp = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr);
box_type box_exp = rtree::values_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
if ( m_exact_match )
result = geometry::equals(box_exp, m_box);
@@ -96,8 +106,9 @@ public:
bool result;
private:
Translator const& m_tr;
Box m_box;
parameters_type const& m_parameters;
translator_type const& m_tr;
box_type m_box;
bool m_is_root;
bool m_exact_match;
};
@@ -111,13 +122,9 @@ bool are_boxes_ok(Rtree const& tree, bool exact_match = true)
RTV rtv(tree);
visitors::are_boxes_ok<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
> v(rtv.translator(), exact_match);
typename RTV::members_holder
> v(tree.parameters(), rtv.translator(), exact_match);
rtv.apply_visitor(v);
return v.result;

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,22 +17,27 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_COUNTS_OK_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
namespace visitors {
template <typename Value, typename Options, typename Box, typename Allocators>
template <typename MembersHolder>
class are_counts_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
inline are_counts_ok(parameters_type const& parameters)
: result(true), m_current_level(0), m_parameters(parameters)
inline are_counts_ok(parameters_type const& parameters, bool check_min = true)
: result(true)
, m_current_level(0)
, m_parameters(parameters)
, m_check_min(check_min)
{}
inline void operator()(internal_node const& n)
@@ -36,7 +46,7 @@ public:
elements_type const& elements = rtree::elements(n);
// root internal node shouldn't contain 0 elements
if ( elements.empty()
if ( (elements.empty() && m_check_min)
|| !check_count(elements) )
{
result = false;
@@ -62,7 +72,7 @@ public:
elements_type const& elements = rtree::elements(n);
// empty leaf in non-root node
if ( ( m_current_level > 0 && elements.empty() )
if ( (m_current_level > 0 && elements.empty() && m_check_min)
|| !check_count(elements) )
{
result = false;
@@ -78,28 +88,26 @@ private:
// root may contain count < min but should never contain count > max
return elements.size() <= m_parameters.get_max_elements()
&& ( elements.size() >= m_parameters.get_min_elements()
|| m_current_level == 0 );
|| m_current_level == 0 || !m_check_min );
}
size_t m_current_level;
parameters_type const& m_parameters;
bool m_check_min;
};
} // namespace visitors
template <typename Rtree> inline
bool are_counts_ok(Rtree const& tree)
bool are_counts_ok(Rtree const& tree, bool check_min = true)
{
typedef utilities::view<Rtree> RTV;
RTV rtv(tree);
visitors::are_counts_ok<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::box_type,
typename RTV::allocators_type
> v(tree.parameters());
typename RTV::members_holder
> v(tree.parameters(), check_min);
rtv.apply_visitor(v);
return v.result;

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -12,17 +17,18 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_ARE_LEVELS_OK_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
namespace visitors {
template <typename Value, typename Options, typename Box, typename Allocators>
template <typename MembersHolder>
class are_levels_ok
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
inline are_levels_ok()
@@ -93,12 +99,9 @@ bool are_levels_ok(Rtree const& tree)
RTV rtv(tree);
visitors::are_levels_ok<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> v;
rtv.apply_visitor(v);
return v.result;

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,7 +15,16 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
#include <boost/mpl/assert.hpp>
#include <limits>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
@@ -79,7 +92,9 @@ struct gl_draw_segment<Segment, 2>
template <typename Indexable, typename Tag>
struct gl_draw_indexable
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Tag);
};
template <typename Box>
@@ -114,16 +129,20 @@ namespace rtree { namespace utilities {
namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct gl_draw
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::translator_type translator_type;
inline gl_draw(Translator const& t,
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline gl_draw(translator_type const& t,
size_t level_first = 0,
size_t level_last = (std::numeric_limits<size_t>::max)(),
typename coordinate_type<Box>::type z_coord_level_multiplier = 1
typename coordinate_type<box_type>::type z_coord_level_multiplier = 1
)
: tr(t)
, level_f(level_first)
@@ -162,7 +181,7 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul);
}
}
size_t level_backup = level;
++level;
@@ -197,10 +216,10 @@ struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type,
}
}
Translator const& tr;
translator_type const& tr;
size_t level_f;
size_t level_l;
typename coordinate_type<Box>::type z_mul;
typename coordinate_type<box_type>::type z_mul;
size_t level;
};
@@ -226,11 +245,7 @@ void gl_draw(Rtree const& tree,
}
visitors::gl_draw<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier);
rtv.apply_visitor(gl_draw_v);

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -13,8 +18,18 @@
#include <iostream>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace utilities {
namespace dispatch {
@@ -66,7 +81,9 @@ struct print_corner<Box, Corner, 1>
template <typename Indexable, typename Tag>
struct print_indexable
{
BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Indexable type.",
Indexable, Tag);
};
template <typename Indexable>
@@ -129,13 +146,16 @@ namespace rtree { namespace utilities {
namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct print : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct print
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::translator_type translator_type;
inline print(std::ostream & o, Translator const& t)
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline print(std::ostream & o, translator_type const& t)
: os(o), tr(t), level(0)
{}
@@ -145,7 +165,7 @@ struct print : public rtree::visitor<Value, typename Options::parameters_type, B
elements_type const& elements = rtree::elements(n);
spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << elements.size() << " @:" << &n << '\n';
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
@@ -189,7 +209,7 @@ struct print : public rtree::visitor<Value, typename Options::parameters_type, B
}
std::ostream & os;
Translator const& tr;
translator_type const& tr;
size_t level;
};
@@ -203,11 +223,7 @@ void print(std::ostream & os, Rtree const& tree)
RTV rtv(tree);
visitors::print<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> print_v(os, rtv.translator());
rtv.apply_visitor(print_v);
}

View File

@@ -5,6 +5,11 @@
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2013 Mateusz Loskot, London, UK.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -13,17 +18,22 @@
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP
#include <algorithm>
#include <boost/tuple/tuple.hpp>
#include <tuple>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/detail/rtree/utilities/view.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace utilities {
namespace visitors {
template <typename Value, typename Options, typename Box, typename Allocators>
struct statistics : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct statistics
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline statistics()
: level(0)
@@ -39,37 +49,37 @@ struct statistics : public rtree::visitor<Value, typename Options::parameters_ty
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
++nodes; // count node
size_t const level_backup = level;
++level;
levels += level++ > levels ? 1 : 0; // count level (root already counted)
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
rtree::apply_visitor(*this, *it->second);
}
level = level_backup;
}
inline void operator()(leaf const& n)
{
{
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
++leaves; // count leaves
std::size_t const v = elements.size();
// count values spread per node and total
values_min = (std::min)(values_min == 0 ? v : values_min, v);
values_max = (std::max)(values_max, v);
values += v;
}
std::size_t level;
std::size_t levels;
std::size_t nodes;
@@ -82,22 +92,19 @@ struct statistics : public rtree::visitor<Value, typename Options::parameters_ty
} // namespace visitors
template <typename Rtree> inline
boost::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
std::tuple<std::size_t, std::size_t, std::size_t, std::size_t, std::size_t, std::size_t>
statistics(Rtree const& tree)
{
typedef utilities::view<Rtree> RTV;
RTV rtv(tree);
visitors::statistics<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::box_type,
typename RTV::allocators_type
typename RTV::members_holder
> stats_v;
rtv.apply_visitor(stats_v);
return boost::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
return std::make_tuple(stats_v.levels, stats_v.nodes, stats_v.leaves, stats_v.values, stats_v.values_min, stats_v.values_max);
}
}}}}}} // namespace boost::geometry::index::detail::rtree::utilities

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -19,13 +23,15 @@ template <typename Rtree>
class view
{
public:
typedef typename Rtree::members_holder members_holder;
typedef typename Rtree::size_type size_type;
typedef typename Rtree::translator_type translator_type;
typedef typename Rtree::value_type value_type;
typedef typename Rtree::options_type options_type;
typedef typename Rtree::box_type box_type;
typedef typename Rtree::allocators_type allocators_type;
typedef typename Rtree::allocators_type allocators_type;
view(Rtree const& rt) : m_rtree(rt) {}

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,20 +16,29 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_CHILDREN_BOX_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_CHILDREN_BOX_HPP
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class children_box
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
public:
inline children_box(Box & result, Translator const& tr)
: m_result(result), m_tr(tr)
inline children_box(box_type & result,
parameters_type const& parameters,
translator_type const& tr)
: m_result(result), m_parameters(parameters), m_tr(tr)
{}
inline void operator()(internal_node const& n)
@@ -32,7 +46,8 @@ public:
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_result = rtree::elements_box<Box>(elements.begin(), elements.end(), m_tr);
m_result = rtree::elements_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
}
inline void operator()(leaf const& n)
@@ -40,12 +55,14 @@ public:
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_result = rtree::values_box<Box>(elements.begin(), elements.end(), m_tr);
m_result = rtree::values_box<box_type>(elements.begin(), elements.end(), m_tr,
index::detail::get_strategy(m_parameters));
}
private:
Box & m_result;
Translator const& m_tr;
box_type & m_result;
parameters_type const& m_parameters;
translator_type const& m_tr;
};
}}} // namespace detail::rtree::visitors

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,30 +15,34 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COPY_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COPY_HPP
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class copy
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
typedef typename allocators_type::node_pointer node_pointer;
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
explicit inline copy(Allocators & allocators)
explicit inline copy(allocators_type & allocators)
: result(0)
, m_allocators(allocators)
{}
inline void operator()(internal_node & n)
{
node_pointer raw_new_node = rtree::create_node<Allocators, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_pointer raw_new_node = rtree::create_node<allocators_type, internal_node>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<internal_node>::type elements_type;
@@ -45,7 +53,7 @@ public:
for (typename elements_type::iterator it = elements.begin();
it != elements.end(); ++it)
{
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::apply_visitor(*this, *it->second); // MAY THROW (V, E: alloc, copy, N: alloc)
// for exception safety
subtree_destroyer auto_result(result, m_allocators);
@@ -61,7 +69,7 @@ public:
inline void operator()(leaf & l)
{
node_pointer raw_new_node = rtree::create_node<Allocators, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
node_pointer raw_new_node = rtree::create_node<allocators_type, leaf>::apply(m_allocators); // MAY THROW, STRONG (N: alloc)
subtree_destroyer new_node(raw_new_node, m_allocators);
typedef typename rtree::elements_type<leaf>::type elements_type;
@@ -82,7 +90,7 @@ public:
node_pointer result;
private:
Allocators & m_allocators;
allocators_type & m_allocators;
};
}}} // namespace detail::rtree::visitors

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +16,12 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP
#include <boost/geometry/index/equal_to.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
#include <boost/geometry/index/parameters.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
@@ -23,10 +34,10 @@ struct count_helper
{
return i;
}
template <typename Translator>
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr)
template <typename Translator, typename Strategy>
static inline bool equals(Indexable const& i, Value const& v, Translator const& tr, Strategy const& s)
{
return geometry::equals(i, tr(v));
return index::detail::equals<Indexable>::apply(i, tr(v), s);
}
};
@@ -38,25 +49,29 @@ struct count_helper<Value, Value>
{
return tr(v);
}
template <typename Translator>
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr)
template <typename Translator, typename Strategy>
static inline bool equals(Value const& v1, Value const& v2, Translator const& tr, Strategy const& s)
{
return tr.equals(v1, v2);
return tr.equals(v1, v2, s);
}
};
template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename ValueOrIndexable, typename MembersHolder>
struct count
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
: public MembersHolder::visitor_const
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef count_helper<ValueOrIndexable, Value> count_help;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline count(ValueOrIndexable const& vori, Translator const& t)
: value_or_indexable(vori), tr(t), found_count(0)
typedef count_helper<ValueOrIndexable, value_type> count_help;
inline count(ValueOrIndexable const& vori, parameters_type const& parameters, translator_type const& t)
: value_or_indexable(vori), m_parameters(parameters), tr(t), found_count(0)
{}
inline void operator()(internal_node const& n)
@@ -68,10 +83,9 @@ struct count
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
if ( geometry::covered_by(
return_ref_or_bounds(
count_help::indexable(value_or_indexable, tr)),
it->first) )
if ( index::detail::covered_by_bounds(count_help::indexable(value_or_indexable, tr),
it->first,
index::detail::get_strategy(m_parameters)) )
{
rtree::apply_visitor(*this, *it->second);
}
@@ -88,7 +102,8 @@ struct count
it != elements.end(); ++it)
{
// if value meets predicates
if ( count_help::equals(value_or_indexable, *it, tr) )
if ( count_help::equals(value_or_indexable, *it, tr,
index::detail::get_strategy(m_parameters)) )
{
++found_count;
}
@@ -96,8 +111,9 @@ struct count
}
ValueOrIndexable const& value_or_indexable;
Translator const& tr;
typename Allocators::size_type found_count;
parameters_type const& m_parameters;
translator_type const& tr;
typename MembersHolder::size_type found_count;
};
}}} // namespace detail::rtree::visitors

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,23 +16,28 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DELETE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_DELETE_HPP
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class destroy
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::node_pointer node_pointer;
inline destroy(node_pointer root_node, Allocators & allocators)
: m_current_node(root_node)
inline destroy(node_pointer node, allocators_type & allocators)
: m_current_node(node)
, m_allocators(allocators)
{}
@@ -48,7 +58,7 @@ public:
it->second = 0;
}
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, node_to_destroy);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, node_to_destroy);
}
inline void operator()(leaf & l)
@@ -56,12 +66,18 @@ public:
boost::ignore_unused(l);
BOOST_GEOMETRY_INDEX_ASSERT(&l == &rtree::get<leaf>(*m_current_node), "invalid pointers");
rtree::destroy_node<Allocators, leaf>::apply(m_allocators, m_current_node);
rtree::destroy_node<allocators_type, leaf>::apply(m_allocators, m_current_node);
}
static inline void apply(node_pointer node, allocators_type & allocators)
{
destroy v(node, allocators);
rtree::apply_visitor(v, *node);
}
private:
node_pointer m_current_node;
Allocators & m_allocators;
allocators_type & m_allocators;
};
}}} // namespace detail::rtree::visitors

View File

@@ -2,7 +2,12 @@
//
// R-tree inserting visitor implementation
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -11,39 +16,53 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_INSERT_HPP
#include <boost/type_traits/is_same.hpp>
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
#include <type_traits>
#endif
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/algorithms/content.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/util/condition.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree {
// Default choose_next_node
template <typename Value, typename Options, typename Box, typename Allocators, typename ChooseNextNodeTag>
template
<
typename MembersHolder,
typename ChooseNextNodeTag = typename MembersHolder::options_type::choose_next_node_tag
>
class choose_next_node;
template <typename Value, typename Options, typename Box, typename Allocators>
class choose_next_node<Value, Options, Box, Allocators, choose_by_content_diff_tag>
template <typename MembersHolder>
class choose_next_node<MembersHolder, choose_by_content_diff_tag>
{
public:
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename rtree::elements_type<internal_node>::type children_type;
typedef typename index::detail::default_content_result<Box>::type content_type;
typedef typename index::detail::default_content_result<box_type>::type content_type;
template <typename Indexable>
static inline size_t apply(internal_node & n,
Indexable const& indexable,
parameters_type const& /*parameters*/,
parameters_type const& parameters,
size_t /*node_relative_level*/)
{
children_type & children = rtree::elements(n);
@@ -64,8 +83,9 @@ public:
child_type const& ch_i = children[i];
// expanded child node's box
Box box_exp(ch_i.first);
geometry::expand(box_exp, indexable);
box_type box_exp(ch_i.first);
index::detail::expand(box_exp, indexable,
index::detail::get_strategy(parameters));
// areas difference
content_type content = index::detail::content(box_exp);
@@ -88,39 +108,49 @@ public:
// ----------------------------------------------------------------------- //
// Not implemented here
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename RedistributeTag>
template
<
typename MembersHolder,
typename RedistributeTag = typename MembersHolder::options_type::redistribute_tag
>
struct redistribute_elements
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_REDISTRIBUTE_TAG_TYPE,
(redistribute_elements));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this RedistributeTag type.",
MembersHolder, RedistributeTag);
};
// ----------------------------------------------------------------------- //
// Split algorithm
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename SplitTag>
template
<
typename MembersHolder,
typename SplitTag = typename MembersHolder::options_type::split_tag
>
class split
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_SPLIT_TAG_TYPE,
(split));
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this SplitTag type.",
MembersHolder, SplitTag);
};
// Default split algorithm
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class split<Value, Options, Translator, Box, Allocators, split_default_tag>
template <typename MembersHolder>
class split<MembersHolder, split_default_tag>
{
protected:
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename MembersHolder::size_type size_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename MembersHolder::node_pointer node_pointer;
public:
typedef index::detail::varray<
@@ -131,51 +161,63 @@ public:
template <typename Node>
static inline void apply(nodes_container_type & additional_nodes,
Node & n,
Box & n_box,
box_type & n_box,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
{
// TODO - consider creating nodes always with sufficient memory allocated
// create additional node, use auto destroyer for automatic destruction on exception
subtree_destroyer second_node(rtree::create_node<Allocators, Node>::apply(allocators), allocators); // MAY THROW, STRONG (N: alloc)
node_pointer n2_ptr = rtree::create_node<allocators_type, Node>::apply(allocators); // MAY THROW, STRONG (N: alloc)
// create reference to the newly created node
Node & n2 = rtree::get<Node>(*second_node);
Node & n2 = rtree::get<Node>(*n2_ptr);
// NOTE: thread-safety
// After throwing an exception by redistribute_elements the original node may be not changed or
// both nodes may be empty. In both cases the tree won't be valid r-tree.
// The alternative is to create 2 (or more) additional nodes here and store backup info
// in the original node, then, if exception was thrown, the node would always have more than max
// elements.
// The alternative is to use moving semantics in the implementations of redistribute_elements,
// it will be possible to throw from boost::move() in the case of e.g. static size nodes.
BOOST_TRY
{
// NOTE: thread-safety
// After throwing an exception by redistribute_elements the original node may be not changed or
// both nodes may be empty. In both cases the tree won't be valid r-tree.
// The alternative is to create 2 (or more) additional nodes here and store backup info
// in the original node, then, if exception was thrown, the node would always have more than max
// elements.
// The alternative is to use moving semantics in the implementations of redistribute_elements,
// it will be possible to throw from std::move() in the case of e.g. static size nodes.
// redistribute elements
Box box2;
redistribute_elements<
Value,
Options,
Translator,
Box,
Allocators,
typename Options::redistribute_tag
>::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy)
// redistribute elements
box_type box2;
redistribute_elements<MembersHolder>
::apply(n, n2, n_box, box2, parameters, translator, allocators); // MAY THROW (V, E: alloc, copy, copy)
// check numbers of elements
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() &&
rtree::elements(n).size() <= parameters.get_max_elements(),
"unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() &&
rtree::elements(n2).size() <= parameters.get_max_elements(),
"unexpected number of elements");
// check numbers of elements
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n).size() &&
rtree::elements(n).size() <= parameters.get_max_elements(),
"unexpected number of elements");
BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= rtree::elements(n2).size() &&
rtree::elements(n2).size() <= parameters.get_max_elements(),
"unexpected number of elements");
// return the list of newly created nodes (this algorithm returns one)
additional_nodes.push_back(rtree::make_ptr_pair(box2, second_node.get())); // MAY THROW, STRONG (alloc, copy)
// return the list of newly created nodes (this algorithm returns one)
additional_nodes.push_back(rtree::make_ptr_pair(box2, n2_ptr)); // MAY THROW, STRONG (alloc, copy)
}
BOOST_CATCH(...)
{
// NOTE: This code is here to prevent leaving the rtree in a state
// after an exception is thrown in which pushing new element could
// result in assert or putting it outside the memory of node elements.
typename rtree::elements_type<Node>::type & elements = rtree::elements(n);
size_type const max_size = parameters.get_max_elements();
if (elements.size() > max_size)
{
rtree::destroy_element<MembersHolder>::apply(elements[max_size], allocators);
elements.pop_back();
}
// release the ptr
second_node.release();
rtree::visitors::destroy<MembersHolder>::apply(n2_ptr, allocators);
BOOST_RETHROW
}
BOOST_CATCH_END
}
};
@@ -226,30 +268,34 @@ struct insert_traverse_data
};
// Default insert visitor
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename Element, typename MembersHolder>
class insert
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
protected:
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
//typedef typename Allocators::internal_node_pointer internal_node_pointer;
//typedef typename allocators_type::internal_node_pointer internal_node_pointer;
typedef internal_node * internal_node_pointer;
inline insert(node_pointer & root,
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level = 0
)
: m_element(element)
@@ -274,17 +320,19 @@ protected:
// NOTE: This is actually only needed because conditionally the bounding
// object may be expanded below. Otherwise the indexable could be
// directly used instead
index::detail::bounds(rtree::element_indexable(m_element, m_translator), m_element_bounds);
index::detail::bounds(rtree::element_indexable(m_element, m_translator),
m_element_bounds,
index::detail::get_strategy(m_parameters));
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
// Enlarge it in case if it's not bounding geometry type.
// It's because Points and Segments are compared WRT machine epsilon
// This ensures that leafs bounds correspond to the stored elements
if (BOOST_GEOMETRY_CONDITION((
boost::is_same<Element, Value>::value
std::is_same<Element, value_type>::value
&& ! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )) )
{
geometry::detail::expand_by_epsilon(m_element_bounds);
@@ -296,14 +344,16 @@ protected:
inline void traverse(Visitor & visitor, internal_node & n)
{
// choose next node
size_t choosen_node_index = rtree::choose_next_node<Value, Options, Box, Allocators, typename Options::choose_next_node_tag>::
apply(n, rtree::element_indexable(m_element, m_translator), m_parameters, m_leafs_level - m_traverse_data.current_level);
size_t choosen_node_index = rtree::choose_next_node<MembersHolder>
::apply(n, rtree::element_indexable(m_element, m_translator),
m_parameters,
m_leafs_level - m_traverse_data.current_level);
// expand the node to contain value
geometry::expand(
index::detail::expand(
rtree::elements(n)[choosen_node_index].first,
m_element_bounds
/*rtree::element_indexable(m_element, m_translator)*/);
m_element_bounds,
index::detail::get_strategy(m_parameters));
// next traversing step
traverse_apply_visitor(visitor, n, choosen_node_index); // MAY THROW (V, E: alloc, copy, N:alloc)
@@ -349,10 +399,10 @@ protected:
template <typename Node>
inline void split(Node & n) const
{
typedef rtree::split<Value, Options, Translator, Box, Allocators, typename Options::split_tag> split_algo;
typedef rtree::split<MembersHolder> split_algo;
typename split_algo::nodes_container_type additional_nodes;
Box n_box;
box_type n_box;
split_algo::apply(additional_nodes, n, n_box, m_parameters, m_translator, m_allocators); // MAY THROW (V, E: alloc, copy, N:alloc)
@@ -376,10 +426,10 @@ protected:
// It's because Points and Segments are compared WRT machine epsilon
// This ensures that leafs' bounds correspond to the stored elements.
if (BOOST_GEOMETRY_CONDITION((
boost::is_same<Node, leaf>::value
std::is_same<Node, leaf>::value
&& ! index::detail::is_bounding_geometry
<
typename indexable_type<Translator>::type
typename indexable_type<translator_type>::type
>::value )))
{
geometry::detail::expand_by_epsilon(n_box);
@@ -401,7 +451,7 @@ protected:
BOOST_GEOMETRY_INDEX_ASSERT(&n == &rtree::get<Node>(*m_root_node), "node should be the root");
// create new root and add nodes
subtree_destroyer new_root(rtree::create_node<Allocators, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
subtree_destroyer new_root(rtree::create_node<allocators_type, internal_node>::apply(m_allocators), m_allocators); // MAY THROW, STRONG (N:alloc)
BOOST_TRY
{
@@ -428,9 +478,9 @@ protected:
// TODO: awulkiew - implement dispatchable split::apply to enable additional nodes creation
Element const& m_element;
Box m_element_bounds;
box_type m_element_bounds;
parameters_type const& m_parameters;
Translator const& m_translator;
translator_type const& m_translator;
size_type const m_relative_level;
size_type const m_level;
@@ -440,30 +490,39 @@ protected:
// traversing input parameters
insert_traverse_data<internal_node, internal_node_pointer, size_type> m_traverse_data;
Allocators & m_allocators;
allocators_type & m_allocators;
};
} // namespace detail
// Insert visitor forward declaration
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename InsertTag>
template
<
typename Element,
typename MembersHolder,
typename InsertTag = typename MembersHolder::options_type::insert_tag
>
class insert;
// Default insert visitor used for nodes elements
// After passing the Element to insert visitor the Element is managed by the tree
// I.e. one should not delete the node passed to the insert visitor after exception is thrown
// because this visitor may delete it
template <typename Element, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Element, Value, Options, Translator, Box, Allocators, insert_default_tag>
: public detail::insert<Element, Value, Options, Translator, Box, Allocators>
template <typename Element, typename MembersHolder>
class insert<Element, MembersHolder, insert_default_tag>
: public detail::insert<Element, MembersHolder>
{
public:
typedef detail::insert<Element, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<Element, MembersHolder> base;
typedef typename base::parameters_type parameters_type;
typedef typename base::translator_type translator_type;
typedef typename base::allocators_type allocators_type;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename base::node_pointer node_pointer;
typedef typename base::size_type size_type;
@@ -471,8 +530,8 @@ public:
size_type & leafs_level,
Element const& element,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level = 0
)
: base(root, leafs_level, element, parameters, translator, allocators, relative_level)
@@ -500,8 +559,7 @@ public:
{
// if the insert fails above, the element won't be stored in the tree
rtree::visitors::destroy<Value, Options, Translator, Box, Allocators> del_v(base::m_element.second, base::m_allocators);
rtree::apply_visitor(del_v, *base::m_element.second);
rtree::visitors::destroy<MembersHolder>::apply(base::m_element.second, base::m_allocators);
BOOST_RETHROW // RETHROW
}
@@ -518,26 +576,31 @@ public:
};
// Default insert visitor specialized for Values elements
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
class insert<Value, Value, Options, Translator, Box, Allocators, insert_default_tag>
: public detail::insert<Value, Value, Options, Translator, Box, Allocators>
template <typename MembersHolder>
class insert<typename MembersHolder::value_type, MembersHolder, insert_default_tag>
: public detail::insert<typename MembersHolder::value_type, MembersHolder>
{
public:
typedef detail::insert<Value, Value, Options, Translator, Box, Allocators> base;
typedef detail::insert<typename MembersHolder::value_type, MembersHolder> base;
typedef typename base::value_type value_type;
typedef typename base::parameters_type parameters_type;
typedef typename base::translator_type translator_type;
typedef typename base::allocators_type allocators_type;
typedef typename base::node node;
typedef typename base::internal_node internal_node;
typedef typename base::leaf leaf;
typedef typename Options::parameters_type parameters_type;
typedef typename base::node_pointer node_pointer;
typedef typename base::size_type size_type;
inline insert(node_pointer & root,
size_type & leafs_level,
Value const& value,
value_type const& value,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators,
translator_type const& translator,
allocators_type & allocators,
size_type relative_level = 0
)
: base(root, leafs_level, value, parameters, translator, allocators, relative_level)
@@ -559,7 +622,7 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT(base::m_traverse_data.current_level == base::m_leafs_level, "unexpected level");
BOOST_GEOMETRY_INDEX_ASSERT(base::m_level == base::m_traverse_data.current_level ||
base::m_level == (std::numeric_limits<size_t>::max)(), "unexpected level");
rtree::elements(n).push_back(base::m_element); // MAY THROW, STRONG (V: alloc, copy)
base::post_traverse(n); // MAY THROW (V: alloc, copy, N: alloc)

View File

@@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -15,11 +19,12 @@ namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Box, typename Allocators>
struct is_leaf : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
template <typename MembersHolder>
struct is_leaf
: public MembersHolder::visitor_const
{
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
is_leaf()
: result(false)

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +16,10 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_ITERATOR_HPP
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,28 +16,39 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_REMOVE_HPP
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/algorithms/detail/covered_by/interface.hpp>
#include <boost/geometry/index/parameters.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/rtree/node/node.hpp>
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
// Default remove algorithm
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class remove
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, false>::type
: public MembersHolder::visitor
{
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::box_type box_type;
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename rtree::node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::node_pointer node_pointer;
typedef typename Allocators::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
typedef typename rtree::elements_type<internal_node>::type::size_type internal_size_type;
@@ -42,10 +58,10 @@ class remove
public:
inline remove(node_pointer & root,
size_type & leafs_level,
Value const& value,
value_type const& value,
parameters_type const& parameters,
Translator const& translator,
Allocators & allocators)
translator_type const& translator,
allocators_type & allocators)
: m_value(value)
, m_parameters(parameters)
, m_translator(translator)
@@ -71,9 +87,9 @@ public:
internal_size_type child_node_index = 0;
for ( ; child_node_index < children.size() ; ++child_node_index )
{
if ( geometry::covered_by(
return_ref_or_bounds(m_translator(m_value)),
children[child_node_index].first) )
if ( index::detail::covered_by_bounds(m_translator(m_value),
children[child_node_index].first,
index::detail::get_strategy(m_parameters)) )
{
// next traversing step
traverse_apply_visitor(n, child_node_index); // MAY THROW
@@ -112,7 +128,8 @@ public:
BOOST_GEOMETRY_INDEX_ASSERT((elements.size() < m_parameters.get_min_elements()) == m_is_underflow, "unexpected state");
rtree::elements(*m_parent)[m_current_child_index].first
= rtree::elements_box<Box>(elements.begin(), elements.end(), m_translator);
= rtree::elements_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
// n is root node
else
@@ -135,7 +152,7 @@ public:
m_root_node = rtree::elements(n)[0].second;
--m_leafs_level;
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, root_to_destroy);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, root_to_destroy);
}
}
}
@@ -149,7 +166,7 @@ public:
// find value and remove it
for ( typename elements_type::iterator it = elements.begin() ; it != elements.end() ; ++it )
{
if ( m_translator.equals(*it, m_value) )
if ( m_translator.equals(*it, m_value, index::detail::get_strategy(m_parameters)) )
{
rtree::move_from_back(elements, it); // MAY THROW (V: copy)
elements.pop_back();
@@ -170,7 +187,8 @@ public:
if ( 0 != m_parent )
{
rtree::elements(*m_parent)[m_current_child_index].first
= rtree::values_box<Box>(elements.begin(), elements.end(), m_translator);
= rtree::values_box<box_type>(elements.begin(), elements.end(), m_translator,
index::detail::get_strategy(m_parameters));
}
}
}
@@ -182,7 +200,7 @@ public:
private:
typedef std::vector< std::pair<size_type, node_pointer> > UnderflowNodes;
typedef std::vector< std::pair<size_type, node_pointer> > underflow_nodes;
void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index)
{
@@ -233,14 +251,14 @@ private:
static inline bool is_leaf(node const& n)
{
visitors::is_leaf<Value, Options, Box, Allocators> ilv;
visitors::is_leaf<MembersHolder> ilv;
rtree::apply_visitor(ilv, n);
return ilv.result;
}
void reinsert_removed_nodes_elements()
{
typename UnderflowNodes::reverse_iterator it = m_underflowed_nodes.rbegin();
typename underflow_nodes::reverse_iterator it = m_underflowed_nodes.rbegin();
BOOST_TRY
{
@@ -256,13 +274,13 @@ private:
{
reinsert_node_elements(rtree::get<leaf>(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::destroy_node<Allocators, leaf>::apply(m_allocators, it->second);
rtree::destroy_node<allocators_type, leaf>::apply(m_allocators, it->second);
}
else
{
reinsert_node_elements(rtree::get<internal_node>(*it->second), it->first); // MAY THROW (V, E: alloc, copy, N: alloc)
rtree::destroy_node<Allocators, internal_node>::apply(m_allocators, it->second);
rtree::destroy_node<allocators_type, internal_node>::apply(m_allocators, it->second);
}
}
@@ -273,7 +291,7 @@ private:
// destroy current and remaining nodes
for ( ; it != m_underflowed_nodes.rend() ; ++it )
{
subtree_destroyer dummy(it->second, m_allocators);
rtree::visitors::destroy<MembersHolder>::apply(it->second, m_allocators);
}
//m_underflowed_nodes.clear();
@@ -294,14 +312,10 @@ private:
{
for ( ; it != elements.end() ; ++it )
{
visitors::insert<
typename elements_type::value_type,
Value, Options, Translator, Box, Allocators,
typename Options::insert_tag
> insert_v(
m_root_node, m_leafs_level, *it,
m_parameters, m_translator, m_allocators,
node_relative_level - 1);
visitors::insert<typename elements_type::value_type, MembersHolder>
insert_v(m_root_node, m_leafs_level, *it,
m_parameters, m_translator, m_allocators,
node_relative_level - 1);
rtree::apply_visitor(insert_v, *m_root_node); // MAY THROW (V, E: alloc, copy, N: alloc)
}
@@ -309,24 +323,23 @@ private:
BOOST_CATCH(...)
{
++it;
rtree::destroy_elements<Value, Options, Translator, Box, Allocators>
::apply(it, elements.end(), m_allocators);
rtree::destroy_elements<MembersHolder>::apply(it, elements.end(), m_allocators);
elements.clear();
BOOST_RETHROW // RETHROW
}
BOOST_CATCH_END
}
Value const& m_value;
value_type const& m_value;
parameters_type const& m_parameters;
Translator const& m_translator;
Allocators & m_allocators;
translator_type const& m_translator;
allocators_type & m_allocators;
node_pointer & m_root_node;
size_type & m_leafs_level;
bool m_is_value_removed;
UnderflowNodes m_underflowed_nodes;
underflow_nodes m_underflowed_nodes;
// traversing input parameters
internal_node_pointer m_parent;

View File

@@ -4,6 +4,11 @@
//
// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2023.
// Modifications copyright (c) 2019-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -11,116 +16,145 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_SPATIAL_QUERY_HPP
#include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
#include <boost/geometry/index/detail/rtree/node/weak_visitor.hpp>
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/parameters.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates, typename OutIter>
template <typename MembersHolder, typename Predicates, typename OutIter>
struct spatial_query
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Allocators::size_type size_type;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
inline spatial_query(Translator const& t, Predicates const& p, OutIter out_it)
: tr(t), pred(p), out_iter(out_it), found_count(0)
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
spatial_query(MembersHolder const& members, Predicates const& p, OutIter out_it)
: m_tr(members.translator())
, m_strategy(index::detail::get_strategy(members.parameters()))
, m_pred(p)
, m_out_iter(out_it)
, m_found_count(0)
{}
inline void operator()(internal_node const& n)
size_type apply(node_pointer ptr, size_type reverse_level)
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
// traverse nodes meeting predicates
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
namespace id = index::detail;
if (reverse_level > 0)
{
// if node meets predicates
// 0 - dummy value
if ( index::detail::predicates_check<index::detail::bounds_tag, 0, predicates_len>(pred, 0, it->first) )
rtree::apply_visitor(*this, *it->second);
}
}
inline void operator()(leaf const& n)
{
typedef typename rtree::elements_type<leaf>::type elements_type;
elements_type const& elements = rtree::elements(n);
// get all values meeting predicates
for (typename elements_type::const_iterator it = elements.begin();
it != elements.end(); ++it)
{
// if value meets predicates
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(pred, *it, tr(*it)) )
internal_node& n = rtree::get<internal_node>(*ptr);
// traverse nodes meeting predicates
for (auto const& p : rtree::elements(n))
{
*out_iter = *it;
++out_iter;
++found_count;
// if node meets predicates (0 is dummy value)
if (id::predicates_check<id::bounds_tag>(m_pred, 0, p.first, m_strategy))
{
apply(p.second, reverse_level - 1);
}
}
}
else
{
leaf& n = rtree::get<leaf>(*ptr);
// get all values meeting predicates
for (auto const& v : rtree::elements(n))
{
// if value meets predicates
if (id::predicates_check<id::value_tag>(m_pred, v, m_tr(v), m_strategy))
{
*m_out_iter = v;
++m_out_iter;
++m_found_count;
}
}
}
return m_found_count;
}
Translator const& tr;
size_type apply(MembersHolder const& members)
{
return apply(members.root, members.leafs_level);
}
Predicates pred;
private:
translator_type const& m_tr;
strategy_type m_strategy;
OutIter out_iter;
size_type found_count;
Predicates const& m_pred;
OutIter m_out_iter;
size_type m_found_count;
};
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators, typename Predicates>
template <typename MembersHolder, typename Predicates>
class spatial_query_incremental
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
{
public:
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::value_type value_type;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Allocators::size_type size_type;
typedef typename Allocators::const_reference const_reference;
typedef typename Allocators::node_pointer node_pointer;
typedef typename index::detail::strategy_type<parameters_type>::type strategy_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename allocators_type::size_type size_type;
typedef typename allocators_type::const_reference const_reference;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename rtree::elements_type<internal_node>::type::const_iterator internal_iterator;
typedef typename rtree::elements_type<leaf>::type leaf_elements;
typedef typename rtree::elements_type<leaf>::type::const_iterator leaf_iterator;
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::value;
struct internal_data
{
internal_data(internal_iterator f, internal_iterator l, size_type rl)
: first(f), last(l), reverse_level(rl)
{}
internal_iterator first;
internal_iterator last;
size_type reverse_level;
};
inline spatial_query_incremental()
: m_translator(NULL)
public:
spatial_query_incremental()
: m_translator(nullptr)
// , m_strategy()
// , m_pred()
, m_values(NULL)
, m_values(nullptr)
, m_current()
{}
inline spatial_query_incremental(Translator const& t, Predicates const& p)
: m_translator(::boost::addressof(t))
spatial_query_incremental(Predicates const& p)
: m_translator(nullptr)
// , m_strategy()
, m_pred(p)
, m_values(NULL)
, m_values(nullptr)
, m_current()
{}
inline void operator()(internal_node const& n)
{
typedef typename rtree::elements_type<internal_node>::type elements_type;
elements_type const& elements = rtree::elements(n);
m_internal_stack.push_back(std::make_pair(elements.begin(), elements.end()));
}
inline void operator()(leaf const& n)
{
m_values = ::boost::addressof(rtree::elements(n));
m_current = rtree::elements(n).begin();
}
spatial_query_incremental(MembersHolder const& members, Predicates const& p)
: m_translator(::boost::addressof(members.translator()))
, m_strategy(index::detail::get_strategy(members.parameters()))
, m_pred(p)
, m_values(nullptr)
, m_current()
{}
const_reference dereference() const
{
@@ -128,9 +162,9 @@ public:
return *m_current;
}
void initialize(node_pointer root)
void initialize(MembersHolder const& members)
{
rtree::apply_visitor(*this, *root);
apply(members.root, members.leafs_level);
search_value();
}
@@ -140,8 +174,38 @@ public:
search_value();
}
bool is_end() const
{
return 0 == m_values;
}
friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r)
{
return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current);
}
private:
void apply(node_pointer ptr, size_type reverse_level)
{
namespace id = index::detail;
if (reverse_level > 0)
{
internal_node& n = rtree::get<internal_node>(*ptr);
auto const& elements = rtree::elements(n);
m_internal_stack.push_back(internal_data(elements.begin(), elements.end(), reverse_level - 1));
}
else
{
leaf& n = rtree::get<leaf>(*ptr);
m_values = ::boost::addressof(rtree::elements(n));
m_current = rtree::elements(n).begin();
}
}
void search_value()
{
namespace id = index::detail;
for (;;)
{
// if leaf is choosen, move to the next value in leaf
@@ -150,9 +214,11 @@ public:
if ( m_current != m_values->end() )
{
// return if next value is found
Value const& v = *m_current;
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(m_pred, v, (*m_translator)(v)) )
value_type const& v = *m_current;
if (id::predicates_check<id::value_tag>(m_pred, v, (*m_translator)(v), m_strategy))
{
return;
}
++m_current;
}
@@ -166,43 +232,38 @@ public:
else
{
// return if there is no more nodes to traverse
if ( m_internal_stack.empty() )
if (m_internal_stack.empty())
{
return;
}
internal_data& current_data = m_internal_stack.back();
// no more children in current node, remove it from stack
if ( m_internal_stack.back().first == m_internal_stack.back().second )
if (current_data.first == current_data.last)
{
m_internal_stack.pop_back();
continue;
}
internal_iterator it = m_internal_stack.back().first;
++m_internal_stack.back().first;
internal_iterator it = current_data.first;
++current_data.first;
// next node is found, push it to the stack
if ( index::detail::predicates_check<index::detail::bounds_tag, 0, predicates_len>(m_pred, 0, it->first) )
rtree::apply_visitor(*this, *(it->second));
if (id::predicates_check<id::bounds_tag>(m_pred, 0, it->first, m_strategy))
{
apply(it->second, current_data.reverse_level);
}
}
}
}
bool is_end() const
{
return 0 == m_values;
}
friend bool operator==(spatial_query_incremental const& l, spatial_query_incremental const& r)
{
return (l.m_values == r.m_values) && (0 == l.m_values || l.m_current == r.m_current );
}
private:
const Translator * m_translator;
const translator_type * m_translator;
strategy_type m_strategy;
Predicates m_pred;
std::vector< std::pair<internal_iterator, internal_iterator> > m_internal_stack;
std::vector<internal_data> m_internal_stack;
const leaf_elements * m_values;
leaf_iterator m_current;
};

View File

@@ -1,6 +1,11 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2021-2023.
// Modifications copyright (c) 2021-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,10 +14,20 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_SERIALIZATION_HPP
//#include <boost/serialization/serialization.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/version.hpp>
//#include <boost/serialization/nvp.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/parameters.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp>
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
// TODO
// how about using the unsigned type capable of storing Max in compile-time versions?
@@ -26,9 +41,15 @@
// each geometry save without this info
// TODO - move to index/detail/serialization.hpp
namespace boost { namespace geometry { namespace index { namespace detail {
namespace boost { namespace geometry { namespace index {
// TODO - use boost::move?
// Forward declaration
template <typename Value, typename Options, typename IndexableGetter, typename EqualTo, typename Allocator>
class rtree;
namespace detail {
// TODO - use std::move?
template<typename T>
class serialization_storage
{
@@ -57,7 +78,7 @@ private:
template <typename T, typename Archive> inline
T serialization_load(const char * name, Archive & ar)
{
namespace bs = boost::serialization;
namespace bs = boost::serialization;
serialization_storage<T> storage(ar, bs::version<T>::value); // load_construct_data
ar >> boost::serialization::make_nvp(name, *storage.address()); // serialize
//ar >> *storage.address(); // serialize
@@ -72,7 +93,7 @@ void serialization_save(T const& t, const char * name, Archive & ar)
ar << boost::serialization::make_nvp(name, t); // serialize
//ar << t; // serialize
}
}}}}
// TODO - move to index/serialization/rtree.hpp
@@ -343,22 +364,29 @@ private:
// TODO - move to index/detail/rtree/load.hpp
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
template <typename MembersHolder>
class load
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
typedef typename MembersHolder::parameters_type parameters_type;
typedef typename MembersHolder::translator_type translator_type;
typedef typename MembersHolder::allocators_type allocators_type;
typedef typename Options::parameters_type parameters_type;
typedef typename MembersHolder::node node;
typedef typename MembersHolder::internal_node internal_node;
typedef typename MembersHolder::leaf leaf;
typedef typename Allocators::node_pointer node_pointer;
typedef rtree::subtree_destroyer<Value, Options, Translator, Box, Allocators> subtree_destroyer;
typedef typename Allocators::size_type size_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef typename allocators_type::size_type size_type;
typedef rtree::subtree_destroyer<MembersHolder> subtree_destroyer;
public:
template <typename Archive> inline static
node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level, size_type & values_count, parameters_type const& parameters, Translator const& translator, Allocators & allocators)
node_pointer apply(Archive & ar, unsigned int version, size_type leafs_level,
size_type & values_count,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators)
{
values_count = 0;
return raw_apply(ar, version, leafs_level, values_count, parameters, translator, allocators);
@@ -366,7 +394,12 @@ public:
private:
template <typename Archive> inline static
node_pointer raw_apply(Archive & ar, unsigned int version, size_type leafs_level, size_type & values_count, parameters_type const& parameters, Translator const& translator, Allocators & allocators, size_type current_level = 0)
node_pointer raw_apply(Archive & ar, unsigned int version, size_type leafs_level,
size_type & values_count,
parameters_type const& parameters,
translator_type const& translator,
allocators_type & allocators,
size_type current_level = 0)
{
//BOOST_GEOMETRY_INDEX_ASSERT(current_level <= leafs_level, "invalid parameter");
@@ -379,13 +412,17 @@ private:
size_t elements_count;
ar >> boost::serialization::make_nvp("s", elements_count);
if ( elements_count < parameters.get_min_elements() || parameters.get_max_elements() < elements_count )
// root may contain count < min but shouldn't contain count > max
if ( (elements_count < parameters.get_min_elements() && current_level > 0)
|| parameters.get_max_elements() < elements_count )
{
BOOST_THROW_EXCEPTION(std::runtime_error("rtree loading error"));
}
if ( current_level < leafs_level )
{
node_pointer n = rtree::create_node<Allocators, internal_node>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
node_pointer n = rtree::create_node<allocators_type, internal_node>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
internal_node & in = rtree::get<internal_node>(*n);
elements_type & elements = rtree::elements(in);
@@ -407,7 +444,7 @@ private:
{
BOOST_GEOMETRY_INDEX_ASSERT(current_level == leafs_level, "unexpected value");
node_pointer n = rtree::create_node<Allocators, leaf>::apply(allocators); // MAY THROW (A)
node_pointer n = rtree::create_node<allocators_type, leaf>::apply(allocators); // MAY THROW (A)
subtree_destroyer auto_remover(n, allocators);
leaf & l = rtree::get<leaf>(*n);
@@ -446,7 +483,7 @@ public:
typedef typename Rtree::value_type value_type;
typedef typename Rtree::options_type options_type;
typedef typename Rtree::box_type box_type;
typedef typename Rtree::allocators_type allocators_type;
typedef typename Rtree::allocators_type allocators_type;
const_private_view(Rtree const& rt) : m_rtree(rt) {}
@@ -471,7 +508,7 @@ public:
typedef typename Rtree::value_type value_type;
typedef typename Rtree::options_type options_type;
typedef typename Rtree::box_type box_type;
typedef typename Rtree::allocators_type allocators_type;
typedef typename Rtree::allocators_type allocators_type;
private_view(Rtree & rt) : m_rtree(rt) {}
@@ -534,10 +571,11 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
typedef typename view::options_type options_type;
typedef typename view::box_type box_type;
typedef typename view::allocators_type allocators_type;
typedef typename view::members_holder members_holder;
typedef typename options_type::parameters_type parameters_type;
typedef typename allocators_type::node_pointer node_pointer;
typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
typedef detail::rtree::subtree_destroyer<members_holder> subtree_destroyer;
view tree(rt);
@@ -551,7 +589,7 @@ void load(Archive & ar, boost::geometry::index::rtree<V, P, I, E, A> & rt, unsig
if ( 0 < values_count )
{
size_type loaded_values_count = 0;
n = detail::rtree::load<value_type, options_type, translator_type, box_type, allocators_type>
n = detail::rtree::load<members_holder>
::apply(ar, version, leafs_level, loaded_values_count, params, tree.members().translator(), tree.members().allocators()); // MAY THROW
subtree_destroyer remover(n, tree.members().allocators());

View File

@@ -2,6 +2,10 @@
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019-2021.
// Modifications copyright (c) 2019-2021 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -9,10 +13,38 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_TRANSLATOR_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_TRANSLATOR_HPP
#include <type_traits>
#include <boost/geometry/strategies/default_strategy.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail {
template <typename Strategy>
struct translator_equals
{
template <typename EqualTo, typename Value>
static inline bool apply(EqualTo const& equal_to,
Value const& v1, Value const& v2,
Strategy const& strategy)
{
return equal_to(v1, v2, strategy);
}
};
template <>
struct translator_equals<default_strategy>
{
template <typename EqualTo, typename Value>
static inline bool apply(EqualTo const& equal_to,
Value const& v1, Value const& v2,
default_strategy const&)
{
return equal_to(v1, v2);
}
};
template <typename IndexableGetter, typename EqualTo>
struct translator
: public IndexableGetter
@@ -30,11 +62,14 @@ struct translator
return IndexableGetter::operator()(value);
}
template <typename Value>
bool equals(Value const& v1, Value const& v2) const
{
return EqualTo::operator()(v1, v2);
}
template <typename Value, typename Strategy>
bool equals(Value const& v1, Value const& v2, Strategy const& strategy) const
{
return translator_equals
<
Strategy
>::apply(static_cast<EqualTo const&>(*this), v1, v2, strategy);
}
};
template <typename IndexableGetter>
@@ -46,8 +81,8 @@ struct result_type
template <typename IndexableGetter>
struct indexable_type
{
typedef typename boost::remove_const<
typename boost::remove_reference<
typedef typename std::remove_const<
typename std::remove_reference<
typename result_type<IndexableGetter>::type
>::type
>::type type;

View File

@@ -1,204 +0,0 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_TUPLES_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_TUPLES_HPP
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_same.hpp>
// TODO move this to index/tuples and separate algorithms
namespace boost { namespace geometry { namespace index { namespace detail {
namespace tuples {
// find_index
namespace detail {
template <typename Tuple, typename El, size_t N>
struct find_index;
template <typename Tuple, typename El, size_t N, typename CurrentEl>
struct find_index_impl
{
static const size_t value = find_index<Tuple, El, N - 1>::value;
};
template <typename Tuple, typename El, size_t N>
struct find_index_impl<Tuple, El, N, El>
{
static const size_t value = N - 1;
};
template <typename Tuple, typename El, typename CurrentEl>
struct find_index_impl<Tuple, El, 1, CurrentEl>
{
BOOST_MPL_ASSERT_MSG(
(false),
ELEMENT_NOT_FOUND,
(find_index_impl));
};
template <typename Tuple, typename El>
struct find_index_impl<Tuple, El, 1, El>
{
static const size_t value = 0;
};
template <typename Tuple, typename El, size_t N>
struct find_index
{
static const size_t value =
find_index_impl<
Tuple,
El,
N,
typename boost::tuples::element<N - 1, Tuple>::type
>::value;
};
} // namespace detail
template <typename Tuple, typename El>
struct find_index
{
static const size_t value =
detail::find_index<
Tuple,
El,
boost::tuples::length<Tuple>::value
>::value;
};
// has
namespace detail {
template <typename Tuple, typename El, size_t N>
struct has
{
static const bool value
= boost::is_same<
typename boost::tuples::element<N - 1, Tuple>::type,
El
>::value
|| has<Tuple, El, N - 1>::value;
};
template <typename Tuple, typename El>
struct has<Tuple, El, 1>
{
static const bool value
= boost::is_same<
typename boost::tuples::element<0, Tuple>::type,
El
>::value;
};
} // namespace detail
template <typename Tuple, typename El>
struct has
{
static const bool value
= detail::has<
Tuple,
El,
boost::tuples::length<Tuple>::value
>::value;
};
// add
template <typename Tuple, typename El>
struct add
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TUPLE_TYPE,
(add));
};
template <typename T1, typename T>
struct add<boost::tuple<T1>, T>
{
typedef boost::tuple<T1, T> type;
};
template <typename T1, typename T2, typename T>
struct add<boost::tuple<T1, T2>, T>
{
typedef boost::tuple<T1, T2, T> type;
};
// add_if
template <typename Tuple, typename El, bool Cond>
struct add_if
{
typedef Tuple type;
};
template <typename Tuple, typename El>
struct add_if<Tuple, El, true>
{
typedef typename add<Tuple, El>::type type;
};
// add_unique
template <typename Tuple, typename El>
struct add_unique
{
typedef typename add_if<
Tuple,
El,
!has<Tuple, El>::value
>::type type;
};
template <typename Tuple,
typename T,
size_t I = 0,
size_t N = boost::tuples::length<Tuple>::value>
struct push_back
{
typedef
boost::tuples::cons<
typename boost::tuples::element<I, Tuple>::type,
typename push_back<Tuple, T, I+1, N>::type
> type;
static type apply(Tuple const& tup, T const& t)
{
return
type(
boost::get<I>(tup),
push_back<Tuple, T, I+1, N>::apply(tup, t)
);
}
};
template <typename Tuple, typename T, size_t N>
struct push_back<Tuple, T, N, N>
{
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
static type apply(Tuple const&, T const& t)
{
return type(t, boost::tuples::null_type());
}
};
} // namespace tuples
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_TAGS_HPP

View File

@@ -1,13 +1,18 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/swap.hpp>
//#include <boost/type_traits/is_empty.hpp>
#include <type_traits>
#include <boost/core/swap.hpp>
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_UTILITIES_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_UTILITIES_HPP
@@ -15,31 +20,31 @@
namespace boost { namespace geometry { namespace index { namespace detail {
template<class T>
static inline void assign_cond(T & l, T const& r, boost::mpl::bool_<true> const&)
static inline void assign_cond(T & l, T const& r, std::true_type)
{
l = r;
}
template<class T>
static inline void assign_cond(T &, T const&, boost::mpl::bool_<false> const&) {}
static inline void assign_cond(T &, T const&, std::false_type) {}
template<class T>
static inline void move_cond(T & l, T & r, boost::mpl::bool_<true> const&)
static inline void move_cond(T & l, T & r, std::true_type)
{
l = ::boost::move(r);
l = std::move(r);
}
template<class T>
static inline void move_cond(T &, T &, boost::mpl::bool_<false> const&) {}
static inline void move_cond(T &, T &, std::false_type) {}
template <typename T> inline
void swap_cond(T & l, T & r, boost::mpl::bool_<true> const&)
void swap_cond(T & l, T & r, std::true_type)
{
::boost::swap(l, r);
}
template <typename T> inline
void swap_cond(T &, T &, boost::mpl::bool_<false> const&) {}
void swap_cond(T &, T &, std::false_type) {}
}}}} // namespace boost::geometry::index::detail

View File

@@ -1,7 +1,11 @@
// Boost.Container varray
//
// Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2013 Andrew Hundt.
// Copyright (c) 2012-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,40 +18,34 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/concept_check.hpp>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/swap.hpp>
#include <boost/core/swap.hpp>
#include <boost/integer.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
// TODO - use std::reverse_iterator and std::iterator_traits
// instead Boost.Iterator to remove dependency?
// or boost/detail/iterator.hpp ?
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/index/detail/assert.hpp>
#include <boost/geometry/index/detail/exception.hpp>
#include <boost/geometry/index/detail/varray_detail.hpp>
#include <boost/concept_check.hpp>
/*!
\defgroup varray_non_member varray non-member functions
*/
namespace boost { namespace geometry { namespace index { namespace detail {
namespace varray_detail {
template <typename Value, std::size_t Capacity>
@@ -56,14 +54,14 @@ struct varray_traits
typedef Value value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef Value * pointer;
typedef const Value * const_pointer;
typedef Value & reference;
typedef const Value & const_reference;
typedef Value* pointer;
typedef const Value* const_pointer;
typedef Value& reference;
typedef const Value& const_reference;
typedef boost::false_type use_memop_in_swap_and_move;
typedef boost::false_type use_optimized_swap;
typedef boost::false_type disable_trivial_init;
typedef std::false_type use_memop_in_swap_and_move;
typedef std::false_type use_optimized_swap;
typedef std::false_type disable_trivial_init;
};
template <typename Varray>
@@ -97,7 +95,7 @@ struct checker
static inline void check_not_empty(Varray const& v)
{
BOOST_GEOMETRY_INDEX_ASSERT(!v.empty(), "the container is empty");
::boost::ignore_unused(v);
}
@@ -125,12 +123,12 @@ varray is a sequence container like boost::container::vector with contiguous sto
change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
A varray is a sequence that supports random access to elements, constant time insertion and
removal of elements at the end, and linear time insertion and removal of elements at the beginning or
removal of elements at the end, and linear time insertion and removal of elements at the beginning or
in the middle. The number of elements in a varray may vary dynamically up to a fixed capacity
because elements are stored within the object itself similarly to an array. However, objects are
because elements are stored within the object itself similarly to an array. However, objects are
initialized as they are inserted into varray unlike C arrays or std::array which must construct
all elements on instantiation. The behavior of varray enables the use of statically allocated
elements in cases with complex object lifetime requirements that would otherwise not be trivially
elements in cases with complex object lifetime requirements that would otherwise not be trivially
possible.
\par Error Handling
@@ -155,11 +153,11 @@ class varray
typedef varray_detail::varray_traits<Value, Capacity> vt;
typedef varray_detail::checker<varray> errh;
BOOST_MPL_ASSERT_MSG(
( boost::is_unsigned<typename vt::size_type>::value &&
BOOST_GEOMETRY_STATIC_ASSERT(
( std::is_unsigned<typename vt::size_type>::value &&
sizeof(typename boost::uint_value_t<Capacity>::least) <= sizeof(typename vt::size_type) ),
SIZE_TYPE_IS_TOO_SMALL_FOR_SPECIFIED_CAPACITY,
(varray)
"Size type is too small for specified capacity.",
typename vt::size_type, std::integral_constant<std::size_t, Capacity>
);
typedef boost::aligned_storage<
@@ -170,19 +168,6 @@ class varray
template <typename V, std::size_t C>
friend class varray;
BOOST_COPYABLE_AND_MOVABLE(varray)
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
public:
template <std::size_t C>
varray & operator=(varray<Value, C> & sv)
{
typedef varray<Value, C> other;
this->operator=(static_cast<const ::boost::rv<other> &>(const_cast<const other &>(sv)));
return *this;
}
#endif
public:
//! @brief The type of elements stored in the container.
typedef typename vt::value_type value_type;
@@ -282,7 +267,7 @@ public:
: m_size(0)
{
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
this->assign(first, last); // may throw
}
@@ -321,7 +306,7 @@ public:
: m_size(other.size())
{
errh::check_capacity(*this, other.size()); // may throw
namespace sv = varray_detail;
sv::uninitialized_copy(other.begin(), other.end(), this->begin()); // may throw
}
@@ -335,7 +320,7 @@ public:
//!
//! @par Complexity
//! Linear O(N).
varray & operator=(BOOST_COPY_ASSIGN_REF(varray) other)
varray& operator=(varray const& other)
{
this->assign(other.begin(), other.end()); // may throw
@@ -357,7 +342,7 @@ public:
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
varray & operator=(BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(varray, value_type, C) other)
varray& operator=(varray<value_type, C> const& other)
{
this->assign(other.begin(), other.end()); // may throw
@@ -369,15 +354,15 @@ public:
//! @param other The varray which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor throws.
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
//! @endinternal
//!
//! @par Complexity
//! Linear O(N).
varray(BOOST_RV_REF(varray) other)
varray(varray&& other)
{
typedef typename
vt::use_memop_in_swap_and_move use_memop_in_swap_and_move;
@@ -392,8 +377,8 @@ public:
//! @param other The varray which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor throws.
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move is false_type - default.
//! @endinternal
@@ -404,7 +389,7 @@ public:
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
varray(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
varray(varray<value_type, C>&& other)
: m_size(other.m_size)
{
errh::check_capacity(*this, other.size()); // may throw
@@ -420,15 +405,15 @@ public:
//! @param other The varray which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
//! @endinternal
//!
//! @par Complexity
//! Linear O(N).
varray & operator=(BOOST_RV_REF(varray) other)
varray& operator=(varray&& other)
{
if ( &other == this )
return *this;
@@ -448,8 +433,8 @@ public:
//! @param other The varray which content will be moved to this one.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor or move assignment throws.
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move is \c false_type - default.
//! @endinternal
@@ -460,7 +445,7 @@ public:
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
varray & operator=(BOOST_RV_REF_2_TEMPL_ARGS(varray, value_type, C) other)
varray& operator=(varray<value_type, C>&& other)
{
errh::check_capacity(*this, other.size()); // may throw
@@ -490,15 +475,15 @@ public:
//! @param other The varray which content will be swapped with this one's content.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
//! @endinternal
//!
//! @par Complexity
//! Linear O(N).
void swap(varray & other)
void swap(varray& other)
{
typedef typename
vt::use_optimized_swap use_optimized_swap;
@@ -513,8 +498,8 @@ public:
//! @param other The varray which content will be swapped with this one's content.
//!
//! @par Throws
//! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c true and Value's move constructor or move assignment throws,
//! @li If \c std::is_nothrow_move_constructible<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//! @internal
//! @li It throws only if \c use_memop_in_swap_and_move and \c use_optimized_swap are \c false_type - default.
//! @endinternal
@@ -525,7 +510,7 @@ public:
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
void swap(varray<value_type, C> & other)
void swap(varray<value_type, C>& other)
{
errh::check_capacity(*this, other.size());
errh::check_capacity(other, this->size());
@@ -533,7 +518,7 @@ public:
typedef typename
vt::use_optimized_swap use_optimized_swap;
this->swap_dispatch(other, use_optimized_swap());
this->swap_dispatch(other, use_optimized_swap());
}
//! @pre <tt>count <= capacity()</tt>
@@ -595,7 +580,7 @@ public:
else
{
errh::check_capacity(*this, count); // may throw
std::uninitialized_fill(this->end(), this->begin() + count, value); // may throw
}
m_size = count; // update end
@@ -639,7 +624,7 @@ public:
typedef typename vt::disable_trivial_init dti;
errh::check_capacity(*this, m_size + 1); // may throw
namespace sv = varray_detail;
sv::construct(dti(), this->end(), value); // may throw
++m_size; // update end
@@ -659,14 +644,14 @@ public:
//!
//! @par Complexity
//! Constant O(1).
void push_back(BOOST_RV_REF(value_type) value)
void push_back(value_type&& value)
{
typedef typename vt::disable_trivial_init dti;
errh::check_capacity(*this, m_size + 1); // may throw
namespace sv = varray_detail;
sv::construct(dti(), this->end(), ::boost::move(value)); // may throw
sv::construct(dti(), this->end(), std::move(value)); // may throw
++m_size; // update end
}
@@ -722,8 +707,8 @@ public:
else
{
// TODO - should move be used only if it's nonthrowing?
value_type & r = *(this->end() - 1);
sv::construct(dti(), this->end(), boost::move(r)); // may throw
value_type& r = *(this->end() - 1);
sv::construct(dti(), this->end(), std::move(r)); // may throw
++m_size; // update end
sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
sv::assign(position, value); // may throw
@@ -749,7 +734,7 @@ public:
//!
//! @par Complexity
//! Constant or linear.
iterator insert(iterator position, BOOST_RV_REF(value_type) value)
iterator insert(iterator position, value_type&& value)
{
typedef typename vt::disable_trivial_init dti;
namespace sv = varray_detail;
@@ -759,17 +744,17 @@ public:
if ( position == this->end() )
{
sv::construct(dti(), position, boost::move(value)); // may throw
sv::construct(dti(), position, std::move(value)); // may throw
++m_size; // update end
}
else
{
// TODO - should move be used only if it's nonthrowing?
value_type & r = *(this->end() - 1);
sv::construct(dti(), this->end(), boost::move(r)); // may throw
value_type& r = *(this->end() - 1);
sv::construct(dti(), this->end(), std::move(r)); // may throw
++m_size; // update end
sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
sv::assign(position, boost::move(value)); // may throw
sv::assign(position, std::move(value)); // may throw
}
return position;
@@ -809,7 +794,7 @@ public:
namespace sv = varray_detail;
difference_type to_move = std::distance(position, this->end());
// TODO - should following lines check for exception and revert to the old size?
if ( count < static_cast<size_type>(to_move) )
@@ -910,9 +895,9 @@ public:
errh::check_iterator_end_eq(*this, first);
errh::check_iterator_end_eq(*this, last);
difference_type n = std::distance(first, last);
//TODO - add invalid range check?
//BOOST_GEOMETRY_INDEX_ASSERT(0 <= n, "invalid range");
//TODO - add this->size() check?
@@ -977,8 +962,6 @@ public:
m_size = count; // update end
}
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! @pre <tt>size() < capacity()</tt>
//!
//! @brief Inserts a Value constructed with
@@ -995,14 +978,14 @@ public:
//! @par Complexity
//! Constant O(1).
template<class ...Args>
void emplace_back(BOOST_FWD_REF(Args) ...args)
void emplace_back(Args&& ...args)
{
typedef typename vt::disable_trivial_init dti;
errh::check_capacity(*this, m_size + 1); // may throw
namespace sv = varray_detail;
sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...); // may throw
sv::construct(dti(), this->end(), std::forward<Args>(args)...); // may throw
++m_size; // update end
}
@@ -1025,7 +1008,7 @@ public:
//! @par Complexity
//! Constant or linear.
template<class ...Args>
iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
iterator emplace(iterator position, Args&& ...args)
{
typedef typename vt::disable_trivial_init dti;
@@ -1036,7 +1019,7 @@ public:
if ( position == this->end() )
{
sv::construct(dti(), position, ::boost::forward<Args>(args)...); // may throw
sv::construct(dti(), position, std::forward<Args>(args)...); // may throw
++m_size; // update end
}
else
@@ -1044,76 +1027,21 @@ public:
// TODO - should following lines check for exception and revert to the old size?
// TODO - should move be used only if it's nonthrowing?
value_type & r = *(this->end() - 1);
sv::construct(dti(), this->end(), boost::move(r)); // may throw
value_type& r = *(this->end() - 1);
sv::construct(dti(), this->end(), std::move(r)); // may throw
++m_size; // update end
sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
value_type * val_p = static_cast<value_type *>(temp_storage.address());
sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
value_type* val_p = static_cast<value_type*>(temp_storage.address());
sv::construct(dti(), val_p, std::forward<Args>(args)...); // may throw
sv::scoped_destructor<value_type> d(val_p);
sv::assign(position, ::boost::move(*val_p)); // may throw
sv::assign(position, std::move(*val_p)); // may throw
}
return position;
}
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
void emplace_back(BOOST_MOVE_UREF##N) \
{ \
typedef typename vt::disable_trivial_init dti; \
\
errh::check_capacity(*this, m_size + 1); /*may throw*/\
\
namespace sv = varray_detail; \
sv::construct(dti(), this->end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/ \
} \
\
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace(iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
{ \
typedef typename vt::disable_trivial_init dti; \
namespace sv = varray_detail; \
\
errh::check_iterator_end_eq(*this, position); \
errh::check_capacity(*this, m_size + 1); /*may throw*/\
\
if ( position == this->end() ) \
{ \
sv::construct(dti(), position BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
++m_size; /*update end*/ \
} \
else \
{ \
/* TODO - should following lines check for exception and revert to the old size? */ \
/* TODO - should move be used only if it's nonthrowing? */ \
\
value_type & r = *(this->end() - 1); \
sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
++m_size; /*update end*/ \
sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
\
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
sv::construct(dti(), val_p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); /*may throw*/\
sv::scoped_destructor<value_type> d(val_p); \
sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
} \
\
return position; \
} \
BOOST_MOVE_ITERATE_0TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE)
#undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_EMPLACE
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
//! @brief Removes all elements from the container.
//!
//! @par Throws
@@ -1307,7 +1235,7 @@ public:
return boost::addressof(*(this->ptr()));
}
//! @brief Returns iterator to the first element.
//!
//! @return iterator to the first element contained in the vector.
@@ -1498,19 +1426,19 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C>
void move_ctor_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
void move_ctor_dispatch(varray<value_type, C>& other, std::true_type /*use_memop*/)
{
::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
m_size = other.m_size;
}
// @par Throws
// @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor throws
// @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor throws.
// @li If std::is_nothrow_move_constructible<Value>::value is true and Value's move constructor throws
// @li If std::is_nothrow_move_constructible<Value>::value is false and Value's copy constructor throws.
// @par Complexity
// Linear O(N).
template <std::size_t C>
void move_ctor_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
void move_ctor_dispatch(varray<value_type, C>& other, std::false_type /*use_memop*/)
{
namespace sv = varray_detail;
sv::uninitialized_move_if_noexcept(other.begin(), other.end(), this->begin()); // may throw
@@ -1522,7 +1450,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C>
void move_assign_dispatch(varray<value_type, C> & other, boost::true_type /*use_memop*/)
void move_assign_dispatch(varray<value_type, C>& other, std::true_type /*use_memop*/)
{
this->clear();
@@ -1531,12 +1459,12 @@ private:
}
// @par Throws
// @li If boost::has_nothrow_move<Value>::value is true and Value's move constructor or move assignment throws
// @li If boost::has_nothrow_move<Value>::value is false and Value's copy constructor or move assignment throws.
// @li If std::is_nothrow_move_constructible<Value>::value is true and Value's move constructor or move assignment throws
// @li If std::is_nothrow_move_constructible<Value>::value is false and Value's copy constructor or move assignment throws.
// @par Complexity
// Linear O(N).
template <std::size_t C>
void move_assign_dispatch(varray<value_type, C> & other, boost::false_type /*use_memop*/)
void move_assign_dispatch(varray<value_type, C>& other, std::false_type /*use_memop*/)
{
namespace sv = varray_detail;
if ( m_size <= static_cast<size_type>(other.size()) )
@@ -1558,18 +1486,17 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C>
void swap_dispatch(varray<value_type, C> & other, boost::true_type const& /*use_optimized_swap*/)
void swap_dispatch(varray<value_type, C>& other, std::true_type /*use_optimized_swap*/)
{
typedef typename
boost::mpl::if_c<
Capacity < C,
aligned_storage_type,
typename varray<value_type, C>::aligned_storage_type
>::type
storage_type;
typedef std::conditional_t
<
(Capacity < C),
aligned_storage_type,
typename varray<value_type, C>::aligned_storage_type
> storage_type;
storage_type temp;
Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
Value* temp_ptr = reinterpret_cast<Value*>(temp.address());
::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
@@ -1584,7 +1511,7 @@ private:
// @par Complexity
// Linear O(N).
template <std::size_t C>
void swap_dispatch(varray<value_type, C> & other, boost::false_type const& /*use_optimized_swap*/)
void swap_dispatch(varray<value_type, C>& other, std::false_type /*use_optimized_swap*/)
{
namespace sv = varray_detail;
@@ -1602,7 +1529,7 @@ private:
// Nothing.
// @par Complexity
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::true_type const& /*use_memop*/)
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, std::true_type /*use_memop*/)
{
//BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
// "incompatible ranges");
@@ -1614,7 +1541,7 @@ private:
sizeof(value_type),
boost::alignment_of<value_type>::value
> temp_storage;
value_type * temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
value_type* temp_ptr = reinterpret_cast<value_type*>(temp_storage.address());
::memcpy(temp_ptr, boost::addressof(*first_sm), sizeof(value_type));
::memcpy(boost::addressof(*first_sm), boost::addressof(*first_la), sizeof(value_type));
@@ -1628,18 +1555,21 @@ private:
// If Value's move constructor or move assignment throws.
// @par Complexity
// Linear O(N).
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, boost::false_type const& /*use_memop*/)
void swap_dispatch_impl(iterator first_sm, iterator last_sm, iterator first_la, iterator last_la, std::false_type /*use_memop*/)
{
//BOOST_GEOMETRY_INDEX_ASSERT(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la),
// "incompatible ranges");
namespace sv = varray_detail;
for (; first_sm != last_sm ; ++first_sm, ++first_la)
{
//boost::swap(*first_sm, *first_la); // may throw
value_type temp(boost::move(*first_sm)); // may throw
*first_sm = boost::move(*first_la); // may throw
*first_la = boost::move(temp); // may throw
//std::iter_swap(first_sm, first_la);
//std::swap(*first_sm, *first_la); // may throw
//boost::swap(*first_sm, *first_la);
value_type temp(std::move(*first_sm)); // may throw
*first_sm = std::move(*first_la); // may throw
*first_la = std::move(temp); // may throw
}
sv::uninitialized_move(first_la, last_la, first_sm); // may throw
sv::destroy(first_la, last_la);
@@ -1656,9 +1586,9 @@ private:
void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
{
BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
errh::check_iterator_end_eq(*this, position);
typename boost::iterator_difference<Iterator>::type
count = std::distance(first, last);
@@ -1693,7 +1623,7 @@ private:
std::ptrdiff_t d = std::distance(position, this->begin() + Capacity);
std::size_t count = sv::uninitialized_copy_s(first, last, position, d); // may throw
errh::check_capacity(*this, count <= static_cast<std::size_t>(d) ? m_size + count : Capacity + 1); // may throw
m_size += count;
@@ -1702,7 +1632,7 @@ private:
{
typename boost::iterator_difference<Iterator>::type
count = std::distance(first, last);
errh::check_capacity(*this, m_size + count); // may throw
this->insert_in_the_middle(position, first, last, count); // may throw
@@ -1871,7 +1801,7 @@ public:
}
// basic
varray & operator=(varray const& /*other*/)
varray& operator=(varray const& /*other*/)
{
//errh::check_capacity(*this, other.size());
return *this;
@@ -1879,7 +1809,7 @@ public:
// basic
template <size_t C>
varray & operator=(varray<value_type, C> const& other)
varray& operator=(varray<value_type, C> const& other)
{
errh::check_capacity(*this, other.size()); // may throw
return *this;
@@ -1900,7 +1830,7 @@ public:
errh::check_capacity(*this, count); // may throw
}
// nothrow
void reserve(size_type count)
{
@@ -1937,7 +1867,7 @@ public:
template <typename Iterator>
void insert(iterator, Iterator first, Iterator last)
{
// TODO - add MPL_ASSERT, check if Iterator is really an iterator
// TODO - add BOOST_GEOMETRY_STATIC_ASSERT, check if Iterator is really an iterator
errh::check_capacity(*this, std::distance(first, last)); // may throw
}
@@ -1960,7 +1890,7 @@ public:
template <typename Iterator>
void assign(Iterator first, Iterator last)
{
// TODO - add MPL_ASSERT, check if Iterator is really an iterator
// TODO - add BOOST_GEOMETRY_STATIC_ASSERT, check if Iterator is really an iterator
errh::check_capacity(*this, std::distance(first, last)); // may throw
}
@@ -2030,8 +1960,8 @@ public:
}
// nothrow
Value * data() { return boost::addressof(*(this->ptr())); }
const Value * data() const { return boost::addressof(*(this->ptr())); }
Value* data() { return boost::addressof(*(this->ptr())); }
const Value* data() const { return boost::addressof(*(this->ptr())); }
// nothrow
iterator begin() { return this->ptr(); }
@@ -2182,7 +2112,7 @@ bool operator>= (varray<V, C1> const& x, varray<V, C2> const& y)
//! @par Complexity
//! Linear O(N).
template<typename V, std::size_t C1, std::size_t C2>
inline void swap(varray<V, C1> & x, varray<V, C2> & y)
inline void swap(varray<V, C1>& x, varray<V, C2>& y)
{
x.swap(y);
}

View File

@@ -2,8 +2,12 @@
//
// varray details
//
// Copyright (c) 2012-2015 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2013 Andrew Hundt.
// Copyright (c) 2012-2023 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2020.
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -12,39 +16,18 @@
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_HPP
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <memory>
#include <limits>
#include <memory>
#include <type_traits>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/int.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/has_trivial_move_constructor.hpp>
#include <boost/type_traits/has_trivial_move_assign.hpp>
//#include <boost/type_traits/has_nothrow_constructor.hpp>
//#include <boost/type_traits/has_nothrow_copy.hpp>
//#include <boost/type_traits/has_nothrow_assign.hpp>
//#include <boost/type_traits/has_nothrow_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/core/addressof.hpp>
#include <boost/iterator/iterator_traits.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/core/addressof.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/iterator/iterator_traits.hpp>
// TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
@@ -53,42 +36,44 @@
#include <boost/container/vector.hpp>
#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail {
namespace boost { namespace geometry { namespace index { namespace detail { namespace varray_detail
{
template <typename I>
struct are_elements_contiguous : boost::is_pointer<I>
struct are_elements_contiguous : std::is_pointer<I>
{};
// EXPERIMENTAL - not finished
// Conditional setup - mark vector iterators defined in known implementations
// as iterators pointing to contiguous ranges
#if defined(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
template <typename Pointer>
struct are_elements_contiguous<
boost::container::container_detail::vector_const_iterator<Pointer>
> : boost::true_type
> : std::true_type
{};
template <typename Pointer>
struct are_elements_contiguous<
boost::container::container_detail::vector_iterator<Pointer>
> : boost::true_type
> : std::true_type
{};
#if defined(BOOST_DINKUMWARE_STDLIB)
template <typename T>
struct are_elements_contiguous<
std::_Vector_const_iterator<T>
> : boost::true_type
> : std::true_type
{};
template <typename T>
struct are_elements_contiguous<
std::_Vector_iterator<T>
> : boost::true_type
> : std::true_type
{};
#elif defined(BOOST_GNU_STDLIB)
@@ -96,7 +81,7 @@ struct are_elements_contiguous<
template <typename P, typename T, typename A>
struct are_elements_contiguous<
__gnu_cxx::__normal_iterator<P, std::vector<T, A> >
> : boost::true_type
> : std::true_type
{};
#elif defined(_LIBCPP_VERSION)
@@ -105,55 +90,78 @@ struct are_elements_contiguous<
//template <typename P>
//struct are_elements_contiguous<
// __wrap_iter<P>
//> : boost::true_type
//> : std::true_type
//{};
#else // OTHER_STDLIB
// TODO - add other iterators implementations
#endif // STDLIB
#endif // BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_ENABLE_VECTOR_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
// True if iterator values are the same and both iterators points to the ranges of contiguous elements
template <typename I, typename O>
struct are_corresponding :
::boost::mpl::and_<
::boost::is_same<
::boost::remove_const<
typename ::boost::iterator_value<I>::type
>,
::boost::remove_const<
typename ::boost::iterator_value<O>::type
>
>,
are_elements_contiguous<I>,
are_elements_contiguous<O>
>
struct is_memop_safe_for_range
: std::integral_constant
<
bool,
std::is_same
<
std::remove_const_t
<
typename ::boost::iterator_value<I>::type
>,
std::remove_const_t
<
typename ::boost::iterator_value<O>::type
>
>::value
&&
are_elements_contiguous<I>::value
&&
are_elements_contiguous<O>::value
&&
std::is_trivially_copyable
<
typename ::boost::iterator_value<O>::type
>::value
>
{};
template <typename I, typename V>
struct is_corresponding_value :
::boost::is_same<
::boost::remove_const<
typename ::boost::iterator_value<I>::type
>,
::boost::remove_const<V>
>
struct is_memop_safe_for_value
: std::integral_constant
<
bool,
std::is_same
<
std::remove_const_t
<
typename ::boost::iterator_value<I>::type
>,
std::remove_const_t<V>
>::value
&&
std::is_trivially_copyable
<
V
>::value
>
{};
// destroy(I, I)
template <typename I>
void destroy_dispatch(I /*first*/, I /*last*/,
boost::true_type const& /*has_trivial_destructor*/)
std::true_type /*has_trivial_destructor*/)
{}
template <typename I>
void destroy_dispatch(I first, I last,
boost::false_type const& /*has_trivial_destructor*/)
std::false_type /*has_trivial_destructor*/)
{
typedef typename boost::iterator_value<I>::type value_type;
for ( ; first != last ; ++first )
@@ -164,19 +172,19 @@ template <typename I>
void destroy(I first, I last)
{
typedef typename boost::iterator_value<I>::type value_type;
destroy_dispatch(first, last, has_trivial_destructor<value_type>());
destroy_dispatch(first, last, std::is_trivially_destructible<value_type>());
}
// destroy(I)
template <typename I>
void destroy_dispatch(I /*pos*/,
boost::true_type const& /*has_trivial_destructor*/)
std::true_type /*has_trivial_destructor*/)
{}
template <typename I>
void destroy_dispatch(I pos,
boost::false_type const& /*has_trivial_destructor*/)
std::false_type /*has_trivial_destructor*/)
{
typedef typename boost::iterator_value<I>::type value_type;
pos->~value_type();
@@ -186,14 +194,14 @@ template <typename I>
void destroy(I pos)
{
typedef typename boost::iterator_value<I>::type value_type;
destroy_dispatch(pos, has_trivial_destructor<value_type>());
destroy_dispatch(pos, std::is_trivially_destructible<value_type>());
}
// copy(I, I, O)
template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
std::true_type /*use_memmove*/)
{
typedef typename boost::iterator_value<I>::type value_type;
typename boost::iterator_difference<I>::type d = std::distance(first, last);
@@ -204,7 +212,7 @@ inline O copy_dispatch(I first, I last, O dst,
template <typename I, typename O>
inline O copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
std::false_type /*use_memmove*/)
{
return std::copy(first, last, dst); // may throw
}
@@ -212,16 +220,7 @@ inline O copy_dispatch(I first, I last, O dst,
template <typename I, typename O>
inline O copy(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_assign<
typename ::boost::iterator_value<O>::type
>
>::type
use_memmove;
return copy_dispatch(first, last, dst, use_memmove()); // may throw
return copy_dispatch(first, last, dst, is_memop_safe_for_range<I, O>()); // may throw
}
// uninitialized_copy(I, I, O)
@@ -229,7 +228,7 @@ inline O copy(I first, I last, O dst)
template <typename I, typename O>
inline
O uninitialized_copy_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type /*use_memcpy*/)
{
typedef typename boost::iterator_value<I>::type value_type;
typename boost::iterator_difference<I>::type d = std::distance(first, last);
@@ -241,7 +240,7 @@ O uninitialized_copy_dispatch(I first, I last, O dst,
template <typename I, typename F>
inline
F uninitialized_copy_dispatch(I first, I last, F dst,
boost::mpl::bool_<false> const& /*use_memcpy*/)
std::false_type /*use_memcpy*/)
{
return std::uninitialized_copy(first, last, dst); // may throw
}
@@ -250,16 +249,7 @@ template <typename I, typename F>
inline
F uninitialized_copy(I first, I last, F dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, F>,
::boost::has_trivial_copy<
typename ::boost::iterator_value<F>::type
>
>::type
use_memcpy;
return uninitialized_copy_dispatch(first, last, dst, use_memcpy()); // may throw
return uninitialized_copy_dispatch(first, last, dst, is_memop_safe_for_range<I, F>()); // may throw
}
// uninitialized_move(I, I, O)
@@ -267,7 +257,7 @@ F uninitialized_copy(I first, I last, F dst)
template <typename I, typename O>
inline
O uninitialized_move_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type /*use_memcpy*/)
{
typedef typename boost::iterator_value<I>::type value_type;
typename boost::iterator_difference<I>::type d = std::distance(first, last);
@@ -279,7 +269,7 @@ O uninitialized_move_dispatch(I first, I last, O dst,
template <typename I, typename O>
inline
O uninitialized_move_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memcpy*/)
std::false_type /*use_memcpy*/)
{
//return boost::uninitialized_move(first, last, dst); // may throw
@@ -289,11 +279,11 @@ O uninitialized_move_dispatch(I first, I last, O dst,
{
typedef typename std::iterator_traits<O>::value_type value_type;
for (; first != last; ++first, ++o )
new (boost::addressof(*o)) value_type(boost::move(*first));
new (boost::addressof(*o)) value_type(std::move(*first));
}
BOOST_CATCH(...)
{
destroy(dst, o);
varray_detail::destroy(dst, o);
BOOST_RETHROW;
}
BOOST_CATCH_END
@@ -305,16 +295,7 @@ template <typename I, typename O>
inline
O uninitialized_move(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_copy<
typename ::boost::iterator_value<O>::type
>
>::type
use_memcpy;
return uninitialized_move_dispatch(first, last, dst, use_memcpy()); // may throw
return uninitialized_move_dispatch(first, last, dst, is_memop_safe_for_range<I, O>()); // may throw
}
// TODO - move uses memmove - implement 2nd version using memcpy?
@@ -324,7 +305,7 @@ O uninitialized_move(I first, I last, O dst)
template <typename I, typename O>
inline
O move_dispatch(I first, I last, O dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
std::true_type /*use_memmove*/)
{
typedef typename boost::iterator_value<I>::type value_type;
typename boost::iterator_difference<I>::type d = std::distance(first, last);
@@ -336,25 +317,16 @@ O move_dispatch(I first, I last, O dst,
template <typename I, typename O>
inline
O move_dispatch(I first, I last, O dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
std::false_type /*use_memmove*/)
{
return boost::move(first, last, dst); // may throw
return std::move(first, last, dst); // may throw
}
template <typename I, typename O>
inline
O move(I first, I last, O dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<I, O>,
::boost::has_trivial_assign<
typename ::boost::iterator_value<O>::type
>
>::type
use_memmove;
return move_dispatch(first, last, dst, use_memmove()); // may throw
return move_dispatch(first, last, dst, is_memop_safe_for_range<I, O>()); // may throw
}
// move_backward(BDI, BDI, BDO)
@@ -362,7 +334,7 @@ O move(I first, I last, O dst)
template <typename BDI, typename BDO>
inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
boost::mpl::bool_<true> const& /*use_memmove*/)
std::true_type /*use_memmove*/)
{
typedef typename boost::iterator_value<BDI>::type value_type;
typename boost::iterator_difference<BDI>::type d = std::distance(first, last);
@@ -375,60 +347,43 @@ BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
template <typename BDI, typename BDO>
inline
BDO move_backward_dispatch(BDI first, BDI last, BDO dst,
boost::mpl::bool_<false> const& /*use_memmove*/)
std::false_type /*use_memmove*/)
{
return boost::move_backward(first, last, dst); // may throw
return std::move_backward(first, last, dst); // may throw
}
template <typename BDI, typename BDO>
inline
BDO move_backward(BDI first, BDI last, BDO dst)
{
typedef typename
::boost::mpl::and_<
are_corresponding<BDI, BDO>,
::boost::has_trivial_assign<
typename ::boost::iterator_value<BDO>::type
>
>::type
use_memmove;
return move_backward_dispatch(first, last, dst, use_memmove()); // may throw
return move_backward_dispatch(first, last, dst, is_memop_safe_for_range<BDI, BDO>()); // may throw
}
template <typename T>
struct has_nothrow_move : public
::boost::mpl::or_<
boost::mpl::bool_<
::boost::has_nothrow_move<
typename ::boost::remove_const<T>::type
>::value
>,
boost::mpl::bool_<
::boost::has_nothrow_move<T>::value
>
>
{};
// uninitialized_move_if_noexcept(I, I, O)
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
{ return varray_detail::uninitialized_move(first, last, dst); }
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst,
std::true_type /*use_move*/)
{
return varray_detail::uninitialized_move(first, last, dst);
}
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
{ return varray_detail::uninitialized_copy(first, last, dst); }
O uninitialized_move_if_noexcept_dispatch(I first, I last, O dst,
std::false_type const& /*use_move*/)
{
return varray_detail::uninitialized_copy(first, last, dst);
}
template <typename I, typename O>
inline
O uninitialized_move_if_noexcept(I first, I last, O dst)
{
typedef typename has_nothrow_move<
typedef std::is_nothrow_move_constructible<
typename ::boost::iterator_value<O>::type
>::type use_move;
> use_move;
return uninitialized_move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
}
@@ -437,21 +392,27 @@ O uninitialized_move_if_noexcept(I first, I last, O dst)
template <typename I, typename O>
inline
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<true> const& /*use_move*/)
{ return move(first, last, dst); }
O move_if_noexcept_dispatch(I first, I last, O dst,
std::true_type /*use_move*/)
{
return varray_detail::move(first, last, dst);
}
template <typename I, typename O>
inline
O move_if_noexcept_dispatch(I first, I last, O dst, boost::mpl::bool_<false> const& /*use_move*/)
{ return copy(first, last, dst); }
O move_if_noexcept_dispatch(I first, I last, O dst,
std::false_type /*use_move*/)
{
return varray_detail::copy(first, last, dst);
}
template <typename I, typename O>
inline
O move_if_noexcept(I first, I last, O dst)
{
typedef typename has_nothrow_move<
typedef std::is_nothrow_move_constructible<
typename ::boost::iterator_value<O>::type
>::type use_move;
> use_move;
return move_if_noexcept_dispatch(first, last, dst, use_move()); // may throw
}
@@ -461,15 +422,15 @@ O move_if_noexcept(I first, I last, O dst)
template <typename I>
inline
void uninitialized_fill_dispatch(I /*first*/, I /*last*/,
boost::true_type const& /*has_trivial_constructor*/,
boost::true_type const& /*disable_trivial_init*/)
std::true_type const& /*has_trivial_constructor*/,
std::true_type const& /*disable_trivial_init*/)
{}
template <typename I>
inline
void uninitialized_fill_dispatch(I first, I last,
boost::true_type const& /*has_trivial_constructor*/,
boost::false_type const& /*disable_trivial_init*/)
std::true_type const& /*has_trivial_constructor*/,
std::false_type const& /*disable_trivial_init*/)
{
typedef typename boost::iterator_value<I>::type value_type;
for ( ; first != last ; ++first )
@@ -479,7 +440,7 @@ void uninitialized_fill_dispatch(I first, I last,
template <typename I, typename DisableTrivialInit>
inline
void uninitialized_fill_dispatch(I first, I last,
boost::false_type const& /*has_trivial_constructor*/,
std::false_type const& /*has_trivial_constructor*/,
DisableTrivialInit const& /*not_used*/)
{
typedef typename boost::iterator_value<I>::type value_type;
@@ -492,7 +453,7 @@ void uninitialized_fill_dispatch(I first, I last,
}
BOOST_CATCH(...)
{
destroy(first, it);
varray_detail::destroy(first, it);
BOOST_RETHROW;
}
BOOST_CATCH_END
@@ -503,22 +464,22 @@ inline
void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
{
typedef typename boost::iterator_value<I>::type value_type;
uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
uninitialized_fill_dispatch(first, last, std::is_trivially_constructible<value_type>(), disable_trivial_init); // may throw
}
// construct(I)
template <typename I>
inline
void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I /*pos*/)
void construct_dispatch(std::true_type /*dont_init*/, I /*pos*/)
{}
template <typename I>
inline
void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
void construct_dispatch(std::false_type /*dont_init*/, I pos)
{
typedef typename ::boost::iterator_value<I>::type value_type;
new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
new (static_cast<void*>(boost::addressof(*pos))) value_type(); // may throw
}
template <typename DisableTrivialInit, typename I>
@@ -526,10 +487,13 @@ inline
void construct(DisableTrivialInit const&, I pos)
{
typedef typename ::boost::iterator_value<I>::type value_type;
typedef typename ::boost::mpl::and_<
boost::has_trivial_constructor<value_type>,
DisableTrivialInit
>::type dont_init;
typedef std::integral_constant
<
bool,
std::is_trivially_constructible<value_type>::value
&&
DisableTrivialInit::value
> dont_init;
construct_dispatch(dont_init(), pos); // may throw
}
@@ -539,7 +503,7 @@ void construct(DisableTrivialInit const&, I pos)
template <typename I, typename V>
inline
void construct_copy_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type /*use_memcpy*/)
{
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
}
@@ -547,7 +511,7 @@ void construct_copy_dispatch(I pos, V const& v,
template <typename I, typename P>
inline
void construct_copy_dispatch(I pos, P const& p,
boost::mpl::bool_<false> const& /*use_memcpy*/)
std::false_type const& /*use_memcpy*/)
{
typedef typename boost::iterator_value<I>::type V;
new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
@@ -558,14 +522,7 @@ inline
void construct(DisableTrivialInit const&,
I pos, P const& p)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, P>,
::boost::has_trivial_copy<P>
>::type
use_memcpy;
construct_copy_dispatch(pos, p, use_memcpy()); // may throw
construct_copy_dispatch(pos, p, is_memop_safe_for_value<I, P>()); // may throw
}
// Needed by push_back(V &&)
@@ -573,81 +530,45 @@ void construct(DisableTrivialInit const&,
template <typename I, typename V>
inline
void construct_move_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type const& /*use_memcpy*/)
{
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
}
template <typename I, typename P>
inline
void construct_move_dispatch(I pos, BOOST_RV_REF(P) p,
boost::mpl::bool_<false> const& /*use_memcpy*/)
void construct_move_dispatch(I pos, P&& p,
std::false_type const& /*use_memcpy*/)
{
typedef typename boost::iterator_value<I>::type V;
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::move(p)); // may throw
new (static_cast<void*>(boost::addressof(*pos))) V(std::move(p)); // may throw
}
template <typename DisableTrivialInit, typename I, typename P>
inline
void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
void construct(DisableTrivialInit const&, I pos, P&& p)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, P>,
::boost::has_trivial_move_constructor<P>
>::type
use_memcpy;
construct_move_dispatch(pos, ::boost::move(p), use_memcpy()); // may throw
construct_move_dispatch(pos, std::move(p), is_memop_safe_for_value<I, P>()); // may throw
}
// Needed by emplace_back() and emplace()
#if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename DisableTrivialInit, typename I, class ...Args>
inline
void construct(DisableTrivialInit const&,
I pos,
BOOST_FWD_REF(Args) ...args)
Args&& ...args)
{
typedef typename boost::iterator_value<I>::type V;
new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
new (static_cast<void*>(boost::addressof(*pos))) V(std::forward<Args>(args)...); // may throw
}
#else // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
// BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 const& p0
// !BOOST_NO_CXX11_RVALUE_REFERENCES -> P0 && p0
// which means that version with one parameter may take V const& v
#define BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT(N) \
template <typename DisableTrivialInit, typename I, typename P BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
inline \
void construct(DisableTrivialInit const&, \
I pos, \
BOOST_FWD_REF(P) p \
BOOST_MOVE_I##N BOOST_MOVE_UREF##N) \
{ \
typedef typename boost::iterator_value<I>::type V; \
new \
(static_cast<void*>(boost::addressof(*pos))) \
V(boost::forward<P>(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N); /*may throw*/ \
} \
BOOST_MOVE_ITERATE_1TO9(BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT)
#undef BOOST_GEOMETRY_INDEX_DETAIL_VARRAY_DETAIL_CONSTRUCT
#endif // !BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif // !BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE
// assign(I, V)
template <typename I, typename V>
inline
void assign_copy_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type /*use_memcpy*/)
{
// TODO - use memmove here?
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
@@ -656,7 +577,7 @@ void assign_copy_dispatch(I pos, V const& v,
template <typename I, typename V>
inline
void assign_copy_dispatch(I pos, V const& v,
boost::mpl::bool_<false> const& /*use_memcpy*/)
std::false_type /*use_memcpy*/)
{
*pos = v; // may throw
}
@@ -665,20 +586,13 @@ template <typename I, typename V>
inline
void assign(I pos, V const& v)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, V>,
::boost::has_trivial_assign<V>
>::type
use_memcpy;
assign_copy_dispatch(pos, v, use_memcpy()); // may throw
assign_copy_dispatch(pos, v, is_memop_safe_for_value<I, V>()); // may throw
}
template <typename I, typename V>
inline
void assign_move_dispatch(I pos, V const& v,
boost::mpl::bool_<true> const& /*use_memcpy*/)
std::true_type /*use_memcpy*/)
{
// TODO - use memmove here?
::memcpy(boost::addressof(*pos), boost::addressof(v), sizeof(V));
@@ -686,24 +600,17 @@ void assign_move_dispatch(I pos, V const& v,
template <typename I, typename V>
inline
void assign_move_dispatch(I pos, BOOST_RV_REF(V) v,
boost::mpl::bool_<false> const& /*use_memcpy*/)
void assign_move_dispatch(I pos, V&& v,
std::false_type /*use_memcpy*/)
{
*pos = boost::move(v); // may throw
*pos = std::move(v); // may throw
}
template <typename I, typename V>
inline
void assign(I pos, BOOST_RV_REF(V) v)
void assign(I pos, V&& v)
{
typedef typename
::boost::mpl::and_<
is_corresponding_value<I, V>,
::boost::has_trivial_move_assign<V>
>::type
use_memcpy;
assign_move_dispatch(pos, ::boost::move(v), use_memcpy());
assign_move_dispatch(pos, std::move(v), is_memop_safe_for_value<I, V>());
}
// uninitialized_copy_s
@@ -727,7 +634,7 @@ inline std::size_t uninitialized_copy_s(I first, I last, F dest, std::size_t max
}
BOOST_CATCH(...)
{
destroy(dest, it);
varray_detail::destroy(dest, it);
BOOST_RETHROW;
}
BOOST_CATCH_END
@@ -746,7 +653,7 @@ public:
~scoped_destructor()
{
if(m_ptr)
destroy(m_ptr);
varray_detail::destroy(m_ptr);
}
void release() { m_ptr = 0; }