diff --git a/data/include/join/json.hpp b/data/include/join/json.hpp index 27c5fc1c..abd67d6d 100644 --- a/data/include/join/json.hpp +++ b/data/include/join/json.hpp @@ -545,83 +545,12 @@ namespace join } /** - * @brief set null key. + * @brief set scalar key. * @param key object key. * @return -1. */ - int setKey ([[maybe_unused]] std::nullptr_t key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set boolean key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] bool key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set integer key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] int32_t key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set unsigned integer key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] uint32_t key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set 64 bits integer key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] int64_t key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set unsigned 64 bits integer key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] uint64_t key) - { - join::lastError = make_error_code (SaxErrc::InvalidKey); - reset (); - return -1; - } - - /** - * @brief set real key. - * @param key object key. - * @return -1. - */ - int setKey ([[maybe_unused]] double key) + template + int setKey ([[maybe_unused]] Key key) { join::lastError = make_error_code (SaxErrc::InvalidKey); reset (); @@ -661,16 +590,6 @@ namespace join return 0; } - /** - * @brief set string key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (const char* key) - { - return setKey (std::string_view (key)); - } - /** * @brief set binary key. * @param key object key. @@ -1244,71 +1163,6 @@ namespace join return read (in, handler); } - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::stringstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::istringstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::fstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::ifstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::iostream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - /** * @brief deserialize a document. * @param document document to deserialize. diff --git a/data/include/join/pack.hpp b/data/include/join/pack.hpp index a4e75261..97290bee 100644 --- a/data/include/join/pack.hpp +++ b/data/include/join/pack.hpp @@ -491,11 +491,12 @@ namespace join } /** - * @brief set null key. + * @brief set scalar key. * @param key object key. * @return 0 on success, -1 otherwise. */ - int setKey ([[maybe_unused]] std::nullptr_t key) + template + int setKey ([[maybe_unused]] Key key) { if (JOIN_UNLIKELY (_depth == 0)) { @@ -503,103 +504,37 @@ namespace join reset (); return -1; } - return setNull (); - } - /** - * @brief set boolean key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (bool key) - { - if (JOIN_UNLIKELY (_depth == 0)) + using Type = ScalarType; + + if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setNull (); } - return setBool (key); - } - - /** - * @brief set integer key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (int32_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) + else if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setBool (static_cast (key)); } - return setInt (key); - } - - /** - * @brief set unsigned integer key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (uint32_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) + else if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setInt (static_cast (key)); } - return setUint (key); - } - - /** - * @brief set 64 bits integer key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (int64_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) + else if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setUint (static_cast (key)); } - return setInt64 (key); - } - - /** - * @brief set unsigned 64 bits integer key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (uint64_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) + else if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setInt64 (static_cast (key)); } - return setUint64 (key); - } - - /** - * @brief set real key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (double key) - { - if (JOIN_UNLIKELY (_depth == 0)) + else if constexpr (std::same_as) { - join::lastError = make_error_code (SaxErrc::InvalidParent); - reset (); - return -1; + return setUint64 (static_cast (key)); + } + else + { + return setDouble (static_cast (key)); } - return setDouble (key); } /** @@ -618,16 +553,6 @@ namespace join return setString (key); } - /** - * @brief set string key. - * @param key object key. - * @return 0 on success, -1 otherwise. - */ - int setKey (const char* key) - { - return setKey (std::string_view (key)); - } - /** * @brief set binary key. * @param key object key. @@ -849,71 +774,6 @@ namespace join return read (in, handler); } - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::stringstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::istringstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::fstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::ifstream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - - /** - * @brief deserialize a document. - * @param document document to deserialize. - * @param handler handler receiving the document. - * @return 0 on success, -1 otherwise. - */ - template - int deserialize (std::iostream& document, Handler& handler) - { - dconv::StreamProbe in (document); - return read (in, handler); - } - /** * @brief deserialize a document. * @param document document to deserialize. diff --git a/data/include/join/value.hpp b/data/include/join/value.hpp index f56687d3..f09709e2 100644 --- a/data/include/join/value.hpp +++ b/data/include/join/value.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -55,14 +56,22 @@ namespace join { - /// forward declaration. + /// forward declarations. template > class BasicValue; - /// forward declaration. template class ValueBuilder; + /// scalar alternative selected by overload resolution for a type. + template + using ScalarType = match_t; + + /// type implicitly convertible to a single scalar alternative, object pointers excluded. + template + concept Scalar = (std::is_null_pointer_v || !std::convertible_to) && + requires { typename ScalarType; }; + /// string. using String = View; @@ -172,143 +181,25 @@ namespace join } /** - * @brief constructs a null value. - * @param value null value. - */ - constexpr BasicValue (std::nullptr_t value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a null value using an allocator owned by the caller. - * @param value null value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (std::nullptr_t value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a boolean value. - * @param value boolean value. - */ - constexpr BasicValue (bool value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a boolean value using an allocator owned by the caller. - * @param value boolean value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (bool value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a integer value. - * @param value integer value. - */ - constexpr BasicValue (int32_t value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a integer value using an allocator owned by the caller. - * @param value integer value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (int32_t value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a unsigned integer value. - * @param value unsigned integer value. - */ - constexpr BasicValue (uint32_t value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a unsigned integer value using an allocator owned by the caller. - * @param value unsigned integer value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (uint32_t value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a 64 bits integer value. - * @param value 64 bits integer value. - */ - constexpr BasicValue (int64_t value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a 64 bits integer value using an allocator owned by the caller. - * @param value 64 bits integer value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (int64_t value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a 64 bits unsigned integer value. - * @param value 64 bits unsigned integer value. - */ - constexpr BasicValue (uint64_t value) - : _data (std::in_place_index, value) - { - } - - /** - * @brief constructs a 64 bits unsigned integer value using an allocator owned by the caller. - * @param value 64 bits unsigned integer value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (uint64_t value, Allocator& allocator) - : BasicValue (allocator) - { - _data.template set (value); - } - - /** - * @brief constructs a real value. - * @param value real value. + * @brief constructs a scalar value. + * @param value scalar value. */ - constexpr BasicValue (double value) - : _data (std::in_place_index, value) + template + constexpr BasicValue (Type value) + : _data (static_cast> (value)) { } /** - * @brief constructs a real value using an allocator owned by the caller. - * @param value real value. + * @brief constructs a scalar value using an allocator owned by the caller. + * @param value scalar value. * @param allocator allocator providing the memory of the value. */ - BasicValue (double value, Allocator& allocator) + template + BasicValue (Type value, Allocator& allocator) : BasicValue (allocator) { - _data.template set (value); + _data = static_cast> (value); } /** @@ -341,16 +232,6 @@ namespace join { } - /** - * @brief constructs a string value from a C-style string using an allocator owned by the caller. - * @param value string value. - * @param allocator allocator providing the memory of the value. - */ - BasicValue (const char* value, Allocator& allocator) - : BasicValue (std::string_view (value), allocator) - { - } - /** * @brief constructs a string value. * @param value string value. @@ -473,79 +354,20 @@ namespace join Value& operator= (std::nullptr_t value) { reset (); - _data.template set (value); - return *this; - } - - /** - * @brief assign a boolean value. - * @param value boolean value. - * @return a reference of the current object. - */ - Value& operator= (bool value) - { - reset (); - _data.template set (value); - return *this; - } - - /** - * @brief assign a integer value. - * @param value integer value. - * @return a reference of the current object. - */ - Value& operator= (int32_t value) - { - reset (); - _data.template set (value); - return *this; - } - - /** - * @brief assign a unsigned integer value. - * @param value unsigned integer value. - * @return a reference of the current object. - */ - Value& operator= (uint32_t value) - { - reset (); - _data.template set (value); - return *this; - } - - /** - * @brief assign a 64 bits integer value. - * @param value 64 bits integer value. - * @return a reference of the current object. - */ - Value& operator= (int64_t value) - { - reset (); - _data.template set (value); - return *this; - } - - /** - * @brief assign a 64 bits unsigned integer value. - * @param value 64 bits unsigned integer value. - * @return a reference of the current object. - */ - Value& operator= (uint64_t value) - { - reset (); - _data.template set (value); + _data = value; return *this; } /** - * @brief assign a real value. - * @param value real value. + * @brief assign a scalar value. + * @param value scalar value. * @return a reference of the current object. */ - Value& operator= (double value) + template + Value& operator= (Type value) { reset (); - _data.template set (value); + _data = static_cast> (value); return *this; } @@ -771,13 +593,33 @@ namespace join } /** - * @brief explicit conversion function for boolean value. - * @return converted boolean value. + * @brief explicit conversion function for scalar value. + * @return converted value. * @throw std::bad_cast. */ - explicit operator bool () const + template + requires std::same_as || std::same_as || std::same_as || + std::same_as || std::same_as || std::same_as || + std::same_as || std::same_as || std::same_as || + std::same_as || std::same_as + explicit operator Type () const { - return getBool (); + if constexpr (std::same_as) + { + return getBool (); + } + else if constexpr (std::same_as) + { + return getFloat (); + } + else if constexpr (std::same_as) + { + return getDouble (); + } + else + { + return convertInteger (); + } } /** @@ -816,40 +658,7 @@ namespace join */ constexpr bool isInt8 () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case UnsignedValue: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Integer64Value: - return _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -859,38 +668,7 @@ namespace join */ constexpr int8_t getInt8 () const { - if (isInt8 ()) - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } - - throwException (); - } - - /** - * @brief explicit conversion function for 8 bits integer value. - * @return converted char value. - * @throw std::bad_cast. - */ - explicit operator int8_t () const - { - return getInt8 (); + return convertInteger (); } /** @@ -899,37 +677,7 @@ namespace join */ constexpr bool isUint8 () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case UnsignedValue: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Integer64Value: - return _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -939,38 +687,7 @@ namespace join */ constexpr uint8_t getUint8 () const { - if (isUint8 ()) - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } - - throwException (); - } - - /** - * @brief explicit conversion function for 8 bits unsigned integer value. - * @return converted unsihed char value. - * @throw std::bad_cast. - */ - explicit operator uint8_t () const - { - return getUint8 (); + return convertInteger (); } /** @@ -979,40 +696,7 @@ namespace join */ constexpr bool isInt16 () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case UnsignedValue: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Integer64Value: - return _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1022,77 +706,16 @@ namespace join */ constexpr int16_t getInt16 () const { - if (isInt16 ()) - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } - - throwException (); + return convertInteger (); } /** - * @brief explicit conversion function for 16 bits integer value. - * @return converted short value. - * @throw std::bad_cast. - */ - explicit operator int16_t () const - { - return getInt16 (); - } - - /** - * @brief check if the variable held by value is a 16 bits unsigned integer value. - * @return true if the variable held by value is a 16 bits unsigned integer value, false otherwise. + * @brief check if the variable held by value is a 16 bits unsigned integer value. + * @return true if the variable held by value is a 16 bits unsigned integer value, false otherwise. */ constexpr bool isUint16 () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case UnsignedValue: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Integer64Value: - return _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1102,38 +725,7 @@ namespace join */ constexpr uint16_t getUint16 () const { - if (isUint16 ()) - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } - - throwException (); - } - - /** - * @brief explicit conversion function for 16 bits unsigned integer value. - * @return converted unsigned short value. - * @throw std::bad_cast. - */ - explicit operator uint16_t () const - { - return getUint16 (); + return convertInteger (); } /** @@ -1142,37 +734,7 @@ namespace join */ constexpr bool isInt () const { - switch (_data.index ()) - { - case IntegerValue: - return true; - - case UnsignedValue: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Integer64Value: - return _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1187,17 +749,7 @@ namespace join return _data.template get (); } - return convertInt (); - } - - /** - * @brief explicit conversion function for 32 bits integer value. - * @return converted integer value. - * @throw std::bad_cast. - */ - explicit operator int32_t () const - { - return getInt (); + return convertInteger (); } /** @@ -1206,34 +758,7 @@ namespace join */ constexpr bool isUint () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= 0; - - case UnsignedValue: - return true; - - case Integer64Value: - return _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= 0 && - _data.template get () <= - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1248,17 +773,7 @@ namespace join return _data.template get (); } - return convertUint (); - } - - /** - * @brief explicit conversion function for 32 bits unsigned integer value. - * @return converted unsigned integer value. - * @throw std::bad_cast. - */ - explicit operator uint32_t () const - { - return getUint (); + return convertInteger (); } /** @@ -1267,29 +782,7 @@ namespace join */ constexpr bool isInt64 () const { - switch (_data.index ()) - { - case IntegerValue: - case UnsignedValue: - case Integer64Value: - return true; - - case Unsigned64Value: - return _data.template get () <= - static_cast (std::numeric_limits::max ()); - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= - static_cast (std::numeric_limits::min ()) && - _data.template get () < - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1304,17 +797,7 @@ namespace join return _data.template get (); } - return convertInt64 (); - } - - /** - * @brief explicit conversion function for 64 bits integer value. - * @return converted integer 64 bits value. - * @throw std::bad_cast. - */ - explicit operator int64_t () const - { - return getInt64 (); + return convertInteger (); } /** @@ -1323,31 +806,7 @@ namespace join */ constexpr bool isUint64 () const { - switch (_data.index ()) - { - case IntegerValue: - return _data.template get () >= 0; - - case UnsignedValue: - return true; - - case Integer64Value: - return _data.template get () >= 0; - - case Unsigned64Value: - return true; - - case RealValue: - return std::trunc (_data.template get ()) == _data.template get () && - _data.template get () >= 0 && - _data.template get () < - static_cast (std::numeric_limits::max ()); - - default: - break; - } - - return false; + return isInteger (); } /** @@ -1362,17 +821,7 @@ namespace join return _data.template get (); } - return convertUint64 (); - } - - /** - * @brief explicit conversion function for 64 bits unsigned integer value. - * @return converted 64 bits unsigned integer value. - * @throw std::bad_cast. - */ - explicit operator uint64_t () const - { - return getUint64 (); + return convertInteger (); } /** @@ -1391,22 +840,7 @@ namespace join */ constexpr float getFloat () const { - if (_data.index () == RealValue) - { - return static_cast (_data.template get ()); - } - - return convertFloat (); - } - - /** - * @brief explicit conversion function for float value. - * @return converted float value. - * @throw std::bad_cast. - */ - explicit operator float () const - { - return getFloat (); + return convertReal (); } /** @@ -1430,17 +864,7 @@ namespace join return _data.template get (); } - return convertDouble (); - } - - /** - * @brief explicit conversion function for double value. - * @return converted double value. - * @throw std::bad_cast. - */ - explicit operator double () const - { - return getDouble (); + return convertReal (); } /** @@ -1542,22 +966,15 @@ namespace join } /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. + * @brief returns a reference to the value at position pos or mapped to key. + * @param key position or key of the element to find. * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at ([[maybe_unused]] std::nullptr_t key) + template + Value& at (Key key) { - for (auto& member : _data.template get ()) - { - if (member.first.isNull ()) - { - return member.second; - } - } - - throwException ("invalid key"); + return const_cast (std::as_const (*this).at (key)); } /** @@ -1566,17 +983,9 @@ namespace join * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at (bool key) + Value& at (std::string_view key) { - for (auto& member : _data.template get ()) - { - if (member.first.isBool () && member.first.getBool () == key) - { - return member.second; - } - } - - throwException ("invalid key"); + return const_cast (std::as_const (*this).at (key)); } /** @@ -1585,22 +994,11 @@ namespace join * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at (int32_t key) + template + requires std::same_as + Value& at (const Key& key) { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isInt () && member.first.getInt () == key) - { - return member.second; - } - } - - throwException ("invalid key"); + return const_cast (std::as_const (*this).at (key)); } /** @@ -1609,46 +1007,41 @@ namespace join * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at (uint32_t key) + template + const Value& at (Key key) const { - if (_data.index () == ArrayValue) + if constexpr (std::integral> && !std::same_as, bool>) { - return elementAt (key); + if (_data.index () == ArrayValue) + { + return elementAt (static_cast> (key)); + } } - for (auto& member : _data.template get ()) + const Member* member = findMember (key); + if (member == nullptr) { - if (member.first.isUint () && member.first.getUint () == key) - { - return member.second; - } + throwException ("invalid key"); } - throwException ("invalid key"); + return member->second; } /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. + * @brief returns a reference to the value mapped to key. + * @param key key of the element to find. * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at (int64_t key) + const Value& at (std::string_view key) const { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto& member : _data.template get ()) + const Member* member = findMember (key); + if (member == nullptr) { - if (member.first.isInt64 () && member.first.getInt64 () == key) - { - return member.second; - } + throwException ("invalid key"); } - throwException ("invalid key"); + return member->second; } /** @@ -1657,560 +1050,104 @@ namespace join * @return a reference to the requested element. * @throw std::bad_cast, std::out_of_range. */ - Value& at (uint64_t key) + template + requires std::same_as + const Value& at (const Key& key) const { if (_data.index () == ArrayValue) { - return elementAt (key); + return elementAt (key.getUint64 ()); } - for (auto& member : _data.template get ()) + const Member* member = findMember (key); + if (member == nullptr) { - if (member.first.isUint64 () && member.first.getUint64 () == key) - { - return member.second; - } + throwException ("invalid key"); } - throwException ("invalid key"); + return member->second; } /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. + * @brief returns a reference to the value at position pos or mapped to key. + * @param key position or key of the element to find. * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. + * @throw std::bad_cast. */ - Value& at (double key) + template + Value& operator[] (Key key) { - for (auto& member : _data.template get ()) + if constexpr (std::integral> && !std::same_as, bool>) { - if (member.first.isDouble () && member.first.getDouble () == key) + if (_data.index () == ArrayValue) { - return member.second; + return _data.template get ()[static_cast> (key)]; } } - throwException ("invalid key"); - } + if (_data.index () == NullValue) + { + _data.template set (); + } - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - Value& at (std::string_view key) - { - for (auto& member : _data.template get ()) + Member* member = findMember (key); + if (member == nullptr) { - if (member.first.isString () && member.first.getString () == key) - { - return member.second; - } + return appendMember (key); } - throwException ("invalid key"); + return member->second; } /** * @brief returns a reference to the value mapped to key. * @param key key of the element to find. * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. + * @throw std::bad_cast. */ - Value& at (const char* key) + Value& operator[] (std::string_view key) { - return at (std::string_view (key)); + if (_data.index () == NullValue) + { + _data.template set (); + } + + Member* member = findMember (key); + if (member == nullptr) + { + return appendMember (key); + } + + return member->second; } /** * @brief returns a reference to the value at position pos or mapped to key. * @param key position or key of the element to find. * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. + * @throw std::bad_cast. */ template requires std::same_as - Value& at (const Key& key) + Value& operator[] (const Key& key) { if (_data.index () == ArrayValue) { - return elementAt (key.getUint64 ()); + return _data.template get ()[key.getUint64 ()]; } - for (auto& member : _data.template get ()) + if (_data.index () == NullValue) { - if (member.first == key) - { - return member.second; - } + _data.template set (); + } + + Member* member = findMember (key); + if (member == nullptr) + { + return appendMember (Value (key, *allocator ()), Value (*allocator ())); } - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at ([[maybe_unused]] std::nullptr_t key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isNull ()) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (bool key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isBool () && member.first.getBool () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (int32_t key) const - { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isInt () && member.first.getInt () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (uint32_t key) const - { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isUint () && member.first.getUint () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (int64_t key) const - { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isInt64 () && member.first.getInt64 () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (uint64_t key) const - { - if (_data.index () == ArrayValue) - { - return elementAt (key); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isUint64 () && member.first.getUint64 () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (double key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isDouble () && member.first.getDouble () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (std::string_view key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isString () && member.first.getString () == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - const Value& at (const char* key) const - { - return at (std::string_view (key)); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast, std::out_of_range. - */ - template - requires std::same_as - const Value& at (const Key& key) const - { - if (_data.index () == ArrayValue) - { - return elementAt (key.getUint64 ()); - } - - for (auto const& member : _data.template get ()) - { - if (member.first == key) - { - return member.second; - } - } - - throwException ("invalid key"); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (std::nullptr_t key) - { - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isNull ()) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (bool key) - { - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isBool () && member.first.getBool () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (int32_t key) - { - if (_data.index () == ArrayValue) - { - return _data.template get ()[key]; - } - - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isInt () && member.first.getInt () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (uint32_t key) - { - if (_data.index () == ArrayValue) - { - return _data.template get ()[key]; - } - - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isUint () && member.first.getUint () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (int64_t key) - { - if (_data.index () == ArrayValue) - { - return _data.template get ()[key]; - } - - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isInt64 () && member.first.getInt64 () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (uint64_t key) - { - if (_data.index () == ArrayValue) - { - return _data.template get ()[key]; - } - - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isUint64 () && member.first.getUint64 () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (double key) - { - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isDouble () && member.first.getDouble () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (std::string_view key) - { - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first.isString () && member.first.getString () == key) - { - return member.second; - } - } - - return appendMember (key); - } - - /** - * @brief returns a reference to the value mapped to key. - * @param key key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - Value& operator[] (const char* key) - { - return operator[] (std::string_view (key)); - } - - /** - * @brief returns a reference to the value at position pos or mapped to key. - * @param key position or key of the element to find. - * @return a reference to the requested element. - * @throw std::bad_cast. - */ - template - requires std::same_as - Value& operator[] (const Key& key) - { - if (_data.index () == ArrayValue) - { - return _data.template get ()[key.getUint64 ()]; - } - - if (_data.index () == NullValue) - { - _data.template set (); - } - - for (auto& member : _data.template get ()) - { - if (member.first == key) - { - return member.second; - } - } - - return appendMember (Value (key, *allocator ()), Value (*allocator ())); + return member->second; } /** @@ -2220,25 +1157,7 @@ namespace join */ bool empty () const { - switch (_data.index ()) - { - case StringValue: - return _data.template get ().empty (); - - case BinaryValue: - return _data.template get ().data.empty (); - - case ArrayValue: - return _data.template get ().empty (); - - case ObjectValue: - return _data.template get ().empty (); - - default: - break; - } - - throwException (); + return size () == 0; } /** @@ -2332,352 +1251,94 @@ namespace join break; } - throwException (); - } - - /** - * @brief insert element in the nested container. - * @param member the element to insert in the nested container. - * @return a reference to the inserted element. - * @throw std::bad_cast. - */ - template - requires std::same_as - Value& insert (const M& member) - { - return appendMember (Value (member.first, *allocator ()), Value (member.second, *allocator ())); - } - - /** - * @brief insert a member built with the allocator of the tree. - * @param key key of the member. - * @param value value of the member. - * @return a reference to the inserted element. - * @throw std::bad_cast. - */ - template - Value& insert (K&& key, T&& value) - { - return appendMember (Value (std::forward (key), *allocator ()), - Value (std::forward (value), *allocator ())); - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase ([[maybe_unused]] std::nullptr_t key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isNull ()) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (bool key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isBool () && it->first.getBool () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (int32_t key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isInt () && it->first.getInt () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (uint32_t key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isUint () && it->first.getUint () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (int64_t key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isInt64 () && it->first.getInt64 () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (uint64_t key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isUint64 () && it->first.getUint64 () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (double key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isDouble () && it->first.getDouble () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (std::string_view key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first.isString () && it->first.getString () == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - size_t erase (const char* key) - { - return erase (std::string_view (key)); - } - - /** - * @brief removes member with the key equivalent to key. - * @param key key of the member to remove. - * @return number of elements removed. - * @throw std::bad_cast. - */ - template - requires std::same_as - size_t erase (const Key& key) - { - auto beg = _data.template get ().begin (); - auto end = _data.template get ().end (); - - for (auto it = beg; it != end; ++it) - { - if (it->first == key) - { - eraseMember (it); - return 1; - } - } - - return 0; - } - - /** - * @brief constructs an element in place at the end of the nested container. - * @param args arguments forwarded to the element constructor. - * @return a reference to the constructed object. - * @throw std::bad_cast. - */ - template - Value& emplaceBack (Args&&... args) - { - return pushBack (Value (std::forward (args)..., *allocator ())); - } - - /** - * @brief appends a null value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. - * @throw std::bad_cast. - */ - Value& pushBack (std::nullptr_t value) - { - return pushBack (Value (value, *allocator ())); - } - - /** - * @brief appends a boolean value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. - * @throw std::bad_cast. - */ - Value& pushBack (bool value) - { - return pushBack (Value (value, *allocator ())); + throwException (); } /** - * @brief appends a integer value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. + * @brief insert element in the nested container. + * @param member the element to insert in the nested container. + * @return a reference to the inserted element. * @throw std::bad_cast. */ - Value& pushBack (int32_t value) + template + requires std::same_as + Value& insert (const M& member) { - return pushBack (Value (value, *allocator ())); + return appendMember (Value (member.first, *allocator ()), Value (member.second, *allocator ())); } /** - * @brief appends a unsigned integer value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. + * @brief insert a member built with the allocator of the tree. + * @param key key of the member. + * @param value value of the member. + * @return a reference to the inserted element. * @throw std::bad_cast. */ - Value& pushBack (uint32_t value) + template + Value& insert (K&& key, T&& value) { - return pushBack (Value (value, *allocator ())); + return appendMember (Value (std::forward (key), *allocator ()), + Value (std::forward (value), *allocator ())); } /** - * @brief appends a 64 bits integer value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. + * @brief removes member with the key equivalent to key. + * @param key key of the member to remove. + * @return number of elements removed. * @throw std::bad_cast. */ - Value& pushBack (int64_t value) + template + requires Scalar || std::same_as + size_t erase (const Key& key) { - return pushBack (Value (value, *allocator ())); + Member* member = findMember (key); + if (member == nullptr) + { + return 0; + } + + eraseMember (member); + return 1; } /** - * @brief appends a 64 bits unsigned integer value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. + * @brief removes member with the key equivalent to key. + * @param key key of the member to remove. + * @return number of elements removed. * @throw std::bad_cast. */ - Value& pushBack (uint64_t value) + size_t erase (std::string_view key) { - return pushBack (Value (value, *allocator ())); + Member* member = findMember (key); + if (member == nullptr) + { + return 0; + } + + eraseMember (member); + return 1; } /** - * @brief appends a real value at the end of the nested container. - * @param value the element to append. - * @return a reference to the pushed object. + * @brief constructs an element in place at the end of the nested container. + * @param args arguments forwarded to the element constructor. + * @return a reference to the constructed object. * @throw std::bad_cast. */ - Value& pushBack (double value) + template + Value& emplaceBack (Args&&... args) { - return pushBack (Value (value, *allocator ())); + return pushBack (Value (std::forward (args)..., *allocator ())); } /** - * @brief appends a string value from a C-style string at the end of the nested container. + * @brief appends a scalar value at the end of the nested container. * @param value the element to append. * @return a reference to the pushed object. * @throw std::bad_cast. */ - Value& pushBack (const char* value) + template + Value& pushBack (Type value) { return pushBack (Value (value, *allocator ())); } @@ -2764,156 +1425,32 @@ namespace join } /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains ([[maybe_unused]] std::nullptr_t key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isNull ()) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (bool key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isBool () && member.first.getBool () == key) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key position or key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (int32_t key) const - { - if (_data.index () == ArrayValue) - { - return key >= 0 && static_cast (key) < _data.template get ().size (); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isInt () && member.first.getInt () == key) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key position or key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (uint32_t key) const - { - if (_data.index () == ArrayValue) - { - return key < _data.template get ().size (); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isUint () && member.first.getUint () == key) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key position or key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (int64_t key) const - { - if (_data.index () == ArrayValue) - { - return key >= 0 && static_cast (key) < _data.template get ().size (); - } - - for (auto const& member : _data.template get ()) - { - if (member.first.isInt64 () && member.first.getInt64 () == key) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. + * @brief checks if the nested container contains an element at position pos or mapped to key. * @param key position or key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. + * @return true if the nested container contains an element at position pos or mapped to key, false otherwise. * @throw std::bad_cast. */ - bool contains (uint64_t key) const + template + bool contains (Key key) const { - if (_data.index () == ArrayValue) - { - return key < _data.template get ().size (); - } - - for (auto const& member : _data.template get ()) + if constexpr (std::integral> && !std::same_as, bool>) { - if (member.first.isUint64 () && member.first.getUint64 () == key) + if (_data.index () == ArrayValue) { - return true; - } - } - - return false; - } + if constexpr (std::is_signed_v>) + { + if (static_cast> (key) < 0) + { + return false; + } + } - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (double key) const - { - for (auto const& member : _data.template get ()) - { - if (member.first.isDouble () && member.first.getDouble () == key) - { - return true; + return static_cast (static_cast> (key)) < + _data.template get ().size (); } } - return false; + return findMember (key) != nullptr; } /** @@ -2924,26 +1461,7 @@ namespace join */ bool contains (std::string_view key) const { - for (auto const& member : _data.template get ()) - { - if (member.first.isString () && member.first.getString () == key) - { - return true; - } - } - - return false; - } - - /** - * @brief checks if the nested container contains an element that is mapped to key. - * @param key key of the element to find. - * @return true if the nested container contains an element mapped to key, false otherwise. - * @throw std::bad_cast. - */ - bool contains (const char* key) const - { - return contains (std::string_view (key)); + return findMember (key) != nullptr; } /** @@ -2961,15 +1479,7 @@ namespace join return key.getUint64 () < _data.template get ().size (); } - for (auto const& member : _data.template get ()) - { - if (member.first == key) - { - return true; - } - } - - return false; + return findMember (key) != nullptr; } /** @@ -3050,124 +1560,28 @@ namespace join /** * @brief three-way compare values. - * @param other value to compare to. - * @return ordering of this value relative to other. - */ - template - requires std::same_as> - constexpr std::partial_ordering operator<=> (const Other& other) const; - - /** - * @brief compare if equal to a null value. - * @param other null value to compare to. - * @return true if equal. - */ - constexpr bool operator== (std::nullptr_t other) const; - - /** - * @brief three-way compare to a null value. - * @param other null value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (std::nullptr_t other) const; - - /** - * @brief compare if equal to a boolean value. - * @param other boolean value to compare to. - * @return true if equal. - */ - constexpr bool operator== (bool other) const; - - /** - * @brief three-way compare to a boolean value. - * @param other boolean value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (bool other) const; - - /** - * @brief compare if equal to a integer value. - * @param other integer value to compare to. - * @return true if equal. - */ - constexpr bool operator== (int32_t other) const; - - /** - * @brief three-way compare to a integer value. - * @param other integer value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (int32_t other) const; - - /** - * @brief compare if equal to a unsigned integer value. - * @param other unsigned integer value to compare to. - * @return true if equal. - */ - constexpr bool operator== (uint32_t other) const; - - /** - * @brief three-way compare to a unsigned integer value. - * @param other unsigned integer value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (uint32_t other) const; - - /** - * @brief compare if equal to a 64 bits integer value. - * @param other 64 bits integer value to compare to. - * @return true if equal. - */ - constexpr bool operator== (int64_t other) const; - - /** - * @brief three-way compare to a 64 bits integer value. - * @param other 64 bits integer value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (int64_t other) const; - - /** - * @brief compare if equal to a 64 bits unsigned integer value. - * @param other 64 bits unsigned integer value to compare to. - * @return true if equal. - */ - constexpr bool operator== (uint64_t other) const; - - /** - * @brief three-way compare to a 64 bits unsigned integer value. - * @param other 64 bits unsigned integer value to compare to. - * @return ordering of this value relative to other. - */ - constexpr std::partial_ordering operator<=> (uint64_t other) const; - - /** - * @brief compare if equal to a real value. - * @param other real value to compare to. - * @return true if equal. - */ - constexpr bool operator== (double other) const; - - /** - * @brief three-way compare to a real value. - * @param other real value to compare to. + * @param other value to compare to. * @return ordering of this value relative to other. */ - constexpr std::partial_ordering operator<=> (double other) const; + template + requires std::same_as> + constexpr std::partial_ordering operator<=> (const Other& other) const; /** - * @brief compare if equal to a C-style string. - * @param other string to compare to. + * @brief compare if equal to a scalar value. + * @param other scalar value to compare to. * @return true if equal. */ - constexpr bool operator== (const char* other) const; + template + constexpr bool operator== (Type other) const; /** - * @brief three-way compare to a C-style string. - * @param other string to compare to. + * @brief three-way compare to a scalar value. + * @param other scalar value to compare to. * @return ordering of this value relative to other. */ - constexpr std::partial_ordering operator<=> (const char* other) const; + template + constexpr std::partial_ordering operator<=> (Type other) const; /** * @brief compare if equal to a string view. @@ -3459,6 +1873,88 @@ namespace join return appendMember (Value (key, *allocator ()), Value (*allocator ())); } + /** + * @brief check if the value matches a scalar key. + * @param key key to match. + * @return true if the value matches the key, false otherwise. + */ + template + constexpr bool matchKey (Key key) const + { + using Type = ScalarType; + + if constexpr (std::same_as) + { + return isNull (); + } + else if constexpr (std::same_as) + { + return isBool () && getBool () == static_cast (key); + } + else if constexpr (std::same_as) + { + return isDouble () && getDouble () == static_cast (key); + } + else + { + return isInteger () && convertInteger () == static_cast (key); + } + } + + /** + * @brief check if the value matches a string key. + * @param key key to match. + * @return true if the value matches the key, false otherwise. + */ + constexpr bool matchKey (std::string_view key) const + { + return isString () && getString () == key; + } + + /** + * @brief check if the value matches a value key. + * @param key key to match. + * @return true if the value matches the key, false otherwise. + */ + template + requires std::same_as + constexpr bool matchKey (const Key& key) const + { + return *this == key; + } + + /** + * @brief find the member mapped to key. + * @param key key of the member to find. + * @return a pointer to the member, nullptr if not found. + * @throw std::bad_cast. + */ + template + Member* findMember (const Key& key) + { + return const_cast (std::as_const (*this).findMember (key)); + } + + /** + * @brief find the member mapped to key. + * @param key key of the member to find. + * @return a pointer to the member, nullptr if not found. + * @throw std::bad_cast. + */ + template + const Member* findMember (const Key& key) const + { + for (auto const& member : _data.template get ()) + { + if (member.first.matchKey (key)) + { + return &member; + } + } + + return nullptr; + } + /** * @brief remove a member of the object. * @param it member to remove. @@ -3479,12 +1975,7 @@ namespace join */ Value& elementAt (size_t pos) { - Array& array = _data.template get (); - if (pos >= array.size ()) - { - throwException ("invalid key"); - } - return array[pos]; + return const_cast (std::as_const (*this).elementAt (pos)); } /** @@ -3658,24 +2149,29 @@ namespace join } /** - * @brief convert the value held by the variant to float. + * @brief convert the value held by the variant to a floating point type. * @return converted value. + * @throw std::bad_cast. */ - float convertFloat () const + template + Type convertReal () const { switch (_data.index ()) { case IntegerValue: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); + + case RealValue: + return static_cast (_data.template get ()); default: break; @@ -3718,140 +2214,71 @@ namespace join } /** - * @brief convert the value held by the variant to int32_t. - * @return converted value. - */ - int32_t convertInt () const - { - if (isInt ()) - { - switch (_data.index ()) - { - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } - - throwException (); - } - - /** - * @brief convert the value held by the variant to uint32_t. - * @return converted value. + * @brief check if the variable held by value fits in an integer type. + * @return true if the variable held by value fits in the integer type, false otherwise. */ - uint32_t convertUint () const + template + constexpr bool isInteger () const { - if (isUint ()) + switch (_data.index ()) { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - return static_cast (_data.template get ()); - } - } + case IntegerValue: + return std::in_range (_data.template get ()); - throwException (); - } + case UnsignedValue: + return std::in_range (_data.template get ()); - /** - * @brief convert the value held by the variant to int64_t. - * @return converted value. - */ - int64_t convertInt64 () const - { - if (isInt64 ()) - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); + case Integer64Value: + return std::in_range (_data.template get ()); - case UnsignedValue: - return static_cast (_data.template get ()); + case Unsigned64Value: + return std::in_range (_data.template get ()); - case Unsigned64Value: - return static_cast (_data.template get ()); + case RealValue: + return std::trunc (_data.template get ()) == _data.template get () && + _data.template get () >= + static_cast (std::numeric_limits::min ()) && + _data.template get () < std::ldexp (1.0, std::numeric_limits::digits); - default: - return static_cast (_data.template get ()); - } + default: + break; } - throwException (); + return false; } /** - * @brief convert the value held by the variant to uint64_t. + * @brief convert the value held by the variant to an integer type. * @return converted value. + * @throw std::bad_cast. */ - uint64_t convertUint64 () const + template + constexpr Type convertInteger () const { - if (isUint64 ()) + if (isInteger ()) { switch (_data.index ()) { case IntegerValue: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); + + case Unsigned64Value: + return static_cast (_data.template get ()); default: - return static_cast (_data.template get ()); + return static_cast (_data.template get ()); } } throwException (); } - /** - * @brief convert the value held by the variant to double. - * @return converted value. - */ - double convertDouble () const - { - switch (_data.index ()) - { - case IntegerValue: - return static_cast (_data.template get ()); - - case UnsignedValue: - return static_cast (_data.template get ()); - - case Integer64Value: - return static_cast (_data.template get ()); - - case Unsigned64Value: - return static_cast (_data.template get ()); - - default: - break; - } - - throwException (); - } - /// variant holding the value. Data _data; @@ -3932,181 +2359,29 @@ namespace join } /** - * @brief compare if equal to a null value. - * @param other null value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (std::nullptr_t other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a null value. - * @param other null value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (std::nullptr_t other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a boolean value. - * @param other boolean value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (bool other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a boolean value. - * @param other boolean value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (bool other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a integer value. - * @param other integer value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (int32_t other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a integer value. - * @param other integer value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (int32_t other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a unsigned integer value. - * @param other unsigned integer value to compare to. + * @brief compare if equal to a scalar value. + * @param other scalar value to compare to. * @return true if equal. */ template - constexpr bool BasicValue::operator== (uint32_t other) const + template + constexpr bool BasicValue::operator== (Type other) const { return *this == BasicValue (other); } /** - * @brief three-way compare to a unsigned integer value. - * @param other unsigned integer value to compare to. + * @brief three-way compare to a scalar value. + * @param other scalar value to compare to. * @return ordering of this value relative to other. */ template - constexpr std::partial_ordering BasicValue::operator<=> (uint32_t other) const + template + constexpr std::partial_ordering BasicValue::operator<=> (Type other) const { return *this <=> BasicValue (other); } - /** - * @brief compare if equal to a 64 bits integer value. - * @param other 64 bits integer value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (int64_t other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a 64 bits integer value. - * @param other 64 bits integer value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (int64_t other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a 64 bits unsigned integer value. - * @param other 64 bits unsigned integer value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (uint64_t other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a 64 bits unsigned integer value. - * @param other 64 bits unsigned integer value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (uint64_t other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a real value. - * @param other real value to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (double other) const - { - return *this == BasicValue (other); - } - - /** - * @brief three-way compare to a real value. - * @param other real value to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (double other) const - { - return *this <=> BasicValue (other); - } - - /** - * @brief compare if equal to a C-style string. - * @param other string to compare to. - * @return true if equal. - */ - template - constexpr bool BasicValue::operator== (const char* other) const - { - return *this == std::string_view (other); - } - - /** - * @brief three-way compare to a C-style string. - * @param other string to compare to. - * @return ordering of this value relative to other. - */ - template - constexpr std::partial_ordering BasicValue::operator<=> (const char* other) const - { - return *this <=> std::string_view (other); - } - /** * @brief compare if equal to a string view. * @param other string to compare to. diff --git a/data/include/join/value_builder.hpp b/data/include/join/value_builder.hpp index 0ce3589e..1f2cc260 100644 --- a/data/include/join/value_builder.hpp +++ b/data/include/join/value_builder.hpp @@ -270,119 +270,12 @@ namespace join } /** - * @brief set null key. + * @brief set scalar key. * @param key object key to set. * @return 0 on success, -1 otherwise. */ - int setKey (std::nullptr_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set boolean key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (bool key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set integer key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (int32_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set unsigned integer key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (uint32_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set 64 bits integer key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (int64_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set unsigned 64 bits integer key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (uint64_t key) - { - if (JOIN_UNLIKELY (_depth == 0)) - { - join::lastError = make_error_code (SaxErrc::InvalidParent); - return -1; - } - - _stack.emplace_back (key); - - return 0; - } - - /** - * @brief set real key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (double key) + template + int setKey (Key key) { if (JOIN_UNLIKELY (_depth == 0)) { @@ -413,16 +306,6 @@ namespace join return 0; } - /** - * @brief set string key. - * @param key object key to set. - * @return 0 on success, -1 otherwise. - */ - int setKey (const char* key) - { - return setKey (std::string_view (key)); - } - /** * @brief set binary key. * @param key object key to set.