WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
exceptions.h
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.3
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#pragma once
10
11#include <cstddef> // nullptr_t
12#include <exception> // exception
13#if JSON_DIAGNOSTICS
14 #include <numeric> // accumulate
15#endif
16#include <stdexcept> // runtime_error
17#include <string> // to_string
18#include <vector> // vector
19
20#include <wpi/detail/value_t.h>
27
29namespace detail
30{
31
32////////////////
33// exceptions //
34////////////////
35
36/// @brief general exception of the @ref basic_json class
37/// @sa https://json.nlohmann.me/api/basic_json/exception/
38class exception : public std::exception
39{
40 public:
41 /// returns the explanatory string
42 const char* what() const noexcept override
43 {
44 return m.what();
45 }
46
47 /// the id of the exception
48 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
49
50 protected:
52 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
53
54 static std::string name(const std::string& ename, int id_)
55 {
56 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
57 }
58
59 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
60 {
61 return "";
62 }
63
64 template<typename BasicJsonType>
65 static std::string diagnostics(const BasicJsonType* leaf_element)
66 {
67#if JSON_DIAGNOSTICS
68 std::vector<std::string> tokens;
69 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
70 {
71 switch (current->m_parent->type())
72 {
73 case value_t::array:
74 {
75 for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i)
76 {
77 if (&current->m_parent->m_data.m_value.array->operator[](i) == current)
78 {
79 tokens.emplace_back(std::to_string(i));
80 break;
81 }
82 }
83 break;
84 }
85
86 case value_t::object:
87 {
88 for (const auto& element : *current->m_parent->m_data.m_value.object)
89 {
90 if (&element.second == current)
91 {
92 tokens.emplace_back(element.first.c_str());
93 break;
94 }
95 }
96 break;
97 }
98
99 case value_t::null: // LCOV_EXCL_LINE
100 case value_t::string: // LCOV_EXCL_LINE
101 case value_t::boolean: // LCOV_EXCL_LINE
102 case value_t::number_integer: // LCOV_EXCL_LINE
103 case value_t::number_unsigned: // LCOV_EXCL_LINE
104 case value_t::number_float: // LCOV_EXCL_LINE
105 case value_t::binary: // LCOV_EXCL_LINE
106 case value_t::discarded: // LCOV_EXCL_LINE
107 default: // LCOV_EXCL_LINE
108 break; // LCOV_EXCL_LINE
109 }
110 }
111
112 if (tokens.empty())
113 {
114 return "";
115 }
116
117 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
118 [](const std::string & a, const std::string & b)
119 {
120 return concat(a, '/', detail::escape(b));
121 });
122 return concat('(', str, ") ");
123#else
124 static_cast<void>(leaf_element);
125 return "";
126#endif
127 }
128
129 private:
130 /// an exception object as storage for error messages
131 std::runtime_error m;
132};
133
134/// @brief exception indicating a parse error
135/// @sa https://json.nlohmann.me/api/basic_json/parse_error/
136class parse_error : public exception
137{
138 public:
139 /*!
140 @brief create a parse error exception
141 @param[in] id_ the id of the exception
142 @param[in] pos the position where the error occurred (or with
143 chars_read_total=0 if the position cannot be
144 determined)
145 @param[in] what_arg the explanatory string
146 @return parse_error object
147 */
148 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
149 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
150 {
151 const std::string w = concat(exception::name("parse_error", id_), "parse error",
152 position_string(pos), ": ", exception::diagnostics(context), what_arg);
153 return {id_, pos.chars_read_total, w.c_str()};
154 }
155
156 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
157 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
158 {
159 const std::string w = concat(exception::name("parse_error", id_), "parse error",
160 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
161 ": ", exception::diagnostics(context), what_arg);
162 return {id_, byte_, w.c_str()};
163 }
164
165 /*!
166 @brief byte index of the parse error
167
168 The byte index of the last read character in the input file.
169
170 @note For an input with n bytes, 1 is the index of the first character and
171 n+1 is the index of the terminating null byte or the end of file.
172 This also holds true when reading a byte vector (CBOR or MessagePack).
173 */
174 const std::size_t byte;
175
176 private:
177 parse_error(int id_, std::size_t byte_, const char* what_arg)
178 : exception(id_, what_arg), byte(byte_) {}
179
180 static std::string position_string(const position_t& pos)
181 {
182 return concat(" at line ", std::to_string(pos.lines_read + 1),
183 ", column ", std::to_string(pos.chars_read_current_line));
184 }
185};
186
187/// @brief exception indicating errors with iterators
188/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
190{
191 public:
192 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
193 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
194 {
195 const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
196 return {id_, w.c_str()};
197 }
198
199 private:
201 invalid_iterator(int id_, const char* what_arg)
202 : exception(id_, what_arg) {}
203};
204
205/// @brief exception indicating executing a member function with a wrong type
206/// @sa https://json.nlohmann.me/api/basic_json/type_error/
207class type_error : public exception
208{
209 public:
210 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
211 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
212 {
213 const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
214 return {id_, w.c_str()};
215 }
216
217 private:
219 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
220};
221
222/// @brief exception indicating access out of the defined range
223/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
225{
226 public:
227 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
228 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
229 {
230 const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
231 return {id_, w.c_str()};
232 }
233
234 private:
236 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
237};
238
239/// @brief exception indicating other library errors
240/// @sa https://json.nlohmann.me/api/basic_json/other_error/
241class other_error : public exception
242{
243 public:
244 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
245 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
246 {
247 const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
248 return {id_, w.c_str()};
249 }
250
251 private:
253 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
254};
255
256} // namespace detail
#define WPI_JSON_NAMESPACE_END
Definition abi_macros.h:59
#define WPI_JSON_NAMESPACE_BEGIN
Definition abi_macros.h:53
Definition base.h:2607
general exception of the basic_json class
Definition exceptions.h:39
const int id
the id of the exception
Definition exceptions.h:48
static std::string diagnostics(std::nullptr_t)
Definition exceptions.h:59
static std::string name(const std::string &ename, int id_)
Definition exceptions.h:54
const char * what() const noexcept override
returns the explanatory string
Definition exceptions.h:42
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition exceptions.h:65
exception indicating errors with iterators
Definition exceptions.h:190
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition exceptions.h:193
exception indicating other library errors
Definition exceptions.h:242
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition exceptions.h:245
exception indicating access out of the defined range
Definition exceptions.h:225
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition exceptions.h:228
exception indicating a parse error
Definition exceptions.h:137
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition exceptions.h:149
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition exceptions.h:157
const std::size_t byte
byte index of the parse error
Definition exceptions.h:174
exception indicating executing a member function with a wrong type
Definition exceptions.h:208
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition exceptions.h:211
#define JSON_HEDLEY_NON_NULL(...)
Definition hedley.h:1288
detail namespace with internal helper functions
Definition input_adapters.h:32
OutStringType concat(Args &&... args)
Definition string_concat.h:137
@ null
null value
@ number_integer
number value (signed integer)
@ boolean
boolean value
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ string
string value
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
struct to capture the start position of the current token
Definition position_t.h:21
std::size_t chars_read_current_line
the number of characters read in the current line
Definition position_t.h:25
std::size_t lines_read
the number of lines read
Definition position_t.h:27
std::size_t chars_read_total
the total number of characters read
Definition position_t.h:23