File indexing completed on 2025-07-01 08:15:15
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
0016 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_HPP
0017
0018 #include <type_traits>
0019
0020 #include <boost/container/vector.hpp>
0021
0022 #include <boost/geometry/core/static_assert.hpp>
0023
0024 #include <boost/geometry/algorithms/expand.hpp>
0025
0026 #include <boost/geometry/index/detail/varray.hpp>
0027
0028 #include <boost/geometry/index/detail/rtree/node/concept.hpp>
0029 #include <boost/geometry/index/detail/rtree/node/pairs.hpp>
0030 #include <boost/geometry/index/detail/rtree/node/node_elements.hpp>
0031 #include <boost/geometry/index/detail/rtree/node/scoped_deallocator.hpp>
0032
0033
0034
0035
0036
0037 #include <boost/geometry/index/detail/rtree/node/variant_visitor.hpp>
0038 #include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
0039 #include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
0040
0041 #include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
0042 #include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
0043
0044 #include <boost/geometry/index/detail/algorithms/bounds.hpp>
0045 #include <boost/geometry/index/detail/is_bounding_geometry.hpp>
0046
0047 #include <boost/geometry/util/constexpr.hpp>
0048
0049 namespace boost { namespace geometry { namespace index {
0050
0051 namespace detail { namespace rtree {
0052
0053
0054
0055 template <typename Box, typename FwdIter, typename Translator, typename Strategy>
0056 inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr,
0057 Strategy const& strategy)
0058 {
0059 Box result;
0060
0061
0062
0063 geometry::assign_inverse(result);
0064
0065
0066
0067
0068 if ( first == last )
0069 return result;
0070
0071 detail::bounds(element_indexable(*first, tr), result, strategy);
0072 ++first;
0073
0074 for ( ; first != last ; ++first )
0075 detail::expand(result, element_indexable(*first, tr), strategy);
0076
0077 return result;
0078 }
0079
0080
0081
0082
0083
0084
0085 template <typename Box, typename FwdIter, typename Translator, typename Strategy>
0086 inline Box values_box(FwdIter first, FwdIter last, Translator const& tr,
0087 Strategy const& strategy)
0088 {
0089 typedef typename std::iterator_traits<FwdIter>::value_type element_type;
0090 BOOST_GEOMETRY_STATIC_ASSERT((is_leaf_element<element_type>::value),
0091 "This function should be called only for elements of leaf nodes.",
0092 element_type);
0093
0094 Box result = elements_box<Box>(first, last, tr, strategy);
0095
0096 #ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
0097 if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry
0098 <
0099 typename indexable_type<Translator>::type
0100 >::value)
0101 {
0102 geometry::detail::expand_by_epsilon(result);
0103 }
0104 #endif
0105
0106 return result;
0107 }
0108
0109
0110 template <typename MembersHolder>
0111 struct destroy_element
0112 {
0113 typedef typename MembersHolder::parameters_type parameters_type;
0114 typedef typename MembersHolder::allocators_type allocators_type;
0115
0116 typedef typename MembersHolder::internal_node internal_node;
0117 typedef typename MembersHolder::leaf leaf;
0118
0119 inline static void apply(typename internal_node::elements_type::value_type & element,
0120 allocators_type & allocators)
0121 {
0122 detail::rtree::visitors::destroy<MembersHolder>::apply(element.second, allocators);
0123
0124 element.second = 0;
0125 }
0126
0127 inline static void apply(typename leaf::elements_type::value_type &,
0128 allocators_type &)
0129 {}
0130 };
0131
0132
0133 template <typename MembersHolder>
0134 struct destroy_elements
0135 {
0136 typedef typename MembersHolder::value_type value_type;
0137 typedef typename MembersHolder::allocators_type allocators_type;
0138
0139 template <typename Range>
0140 inline static void apply(Range & elements, allocators_type & allocators)
0141 {
0142 apply(boost::begin(elements), boost::end(elements), allocators);
0143 }
0144
0145 template <typename It>
0146 inline static void apply(It first, It last, allocators_type & allocators)
0147 {
0148 typedef std::is_same
0149 <
0150 value_type, typename std::iterator_traits<It>::value_type
0151 > is_range_of_values;
0152
0153 apply_dispatch(first, last, allocators, is_range_of_values());
0154 }
0155
0156 private:
0157 template <typename It>
0158 inline static void apply_dispatch(It first, It last, allocators_type & allocators,
0159 std::false_type )
0160 {
0161 for ( ; first != last ; ++first )
0162 {
0163 detail::rtree::visitors::destroy<MembersHolder>::apply(first->second, allocators);
0164
0165 first->second = 0;
0166 }
0167 }
0168
0169 template <typename It>
0170 inline static void apply_dispatch(It , It , allocators_type & ,
0171 std::true_type )
0172 {}
0173 };
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 template <typename Container, typename Iterator>
0215 void move_from_back(Container & container, Iterator it)
0216 {
0217 BOOST_GEOMETRY_INDEX_ASSERT(!container.empty(), "cannot copy from empty container");
0218 Iterator back_it = container.end();
0219 --back_it;
0220 if ( it != back_it )
0221 {
0222 *it = std::move(*back_it);
0223 }
0224 }
0225
0226 }}
0227
0228 }}}
0229
0230 #endif