1- #pragma once
2-
3- #include < iostream>
4- #include < sstream>
5- #include < fstream>
6- #include < filesystem>
71#include < vector>
82#include < limits>
93#include < cassert>
104#include < optional>
11-
12- #include " aocio.hpp"
13-
14- #ifndef AOC_INPUT_PATH
15- #define AOC_INPUT_PATH " "
16- #endif
17-
18- #ifndef AOC_INPUT_DIR
19- #define AOC_INPUT_DIR " "
20- #endif
21-
22- namespace aocio
23- {
24- bool file_getlines (std::string_view fname, std::vector<std::string>& lines);
25- void line_tokenise (const std::string& line, const std::string& delims, const std::string& preserved_delims, std::vector<std::string>& tokens);
26-
27- int parse_num (const std::string &str);
28- int64_t parse_num_i64 (const std::string& str);
29-
30- inline void print_day ()
31- {
32- std::string day_name {std::filesystem::path (AOC_INPUT_DIR).parent_path ().filename ()};
33-
34- if (day_name.size ()) {
35- day_name[0 ] = std::toupper (day_name[0 ]);
36- }
37-
38- std::string debug_release;
39- #ifdef NDEBUG
40- debug_release = " Release" ;
41- #else
42- debug_release = " Debug" ;
43- #endif
44-
45- std::cout << day_name << " (" << debug_release << " )\n " ;
46- }
47- }
5+ #include " vec.hpp"
486
497namespace aocutil
508{
519
52- template <typename T>
53- struct Vec2 {
54- T x, y;
55-
56- Vec2 operator +(const Vec2& v) const
57- {
58- return Vec2{.x = x + v.x , .y = y + v.y };
59- }
60-
61- Vec2 operator -(const Vec2& v) const
62- {
63- return Vec2{.x = x - v.x , .y = y - v.y };
64- }
65-
66- bool operator ==(const Vec2& v) const = default ;
67- };
68-
6910template <typename RowType, typename ElemType>
70- class Grid ;
11+ class Grid ; // Forward declaration for the iterators.
7112
7213// cf. on custom iterators: https://internalpointers.com/post/writing-custom-iterators-modern-cpp (last retrieved 2024-06-19)
7314template <typename RowType, typename ElemType, bool is_const>
@@ -80,8 +21,6 @@ struct GridColIterator
8021 using reference = typename std::conditional_t <is_const, const ElemType&, ElemType&>;
8122 using parent_ptr_type = typename std::conditional_t <is_const, const Grid<RowType, ElemType>*, Grid<RowType, ElemType>*>;
8223
83- // GridColIterator() = default;
84-
8524 GridColIterator (int column, int row, parent_ptr_type parent) : col(column), current_row(row), parent(parent)
8625 {
8726 assert (parent);
@@ -160,7 +99,7 @@ struct GridColIterator
16099 {
161100 int new_row = current_row - n;
162101 if (new_row < 0 || new_row >= parent->height ()) {
163- throw std::out_of_range (" GridIter : subscript out of range" );
102+ throw std::out_of_range (" GridColIterator : subscript out of range" );
164103 }
165104 return parent->at (col, new_row);
166105 }
@@ -187,13 +126,24 @@ struct GridColIterator
187126 return iter - n;
188127 }
189128
190- friend bool operator ==(const GridColIterator& a, const GridColIterator& b) {assert (a.col == b.col && a.parent == b.parent ); return a.current_row == b.current_row ; };
191- friend bool operator !=(const GridColIterator& a, const GridColIterator& b) {assert (a.col == b.col && a.parent == b.parent ); return a.current_row != b.current_row ;};
129+ friend bool operator ==(const GridColIterator& a, const GridColIterator& b)
130+ {
131+ assert (a.col == b.col && a.parent == b.parent );
132+ bool eq = a.current_row == b.current_row ;
133+ assert (!(eq && (a.ptr != b.ptr )));
134+ return eq;
135+ };
136+
137+ friend bool operator !=(const GridColIterator& a, const GridColIterator& b)
138+ {
139+ assert (a.col == b.col && a.parent == b.parent );
140+ return a.current_row != b.current_row ;
141+ };
192142
193143private:
194144 int col;
195145 int current_row;
196- parent_ptr_type parent = nullptr ; // ptr itself is const (and parent_ptr_type depending on is_const).
146+ parent_ptr_type parent = nullptr ;
197147 pointer ptr;
198148};
199149
@@ -208,8 +158,6 @@ struct GridIterator
208158 using reference = typename std::conditional_t <is_const, const ElemType&, ElemType&>;
209159 using parent_ptr_type = typename std::conditional_t <is_const, const Grid<RowType, ElemType>*, Grid<RowType, ElemType>*>;
210160
211- // GridIterator() = default;
212-
213161 GridIterator (int column, int row, parent_ptr_type parent) : current_col(column), current_row(row), parent(parent)
214162 {
215163 assert (parent);
@@ -332,7 +280,7 @@ struct GridIterator
332280 int new_col = new_idx % parent->width ();
333281 int new_row = new_idx / parent->width ();
334282 if (!parent->pos_on_grid (new_col, new_row)) {
335- throw std::out_of_range (" Grid : subscript out of range." );
283+ throw std::out_of_range (" GridIterator : subscript out of range." );
336284 }
337285 return parent->at (new_col, new_row);
338286 }
@@ -363,8 +311,18 @@ struct GridIterator
363311 return iter - n;
364312 }
365313
366- friend bool operator ==(const GridIterator& a, const GridIterator& b) {assert (a.parent == b.parent ); return a.ptr == b.ptr ;};
367- friend bool operator !=(const GridIterator& a, const GridIterator& b) {assert (a.parent == b.parent ); return a.ptr != b.ptr ;};
314+ friend bool operator ==(const GridIterator& a, const GridIterator& b)
315+ {
316+ assert (a.parent == b.parent );
317+ return a.ptr == b.ptr && (a.current_col == b.current_col && a.current_row == b.current_row );
318+ };
319+
320+ friend bool operator !=(const GridIterator& a, const GridIterator& b)
321+ {
322+ assert (a.parent == b.parent );
323+ assert (!((a.ptr != b.ptr ) && (a.current_col == b.current_col && a.current_row == b.current_row )));
324+ return a.ptr != b.ptr ;
325+ };
368326
369327private:
370328 int current_col = 0 ;
@@ -567,15 +525,4 @@ class Grid
567525 }
568526};
569527
570- }
571-
572- template <typename T>
573- struct std ::hash<aocutil::Vec2<T>>
574- {
575- std::size_t operator ()(const aocutil::Vec2<T>& v) const noexcept
576- {
577- std::size_t h1 = std::hash<T>{}(v.x );
578- std::size_t h2 = std::hash<T>{}(v.y );
579- return h1 ^ (h2 << 1 ); // cf. https://en.cppreference.com/w/cpp/utility/hash (last retrieved 2024-06-17)
580- }
581- };
528+ }
0 commit comments