GEOS 3.14.0dev
TemplateSTRNode.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2020-2021 Daniel Baston
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU Lesser General Public Licence as published
10 * by the Free Software Foundation.
11 * See the COPYING file for more information.
12 *
13 **********************************************************************/
14
15#pragma once
16
17#include <utility>
18
19namespace geos {
20namespace index {
21namespace strtree {
22
23template<typename ItemType, typename BoundsTraits>
24class TemplateSTRNode {
25private:
26 using BoundsType = typename BoundsTraits::BoundsType;
27
28 BoundsType bounds;
29
30 union Body {
31 ItemType item;
32 const TemplateSTRNode* childrenEnd;
33
34 explicit Body (ItemType&& p_item) : item(std::forward<ItemType>(p_item)) {}
35
36 explicit Body (const ItemType& p_item) : item(p_item) {}
37
38 explicit Body (const TemplateSTRNode<ItemType, BoundsTraits>* p_childrenEnd) : childrenEnd(p_childrenEnd) {}
39
40 ~Body() = default;
41 } data;
42 const TemplateSTRNode* children;
43
44public:
45 ~TemplateSTRNode() {
46 if (isLeaf()) {
47 data.item.~ItemType();
48 }
49 }
50
51 TemplateSTRNode(ItemType&& p_item, const BoundsType& env) :
52 bounds(env),
53 data(std::forward<ItemType>(p_item)),
54 children(nullptr)
55 {}
56
57 TemplateSTRNode(const ItemType& p_item, const BoundsType& env) :
58 bounds(env),
59 data(p_item),
60 children(nullptr)
61 {}
62
63 TemplateSTRNode(const TemplateSTRNode* begin, const TemplateSTRNode* end) :
64 bounds(boundsFromChildren(begin, end)),
65 data(end),
66 children(begin)
67 {}
68
69 const TemplateSTRNode* beginChildren() const {
70 return children;
71 }
72
73 const TemplateSTRNode* endChildren() const {
74 return data.childrenEnd;
75 }
76
77 bool isDeleted() const {
78 return children == this;
79 }
80
81 bool isLeaf() const {
82 return children == nullptr || children == this;
83 }
84
85 bool isComposite() const {
86 return !isLeaf();
87 }
88
89 bool boundsIntersect(const BoundsType& queryBounds) const {
90 return BoundsTraits::intersects(getBounds(), queryBounds);
91 }
92
93 double getSize() const {
94 return BoundsTraits::size(getBounds());
95 }
96
97 static BoundsType boundsFromChildren(const TemplateSTRNode* from, const TemplateSTRNode* to) {
98 BoundsType bnds = from->getBounds();
99
100 for (auto *child = from + 1; child < to; ++child) {
101 BoundsTraits::expandToInclude(bnds, child->getBounds());
102 }
103
104 return bnds;
105 }
106
107 BoundsType boundsFromChildren() const {
108 return boundsFromChildren(children, data.childrenEnd);
109 }
110
111 const BoundsType& getBounds() const {
112 return bounds;
113 }
114
115 std::size_t getNumNodes() const
116 {
117 if (isLeaf()) {
118 return isDeleted() ? 0 : 1;
119 }
120
121 std::size_t count = 1;
122 for (const auto* child = beginChildren(); child != endChildren(); ++child) {
123 count += child->getNumNodes();
124 }
125
126 return count;
127 }
128
129 std::size_t getNumLeafNodes() const
130 {
131 if (isLeaf()) {
132 return isDeleted() ? 0 : 1;
133 }
134
135 std::size_t count = 0;
136 for (const auto* child = beginChildren(); child != endChildren(); ++child) {
137 count += child->getNumNodes();
138 }
139 return count;
140 }
141
142 const ItemType& getItem() const {
143 assert(!isDeleted());
144 return data.item;
145 }
146
147 void removeItem() {
148 children = this;
149 }
150
151};
152
153}
154}
155}
156
Basic namespace for all GEOS functionalities.
Definition geos.h:39