7#include "exception.hpp"
8#include "alignment.hpp"
14template<arrangement Arrangement>
23 is_absolute(
false), is_opposite(
false), alignment(0), span(1), index(0) {}
31 tt_axiom(is_absolute);
35 ttlet index_ = (size == 0 || !is_opposite) ? index : size - index - span;
37 tt_axiom(index_ >= 0 && index_ < size);
47 tt_axiom(is_absolute);
51 ttlet index_span = (size == 0 || !is_opposite) ? index + span : size - index;
53 tt_axiom(index_span >= 1 && index_span <= size);
63 tt_axiom(alignment >= 0 && alignment < span);
65 ttlet aligned_to_ =
begin(size) + alignment;
67 tt_axiom(aligned_to_ >= 0 && aligned_to_ < size);
71 [[nodiscard]]
constexpr bool operator==(
cell_address_axis const &rhs)
const noexcept
74 tt_axiom(alignment >= 0);
75 tt_axiom(rhs.span >= 1);
76 tt_axiom(rhs.alignment >= 0);
79 is_absolute == rhs.is_absolute &&
80 is_opposite == rhs.is_opposite &&
83 alignment == rhs.alignment;
87 [[nodiscard]]
friend constexpr cell_address_axis
88 operator*(cell_address_axis
const &lhs, cell_address_axis
const &rhs)
noexcept
92 tt_axiom(lhs.span >= 1);
95 tt_axiom(lhs.alignment >= 0);
96 r.alignment = lhs.alignment;
98 if (lhs.is_absolute) {
100 r.is_opposite = lhs.is_opposite;
104 r.is_absolute = rhs.is_absolute;
105 r.is_opposite = rhs.is_opposite;
106 if (lhs.is_opposite == rhs.is_opposite) {
107 r.index = rhs.index + lhs.index;
109 r.index = rhs.index - lhs.index;
116 [[nodiscard]]
friend std::string to_string(cell_address_axis
const &rhs)
noexcept
120 auto axis = Arrangement == arrangement::row ? (rhs.is_opposite ?
'T' :
'B') : (rhs.is_opposite ?
'R' :
'L');
122 if (!rhs.is_absolute) {
123 if (rhs.index != 0) {
124 r += fmt::format(
"{}{:+}", axis, rhs.index);
127 r += fmt::format(
"{}{}", axis, rhs.index);
130 tt_axiom(rhs.span >= 1);
132 if (std::ssize(r) == 0) {
135 r += fmt::format(
":{}", rhs.span);
137 tt_axiom(rhs.alignment >= 0);
138 if (rhs.alignment != 0) {
139 r += fmt::format(
":{}", rhs.alignment);
146 friend struct cell_address;
153 [[nodiscard]]
constexpr cell_address() noexcept : row(), column() {}
162 [[nodiscard]]
constexpr cell_address(
char const *str) : row(), column()
164 enum class state_t { Idle, Coord, Number };
165 enum class part_t { Coord, Span, Alignment };
168 part_t part = part_t::Coord;
169 bool is_absolute =
false;
170 bool is_positive =
true;
173 auto state = state_t::Idle;
183 part = part_t::Coord;
189 state = state_t::Coord;
194 state = state_t::Coord;
199 state = state_t::Coord;
204 state = state_t::Coord;
220 state = state_t::Number;
225 state = state_t::Number;
230 state = state_t::Number;
237 state = state_t::Number;
242 case state_t::Number:
243 if (c >=
'0' && c <=
'9') {
245 value +=
static_cast<int>(c -
'0');
255 ttlet is_row = axis ==
'B' || axis ==
'T';
256 ttlet is_opposite = axis ==
'R' || axis ==
'T';
260 row.index = narrow_cast<int16_t>(value);
261 row.is_opposite = is_opposite;
262 row.is_absolute = is_absolute;
264 column.index = narrow_cast<int16_t>(value);
265 column.is_opposite = is_opposite;
266 column.is_absolute = is_absolute;
272 row.span = narrow_cast<int8_t>(value);
273 row.is_opposite = is_opposite;
275 column.span = narrow_cast<int8_t>(value);
276 column.is_opposite = is_opposite;
280 case part_t::Alignment:
282 row.alignment = narrow_cast<int8_t>(value);
284 column.alignment = narrow_cast<int8_t>(value);
288 default: tt_no_default();
298 state = state_t::Number;
304 part = part_t::Alignment;
306 state = state_t::Number;
309 case part_t::Alignment:
312 default: tt_no_default();
318 state = state_t::Idle;
323 default: tt_no_default();
340 [[nodiscard]]
constexpr bool operator==(
cell_address const &rhs)
const noexcept
342 return this->row == rhs.row && this->column == rhs.column;
350 r.row = lhs.row * rhs.row;
351 r.column = lhs.column * rhs.column;
358 return to_string(rhs.column) + to_string(rhs.row);
363 return lhs << to_string(rhs);
367[[nodiscard]]
constexpr cell_address
operator"" _ca(
char const *str,
size_t str_len)
noexcept
369 return cell_address{str};
Definition cell_address.hpp:15
ssize_t end(ssize_t size) const noexcept
Find one beyond the end of the cell.
Definition cell_address.hpp:45
ssize_t begin(ssize_t size) const noexcept
Find the begin of the cell.
Definition cell_address.hpp:29
ssize_t aligned_to(ssize_t size) const noexcept
Find on which cell this aligns to.
Definition cell_address.hpp:61
Definition cell_address.hpp:149
friend constexpr cell_address operator*(cell_address const &lhs, cell_address const &rhs) noexcept
Transform rhs by lhs.
Definition cell_address.hpp:347
constexpr cell_address(char const *str)
Parse a cell position.
Definition cell_address.hpp:162
constexpr cell_address & operator*=(cell_address const &rhs) noexcept
Transform lhs/this by rhs.
Definition cell_address.hpp:334
Exception thrown during parsing on an error.
Definition exception.hpp:21