1#ifndef SIMDJSON_INLINE_ERROR_H
2#define SIMDJSON_INLINE_ERROR_H
3
4#include <cstring>
5#include <string>
6#include <utility>
7#include "simdjson/error.h"
8
9namespace simdjson {
10namespace internal {
11 // We store the error code so we can validate the error message is associated with the right code
12 struct error_code_info {
13 error_code code;
14 const char* message; // do not use a fancy std::string where a simple C string will do (no alloc, no destructor)
15 };
16 // These MUST match the codes in error_code. We check this constraint in basictests.
17 extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[];
18} // namespace internal
19
20
21inline const char *error_message(error_code error) noexcept {
22 // If you're using error_code, we're trusting you got it from the enum.
23 return internal::error_codes[int(error)].message;
24}
25
26// deprecated function
27#ifndef SIMDJSON_DISABLE_DEPRECATED_API
28inline const std::string error_message(int error) noexcept {
29 if (error < 0 || error >= error_code::NUM_ERROR_CODES) {
30 return internal::error_codes[UNEXPECTED_ERROR].message;
31 }
32 return internal::error_codes[error].message;
33}
34#endif // SIMDJSON_DISABLE_DEPRECATED_API
35
36inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept {
37 return out << error_message(error);
38}
39
40namespace internal {
41
42//
43// internal::simdjson_result_base<T> inline implementation
44//
45
46template<typename T>
47simdjson_inline void simdjson_result_base<T>::tie(T &value, error_code &error) && noexcept {
48 error = this->second;
49 if (!error) {
50 value = std::forward<simdjson_result_base<T>>(*this).first;
51 }
52}
53
54template<typename T>
55simdjson_warn_unused simdjson_inline error_code simdjson_result_base<T>::get(T &value) && noexcept {
56 error_code error;
57 std::forward<simdjson_result_base<T>>(*this).tie(value, error);
58 return error;
59}
60
61template<typename T>
62simdjson_inline error_code simdjson_result_base<T>::error() const noexcept {
63 return this->second;
64}
65
66#if SIMDJSON_EXCEPTIONS
67
68template<typename T>
69simdjson_inline T& simdjson_result_base<T>::value() & noexcept(false) {
70 if (error()) { throw simdjson_error(error()); }
71 return this->first;
72}
73
74template<typename T>
75simdjson_inline T&& simdjson_result_base<T>::value() && noexcept(false) {
76 return std::forward<simdjson_result_base<T>>(*this).take_value();
77}
78
79template<typename T>
80simdjson_inline T&& simdjson_result_base<T>::take_value() && noexcept(false) {
81 if (error()) { throw simdjson_error(error()); }
82 return std::forward<T>(this->first);
83}
84
85template<typename T>
86simdjson_inline simdjson_result_base<T>::operator T&&() && noexcept(false) {
87 return std::forward<simdjson_result_base<T>>(*this).take_value();
88}
89
90#endif // SIMDJSON_EXCEPTIONS
91
92template<typename T>
93simdjson_inline const T& simdjson_result_base<T>::value_unsafe() const& noexcept {
94 return this->first;
95}
96
97template<typename T>
98simdjson_inline T&& simdjson_result_base<T>::value_unsafe() && noexcept {
99 return std::forward<T>(this->first);
100}
101
102template<typename T>
103simdjson_inline simdjson_result_base<T>::simdjson_result_base(T &&value, error_code error) noexcept
104 : std::pair<T, error_code>(std::forward<T>(value), error) {}
105template<typename T>
106simdjson_inline simdjson_result_base<T>::simdjson_result_base(error_code error) noexcept
107 : simdjson_result_base(T{}, error) {}
108template<typename T>
109simdjson_inline simdjson_result_base<T>::simdjson_result_base(T &&value) noexcept
110 : simdjson_result_base(std::forward<T>(value), SUCCESS) {}
111template<typename T>
112simdjson_inline simdjson_result_base<T>::simdjson_result_base() noexcept
113 : simdjson_result_base(T{}, UNINITIALIZED) {}
114
115} // namespace internal
116
117///
118/// simdjson_result<T> inline implementation
119///
120
121template<typename T>
122simdjson_inline void simdjson_result<T>::tie(T &value, error_code &error) && noexcept {
123 std::forward<internal::simdjson_result_base<T>>(*this).tie(value, error);
124}
125
126template<typename T>
127simdjson_warn_unused simdjson_inline error_code simdjson_result<T>::get(T &value) && noexcept {
128 return std::forward<internal::simdjson_result_base<T>>(*this).get(value);
129}
130
131template<typename T>
132simdjson_inline error_code simdjson_result<T>::error() const noexcept {
133 return internal::simdjson_result_base<T>::error();
134}
135
136#if SIMDJSON_EXCEPTIONS
137
138template<typename T>
139simdjson_inline T& simdjson_result<T>::value() & noexcept(false) {
140 return internal::simdjson_result_base<T>::value();
141}
142
143template<typename T>
144simdjson_inline T&& simdjson_result<T>::value() && noexcept(false) {
145 return std::forward<internal::simdjson_result_base<T>>(*this).value();
146}
147
148template<typename T>
149simdjson_inline T&& simdjson_result<T>::take_value() && noexcept(false) {
150 return std::forward<internal::simdjson_result_base<T>>(*this).take_value();
151}
152
153template<typename T>
154simdjson_inline simdjson_result<T>::operator T&&() && noexcept(false) {
155 return std::forward<internal::simdjson_result_base<T>>(*this).take_value();
156}
157
158#endif // SIMDJSON_EXCEPTIONS
159
160template<typename T>
161simdjson_inline const T& simdjson_result<T>::value_unsafe() const& noexcept {
162 return internal::simdjson_result_base<T>::value_unsafe();
163}
164
165template<typename T>
166simdjson_inline T&& simdjson_result<T>::value_unsafe() && noexcept {
167 return std::forward<internal::simdjson_result_base<T>>(*this).value_unsafe();
168}
169
170template<typename T>
171simdjson_inline simdjson_result<T>::simdjson_result(T &&value, error_code error) noexcept
172 : internal::simdjson_result_base<T>(std::forward<T>(value), error) {}
173template<typename T>
174simdjson_inline simdjson_result<T>::simdjson_result(error_code error) noexcept
175 : internal::simdjson_result_base<T>(error) {}
176template<typename T>
177simdjson_inline simdjson_result<T>::simdjson_result(T &&value) noexcept
178 : internal::simdjson_result_base<T>(std::forward<T>(value)) {}
179template<typename T>
180simdjson_inline simdjson_result<T>::simdjson_result() noexcept
181 : internal::simdjson_result_base<T>() {}
182
183} // namespace simdjson
184
185#endif // SIMDJSON_INLINE_ERROR_H
186