7#include <initializer_list>
28template <
typename T,
typename U>
30 constexpr const bool is_different_signedness =
31 (std::is_signed<T>::value != std::is_signed<U>::value);
33 const T t =
static_cast<T
>(u);
35 if (
static_cast<U
>(t) != u ||
36 (is_different_signedness && ((t < T{}) != (u < U{})))) {
54template <
typename T,
typename U>
56 constexpr const bool is_different_signedness =
57 (std::is_signed<T>::value != std::is_signed<U>::value);
59 const T t =
static_cast<T
>(u);
61 if (
static_cast<U
>(t) != u ||
62 (is_different_signedness && ((t < T{}) != (u < U{})))) {
80 using Null = std::nullptr_t;
95 using Object = std::map<std::string, JsonValue>;
100 using Array = std::vector<JsonValue>;
118 if (std::isnan(v) || std::isinf(v)) {
129 JsonValue(std::int8_t v) noexcept : value(
static_cast<std::int64_t
>(v)) {}
135 JsonValue(std::uint8_t v) noexcept : value(
static_cast<std::uint64_t
>(v)) {}
141 JsonValue(std::int16_t v) noexcept : value(
static_cast<std::int64_t
>(v)) {}
147 JsonValue(std::uint16_t v) noexcept : value(
static_cast<std::uint64_t
>(v)) {}
153 JsonValue(std::int32_t v) noexcept : value(
static_cast<std::int64_t
>(v)) {}
159 JsonValue(std::uint32_t v) noexcept : value(
static_cast<std::uint64_t
>(v)) {}
184 JsonValue(std::string&& v) noexcept : value(std::move(v)) {}
194 JsonValue(
const std::map<std::string, JsonValue>& v) : value(v) {}
199 JsonValue(std::map<std::string, JsonValue>&& v) : value(
std::move(v)) {}
204 JsonValue(
const std::vector<JsonValue>& v) : value(v) {}
209 JsonValue(std::vector<JsonValue>&& v) noexcept : value(std::move(v)) {}
220 JsonValue(std::initializer_list<std::pair<const std::string, JsonValue>> v)
250 template <
typename T>
252 const JsonValue* pValue = this->getValuePtrForKey(key);
257 return std::get_if<T>(&pValue->
value);
275 JsonValue* pValue = this->getValuePtrForKey(key);
276 return std::get_if<T>(&pValue->
value);
296 typename std::enable_if<
297 std::is_integral<To>::value ||
298 std::is_floating_point<To>::value>::type* =
nullptr>
299 [[nodiscard]] std::optional<To>
301 const Object& pObject = std::get<Object>(this->value);
302 const auto it = pObject.find(key);
303 if (it == pObject.end()) {
306 return it->second.getSafeNumber<To>();
330 typename std::enable_if<
331 std::is_integral<To>::value ||
332 std::is_floating_point<To>::value>::type* =
nullptr>
334 const std::string& key,
335 To defaultValue)
const {
336 const Object& pObject = std::get<Object>(this->value);
337 const auto it = pObject.find(key);
338 if (it == pObject.end()) {
341 return it->second.getSafeNumberOrDefault<To>(defaultValue);
351 [[nodiscard]]
inline bool hasKey(
const std::string& key)
const {
352 const Object* pObject = std::get_if<Object>(&this->value);
357 return pObject->find(key) != pObject->end();
370 typename std::enable_if<
371 std::is_integral<To>::value ||
372 std::is_floating_point<To>::value>::type* =
nullptr>
374 const std::uint64_t* uInt = std::get_if<std::uint64_t>(&this->value);
376 return losslessNarrow<To>(*uInt);
379 const std::int64_t* sInt = std::get_if<std::int64_t>(&this->value);
381 return losslessNarrow<To>(*sInt);
384 const double* real = std::get_if<double>(&this->value);
386 return losslessNarrow<To>(*real);
401 typename std::enable_if<
402 std::is_integral<To>::value ||
403 std::is_floating_point<To>::value>::type* =
nullptr>
405 const std::uint64_t* uInt = std::get_if<std::uint64_t>(&this->value);
407 return losslessNarrowOrDefault<To>(*uInt, defaultValue);
410 const std::int64_t* sInt = std::get_if<std::int64_t>(&this->value);
412 return losslessNarrowOrDefault<To>(*sInt, defaultValue);
415 const double* real = std::get_if<double>(&this->value);
417 return losslessNarrowOrDefault<To>(*real, defaultValue);
431 return std::get<JsonValue::Object>(this->value);
441 return std::get<String>(this->value);
451 return std::get<JsonValue::Array>(this->value);
462 [[nodiscard]] std::vector<std::string>
472 return std::get<bool>(this->value);
481 return std::get<double>(this->value);
491 return std::get<std::uint64_t>(this->value);
501 return std::get<std::int64_t>(this->value);
509 const auto* v = std::get_if<bool>(&this->value);
523 const auto* v = std::get_if<JsonValue::String>(&this->value);
535 [[nodiscard]]
inline double
537 const auto* v = std::get_if<double>(&this->value);
549 [[nodiscard]]
inline std::uint64_t
551 const auto* v = std::get_if<std::uint64_t>(&this->value);
563 [[nodiscard]]
inline std::int64_t
565 const auto* v = std::get_if<std::int64_t>(&this->value);
576 [[nodiscard]]
inline bool isNull() const noexcept {
577 return std::holds_alternative<Null>(this->value);
585 [[nodiscard]]
inline bool isNumber() const noexcept {
586 return isDouble() || isUint64() || isInt64();
592 [[nodiscard]]
inline bool isBool() const noexcept {
593 return std::holds_alternative<Bool>(this->value);
599 [[nodiscard]]
inline bool isString() const noexcept {
600 return std::holds_alternative<String>(this->value);
606 [[nodiscard]]
inline bool isObject() const noexcept {
607 return std::holds_alternative<Object>(this->value);
613 [[nodiscard]]
inline bool isArray() const noexcept {
614 return std::holds_alternative<Array>(this->value);
620 [[nodiscard]]
inline bool isDouble() const noexcept {
621 return std::holds_alternative<double>(this->value);
627 [[nodiscard]]
inline bool isUint64() const noexcept {
628 return std::holds_alternative<std::uint64_t>(this->value);
634 [[nodiscard]]
inline bool isInt64() const noexcept {
635 return std::holds_alternative<std::int64_t>(this->value);
642 return this->value == rhs.value;
650 int64_t operator()([[maybe_unused]]
const Null& ) {
return 0; }
651 int64_t operator()([[maybe_unused]]
const double& ) {
654 int64_t operator()([[maybe_unused]]
const std::uint64_t& ) {
657 int64_t operator()([[maybe_unused]]
const std::int64_t& ) {
660 int64_t operator()([[maybe_unused]]
const Bool& ) {
return 0; }
661 int64_t operator()(
const String& inside) {
662 return int64_t(inside.capacity() *
sizeof(
char));
664 int64_t operator()(
const Object& inside) {
667 int64_t(inside.size() * (
sizeof(std::string) +
sizeof(
JsonValue)));
668 for (
const auto& [k, v] : inside) {
669 accum += int64_t(k.capacity() *
sizeof(
char) -
sizeof(std::string));
670 accum += v.getSizeBytes() - int64_t(
sizeof(
JsonValue));
675 int64_t operator()(
const Array& inside) {
677 accum += int64_t(
sizeof(
JsonValue) * inside.capacity());
679 accum += v.getSizeBytes() - int64_t(
sizeof(
JsonValue));
685 return static_cast<int64_t
>(
sizeof(
JsonValue)) +
686 std::visit(Operation{}, this->value);
A generic implementation of a value in a JSON structure.
std::vector< std::string > getArrayOfStrings(const std::string &defaultString) const
Gets an array of strings from the value.
std::map< std::string, JsonValue > Object
The type to represent an Object JSON value.
JsonValue(std::int8_t v) noexcept
Creates a std::int64_t JSON value (Widening conversion from std::int8_t).
std::optional< To > getSafeNumericalValueForKey(const std::string &key) const
Converts the numerical value corresponding to the given key to the provided numerical template type.
bool getBool() const
Gets the bool from the value.
JsonValue(const std::map< std::string, JsonValue > &v)
Creates an Object JSON value with the given properties.
bool isInt64() const noexcept
Returns whether this value is a std::int64_t value.
const JsonValue::String & getString() const
Gets the string from the value.
JsonValue(std::int16_t v) noexcept
Creates a std::int64_t JSON value (Widening conversion from std::int16_t).
bool isNumber() const noexcept
Returns whether this value is a double, std::uint64_t or std::int64_t. Use this function in conjuncti...
bool isDouble() const noexcept
Returns whether this value is a double value.
JsonValue(std::vector< JsonValue > &&v) noexcept
Creates an Array JSON value with the given elements.
std::vector< JsonValue > Array
The type to represent an Array JSON value.
double getDoubleOrDefault(double defaultValue) const noexcept
Gets the double from the value or returns defaultValue.
JsonValue * getValuePtrForKey(const std::string &key)
Attempts to obtain a pointer to a JsonValue for the given key on this object.
JsonValue(std::initializer_list< JsonValue > v)
Creates an JSON value from the given initializer list.
JsonValue(std::uint16_t v) noexcept
Creates a std::uint64_t JSON value (Widening conversion from std::uint16_t).
std::variant< Null, double, std::uint64_t, std::int64_t, Bool, String, Object, Array > value
The actual value.
bool isBool() const noexcept
Returns whether this value is a Bool value.
const JsonValue::String getStringOrDefault(String defaultValue) const
Gets the string from the value or returns defaultValue.
JsonValue(std::nullptr_t) noexcept
Creates a null JSON value.
JsonValue(std::string &&v) noexcept
Creates a String JSON value.
bool Bool
The type to represent a Bool JSON value.
JsonValue(bool v) noexcept
Creates a Bool JSON value.
bool isNull() const noexcept
Returns whether this value is a null value.
const T * getValuePtrForKey(const std::string &key) const
Gets a typed value corresponding to the given key in the object represented by this instance.
std::uint64_t getUint64() const
Gets the std::uint64_t from the value.
bool operator==(const JsonValue &rhs) const noexcept
Returns true if two values are equal.
std::int64_t getInt64OrDefault(std::int64_t defaultValue) const noexcept
Gets the int64_t from the value or returns defaultValue.
std::string String
The type to represent a String JSON value.
JsonValue(const char *v)
Creates a String JSON value.
bool isUint64() const noexcept
Returns whether this value is a std::uint64_t value.
T * getValuePtrForKey(const std::string &key)
Gets a typed value corresponding to the given key in the object represented by this instance.
JsonValue(std::int64_t v) noexcept
Creates a std::int64_t JSON value.
bool isArray() const noexcept
Returns whether this value is an Array value.
JsonValue() noexcept
Default constructor.
bool isString() const noexcept
Returns whether this value is a String value.
bool isObject() const noexcept
Returns whether this value is an Object value.
JsonValue(double v) noexcept
Creates a Number JSON value.
std::int64_t getInt64() const
Gets the std::int64_t from the value.
JsonValue(std::map< std::string, JsonValue > &&v)
Creates an Object JSON value with the given properties.
bool getBoolOrDefault(bool defaultValue) const noexcept
Gets the bool from the value or returns defaultValue.
To getSafeNumberOrDefault(To defaultValue) const noexcept
Gets the numerical quantity from the value casted to the To type or returns defaultValue if unable to...
double getDouble() const
Gets the double from the value.
JsonValue(const std::string &v)
Creates a String JSON value.
JsonValue(std::uint32_t v) noexcept
Creates a std::uint64_t JSON value (Widening conversion from std::uint32_t).
const JsonValue::Object & getObject() const
Gets the object from the value.
const JsonValue * getValuePtrForKey(const std::string &key) const
Attempts to obtain a pointer to a JsonValue for the given key on this object.
std::uint64_t getUint64OrDefault(std::uint64_t defaultValue) const noexcept
Gets the uint64_t from the value or returns defaultValue.
JsonValue(std::uint8_t v) noexcept
Creates a std::uint64_t JSON value (Widening conversion from std::uint8_t).
int64_t getSizeBytes() const noexcept
Returns the size in bytes of this JsonValue.
JsonValue(std::int32_t v) noexcept
Creates a std::int64_t JSON value (Widening conversion from std::int32_t).
JsonValue(std::uint64_t v) noexcept
Creates a std::uint64_t JSON value.
std::optional< To > getSafeNumber() const
Gets the numerical quantity from the value casted to the To type. This function should be used over g...
To getSafeNumericalValueOrDefaultForKey(const std::string &key, To defaultValue) const
Converts the numerical value corresponding to the given key to the provided numerical template type.
const JsonValue::Array & getArray() const
Gets the array from the value.
JsonValue(const std::vector< JsonValue > &v)
Creates an Array JSON value with the given elements.
JsonValue(std::initializer_list< std::pair< const std::string, JsonValue > > v)
Creates an JSON value from the given initializer list.
std::nullptr_t Null
The type to represent a null JSON value.
bool hasKey(const std::string &key) const
Determines if this value is an Object and has the given key.
Utility classes for Cesium.
constexpr T losslessNarrowOrDefault(U u, T defaultValue) noexcept
Attempts a narrowing conversion of U into T without losing information. If a lossless conversion can'...
constexpr std::optional< T > losslessNarrow(U u) noexcept
Attempts a narrowing conversion of U into T without losing information. If a lossless conversion can'...