GEOS  3.13.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 
19 namespace geos {
20 namespace index {
21 namespace strtree {
22 
23 template<typename ItemType, typename BoundsTraits>
24 class TemplateSTRNode {
25 private:
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 
44 public:
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: Angle.h:25