#ifndef SIMDJSON_ERROR_INL_H #define SIMDJSON_ERROR_INL_H #include "simdjson/error.h" #include namespace simdjson { inline bool is_fatal(error_code error) noexcept { return error == TAPE_ERROR || error == INCOMPLETE_ARRAY_OR_OBJECT || error == OUT_OF_ORDER_ITERATION || error == DEPTH_ERROR; } namespace internal { // We store the error code so we can validate the error message is associated with the right code struct error_code_info { error_code code; const char* message; // do not use a fancy std::string where a simple C string will do (no alloc, no destructor) }; // These MUST match the codes in error_code. We check this constraint in basictests. extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[]; } // namespace internal inline const char *error_message(error_code error) noexcept { // If you're using error_code, we're trusting you got it from the enum. return internal::error_codes[int(error)].message; } // deprecated function #ifndef SIMDJSON_DISABLE_DEPRECATED_API inline const std::string error_message(int error) noexcept { if (error < 0 || error >= error_code::NUM_ERROR_CODES) { return internal::error_codes[UNEXPECTED_ERROR].message; } return internal::error_codes[error].message; } #endif // SIMDJSON_DISABLE_DEPRECATED_API inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept { return out << error_message(error); } namespace internal { // // internal::simdjson_result_base inline implementation // template simdjson_inline void simdjson_result_base::tie(T &value, error_code &error) && noexcept { error = this->second; if (!error) { value = std::forward>(*this).first; } } template simdjson_warn_unused simdjson_inline error_code simdjson_result_base::get(T &value) && noexcept { error_code error; std::forward>(*this).tie(value, error); return error; } template simdjson_inline error_code simdjson_result_base::error() const noexcept { return this->second; } template simdjson_inline bool simdjson_result_base::has_value() const noexcept { return this->error() == SUCCESS; } #if SIMDJSON_EXCEPTIONS template simdjson_inline T& simdjson_result_base::operator*() & noexcept(false) { return this->value(); } template simdjson_inline T&& simdjson_result_base::operator*() && noexcept(false) { return std::forward>(*this).value(); } template simdjson_inline T* simdjson_result_base::operator->() noexcept(false) { if (this->error()) { throw simdjson_error(this->error()); } return &this->first; } template simdjson_inline const T* simdjson_result_base::operator->() const noexcept(false) { if (this->error()) { throw simdjson_error(this->error()); } return &this->first; } template simdjson_inline T& simdjson_result_base::value() & noexcept(false) { if (error()) { throw simdjson_error(error()); } return this->first; } template simdjson_inline T&& simdjson_result_base::value() && noexcept(false) { return std::forward>(*this).take_value(); } template simdjson_inline T&& simdjson_result_base::take_value() && noexcept(false) { if (error()) { throw simdjson_error(error()); } return std::forward(this->first); } template simdjson_inline simdjson_result_base::operator T&&() && noexcept(false) { return std::forward>(*this).take_value(); } #endif // SIMDJSON_EXCEPTIONS template simdjson_inline const T& simdjson_result_base::value_unsafe() const& noexcept { return this->first; } template simdjson_inline T&& simdjson_result_base::value_unsafe() && noexcept { return std::forward(this->first); } template simdjson_inline simdjson_result_base::simdjson_result_base(T &&value, error_code error) noexcept : std::pair(std::forward(value), error) {} template simdjson_inline simdjson_result_base::simdjson_result_base(error_code error) noexcept : simdjson_result_base(T{}, error) {} template simdjson_inline simdjson_result_base::simdjson_result_base(T &&value) noexcept : simdjson_result_base(std::forward(value), SUCCESS) {} template simdjson_inline simdjson_result_base::simdjson_result_base() noexcept : simdjson_result_base(T{}, UNINITIALIZED) {} } // namespace internal /// /// simdjson_result inline implementation /// template simdjson_inline void simdjson_result::tie(T &value, error_code &error) && noexcept { std::forward>(*this).tie(value, error); } template simdjson_warn_unused simdjson_inline error_code simdjson_result::get(T &value) && noexcept { return std::forward>(*this).get(value); } template simdjson_inline error_code simdjson_result::error() const noexcept { return internal::simdjson_result_base::error(); } #if SIMDJSON_EXCEPTIONS template simdjson_inline T& simdjson_result::value() & noexcept(false) { return internal::simdjson_result_base::value(); } template simdjson_inline T&& simdjson_result::value() && noexcept(false) { return std::forward>(*this).value(); } template simdjson_inline T&& simdjson_result::take_value() && noexcept(false) { return std::forward>(*this).take_value(); } template simdjson_inline simdjson_result::operator T&&() && noexcept(false) { return std::forward>(*this).take_value(); } #endif // SIMDJSON_EXCEPTIONS template simdjson_inline const T& simdjson_result::value_unsafe() const& noexcept { return internal::simdjson_result_base::value_unsafe(); } template simdjson_inline T&& simdjson_result::value_unsafe() && noexcept { return std::forward>(*this).value_unsafe(); } template simdjson_inline simdjson_result::simdjson_result(T &&value, error_code error) noexcept : internal::simdjson_result_base(std::forward(value), error) {} template simdjson_inline simdjson_result::simdjson_result(error_code error) noexcept : internal::simdjson_result_base(error) {} template simdjson_inline simdjson_result::simdjson_result(T &&value) noexcept : internal::simdjson_result_base(std::forward(value)) {} template simdjson_inline simdjson_result::simdjson_result() noexcept : internal::simdjson_result_base() {} } // namespace simdjson #endif // SIMDJSON_ERROR_INL_H