Skip to content

Commit 9504665

Browse files
committed
Added No Exceptions Option
1 parent 2a0e1f9 commit 9504665

9 files changed

Lines changed: 306 additions & 98 deletions

CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
cmake_minimum_required(VERSION 3.16)
2-
project(pcre2cpp VERSION 1.1.2 LANGUAGES CXX)
2+
project(pcre2cpp VERSION 1.2.0 LANGUAGES CXX)
33

44
set(CMAKE_CXX_STANDARD 20)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)
66
set(CMAKE_CXX_EXTENSIONS OFF)
77

8-
option(BUILD_PCRE2CPP_TESTS "Build pcre2cpp tests" OFF)
8+
option(BUILD_PCRE2CPP_TESTS "Build pcre2cpp tests" OFF)
9+
option(PCRE2CPP_ENABLE_EXCEPTIONS "Enable Exceptions in pcre2cpp" ON )
910

1011
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/third_party.cmake)
1112

@@ -44,6 +45,10 @@ else()
4445
#target_compile_options(${PROJECT_NAME} INTERFACE -Wall -Wextra -Wpendantic -Werror)
4546
endif()
4647

48+
if(NOT PCRE2CPP_ENABLE_EXCEPTIONS)
49+
target_compile_definitions(${PROJECT_NAME} INTERFACE PCRE2CPP_NO_EXCEPTIONS)
50+
endif()
51+
4752
# Optimizations
4853
target_compile_options(${PROJECT_NAME} INTERFACE
4954
# MSVC/clang with MSVC frontend

include/pcre2cpp/match_result.hpp

Lines changed: 96 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,99 @@
2020
namespace 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
}

include/pcre2cpp/pcre2cpp_config.hpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
#pragma region VERSION
1818
#define PCRE2CPP_VERSION_MAJOR 1
19-
#define PCRE2CPP_VERSION_MINOR 1
20-
#define PCRE2CPP_VERSION_PATCH 2
19+
#define PCRE2CPP_VERSION_MINOR 2
20+
#define PCRE2CPP_VERSION_PATCH 0
2121

2222
#define _PCRE2CPP_STRINGIFY_HELPER(x) #x
2323

@@ -36,7 +36,7 @@
3636
#pragma endregion VERSION
3737

3838
#pragma region LAST_UPDATE
39-
#define PCRE2CPP_LAST_UPDATE_DAY 02
39+
#define PCRE2CPP_LAST_UPDATE_DAY 03
4040
#define PCRE2CPP_LAST_UPDATE_MONTH 12
4141
#define PCRE2CPP_LAST_UPDATE_YEAR 2025
4242

@@ -47,4 +47,14 @@
4747
#define PCRE2CPP_LAST_UPDATE_DATE _PCRE2CPP_LAST_UPDATE_DATE_HELPER(PCRE2CPP_LAST_UPDATE_DAY, \
4848
PCRE2CPP_LAST_UPDATE_MONTH, \
4949
PCRE2CPP_LAST_UPDATE_YEAR)
50-
#pragma endregion LAST_UPDATE
50+
#pragma endregion LAST_UPDATE
51+
52+
#pragma region CPP_FLAGS
53+
54+
#ifdef PCRE2CPP_NO_EXCEPTIONS
55+
#define PCRE2CPP_NOEXCEPT noexcept
56+
#else
57+
#define PCRE2CPP_NOEXCEPT
58+
#endif
59+
60+
#pragma endregion

0 commit comments

Comments
 (0)