2020namespace pcre2cpp {
2121 template <size_t utf>
2222 class basic_match_result {
23+ public:
24+ static constexpr size_t bad_offset = static_cast <size_t >(-1 );
25+
2326 private:
2427 using _string_type = _pcre2_data<utf>::string_type;
2528 using _match_value = std::pair<size_t , _string_type>;
29+ #ifndef PCRE2CPP_NO_EXCEPTIONS
2630 using _match_result_exception = basic_match_result_exception<utf>;
31+ #endif
2732 using _named_sub_values_table = std::unordered_map<_string_type, size_t >;
2833 using _named_sub_values_table_ptr = std::shared_ptr<_named_sub_values_table>;
2934
3035 struct _value_result_data {
31- bool found = false ;
32- size_t search_offset = 0 ;
33- _match_value result = { 0 , _string_type () };
36+ size_t search_offset = bad_offset;
37+ _match_value result = { bad_offset, _string_type () };
3438 std::vector<_match_value> sub_results = {};
3539 _named_sub_values_table_ptr named_sub_values = {};
40+ bool found = false ;
3641 };
3742
3843 std::variant<int , _value_result_data> _data = _value_result_data();
3944
40- constexpr size_t _get_named_sub_result_idx (const _string_type& name) const {
45+ constexpr size_t _get_named_sub_result_idx (const _string_type& name) const PCRE2CPP_NOEXCEPT {
4146 auto & named_sub_values = std::get<_value_result_data>(_data).named_sub_values ;
4247 auto itr = named_sub_values->find (name);
48+
4349 if (itr == named_sub_values->end ()) {
44- _string_type message = " Subexpression with provided name '" ;
45- message += name;
46- message += " ' not found" ;
47- throw _match_result_exception (" Subexpression with provided name not found" );
50+ #ifdef PCRE2CPP_NO_EXCEPTIONS
51+ return static_cast <size_t >(-1 );
52+ #else
53+ if constexpr (utf == 8 ) {
54+ _string_type message = " Subexpression with provided name '" ;
55+ message += name;
56+ message += " ' not found" ;
57+ throw _match_result_exception (message);
58+ }
59+ else if constexpr (utf == 16 ) {
60+ _string_type message = L" Subexpression with provided name '" ;
61+ message += name;
62+ message += L" ' not found" ;
63+ throw _match_result_exception (message);
64+ }
65+ else if constexpr (utf == 32 ) {
66+ _string_type message = U" Subexpression with provided name '" ;
67+ message += name;
68+ message += U" ' not found" ;
69+ throw _match_result_exception (message);
70+ }
71+ #endif
4872 }
4973
5074 return itr->second ;
5175 }
52- constexpr _match_value _get_sub_result (const size_t & idx) const {
76+ constexpr _match_value _get_sub_result (const size_t & idx) const PCRE2CPP_NOEXCEPT {
5377 auto & sub_results = std::get<_value_result_data>(_data).sub_results ;
54- if (idx >= sub_results.size ())
55- throw basic_match_result_exception<utf>(" subexpression index out of bounds" );
78+ if (idx >= sub_results.size ()) {
79+ #ifdef PCRE2CPP_NO_EXCEPTIONS
80+ if constexpr (utf == 8 ) {
81+ return { static_cast <size_t >(-1 ), " " };
82+ }
83+ else if constexpr (utf == 16 ) {
84+ return { static_cast <size_t >(-1 ), L" " };
85+ }
86+ else if constexpr (utf == 32 ) {
87+ return { static_cast <size_t >(-1 ), U" " };
88+ }
89+ #else
90+ if constexpr (utf == 8 ) {
91+ throw basic_match_result_exception<utf>(" Subexpression index out of bounds" );
92+ }
93+ else if constexpr (utf == 16 ) {
94+ throw basic_match_result_exception<utf>(L" Subexpression index out of bounds" );
95+ }
96+ else if constexpr (utf == 32 ) {
97+ throw basic_match_result_exception<utf>(U" Subexpression index out of bounds" );
98+ }
99+ #endif
100+ }
56101 return sub_results[idx];
57102 }
58103
59104 public:
105+
60106 constexpr basic_match_result () noexcept = default;
61107 constexpr basic_match_result (int error_code) noexcept
62108 : _data(error_code) {}
63109 constexpr basic_match_result (const size_t & search_offset,
64110 const _named_sub_values_table_ptr& named_sub_values) noexcept
65- : _data(_value_result_data{ false , search_offset, { 0 , _string_type () }, {}, named_sub_values }) {}
111+ : _data(_value_result_data{ search_offset, { bad_offset , _string_type () }, {}, named_sub_values, false }) {}
66112 constexpr basic_match_result (const size_t & search_offset, const _match_value& result,
67113 const std::vector<_match_value>& sub_results,
68114 const _named_sub_values_table_ptr& named_sub_values) noexcept
69- : _data(_value_result_data{ true , search_offset, result, sub_results, named_sub_values }) { }
115+ : _data(_value_result_data{ search_offset, result, sub_results, named_sub_values, true }) { }
70116 constexpr basic_match_result (const basic_match_result<utf>& mr) noexcept = default;
71117 ~basic_match_result () = default ;
72118
@@ -78,32 +124,51 @@ namespace pcre2cpp {
78124 if (!has_error ()) return 0 ;
79125 return std::get<int >(_data);
80126 }
127+ #ifdef PCRE2CPP_NO_EXCEPTIONS
128+ constexpr _string_type get_error_message () const noexcept {
129+ if (!has_error ()) {
130+ if constexpr (utf == 8 ) {
131+ return " " ;
132+ }
133+ else if constexpr (utf == 16 ) {
134+ return L" " ;
135+ }
136+ else if constexpr (utf == 32 ) {
137+ return U" " ;
138+ }
139+ }
140+ return pcre2cpp::generate_error_message<utf>(std::get<int >(_data));
141+ }
142+ #else
81143 constexpr void throw_error () const {
82144 if (!has_error ()) return ;
83145 throw _match_result_exception (std::get<int >(_data));
84146 }
147+ #endif
85148#pragma endregion ERRORS
86149
87150#pragma region RESULTS
88- constexpr bool has_result () const noexcept { return std::holds_alternative<_value_result_data>(_data); }
151+ constexpr bool has_result () const noexcept {
152+ return std::holds_alternative<_value_result_data>(_data);
153+ }
89154 constexpr bool has_value () const noexcept {
90155 if (!has_result ()) return false ;
91156 return std::get<_value_result_data>(_data).found ;
92157 }
93158 constexpr size_t get_search_offset () const noexcept {
94- if (!has_result ()) return 0 ;
159+ if (!has_result ()) return bad_offset ;
95160 return std::get<_value_result_data>(_data).search_offset ;
96161 }
97162
98163#pragma region RESULT
99164#pragma region OFFSETS
100165 constexpr size_t get_result_global_offset () const noexcept {
101- if (!has_value ()) return 0 ;
166+ if (!has_value ()) return bad_offset ;
102167 auto & value = std::get<_value_result_data>(_data);
103168 return value.search_offset + value.result .first ;
104169 }
105170 constexpr size_t get_result_relative_offset () const noexcept {
106- if (!has_value ()) return 0 ;
171+ if (!has_value ()) return bad_offset ;
107172 return std::get<_value_result_data>(_data).result .first ;
108173 }
109174#pragma endregion OFFSETS
@@ -123,36 +188,36 @@ namespace pcre2cpp {
123188 }
124189
125190#pragma region OFFSETS
126- constexpr size_t get_sub_result_global_offset (const size_t & idx) const {
127- if (!has_value ()) return 0 ;
191+ constexpr size_t get_sub_result_global_offset (const size_t & idx) const PCRE2CPP_NOEXCEPT {
192+ if (!has_value ()) return bad_offset ;
128193 _match_value sub_result = _get_sub_result (idx);
129194 auto & value = std::get<_value_result_data>(_data);
130195 return value.search_offset + value.result .first + sub_result.first ;
131196 }
132- constexpr size_t get_sub_result_relative_offset (const size_t & idx) const {
133- if (!has_value ()) return 0 ;
197+ constexpr size_t get_sub_result_relative_offset (const size_t & idx) const PCRE2CPP_NOEXCEPT {
198+ if (!has_value ()) return bad_offset ;
134199 _match_value sub_result = _get_sub_result (idx);
135200 auto & value = std::get<_value_result_data>(_data);
136201 return value.result .first + sub_result.first ;
137202 }
138- constexpr size_t get_sub_result_in_result_offset (const size_t & idx) const {
139- if (!has_value ()) return 0 ;
203+ constexpr size_t get_sub_result_in_result_offset (const size_t & idx) const PCRE2CPP_NOEXCEPT {
204+ if (!has_value ()) return bad_offset ;
140205 return _get_sub_result (idx).first ;
141206 }
142- constexpr size_t get_sub_result_global_offset (const _string_type& name) const {
143- if (!has_value ()) return 0 ;
207+ constexpr size_t get_sub_result_global_offset (const _string_type& name) const PCRE2CPP_NOEXCEPT {
208+ if (!has_value ()) return bad_offset ;
144209 _match_value sub_result = _get_sub_result (_get_named_sub_result_idx (name));
145210 auto & value = std::get<_value_result_data>(_data);
146211 return value.search_offset + value.result .first + sub_result.first ;
147212 }
148- constexpr size_t get_sub_result_relative_offset (const _string_type& name) const {
149- if (!has_value ()) return 0 ;
213+ constexpr size_t get_sub_result_relative_offset (const _string_type& name) const PCRE2CPP_NOEXCEPT {
214+ if (!has_value ()) return bad_offset ;
150215 _match_value sub_result = _get_sub_result (_get_named_sub_result_idx (name));
151216 auto & value = std::get<_value_result_data>(_data);
152217 return value.result .first + sub_result.first ;
153218 }
154- constexpr size_t get_sub_result_in_result_offset (const _string_type& name) const {
155- if (!has_value ()) return 0 ;
219+ constexpr size_t get_sub_result_in_result_offset (const _string_type& name) const PCRE2CPP_NOEXCEPT {
220+ if (!has_value ()) return bad_offset ;
156221 return _get_sub_result (_get_named_sub_result_idx (name)).first ;
157222 }
158223 constexpr std::vector<size_t > get_sub_results_global_offsets () const noexcept {
@@ -194,11 +259,11 @@ namespace pcre2cpp {
194259#pragma endregion OFFSETS
195260
196261#pragma region VALUE
197- constexpr _string_type get_sub_result_value (const size_t & idx) const {
262+ constexpr _string_type get_sub_result_value (const size_t & idx) const PCRE2CPP_NOEXCEPT {
198263 if (!has_value ()) return _string_type ();
199264 return _get_sub_result (idx).second ;
200265 }
201- constexpr _string_type get_sub_result_value (const _string_type& name) const {
266+ constexpr _string_type get_sub_result_value (const _string_type& name) const PCRE2CPP_NOEXCEPT {
202267 if (!has_value ()) return _string_type ();
203268 return _get_sub_result (_get_named_sub_result_idx (name)).second ;
204269 }
0 commit comments