WPILibC++ 2024.3.2
exceptions.h
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.2
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 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#include <stdexcept> // runtime_error
14#include <string> // to_string
15#include <vector> // vector
16
17#include <wpi/detail/value_t.h>
24
25
27namespace detail
28{
29
30////////////////
31// exceptions //
32////////////////
33
34/// @brief general exception of the @ref basic_json class
35/// @sa https://json.nlohmann.me/api/basic_json/exception/
37{
38 public:
39 /// returns the explanatory string
40 const char* what() const noexcept override
41 {
42 return m.what();
43 }
44
45 /// the id of the exception
46 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
47
48 protected:
50 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
51
52 static std::string name(const std::string& ename, int id_)
53 {
54 return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
55 }
56
57 static std::string diagnostics(std::nullptr_t /*leaf_element*/)
58 {
59 return "";
60 }
61
62 template<typename BasicJsonType>
63 static std::string diagnostics(const BasicJsonType* leaf_element)
64 {
65#if JSON_DIAGNOSTICS
66 std::vector<std::string> tokens;
67 for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
68 {
69 switch (current->m_parent->type())
70 {
71 case value_t::array:
72 {
73 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
74 {
75 if (&current->m_parent->m_value.array->operator[](i) == current)
76 {
77 tokens.emplace_back(std::to_string(i));
78 break;
79 }
80 }
81 break;
82 }
83
84 case value_t::object:
85 {
86 for (const auto& element : *current->m_parent->m_value.object)
87 {
88 if (&element.second == current)
89 {
90 tokens.emplace_back(element.first.c_str());
91 break;
92 }
93 }
94 break;
95 }
96
97 case value_t::null: // LCOV_EXCL_LINE
98 case value_t::string: // LCOV_EXCL_LINE
99 case value_t::boolean: // LCOV_EXCL_LINE
100 case value_t::number_integer: // LCOV_EXCL_LINE
101 case value_t::number_unsigned: // LCOV_EXCL_LINE
102 case value_t::number_float: // LCOV_EXCL_LINE
103 case value_t::binary: // LCOV_EXCL_LINE
104 case value_t::discarded: // LCOV_EXCL_LINE
105 default: // LCOV_EXCL_LINE
106 break; // LCOV_EXCL_LINE
107 }
108 }
109
110 if (tokens.empty())
111 {
112 return "";
113 }
114
115 auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
116 [](const std::string & a, const std::string & b)
117 {
118 return concat(a, '/', detail::escape(b));
119 });
120 return concat('(', str, ") ");
121#else
122 static_cast<void>(leaf_element);
123 return "";
124#endif
125 }
126
127 private:
128 /// an exception object as storage for error messages
129 std::runtime_error m;
130};
131
132/// @brief exception indicating a parse error
133/// @sa https://json.nlohmann.me/api/basic_json/parse_error/
134class parse_error : public exception
135{
136 public:
137 /*!
138 @brief create a parse error exception
139 @param[in] id_ the id of the exception
140 @param[in] pos the position where the error occurred (or with
141 chars_read_total=0 if the position cannot be
142 determined)
143 @param[in] what_arg the explanatory string
144 @return parse_error object
145 */
146 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
147 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
148 {
149 std::string w = concat(exception::name("parse_error", id_), "parse error",
150 position_string(pos), ": ", exception::diagnostics(context), what_arg);
151 return {id_, pos.chars_read_total, w.c_str()};
152 }
153
154 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
155 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
156 {
157 std::string w = concat(exception::name("parse_error", id_), "parse error",
158 (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
159 ": ", exception::diagnostics(context), what_arg);
160 return {id_, byte_, w.c_str()};
161 }
162
163 /*!
164 @brief byte index of the parse error
165
166 The byte index of the last read character in the input file.
167
168 @note For an input with n bytes, 1 is the index of the first character and
169 n+1 is the index of the terminating null byte or the end of file.
170 This also holds true when reading a byte vector (CBOR or MessagePack).
171 */
172 const std::size_t byte;
173
174 private:
175 parse_error(int id_, std::size_t byte_, const char* what_arg)
176 : exception(id_, what_arg), byte(byte_) {}
177
178 static std::string position_string(const position_t& pos)
179 {
180 return concat(" at line ", std::to_string(pos.lines_read + 1),
181 ", column ", std::to_string(pos.chars_read_current_line));
182 }
183};
184
185/// @brief exception indicating errors with iterators
186/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
188{
189 public:
190 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
191 static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
192 {
193 std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
194 return {id_, w.c_str()};
195 }
196
197 private:
199 invalid_iterator(int id_, const char* what_arg)
200 : exception(id_, what_arg) {}
201};
202
203/// @brief exception indicating executing a member function with a wrong type
204/// @sa https://json.nlohmann.me/api/basic_json/type_error/
205class type_error : public exception
206{
207 public:
208 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
209 static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
210 {
211 std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
212 return {id_, w.c_str()};
213 }
214
215 private:
217 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
218};
219
220/// @brief exception indicating access out of the defined range
221/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
223{
224 public:
225 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
226 static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
227 {
228 std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
229 return {id_, w.c_str()};
230 }
231
232 private:
234 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
235};
236
237/// @brief exception indicating other library errors
238/// @sa https://json.nlohmann.me/api/basic_json/other_error/
239class other_error : public exception
240{
241 public:
242 template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
243 static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
244 {
245 std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
246 return {id_, w.c_str()};
247 }
248
249 private:
251 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
252};
253
254} // namespace detail
you may not use this file except in compliance with the License You may obtain a copy of the License at software distributed under the License is distributed on an AS IS WITHOUT WARRANTIES OR CONDITIONS OF ANY either express or implied See the License for the specific language governing permissions and limitations under the License LLVM Exceptions to the Apache License As an exception
Definition: ThirdPartyNotices.txt:289
#define WPI_JSON_NAMESPACE_END
Definition: abi_macros.h:59
#define WPI_JSON_NAMESPACE_BEGIN
Definition: abi_macros.h:53
general exception of the basic_json class
Definition: exceptions.h:37
const int id
the id of the exception
Definition: exceptions.h:46
static std::string diagnostics(std::nullptr_t)
Definition: exceptions.h:57
static std::string name(const std::string &ename, int id_)
Definition: exceptions.h:52
const char * what() const noexcept override
returns the explanatory string
Definition: exceptions.h:40
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: exceptions.h:63
exception indicating errors with iterators
Definition: exceptions.h:188
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: exceptions.h:191
exception indicating other library errors
Definition: exceptions.h:240
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: exceptions.h:243
exception indicating access out of the defined range
Definition: exceptions.h:223
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: exceptions.h:226
exception indicating a parse error
Definition: exceptions.h:135
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:147
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: exceptions.h:155
const std::size_t byte
byte index of the parse error
Definition: exceptions.h:172
exception indicating executing a member function with a wrong type
Definition: exceptions.h:206
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: exceptions.h:209
#define JSON_HEDLEY_NON_NULL(...)
Definition: hedley.h:1288
detail namespace with internal helper functions
Definition: xchar.h:20
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)
std::string to_string(const T &t)
Definition: base.h:92
b
Definition: data.h:44
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