HooverChessUtils_PgnReader 0.9.0
Loading...
Searching...
No Matches
pgnreader-string-utils.h
Go to the documentation of this file.
1// Hoover Chess Utilities / PGN reader
2// Copyright (C) 2025 Sami Kiminki
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17#ifndef HOOVER_CHESS_UTILS__PGN_READER__PGNREADER_STRING_UTILS_H_INCLUDED
18#define HOOVER_CHESS_UTILS__PGN_READER__PGNREADER_STRING_UTILS_H_INCLUDED
19
20#include "chessboard.h"
21#include "chessboard-types.h"
22
23#include <algorithm>
24#include <array>
25#include <cassert>
26#include <cstddef>
27#include <limits>
28#include <string_view>
29#include <type_traits>
30
32{
33
36
43
55template <std::size_t t_maxLen>
57{
58 static_assert(t_maxLen > 0U);
59 static_assert(t_maxLen <= 255U);
60
61private:
62 std::uint8_t m_length;
63 std::array<char, t_maxLen> m_storage;
64
65public:
66
69 constexpr MiniString() noexcept : m_length { }
70 {
71 }
72
76 {
77 }
78
80 MiniString(const MiniString &) = default;
81
83 MiniString(MiniString &&) = default;
84
86 MiniString &operator = (const MiniString &) & = default;
87
90
92 ~MiniString() = default;
93
101 constexpr void setLength(std::uint8_t length) noexcept
102 {
103 assert(length <= t_maxLen);
104
105 m_length = length;
106 }
107
114 constexpr void assign(const char *str) noexcept
115 {
116 std::size_t len { };
117
118 while (*str != '\0' && len < t_maxLen)
119 m_storage[len++] = *str++;
120
121 m_length = len;
122 }
123
129 constexpr void assign(const char *str, std::size_t strLen) noexcept
130 {
131 const std::size_t len { std::min(capacity(), strLen) };
132
133 for (std::size_t i { }; i < len; ++i)
134 m_storage[i] = str[i];
135
136 m_length = len;
137 }
138
144 constexpr inline char operator [] (std::size_t index) const noexcept
145 {
146 assert(index <= t_maxLen);
147 return m_storage[index];
148 }
149
164 constexpr inline char &operator [] (std::size_t index) noexcept
165 {
166 assert(index <= t_maxLen);
167 return m_storage[index];
168 }
169
174 constexpr inline char *data() noexcept
175 {
176 return m_storage.data();
177 }
178
183 constexpr inline const char *data() const noexcept
184 {
185 return m_storage.data();
186 }
187
192 static constexpr inline std::size_t capacity() noexcept
193 {
194 return t_maxLen;
195 }
196
200 constexpr inline std::size_t size() const noexcept
201 {
202 assert(m_length <= t_maxLen);
203 return m_length;
204 }
205
215 constexpr std::string_view getStringView() const
216 {
217 return std::string_view { m_storage.data(), size() };
218 }
219};
220
232
235{
236public:
241 static constexpr inline char colChar(Square sq) noexcept
242 {
243 return 'a' + columnOf(sq);
244 }
245
250 static constexpr inline char rowChar(Square sq) noexcept
251 {
252 return '1' + rowOf(sq);
253 }
254
287
294 static MiniString<13U> plyNumToString(std::uint32_t plyNum) noexcept
295 {
296 return moveNumToString(moveNumOfPly(plyNum), colorOfPly(plyNum));
297 }
298
308 template <std::size_t bufSize, typename UintRangeType, typename UintType>
309 static char *genUnsignedToString(char *s, UintType num) noexcept
310 {
311 static_assert(std::is_unsigned_v<UintType>);
312 static_assert(std::is_integral_v<UintType>);
313 static_assert(std::is_unsigned_v<UintRangeType>);
314 static_assert(std::is_integral_v<UintRangeType>);
315 static_assert(std::numeric_limits<UintRangeType>::digits10 + 1U == bufSize);
316
317 // force limit the range
318 num &= std::numeric_limits<UintRangeType>::max();
319
320 char *i = s;
321
322 do
323 {
324 *i++ = '0' + (num % 10U);
325 num /= 10U;
326 }
327 while (num > 0U);
328
329 // Workaround for GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757
330 //
331 // This should be just:
332 //
333 // std::reverse(s, i);
334
335 const std::size_t len = i - s;
336 [[assume(len <= bufSize)]];
337
338 for (std::size_t c { }; c < len / 2U; ++c)
339 std::swap(s[c], s[len - c - 1U]);
340
341 return i;
342 }
343
351 static MiniString<13U> moveNumToString(std::uint_fast32_t moveNum, Color turn) noexcept
352 {
353 // max length: "4294967295..."
354 // 1234567890123 = 13 chars
356
357 char *i = ret.data();
358
360
361 *i++ = '.';
362 if (turn == Color::BLACK)
363 {
364 *i++ = '.';
365 *i++ = '.';
366 }
367
368 ret.setLength(i - ret.data());
369 return ret;
370 }
371
377 static constexpr char promoPieceChar(Piece promo) noexcept
378 {
379 static_assert(Piece::KNIGHT == Piece { 2U });
380 static_assert(Piece::BISHOP == Piece { 3U });
381 static_assert(Piece::ROOK == Piece { 4U });
382 static_assert(Piece::QUEEN == Piece { 5U });
383
384 std::uint32_t pieceCharactersWord {
385 (static_cast<std::uint32_t>('R') << 0U) |
386 (static_cast<std::uint32_t>('Q') << 8U) |
387 (static_cast<std::uint32_t>('N') << 16U) |
388 (static_cast<std::uint32_t>('B') << 24U) };
389
390 unsigned int shift { (static_cast<std::uint8_t>(promo) & 3U) * 8U };
391 return static_cast<char>((pieceCharactersWord >> shift) & 0xFFU);
392 }
393
433 static constexpr MiniString<1U> pieceToSanStr(Piece p) noexcept
434 {
435 static_assert(Piece::NONE == Piece { 0U });
436 static_assert(Piece::PAWN == Piece { 1U });
437 static_assert(Piece::KNIGHT == Piece { 2U });
438 static_assert(Piece::BISHOP == Piece { 3U });
439 static_assert(Piece::ROOK == Piece { 4U });
440 static_assert(Piece::QUEEN == Piece { 5U });
441 static_assert(Piece::KING == Piece { 6U });
442
443 constexpr std::uint64_t pieceCharactersWord {
444 (static_cast<std::uint64_t>('?') << 0U) |
445 (static_cast<std::uint64_t>('N') << 16U) |
446 (static_cast<std::uint64_t>('B') << 24U) |
447 (static_cast<std::uint64_t>('R') << 32U) |
448 (static_cast<std::uint64_t>('Q') << 40U) |
449 (static_cast<std::uint64_t>('K') << 48U) };
450
451 if (p > Piece::KING)
452 p = Piece::NONE;
453
454 const unsigned int index { static_cast<unsigned int>(p) };
455
456 char pieceCharacter { static_cast<char>((pieceCharactersWord >> (index * 8U)) & 0xFFU) };
457
459 ret[0U] = pieceCharacter;
460 ret.setLength(pieceCharacter != '\0' ? 1U : 0U);
461
462 return ret;
463 }
464
620
640
650 static std::string_view pieceAndColorToString(PieceAndColor pc) noexcept;
651
660 static std::string_view squareToString(Square sq, std::string_view emptySquareName) noexcept;
661
667
672 static void boardToFEN(const ChessBoard &board, FenString &fen) noexcept;
673
674};
675
677
678}
679
680#endif
The chessboard.
Definition chessboard.h:589
A Pascal-style length-prefixed string with the specified maximum length.
Definition pgnreader-string-utils.h:57
constexpr MiniString() noexcept
Initializing constructor. Sets the length of the contained string to 0.
Definition pgnreader-string-utils.h:69
std::array< char, t_maxLen > m_storage
Definition pgnreader-string-utils.h:63
constexpr void assign(const char *str) noexcept
Assigns a C-string.
Definition pgnreader-string-utils.h:114
constexpr void assign(const char *str, std::size_t strLen) noexcept
Assigns a string with length. In case the string is longer than the maximum capacity,...
Definition pgnreader-string-utils.h:129
constexpr char * data() noexcept
Returns a pointer to the string data. The string may be non-terminated by ('\0').
Definition pgnreader-string-utils.h:174
MiniString & operator=(const MiniString &) &=default
Copy assignment (default)
constexpr void setLength(std::uint8_t length) noexcept
Sets the length of the contained string without resetting the contents.
Definition pgnreader-string-utils.h:101
std::uint8_t m_length
Definition pgnreader-string-utils.h:62
~MiniString()=default
Destructor (default)
constexpr MiniString(MiniString_Uninitialized) noexcept
Non-initializing constructor. The state of the object is undefined.
Definition pgnreader-string-utils.h:75
constexpr const char * data() const noexcept
Returns a const pointer to the string data. The string may be non-terminated by ('\0').
Definition pgnreader-string-utils.h:183
MiniString(const MiniString &)=default
Copy constructor (default)
constexpr std::size_t size() const noexcept
Returns the size of the string.
Definition pgnreader-string-utils.h:200
constexpr std::string_view getStringView() const
Returns a string view to the string.
Definition pgnreader-string-utils.h:215
MiniString(MiniString &&)=default
Move constructor (default)
constexpr char operator[](std::size_t index) const noexcept
Returns a character at a specified offset. This function does not perform an index bounds check.
Definition pgnreader-string-utils.h:144
static constexpr std::size_t capacity() noexcept
Returns the capacity (maximum size) of a string to hold.
Definition pgnreader-string-utils.h:192
A legal move. Important: see the note!
Definition chessboard.h:198
Set of squares. Implemented using a bit-mask.
Definition chessboard-types-squareset.h:35
Miscellaneous string utilities.
Definition pgnreader-string-utils.h:235
static MiniString< 2U > sourceMaskToString(SquareSet srcMask) noexcept
Source mask to SAN notation.
static constexpr char colChar(Square sq) noexcept
Returns a file (column) designation character for a square, lower-case.
Definition pgnreader-string-utils.h:241
static MiniString< 7U > moveToSan(const ChessBoard &board, Move move)
Generates minimal SAN for a move. The move is fully validated by this function.
Definition pgnreader-string-utils.h:635
static constexpr MiniString< 1U > pieceToSanStr(Piece p) noexcept
Translates piece to SAN string.
Definition pgnreader-string-utils.h:433
static MiniString< 13U > plyNumToString(std::uint32_t plyNum) noexcept
Ply number to move string (e.g., "5." or "11...")
Definition pgnreader-string-utils.h:294
static constexpr char rowChar(Square sq) noexcept
Returns a rank (row) designation character for a square, lower-case.
Definition pgnreader-string-utils.h:250
static std::string_view pieceAndColorToString(PieceAndColor pc) noexcept
Returns a name string for PieceAndColor.
static constexpr char promoPieceChar(Piece promo) noexcept
Translates promotion piece to character (N/B/R/Q). Return value is unspecified for any other piece va...
Definition pgnreader-string-utils.h:377
static MiniString< 7U > moveToSanAndPlay(ChessBoard &board, Move move)
Generates minimal SAN for a move and plays it. The move is fully validated by this function.
static void boardToFEN(const ChessBoard &board, FenString &fen) noexcept
Builds a FEN string for the position on board.
static MiniString< 13U > moveNumToString(std::uint_fast32_t moveNum, Color turn) noexcept
Move number and side-to-move to move string (e.g., "5." or "11...")
Definition pgnreader-string-utils.h:351
static std::string_view moveTypeAndPromotionToString(MoveTypeAndPromotion typeAndPromotion) noexcept
Move type and promotion code to string.
static std::string_view squareToString(Square sq, std::string_view emptySquareName) noexcept
Returns a name string for Square.
static char * genUnsignedToString(char *s, UintType num) noexcept
Generic unsigned integer to string converter.
Definition pgnreader-string-utils.h:309
MoveTypeAndPromotion
Move type (4 bits, range: 0..15)
Definition chessboard.h:91
constexpr Color colorOfPly(std::uint_fast32_t plyNum) noexcept
Returns side to move for a ply number.
Definition pgnreader-types.h:66
constexpr RowColumn rowOf(Square sq) noexcept
Returns row number of square.
Definition chessboard-types.h:343
constexpr std::uint_fast32_t moveNumOfPly(std::uint_fast32_t plyNum) noexcept
Computes the full move for a ply number.
Definition pgnreader-types.h:75
PieceAndColor
Named piece and color.
Definition chessboard-types.h:219
Piece
Named piece.
Definition chessboard-types.h:204
Color
Color of a piece or side to move.
Definition chessboard-types.h:194
Square
Named square.
Definition chessboard-types.h:122
constexpr RowColumn columnOf(Square sq) noexcept
Returns column number of square.
Definition chessboard-types.h:331
@ NONE
Value representing no piece.
@ BLACK
Black piece or black side to move.
Definition chessboard-types-squareset.h:30
Tag for unitialized storage. This is a tiny optimization to save a single write when constructing a M...
Definition pgnreader-string-utils.h:42