42#ifndef UFO_CONTAINER_TREE_KEY_HPP
43#define UFO_CONTAINER_TREE_KEY_HPP
46#include <ufo/morton/morton.hpp>
47#include <ufo/numeric/vec.hpp>
59template <std::
size_t Dim>
63 using key_type = std::uint32_t;
65 using depth_type = key_type;
66 using size_type = std::size_t;
75 constexpr TreeKey()
noexcept =
default;
78 constexpr TreeKey(
Key key, depth_type depth) :
Key(key), depth_(depth) {}
96 [[nodiscard]]
static constexpr depth_type maxDepth()
noexcept
103 return std::numeric_limits<key_type>::digits - 1;
112 [[nodiscard]]
constexpr bool valid()
const noexcept {
return maxDepth() >= depth_; }
114 [[nodiscard]]
constexpr depth_type depth()
const noexcept {
return depth_; }
116 [[nodiscard]]
constexpr TreeKey toDepth(depth_type depth)
const
118 assert(maxDepth() >= depth);
132 assert(maxDepth() >= depth);
134 if (depth_ > depth) {
135 *
this <<= depth_ - depth;
137 *
this >>= depth - depth_;
139 this->depth_ = depth;
144 [[nodiscard]]
constexpr key_type offset() const noexcept {
return offset(depth_); }
146 [[nodiscard]]
constexpr key_type offset(depth_type depth)
const noexcept
148 assert(maxDepth() >= depth);
149 assert(depth_ <= depth);
151 auto v = (*
this >> (depth - depth_)) & key_type(1);
153 for (std::size_t i = 1; Dim > i; ++i) {
159 [[nodiscard]]
constexpr TreeKey parent()
const
161 assert(maxDepth() > depth_);
169 void swap(TreeKey& other)
noexcept
172 static_cast<Key&
>(*this).swap(
static_cast<Key&
>(other));
173 swap(depth_, other.depth_);
180using BinaryKey = TreeKey<1>;
181using QuadKey = TreeKey<2>;
182using OctKey = TreeKey<3>;
183using HexKey = TreeKey<4>;
185template <std::
size_t Dim>
186std::ostream& operator<<(std::ostream& out, TreeKey<Dim>
const& key)
188 return out << static_cast<typename TreeKey<Dim>::Key
const&>(key)
189 <<
" d: " << key.depth();
192template <std::
size_t Dim>
193void swap(TreeKey<Dim>& lhs, TreeKey<Dim>& rhs)
noexcept
204template <std::
size_t Dim>
205[[nodiscard]]
constexpr bool operator==(TreeKey<Dim>
const& lhs,
206 TreeKey<Dim>
const& rhs)
noexcept
208 using Key =
typename TreeKey<Dim>::Key;
209 return static_cast<Key const&
>(lhs) ==
static_cast<Key const&
>(rhs) &&
210 lhs.depth() == rhs.depth();
213template <std::
size_t Dim>
214[[nodiscard]]
constexpr bool operator!=(TreeKey<Dim>
const& lhs,
215 TreeKey<Dim>
const& rhs)
noexcept
217 return !(lhs == rhs);
220template <std::
size_t Dim>
221[[nodiscard]]
constexpr bool operator<(TreeKey<Dim>
const& lhs,
222 TreeKey<Dim>
const& rhs)
noexcept
224 for (std::size_t i{}; Dim > i; ++i) {
225 if (lhs[i] < rhs[i]) {
227 }
else if (lhs[i] > rhs[i]) {
234template <std::
size_t Dim>
235[[nodiscard]]
constexpr bool operator<=(TreeKey<Dim>
const& lhs,
236 TreeKey<Dim>
const& rhs)
noexcept
238 for (std::size_t i{}; Dim > i; ++i) {
239 if (lhs[i] < rhs[i]) {
241 }
else if (lhs[i] > rhs[i]) {
248template <std::
size_t Dim>
249[[nodiscard]]
constexpr bool operator>(TreeKey<Dim>
const& lhs,
250 TreeKey<Dim>
const& rhs)
noexcept
252 for (std::size_t i{}; Dim > i; ++i) {
253 if (lhs[i] > rhs[i]) {
255 }
else if (lhs[i] < rhs[i]) {
262template <std::
size_t Dim>
263[[nodiscard]]
constexpr bool operator>=(TreeKey<Dim>
const& lhs,
264 TreeKey<Dim>
const& rhs)
noexcept
266 for (std::size_t i{}; Dim > i; ++i) {
267 if (lhs[i] > rhs[i]) {
269 }
else if (lhs[i] < rhs[i]) {
282template <std::
size_t Dim>
283[[nodiscard]]
constexpr TreeKey<Dim> operator+(TreeKey<Dim> key, std::uint32_t v)
noexcept
289template <std::
size_t Dim>
290[[nodiscard]]
constexpr TreeKey<Dim> operator+(TreeKey<Dim> key,
291 Vec<Dim, std::uint32_t>
const& v)
noexcept
297template <std::
size_t Dim>
298[[nodiscard]]
constexpr TreeKey<Dim> operator+(std::uint32_t v, TreeKey<Dim> key)
noexcept
304template <std::
size_t Dim>
305[[nodiscard]]
constexpr TreeKey<Dim> operator+(Vec<Dim, std::uint32_t>
const& v,
306 TreeKey<Dim> key)
noexcept
312template <std::
size_t Dim>
313[[nodiscard]]
constexpr TreeKey<Dim> operator-(TreeKey<Dim> key, std::uint32_t v)
noexcept
319template <std::
size_t Dim>
320[[nodiscard]]
constexpr TreeKey<Dim> operator-(TreeKey<Dim> key,
321 Vec<Dim, std::uint32_t>
const& v)
noexcept
327template <std::
size_t Dim>
328[[nodiscard]]
constexpr TreeKey<Dim> operator-(std::uint32_t v, TreeKey<Dim> key)
noexcept
334template <std::
size_t Dim>
335[[nodiscard]]
constexpr TreeKey<Dim> operator-(Vec<Dim, std::uint32_t>
const& v,
336 TreeKey<Dim> key)
noexcept
345template <std::
size_t Dim>
346struct hash<
ufo::TreeKey<Dim>> {
350 return static_cast<std::size_t
>(
constexpr void setDepth(depth_type depth) noexcept
Change the depth of the key.
All vision-related classes and functions.
A fixed-size arithmetic vector of up to 4 dimensions.