update boost
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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)();
|
||||
|
||||
@@ -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 <
|
||||
|
||||
@@ -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 <
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
107
linx64/include/boost/geometry/index/detail/maxmin_heap.hpp
Normal file
107
linx64/include/boost/geometry/index/detail/maxmin_heap.hpp
Normal 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
|
||||
@@ -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
|
||||
<
|
||||
|
||||
521
linx64/include/boost/geometry/index/detail/minmax_heap.hpp
Normal file
521
linx64/include/boost/geometry/index/detail/minmax_heap.hpp
Normal 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
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
150
linx64/include/boost/geometry/index/detail/priority_dequeue.hpp
Normal file
150
linx64/include/boost/geometry/index/detail/priority_dequeue.hpp
Normal 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
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user