Skip to content

Commit a44ea46

Browse files
Add constexpr specifier to JSON type check functions for improved performance
1 parent e7cf44d commit a44ea46

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

include/json.hpp

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,57 +196,57 @@ namespace json
196196
*
197197
* @return true if the JSON value is null, false otherwise.
198198
*/
199-
[[nodiscard]] bool is_null() const noexcept { return value.index() == 0; }
199+
[[nodiscard]] constexpr bool is_null() const noexcept { return value.index() == 0; }
200200
/**
201201
* @brief Checks if the JSON value is a boolean.
202202
*
203203
* @return true if the JSON value is a boolean, false otherwise.
204204
*/
205-
[[nodiscard]] bool is_boolean() const noexcept { return value.index() == 1; }
205+
[[nodiscard]] constexpr bool is_boolean() const noexcept { return value.index() == 1; }
206206
/**
207207
* @brief Checks if the JSON value is an integer.
208208
*
209209
* @return true if the JSON value is an integer, false otherwise.
210210
*/
211-
[[nodiscard]] bool is_integer() const noexcept { return value.index() == 2; }
211+
[[nodiscard]] constexpr bool is_integer() const noexcept { return value.index() == 2; }
212212
/**
213213
* @brief Checks if the JSON value is an unsigned integer.
214214
*
215215
* @return true if the JSON value is an unsigned integer, false otherwise.
216216
*/
217-
[[nodiscard]] bool is_unsigned() const noexcept { return value.index() == 3; }
217+
[[nodiscard]] constexpr bool is_unsigned() const noexcept { return value.index() == 3; }
218218
/**
219219
* @brief Checks if the JSON value is a floating-point number.
220220
*
221221
* @return true if the JSON value is a floating-point number, false otherwise.
222222
*/
223-
[[nodiscard]] bool is_float() const noexcept { return value.index() == 4; }
223+
[[nodiscard]] constexpr bool is_float() const noexcept { return value.index() == 4; }
224224
/**
225225
* @brief Checks if the JSON value is a number.
226226
*
227227
* This function checks if the JSON value is of type integer, unsigned integer, or floating-point number.
228228
*
229229
* @return true if the JSON value is a number, false otherwise.
230230
*/
231-
[[nodiscard]] bool is_number() const noexcept { return value.index() == 2 || value.index() == 3 || value.index() == 4; }
231+
[[nodiscard]] constexpr bool is_number() const noexcept { return value.index() == 2 || value.index() == 3 || value.index() == 4; }
232232
/**
233233
* @brief Checks if the JSON value is a string.
234234
*
235235
* @return true if the JSON value is a string, false otherwise.
236236
*/
237-
[[nodiscard]] bool is_string() const noexcept { return value.index() == 5; }
237+
[[nodiscard]] constexpr bool is_string() const noexcept { return value.index() == 5; }
238238
/**
239239
* @brief Checks if the JSON value is an object.
240240
*
241241
* @return true if the JSON value is an object, false otherwise.
242242
*/
243-
[[nodiscard]] bool is_object() const noexcept { return value.index() == 6; }
243+
[[nodiscard]] constexpr bool is_object() const noexcept { return value.index() == 6; }
244244
/**
245245
* @brief Checks if the JSON value is an array.
246246
*
247247
* @return true if the JSON value is an array, false otherwise.
248248
*/
249-
[[nodiscard]] bool is_array() const noexcept { return value.index() == 7; }
249+
[[nodiscard]] constexpr bool is_array() const noexcept { return value.index() == 7; }
250250

251251
/**
252252
* @brief Checks if the JSON value is a primitive type.
@@ -256,15 +256,15 @@ namespace json
256256
*
257257
* @return true if the JSON value is a primitive type, false otherwise.
258258
*/
259-
[[nodiscard]] bool is_primitive() const noexcept { return is_null() || is_boolean() || is_integer() || is_unsigned() || is_float() || is_string(); }
259+
[[nodiscard]] constexpr bool is_primitive() const noexcept { return is_null() || is_boolean() || is_integer() || is_unsigned() || is_float() || is_string(); }
260260
/**
261261
* @brief Checks if the JSON value is a structured type.
262262
*
263263
* This function checks if the JSON value is either an object or an array.
264264
*
265265
* @return true if the JSON value is a structured type (object or array), false otherwise.
266266
*/
267-
[[nodiscard]] bool is_structured() const noexcept { return is_object() || is_array(); }
267+
[[nodiscard]] constexpr bool is_structured() const noexcept { return is_object() || is_array(); }
268268

