FireSTARR
Loading...
Searching...
No Matches
Location.h
1/* Copyright (c) Queen's Printer for Ontario, 2020. */
2/* Copyright (c) His Majesty the King in Right of Canada as represented by the Minister of Natural Resources, 2021-2025. */
3
4/* SPDX-License-Identifier: AGPL-3.0-or-later */
5
6#pragma once
7#include "stdafx.h"
8#include "Util.h"
9#include "Log.h"
10namespace fs::topo
11{
12// have static versions of these outside Position so we can test with static_assert
20[[nodiscard]] static inline constexpr HashSize do_hash(
21 const uint32_t XYBits,
22 const Idx row,
23 const Idx column) noexcept
24{
25 return (static_cast<HashSize>(row) << XYBits) + static_cast<HashSize>(column);
26}
33[[nodiscard]] static inline constexpr Idx unhash_row(
34 const uint32_t XYBits,
35 const Topo hash) noexcept
36{
37 // don't need to use mask since bits just get shifted out
38 return static_cast<Idx>(hash >> XYBits);
39}
46[[nodiscard]] static inline constexpr Idx unhash_column(
47 const Topo ColumnMask,
48 const Topo hash) noexcept
49{
50 return static_cast<Idx>(hash & ColumnMask);
51}
55template <class V>
57{
58public:
59 Position() = default;
64 [[nodiscard]] constexpr Idx row() const noexcept
65 {
66 return unhashRow(hash());
67 }
72 [[nodiscard]] constexpr Idx column() const noexcept
73 {
74 return unhashColumn(hash());
75 }
80 [[nodiscard]] constexpr HashSize hash() const noexcept
81 {
82#ifdef DEBUG_POINTS
83 constexpr int num_bits = std::numeric_limits<HashSize>::digits;
84 constexpr Topo m = util::bit_mask<num_bits, Topo>();
85 logging::check_equal(
86 static_cast<HashSize>(topo_data_),
87 static_cast<HashSize>(m & topo_data_),
88 "hash()");
89#endif
90 // can get away with just casting because all the other bits are outside this area
91 return static_cast<HashSize>(topo_data_);
92 }
98 [[nodiscard]] constexpr bool operator==(const Position& rhs) const noexcept
99 {
100 return hash() == rhs.hash();
101 }
107 [[nodiscard]] constexpr bool operator!=(const Position& rhs) const noexcept
108 {
109 return !(*this == rhs);
110 }
111protected:
119 static constexpr uint32_t XYBits = std::bit_width<uint32_t>(MAX_ROWS - 1);
120 static_assert(util::pow_int<XYBits, size_t>(2) == MAX_ROWS);
121 static_assert(util::pow_int<XYBits, size_t>(2) == MAX_COLUMNS);
125 static constexpr uint32_t PositionBits = XYBits * 2;
129 static constexpr Topo ColumnMask = util::bit_mask<XYBits, Topo>();
133 static constexpr Topo HashMask = util::bit_mask<PositionBits, Topo>();
134 static_assert(HashMask >= static_cast<size_t>(MAX_COLUMNS) * MAX_ROWS - 1);
135 static_assert(HashMask <= std::numeric_limits<HashSize>::max());
140 explicit constexpr Position(const Topo& topo) noexcept
141 : topo_data_(topo)
142 {
143 }
150 [[nodiscard]] static constexpr HashSize doHash(
151 const Idx row,
152 const Idx column) noexcept
153 {
154 return do_hash(XYBits, row, column);
155// make sure hashing/unhashing works
156#define ROW_MIN 0
157#define ROW_MAX (MAX_ROWS - 1)
158#define COL_MIN 0
159#define COL_MAX (MAX_COLUMNS - 1)
160 static_assert(ROW_MIN == unhash_row(XYBits, do_hash(XYBits, ROW_MIN, COL_MIN)));
161 static_assert(COL_MIN == unhash_column(ColumnMask, do_hash(XYBits, ROW_MIN, COL_MIN)));
162 static_assert(ROW_MIN == unhash_row(XYBits, do_hash(XYBits, ROW_MIN, COL_MAX)));
163 static_assert(COL_MAX == unhash_column(ColumnMask, do_hash(XYBits, ROW_MIN, COL_MAX)));
164 static_assert(ROW_MAX == unhash_row(XYBits, do_hash(XYBits, ROW_MAX, COL_MIN)));
165 static_assert(COL_MIN == unhash_column(ColumnMask, do_hash(XYBits, ROW_MAX, COL_MIN)));
166 static_assert(ROW_MAX == unhash_row(XYBits, do_hash(XYBits, ROW_MAX, COL_MAX)));
167 static_assert(COL_MAX == unhash_column(ColumnMask, do_hash(XYBits, ROW_MAX, COL_MAX)));
168#undef ROW_MIN
169#undef ROW_MAX
170#undef COL_MIN
171#undef COL_MAX
172 }
178 [[nodiscard]] static constexpr Idx unhashRow(const Topo hash) noexcept
179 {
180 return unhash_row(XYBits, hash);
181 }
187 [[nodiscard]] static constexpr Idx unhashColumn(const Topo hash) noexcept
188 {
189 return unhash_column(ColumnMask, hash);
190 }
191};
192template <class V>
193inline bool operator<(const Position<V>& lhs, const Position<V>& rhs)
194{
195 return lhs.hash() < rhs.hash();
196}
197template <class V>
198inline bool operator>(const Position<V>& lhs, const Position<V>& rhs)
199{
200 return rhs < lhs;
201}
202template <class V>
203inline bool operator<=(const Position<V>& lhs, const Position<V>& rhs)
204{
205 return !(lhs > rhs);
206}
207template <class V>
208inline bool operator>=(const Position<V>& lhs, const Position<V>& rhs)
209{
210 return !(lhs < rhs);
211}
212
213#ifdef DEBUG_DIRECTIONS
214// FIX: seems like there must be something with enum type that would be better?
215static const map<CellIndex, const char*> DIRECTION_NAMES{
216 {DIRECTION_NONE, "NONE"},
217 {DIRECTION_W, "W"},
218 {DIRECTION_E, "E"},
219 {DIRECTION_S, "S"},
220 {DIRECTION_N, "N"},
221 {DIRECTION_SW, "SW"},
222 {DIRECTION_NE, "NE"},
223 {DIRECTION_NW, "NW"},
224 {DIRECTION_SE, "SE"}};
225#endif
226
228 : public Position<HashSize>
229{
230public:
231 using Position::Position;
236// NOTE: do this so that we don't get warnings about unused variables in release mode
237#ifdef NDEBUG
238 explicit constexpr Location(const Idx, const Idx, const HashSize hash) noexcept
239#else
240 explicit Location(const Idx row, const Idx column, const HashSize hash) noexcept
241#endif
242 : Location(hash & HashMask)
243 {
244#ifdef DEBUG_GRIDS
245 logging::check_fatal(
246 row < 0 || row >= MAX_ROWS,
247 "Row %d is out of bounds (%d, %d)",
248 row,
249 0,
250 MAX_ROWS);
251 logging::check_fatal(
252 column < 0 || column >= MAX_COLUMNS,
253 "Column %d is out of bounds (%d, %d)",
254 column,
255 0,
256 MAX_COLUMNS);
257 logging::check_fatal(
260 "Hash is incorrect (%d, %d)",
261 row,
262 column);
263#endif
264 }
270#ifdef NDEBUG
271 constexpr
272#endif
273 Location(const Idx row, const Idx column) noexcept
275 {
276#ifdef DEBUG_GRIDS
277 logging::check_fatal(row >= MAX_ROWS || column >= MAX_COLUMNS, "Location out of bounds (%d, %d)", row, column);
278#endif
279 }
280 Location(const Coordinates& coord)
281 : Location(std::get<0>(coord), std::get<1>(coord))
282 {
283 }
288 explicit constexpr Location(const HashSize& hash_size) noexcept
289 : Position(static_cast<HashSize>(hash_size))
290 {
291 }
296 template <class P>
297 explicit constexpr Location(const Position<P>& position) noexcept
298 : Position(static_cast<HashSize>(position.hash()))
299 {
300 }
301};
310CellIndex
311 relativeIndex(const Location& src, const Location& dst) noexcept;
312}
Definition Location.h:229
Location(const Idx row, const Idx column, const HashSize hash) noexcept
Construct using hash of row and column.
Definition Location.h:240
Location(const Idx row, const Idx column) noexcept
Constructor.
Definition Location.h:273
constexpr Location(const HashSize &hash_size) noexcept
Construct with given hash that may contain data from subclasses.
Definition Location.h:288
constexpr Location(const Position< P > &position) noexcept
Construct with given hash that may contain data from subclasses.
Definition Location.h:297
A Position with a row and column.
Definition Location.h:57
static constexpr Idx unhashColumn(const Topo hash) noexcept
Column.
Definition Location.h:187
constexpr Idx row() const noexcept
Row.
Definition Location.h:64
static constexpr Topo HashMask
Hash mask for bits being used for Position data.
Definition Location.h:133
constexpr bool operator!=(const Position &rhs) const noexcept
Inequality operator.
Definition Location.h:107
V topo_data_
Stored hash that contains row and column data.
Definition Location.h:115
static constexpr uint32_t PositionBits
Number of bits to use for storing Position data.
Definition Location.h:125
constexpr HashSize hash() const noexcept
Hash derived from row and column.
Definition Location.h:80
constexpr Idx column() const noexcept
Column.
Definition Location.h:72
static constexpr HashSize doHash(const Idx row, const Idx column) noexcept
Create a hash from given values.
Definition Location.h:150
constexpr bool operator==(const Position &rhs) const noexcept
Equality operator.
Definition Location.h:98
constexpr Position(const Topo &topo) noexcept
Construct with given hash that may contain data from subclasses.
Definition Location.h:140
static constexpr uint32_t XYBits
Number of bits to use for storing one coordinate of Position data.
Definition Location.h:119
static constexpr Idx unhashRow(const Topo hash) noexcept
Row from hash.
Definition Location.h:178
static constexpr Topo ColumnMask
Hash mask for bits being used for Position data.
Definition Location.h:129
Definition util.h:14