DYT/Tool/OpenSceneGraph-3.6.5/include/geos/index/strtree/TemplateSTRNode.h
2024-12-25 07:49:36 +08:00

157 lines
3.6 KiB
C++

/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2020-2021 Daniel Baston
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************/
#pragma once
#include <utility>
namespace geos {
namespace index {
namespace strtree {
template<typename ItemType, typename BoundsTraits>
class TemplateSTRNode {
private:
using BoundsType = typename BoundsTraits::BoundsType;
BoundsType bounds;
union Body {
ItemType item;
const TemplateSTRNode* childrenEnd;
explicit Body (ItemType&& p_item) : item(std::forward<ItemType>(p_item)) {}
explicit Body (const ItemType& p_item) : item(p_item) {}
explicit Body (const TemplateSTRNode<ItemType, BoundsTraits>* p_childrenEnd) : childrenEnd(p_childrenEnd) {}
~Body() = default;
} data;
const TemplateSTRNode* children;
public:
~TemplateSTRNode() {
if (isLeaf()) {
data.item.~ItemType();
}
}
TemplateSTRNode(ItemType&& p_item, const BoundsType& env) :
bounds(env),
data(std::forward<ItemType>(p_item)),
children(nullptr)
{}
TemplateSTRNode(const ItemType& p_item, const BoundsType& env) :
bounds(env),
data(p_item),
children(nullptr)
{}
TemplateSTRNode(const TemplateSTRNode* begin, const TemplateSTRNode* end) :
bounds(boundsFromChildren(begin, end)),
data(end),
children(begin)
{}
const TemplateSTRNode* beginChildren() const {
return children;
}
const TemplateSTRNode* endChildren() const {
return data.childrenEnd;
}
bool isDeleted() const {
return children == this;
}
bool isLeaf() const {
return children == nullptr || children == this;
}
bool isComposite() const {
return !isLeaf();
}
bool boundsIntersect(const BoundsType& queryBounds) const {
return BoundsTraits::intersects(getBounds(), queryBounds);
}
double getSize() const {
return BoundsTraits::size(getBounds());
}
static BoundsType boundsFromChildren(const TemplateSTRNode* from, const TemplateSTRNode* to) {
BoundsType bnds = from->getBounds();
for (auto *child = from + 1; child < to; ++child) {
BoundsTraits::expandToInclude(bnds, child->getBounds());
}
return bnds;
}
BoundsType boundsFromChildren() const {
return boundsFromChildren(children, data.childrenEnd);
}
const BoundsType& getBounds() const {
return bounds;
}
std::size_t getNumNodes() const
{
if (isLeaf()) {
return isDeleted() ? 0 : 1;
}
std::size_t count = 1;
for (const auto* child = beginChildren(); child != endChildren(); ++child) {
count += child->getNumNodes();
}
return count;
}
std::size_t getNumLeafNodes() const
{
if (isLeaf()) {
return isDeleted() ? 0 : 1;
}
std::size_t count = 0;
for (const auto* child = beginChildren(); child != endChildren(); ++child) {
count += child->getNumNodes();
}
return count;
}
const ItemType& getItem() const {
assert(!isDeleted());
return data.item;
}
void removeItem() {
children = this;
}
};
}
}
}