REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
assert_eval.hpp
Go to the documentation of this file.
1
11#ifndef REAL_ASSERT_EVAL_HPP
12#define REAL_ASSERT_EVAL_HPP
13
14// Internal — do not include directly.
15// Users: #include <real/real.hpp> (or the documented opt-ins <real/dfa.hpp>, <real/std/regex.hpp>).
16
17#include <cstddef>
18#include <cstdint>
19#include <string_view>
20
22#include "real/core/program.hpp"
24#include "real/unicode/utf8.hpp"
25
26namespace real::detail {
27
30 [[nodiscard]] constexpr bool word_before(std::string_view text,
31 std::size_t pos,
32 bool ascii_word)
33 {
34 if (pos == 0) {
35 return false;
36 }
37 const auto prev {static_cast<std::uint8_t>(text[pos - 1])};
38 // ASCII fast path: an ASCII byte is a whole one-byte code point, and is_word_cp agrees with
39 // is_ascii_word_byte on it — so the common case skips the back-decode entirely.
40 if (prev < 0x80U || ascii_word) {
41 return is_ascii_word_byte(prev);
42 }
43 std::size_t i {pos - 1};
44 std::size_t steps {0};
45 while (i > 0 && (static_cast<std::uint8_t>(text[i]) & 0xC0U) == 0x80U && steps < 3) {
46 --i;
47 ++steps;
48 }
50 if (!dc.valid || i + dc.length != pos) {
51 return false; // malformed, or the sequence does not end exactly at pos
52 }
53 return is_word_cp(dc.cp);
54 }
55
58 [[nodiscard]] constexpr bool word_after(std::string_view text,
59 std::size_t pos,
60 bool ascii_word)
61 {
62 if (pos >= text.size()) {
63 return false;
64 }
65 const auto here {static_cast<std::uint8_t>(text[pos])};
66 if (here < 0x80U || ascii_word) {
67 return is_ascii_word_byte(here);
68 }
69 const decoded_codepoint dc {decode_codepoint_strict(text, pos)};
70 return dc.valid && is_word_cp(dc.cp);
71 }
72
81 [[nodiscard]] constexpr bool assertion_holds(assert_kind kind,
82 std::string_view text,
83 std::size_t pos,
84 bool ascii_word)
85 {
86 const std::size_t len {text.size()};
87 const auto byte_at = [&](std::size_t i) { return static_cast<std::uint8_t>(text[i]); };
88 bool result {};
89 switch (kind) {
91 result = pos == 0;
92 break;
94 result = pos == len;
95 break;
97 result = pos == len || (pos + 1 == len && byte_at(pos) == '\n');
98 break;
100 result = pos == 0 || byte_at(pos - 1) == '\n';
101 break;
103 result = pos == len || byte_at(pos) == '\n';
104 break;
107 {
108 const bool before {word_before(text, pos, ascii_word)};
109 const bool after {word_after(text, pos, ascii_word)};
110 result = (before != after) == (kind == assert_kind::word_boundary);
111 }
112 break;
115 {
116 const bool before {word_before(text, pos, ascii_word)};
117 const bool after {word_after(text, pos, ascii_word)};
118 result = kind == assert_kind::word_start ? (!before && after) : (before && !after);
119 }
120 break;
121 }
122 return result;
123 }
124} // namespace real::detail
125
126#endif // REAL_ASSERT_EVAL_HPP
256-bit byte set with O(1) membership, fully constexpr.
constexpr decoded_codepoint decode_codepoint_strict(std::string_view text, std::size_t pos)
Strictly decodes and validates the UTF-8 sequence at text[pos].
Definition utf8.hpp:44
constexpr bool word_after(std::string_view text, std::size_t pos, bool ascii_word)
Word-ness of the code point starting at pos — the right side of a boundary. False at the text end or ...
constexpr bool word_before(std::string_view text, std::size_t pos, bool ascii_word)
Word-ness of the code point ending at pos — the left side of a boundary. False at the text start or o...
constexpr bool is_word_cp(char32_t cp)
Whether cp is a Unicode word / digit / whitespace code point (== re \w/\d/\s).
constexpr bool is_ascii_word_byte(std::uint8_t byte)
Reports whether byte is an ASCII "word" byte ([0-9A-Za-z_]).
constexpr bool assertion_holds(assert_kind kind, std::string_view text, std::size_t pos, bool ascii_word)
Evaluates a zero-width assertion at pos in text.
assert_kind
Kind of zero-width assertion carried in assert_position's arg8.
Definition program.hpp:208
@ word_start
< (non-word/start on the left, word on the right).
@ word_end
> (word on the left, non-word/end on the right).
@ line_start
^ with multiline.
@ line_end
$ with multiline.
@ word_boundary
\b (Unicode word-ness in text mode; ASCII in bytes / re.A).
@ text_start
\A, and ^ without multiline.
@ text_end_or_final_newline
$ without multiline (Python semantics).
Compiled form of a pattern and the public flags / error types.
The result of a strict UTF-8 decode: the code point, its byte length, and validity.
Definition utf8.hpp:25
bool valid
Whether the sequence is a well-formed, canonical code point.
Definition utf8.hpp:28
Unicode \w / \d / \s property ranges and their lookups.
UTF-8 position arithmetic for match iteration.