20 #ifndef ANTKEEPER_GEOM_HYPEROCTREE_HPP
21 #define ANTKEEPER_GEOM_HYPEROCTREE_HPP
30 #include <type_traits>
31 #include <unordered_set>
49 template <std::
unsigned_
integral T>
50 using hyperoctree_dfs_pre_compare = std::less<T>;
53 template <std::
unsigned_
integral T, std::
size_t DepthBits>
54 struct hyperoctree_bfs_compare
56 constexpr
bool operator()(
const T& lhs,
const T& rhs)
const noexcept
58 return std::rotr(lhs, DepthBits) < std::rotr(rhs, DepthBits);
63 template <hyperoctree_order Order, std::
unsigned_
integral T, std::
size_t DepthBits>
64 struct hyperoctree_container {};
67 template <std::
unsigned_
integral T, std::
size_t DepthBits>
70 typedef std::unordered_set<T>
type;
74 template <std::
unsigned_
integral T, std::
size_t DepthBits>
77 typedef std::set<T, hyperoctree_dfs_pre_compare<T>>
type;
81 template <std::
unsigned_
integral T, std::
size_t DepthBits>
84 typedef std::set<T, hyperoctree_bfs_compare<T, DepthBits>>
type;
97 template <std::
unsigned_
integral T, std::
size_t N, hyperoctree_order Order = hyperoctree_order::dfs_pre>
128 static consteval std::size_t find_max_depth() noexcept
131 for (std::size_t i = 1; i <=
sizeof(T) * 8; ++i)
184 typedef typename hyperoctree_container<order, node_type, depth_bits>::type
container_type;
187 typedef typename container_type::iterator
iterator;
343 return nodes.begin();
347 return nodes.begin();
351 return nodes.cbegin();
385 return nodes.rbegin();
387 return nodes.begin();
392 return nodes.rbegin();
394 return nodes.begin();
399 return nodes.crbegin();
401 return nodes.cbegin();
429 return nodes.crend();
447 return nodes.empty();
455 inline bool full() const noexcept
467 inline std::size_t
size() const noexcept
551 return nodes.contains(
node);
572 template <std::
unsigned_
integral T, std::
size_t N>
Hashed linear hyperoctree.
hyperoctree()
Constructs a hyperoctree with a single root node.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the first node of the revered hyperoctree, in the traversal order speci...
bool contains(node_type node) const
Checks if a node is contained within the hyperoctree.
static constexpr node_type resolution
Resolution in each dimension.
const_iterator begin() const noexcept
Returns an iterator to the first node, in the traversal order specified by hyperoctree::order.
const_reverse_iterator crend() const noexcept
Returns a reverse iterator to the node following the last node of the reverse hyperoctree,...
static constexpr std::size_t dimensions
Number of dimensions.
bool is_leaf(node_type node) const
Checks if a node has no children.
static constexpr node_type depth(node_type node) noexcept
Extracts the depth of a node from its identifier.
static constexpr node_type root
Node identifier of the persistent root node.
static constexpr node_type parent(node_type node) noexcept
Constructs an identifier for the parent of a node.
static constexpr std::size_t max_node_count
Number of nodes in a full hyperoctree.
reverse_iterator rend() noexcept
Returns a reverse iterator to the node following the last node of the reverse hyperoctree,...
static constexpr node_type depth_bits
Number of bits required to encode the depth of a node.
const_iterator cend() const noexcept
Returns an iterator to the node following the last node, in the traversal order specified by hyperoct...
static constexpr node_type siblings_per_node
Number of siblings per node.
bool full() const noexcept
Checks if the hyperoctree is full.
iterator begin() noexcept
Returns an iterator to the first node, in the traversal order specified by hyperoctree::order.
iterator end() noexcept
Returns an iterator to the node following the last node, in the traversal order specified by hyperoct...
const_reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the first node of the revered hyperoctree, in the traversal order speci...
T node_type
Node identifier type.
static constexpr node_type node_bits
Number of bits in the node type.
constexpr std::size_t max_size() const noexcept
Returns the total number of nodes the hyperoctree is capable of containing.
static constexpr node_type child(node_type node, T n) noexcept
Constructs an identifier for the nth child of a node.
static constexpr std::array< node_type, 2 > split(node_type node) noexcept
Extracts the depth and Morton location code of a node from its identifier.
static constexpr node_type ancestor(node_type node, node_type depth) noexcept
Constructs an identifier for the ancestor of a node at a given depth.
static constexpr node_type max_depth
Maximum node depth level.
std::size_t size() const noexcept
Returns the number of nodes in the hyperoctree.
const_iterator end() const noexcept
Returns an iterator to the node following the last node, in the traversal order specified by hyperoct...
static constexpr node_type common_ancestor(node_type a, node_type b) noexcept
Constructs an identifier for the first common ancestor of two nodes.
const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator to the first node of the revered hyperoctree, in the traversal order speci...
static constexpr node_type children_per_node
Number of children per node.
std::conditional< order !=hyperoctree_order::unordered, std::reverse_iterator< const_iterator >, const_iterator >::type const_reverse_iterator
Constant reverse iterator type.
static constexpr node_type sibling(node_type node, node_type n) noexcept
Constructs an identifier for the nth sibling of a node.
static constexpr node_type node(node_type depth, node_type location) noexcept
Constructs an identifier for a node at the given depth and location.
hyperoctree_container< order, node_type, depth_bits >::type container_type
Node container type.
void erase(node_type node)
Erases a node, along with its descendants, siblings, and descendants of siblings.
const_reverse_iterator rend() const noexcept
Returns a reverse iterator to the node following the last node of the reverse hyperoctree,...
bool empty() const noexcept
Checks if the hyperoctree has no nodes.
container_type::iterator iterator
Iterator type.
void insert(node_type node)
Inserts a node and its siblings into the hyperoctree, inserting ancestors as necessary.
const_iterator cbegin() const noexcept
Returns an iterator to the first node, in the traversal order specified by hyperoctree::order.
container_type::const_iterator const_iterator
Constant iterator type.
std::conditional< order !=hyperoctree_order::unordered, std::reverse_iterator< iterator >, iterator >::type reverse_iterator
Reverse iterator type.
static constexpr hyperoctree_order order
Node storage and traversal order.
static constexpr node_type divider_bits
Number of bits separating the depth and Morton location code in a node identifier.
static constexpr node_type location(node_type node) noexcept
Extracts the Morton location code of a node from its identifier.
void clear()
Erases all nodes except the root node, which is persistent.
static constexpr node_type location_bits
Number of bits required to encode the Morton location code of a node.
hyperoctree_order
Orders in which hyperoctree nodes can be stored and traversed.
@ unordered
Hyperoctree nodes are unordered, potentially resulting in faster insertions through the internal use ...
@ bfs
Hyperoctree nodes are stored and traversed in breadth-first order.
@ dfs_pre
Hyperoctree nodes are stored and traversed in depth-first preorder.