Skip to content

Commit d812b56

Browse files
committed
Add method to forcefully set a lexer's position
1 parent e79e80e commit d812b56

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

fly/types/string/lexer.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ class BasicLexer
6060
*/
6161
constexpr std::size_t position() const;
6262

63+
/**
64+
* Set the lexer's current position into the C-string literal.
65+
*
66+
* The provided position is not checked for validity. If the position is past-the-end of the
67+
* C-string literal, further operations will fail (i.e. |peek| and |consume| will return
68+
* std::nullopt).
69+
*
70+
* @param position The lexer's new position.
71+
*/
72+
constexpr void set_position(std::size_t position);
73+
6374
/**
6475
* If a character is available at the current position (or some offset from the current
6576
* position) in the C-string literal, return that character.
@@ -166,6 +177,13 @@ constexpr std::size_t BasicLexer<CharType>::position() const
166177
return m_index;
167178
}
168179

180+
//==================================================================================================
181+
template <typename CharType>
182+
constexpr void BasicLexer<CharType>::set_position(std::size_t position)
183+
{
184+
m_index = position;
185+
}
186+
169187
//==================================================================================================
170188
template <typename CharType>
171189
constexpr std::optional<CharType> BasicLexer<CharType>::peek(std::size_t offset)

test/types/string/lexer.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,30 @@ CATCH_TEMPLATE_TEST_CASE("BasicLexer", "[string]", char, wchar_t, char8_t, char1
6262
CATCH_CHECK_FALSE(lexer.consume());
6363
}
6464

65+
CATCH_SECTION("Setting the lexer's position mutates internal pointer")
66+
{
67+
Lexer lexer(FLY_ARR(char_type, "ab"));
68+
CATCH_CHECK(lexer.position() == 0);
69+
70+
lexer.set_position(1);
71+
CATCH_CHECK(lexer.position() == 1);
72+
73+
auto p1 = lexer.peek();
74+
CATCH_REQUIRE(p1.has_value());
75+
CATCH_CHECK(p1.value() == FLY_CHR(char_type, 'b'));
76+
77+
lexer.set_position(0);
78+
CATCH_CHECK(lexer.position() == 0);
79+
80+
auto p2 = lexer.peek();
81+
CATCH_REQUIRE(p2.has_value());
82+
CATCH_CHECK(p2.value() == FLY_CHR(char_type, 'a'));
83+
84+
lexer.set_position(2);
85+
CATCH_CHECK(lexer.position() == 2);
86+
CATCH_CHECK_FALSE(lexer.peek());
87+
}
88+
6589
CATCH_SECTION("Peeking does not advance internal pointer")
6690
{
6791
Lexer lexer(FLY_ARR(char_type, "ab"));

0 commit comments

Comments
 (0)