269269
/**
270270
* @brief Returns the type of the JSON value.
@@ -274,7 +274,7 @@ namespace json
274274
*
275275
* @return The type of the JSON value.
276276
*/
277-
[[nodiscard]] json_type get_type() const noexcept
277+
[[nodiscard]] constexpr json_type get_type() const noexcept
278278
{
279279
switch (value.index())
280280
{
@@ -326,6 +326,8 @@ namespace json
326326
*/
327327
[[nodiscard]] bool contains(std::string_view key) const { return is_object() && std::get<std::map<std::string, json, std::less<>>>(value).count(key) > 0; }
328328

329+
[[nodiscard]] bool operator==(std::nullptr_t) const noexcept { return value.index() == 0; }
330+
329331
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
330332
[[nodiscard]] bool operator==(T num) const noexcept
331333
{
@@ -347,7 +349,9 @@ namespace json
347349
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char *>, int> = 0>
348350
[[nodiscard]] bool operator==(T &&str) const noexcept { return value.index() == 5 && std::get<std::string>(value) == std::string(str); }
349351

350-
template <typename T, std::enable_if_t<std::is_arithmetic_v<T> && !std::is_same_v<std::decay_t<T>, bool>, int> = 0>
352+
[[nodiscard]] bool operator!=(std::nullptr_t) const noexcept { return value.index() != 0; }
353+
354+
template <typename T, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
351355
[[nodiscard]] bool operator!=(T num) const noexcept
352356
{
353357
switch (value.index())
@@ -368,6 +372,37 @@ namespace json
368372
template <typename T, std::enable_if_t<std::is_same_v<std::decay_t<T>, std::string> || std::is_same_v<std::decay_t<T>, std::string_view> || std::is_same_v<std::decay_t<T>, const char *>, int> = 0>
369373
[[nodiscard]] bool operator!=(T &&str) const noexcept { return value.index() != 5 || std::get<std::string>(value) != std::string(str); }
370374

375+
/**
376+
* @brief Get the JSON value as the specified type T.
377+
*
378+
* This templated function provides explicit conversion of the JSON value to type T.
379+
* Use this when you want to be explicit about the conversion or when implicit
380+
* conversion operators might be ambiguous.
381+
*
382+
* @tparam T The type to convert the JSON value to.
383+
* @return The JSON value converted to type T.
384+
*/
385+
template <typename T>
386+
[[nodiscard]] T get() const noexcept
387+
{
388+
if constexpr (std::is_same_v<T, bool>)
389+
return static_cast<bool>(*this);
390+
else if constexpr (std::is_integral_v<T> && std::is_signed_v<T>)
391+
return static_cast<int64_t>(*this);
392+
else if constexpr (std::is_integral_v<T> && std::is_unsigned_v<T>)
393+
return static_cast<uint64_t>(*this);
394+
else if constexpr (std::is_floating_point_v<T>)
395+
return static_cast<double>(*this);
396+
else if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view> || std::is_same_v<T, const char *>)
397+
return static_cast<std::string>(*this);
398+
else if constexpr (std::is_same_v<T, std::map<std::string, json, std::less<>>>)
399+
return static_cast<std::map<std::string, json, std::less<>>>(*this);
400+
else if constexpr (std::is_same_v<T, std::vector<json>>)
401+
return static_cast<std::vector<json>>(*this);
402+
else
403+
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view> || std::is_same_v<T, const char *> || std::is_same_v<T, std::map<std::string, json, std::less<>>> || std::is_same_v<T, std::vector<json>>, "Unsupported type for json::get<T>()");
404+
}
405+
371406
/**
372407
* @brief Conversion operator to bool.
373408
*
@@ -387,7 +422,7 @@ namespace json
387422
case 3:
388423
return std::get<uint64_t>(value) != 0;
389424
case 4:
390-
return !std::get<double>(value);
425+
return std::get<double>(value) != 0.0;
391426
case 5:
392427
return !std::get<std::string>(value).empty();
393428
case 6:

0 commit comments

Comments
 (0)