diff --git a/core/include/join/view.hpp b/core/include/join/view.hpp index a32e4c22..5b152aea 100644 --- a/core/include/join/view.hpp +++ b/core/include/join/view.hpp @@ -68,7 +68,16 @@ namespace join * @brief get the first element. * @return pointer to the first element. */ - constexpr Type* data () const noexcept + constexpr Type* data () noexcept + { + return _data; + } + + /** + * @brief get the first element. + * @return pointer to the first element. + */ + constexpr const Type* data () const noexcept { return _data; } @@ -95,7 +104,16 @@ namespace join * @brief get an iterator to the first element. * @return iterator to the first element. */ - constexpr Type* begin () const noexcept + constexpr Type* begin () noexcept + { + return _data; + } + + /** + * @brief get an iterator to the first element. + * @return iterator to the first element. + */ + constexpr const Type* begin () const noexcept { return _data; } @@ -104,17 +122,36 @@ namespace join * @brief get an iterator past the last element. * @return iterator past the last element. */ - constexpr Type* end () const noexcept + constexpr Type* end () noexcept { return _data + _size; } + /** + * @brief get an iterator past the last element. + * @return iterator past the last element. + */ + constexpr const Type* end () const noexcept + { + return _data + _size; + } + + /** + * @brief access an element. + * @param pos element position. + * @return element. + */ + constexpr Type& operator[] (size_t pos) noexcept + { + return _data[pos]; + } + /** * @brief access an element. * @param pos element position. * @return element. */ - constexpr Type& operator[] (size_t pos) const noexcept + constexpr const Type& operator[] (size_t pos) const noexcept { return _data[pos]; } diff --git a/core/tests/view_test.cpp b/core/tests/view_test.cpp index 5a5686f4..eeb73aa6 100644 --- a/core/tests/view_test.cpp +++ b/core/tests/view_test.cpp @@ -68,6 +68,10 @@ TEST (View, data) int values[] = {1, 2, 3}; EXPECT_EQ (View ().data (), nullptr); EXPECT_EQ (View (values, 3).data (), values); + + const View constant (values, 3); + static_assert (std::is_same_v); + EXPECT_EQ (constant.data (), values); } /** @@ -100,6 +104,10 @@ TEST (View, begin) View view (values, 3); EXPECT_EQ (view.begin (), values); EXPECT_EQ (*view.begin (), 1); + + const View constant (values, 3); + static_assert (std::is_same_v); + EXPECT_EQ (constant.begin (), values); } /** @@ -111,6 +119,10 @@ TEST (View, end) View view (values, 3); EXPECT_EQ (view.end (), values + 3); + const View constant (values, 3); + static_assert (std::is_same_v); + EXPECT_EQ (constant.end (), values + 3); + int sum = 0; for (int value : view) { @@ -130,6 +142,10 @@ TEST (View, at) EXPECT_EQ (view[2], 3); view[1] = 5; EXPECT_EQ (values[1], 5); + + const View constant (values, 3); + static_assert (std::is_same_v); + EXPECT_EQ (constant[1], 5); } /** diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 468ffe82..96156e34 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -17,7 +17,6 @@ set(PUBLIC_HEADERS ) set(SOURCES - src/value.cpp src/sax_error.cpp src/json.cpp src/zstream.cpp diff --git a/data/include/join/json.hpp b/data/include/join/json.hpp index 72cd6936..89424582 100644 --- a/data/include/join/json.hpp +++ b/data/include/join/json.hpp @@ -499,8 +499,8 @@ namespace join * @param object object to write. * @return object members in insertion order. */ - template - const Object& members (const Object& object) const noexcept + template + const View& members (const View& object) const noexcept requires (Mode == JsonWriteMode::None) { return object; @@ -511,12 +511,12 @@ namespace join * @param object object to write. * @return sorted object members. */ - template - std::vector> members (const Object& object) const + template + std::vector> members (const View& object) const requires (Mode == JsonWriteMode::Canonical) { - std::vector> sorted (object.begin (), object.end ()); - std::sort (sorted.begin (), sorted.end (), [] (const Member& a, const Member& b) { + std::vector> sorted (object.begin (), object.end ()); + std::sort (sorted.begin (), sorted.end (), [] (const Type& a, const Type& b) { if (!a.first.isString () || !b.first.isString ()) { return !a.first.isString () && b.first.isString (); @@ -783,27 +783,32 @@ namespace join 1000000000000000000ULL, 10000000000000000000ULL}; - uint64_t high = value / 100000000; - uint64_t top = high / 100000000; - uint32_t mid = static_cast (high - top * 100000000); - uint32_t low = static_cast (value - high * 100000000); - - char buffer[40]; - std::memcpy (buffer, &details::digitPairs[(top / 100) * 2], 2); - std::memcpy (buffer + 2, &details::digitPairs[(top % 100) * 2], 2); - std::memcpy (buffer + 4, &details::digitPairs[(mid / 1000000) * 2], 2); - std::memcpy (buffer + 6, &details::digitPairs[(mid / 10000 % 100) * 2], 2); - std::memcpy (buffer + 8, &details::digitPairs[(mid / 100 % 100) * 2], 2); - std::memcpy (buffer + 10, &details::digitPairs[(mid % 100) * 2], 2); - std::memcpy (buffer + 12, &details::digitPairs[(low / 1000000) * 2], 2); - std::memcpy (buffer + 14, &details::digitPairs[(low / 10000 % 100) * 2], 2); - std::memcpy (buffer + 16, &details::digitPairs[(low / 100 % 100) * 2], 2); - std::memcpy (buffer + 18, &details::digitPairs[(low % 100) * 2], 2); - size_t length = ((64 - __builtin_clzll (value | 1)) * 1233) >> 12; length += (value >= pow10[length]) + (value == 0); - appendDigits (buffer + 20 - length, length); + if (JOIN_UNLIKELY (sizeof (_buffer) - _size < 20)) + { + flush (); + } + + char* out = _buffer + _size + length; + while (value >= 100) + { + out -= 2; + std::memcpy (out, &details::digitPairs[(value % 100) * 2], 2); + value /= 100; + } + + if (value >= 10) + { + std::memcpy (out - 2, &details::digitPairs[value * 2], 2); + } + else + { + *(out - 1) = static_cast ('0' + value); + } + + _size += length; } /** @@ -931,21 +936,6 @@ namespace join _size += size; } - /** - * @brief append the digits of a number, read 20 bytes at a time. - * @param digits digits followed by enough readable bytes to read 20. - * @param length number of digits. - */ - inline void appendDigits (const char* digits, size_t length) - { - if (JOIN_UNLIKELY (sizeof (_buffer) - _size < 20)) - { - flush (); - } - std::memcpy (_buffer + _size, digits, 20); - _size += length; - } - /** * @brief write comma. */ @@ -1299,10 +1289,15 @@ namespace join * @param value value receiving the document. * @return 0 on success, -1 otherwise. */ - template - int read (ProbeType& document, Value& value) + template + int read (ProbeType& document, BasicValue& value) { - return read (document, ValueBuilder (value)); + int result = read (document, ValueBuilder (value)); + if (JOIN_UNLIKELY (result != 0)) + { + value = nullptr; + } + return result; } /** diff --git a/data/include/join/pack.hpp b/data/include/join/pack.hpp index e55ef893..af7fc87b 100644 --- a/data/include/join/pack.hpp +++ b/data/include/join/pack.hpp @@ -410,7 +410,8 @@ namespace join * @param object object to write. * @return object members in insertion order. */ - const Object& members (const Object& object) const noexcept + template + const View& members (const View& object) const noexcept { return object; } @@ -827,10 +828,15 @@ namespace join * @param value value receiving the document. * @return 0 on success, -1 otherwise. */ - template - int read (ProbeType& document, Value& value) + template + int read (ProbeType& document, BasicValue& value) { - return read (document, ValueBuilder (value)); + int result = read (document, ValueBuilder (value)); + if (JOIN_UNLIKELY (result != 0)) + { + value = nullptr; + } + return result; } /** @@ -971,7 +977,7 @@ namespace join * @return 0 on success, -1 otherwise. */ template - int readArray (ProbeType& document, Handler& handler, size_t depth) + __attribute__ ((noinline)) int readArray (ProbeType& document, Handler& handler, size_t depth) { if (JOIN_UNLIKELY (depth == saxMaxDepth)) { @@ -1026,7 +1032,7 @@ namespace join * @return 0 on success, -1 otherwise. */ template - int readObject (ProbeType& document, Handler& handler, size_t depth) + __attribute__ ((noinline)) int readObject (ProbeType& document, Handler& handler, size_t depth) { if (JOIN_UNLIKELY (depth == saxMaxDepth)) { @@ -1161,6 +1167,19 @@ namespace join len = static_cast (document.get ()) & ~0xa0u; } + if constexpr (std::is_same_v) + { + if (JOIN_UNLIKELY (static_cast (document.end () - document.tell ()) < len)) + { + join::lastError = make_error_code (SaxErrc::Truncated); + return -1; + } + + std::string_view output (document.tell (), len); + document.seek (document.tell () + len); + return isKey ? handler.setKey (output) : handler.setString (output); + } + thread_local std::string cache; std::string output = std::move (cache); output.clear (); diff --git a/data/include/join/sax.hpp b/data/include/join/sax.hpp index 93ab323d..d80b63e0 100644 --- a/data/include/join/sax.hpp +++ b/data/include/join/sax.hpp @@ -159,7 +159,8 @@ namespace join * @param object object to write. * @return object members in insertion order. */ - const Object& members (const Object& object) const noexcept + template + const View& members (const View& object) const noexcept { return object; } diff --git a/data/include/join/value.hpp b/data/include/join/value.hpp index 5d4310de..d32672bc 100644 --- a/data/include/join/value.hpp +++ b/data/include/join/value.hpp @@ -26,31 +26,43 @@ #define JOIN_DATA_VALUE_HPP // libjoin. +#include #include #include +#include #include +#include // C++. +#include #include #include +#include +#include #include -#include -#include +#include +#include #include -#include #include +#include // C. #include +#include #include namespace join { /// forward declaration. - class Value; + template > + class BasicValue; - /// array. - using Array = std::vector; + /// forward declaration. + template + class ValueBuilder; + + /// string. + using String = View; /** * @brief member. @@ -79,22 +91,25 @@ namespace join Type second; }; - /// object member. - using Member = BasicMember; - - /// object. - using Object = std::vector; - /** - * @brief value class. + * @brief value class, the root owning or borrowing the allocator shared by its children. */ - class Value + template + class BasicValue { - /// variant type holding the value. - using Data = - Variant; - public: + /// value. + using Value = BasicValue; + + /// array. + using Array = View; + + /// member. + using Member = BasicMember; + + /// object. + using Object = View; + /** * @brief nested value type index. */ @@ -115,95 +130,195 @@ namespace join /** * @brief default constructor. */ - constexpr Value () = default; + constexpr BasicValue () noexcept = default; + + /** + * @brief constructs a null value using an allocator owned by the caller. + * @param allocator allocator providing the memory of the value. + */ + explicit BasicValue (Allocator& allocator) + : _allocator (std::addressof (allocator)) + , _owner (false) + { + } /** * @brief constructs a null value. * @param value null value. */ - constexpr Value (std::nullptr_t 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 Value (bool value) + constexpr BasicValue (bool value) : _data (std::in_place_index, value) { } /** - * @brief constructs an integer 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 Value (int32_t value) + constexpr BasicValue (int32_t value) : _data (std::in_place_index, value) { } /** - * @brief constructs an unsigned integer 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 Value (uint32_t 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 Value (int64_t 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 Value (uint64_t 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. */ - constexpr Value (double value) + constexpr BasicValue (double value) : _data (std::in_place_index, value) { } /** - * @brief constructs a string value from a C-style string. - * @param value string value. + * @brief constructs a real value using an allocator owned by the caller. + * @param value real value. + * @param allocator allocator providing the memory of the value. */ - Value (const char* value) - : _data (std::in_place_index, value) + BasicValue (double value, Allocator& allocator) + : BasicValue (allocator) { + _data.template set (value); } /** * @brief constructs a string value from a string view. * @param value string value. */ - Value (std::string_view value) - : _data (std::in_place_index, value) + BasicValue (std::string_view value) + : BasicValue (nullptr) { + _data.template set (copyString (value)); } /** - * @brief constructs a string value. + * @brief constructs a string value from a string view using an allocator owned by the caller. + * @param value string value. + * @param allocator allocator providing the memory of the value. + */ + BasicValue (std::string_view value, Allocator& allocator) + : BasicValue (allocator) + { + _data.template set (copyString (value)); + } + + /** + * @brief constructs a string value from a C-style string. + * @param value string value. + */ + BasicValue (const char* value) + : BasicValue (std::string_view (value)) + { + } + + /** + * @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. */ - Value (const std::string& value) - : _data (std::in_place_index, value) + BasicValue (const char* value, Allocator& allocator) + : BasicValue (std::string_view (value), allocator) { } @@ -211,8 +326,8 @@ namespace join * @brief constructs a string value. * @param value string value. */ - Value (std::string&& value) - : _data (std::in_place_index, std::move (value)) + BasicValue (const std::string& value) + : BasicValue (std::string_view (value)) { } @@ -220,68 +335,328 @@ namespace join * @brief constructs an array value. * @param value array value. */ - Value (const Array& value) - : _data (std::in_place_index, value) + BasicValue (Array value) + : BasicValue (nullptr) { + _data.template set (copyArray (value)); } /** - * @brief constructs an array value. + * @brief constructs an array value using an allocator owned by the caller. * @param value array value. + * @param allocator allocator providing the memory of the value. */ - Value (Array&& value) - : _data (std::in_place_index, std::move (value)) + BasicValue (Array value, Allocator& allocator) + : BasicValue (allocator) { + _data.template set (copyArray (value)); } /** * @brief constructs an object value. * @param value object value. */ - Value (const Object& value) - : _data (std::in_place_index, value) + BasicValue (Object value) + : BasicValue (nullptr) { + _data.template set (copyObject (value)); } /** - * @brief constructs an object value. + * @brief constructs an object value using an allocator owned by the caller. * @param value object value. + * @param allocator allocator providing the memory of the value. */ - Value (Object&& value) - : _data (std::in_place_index, std::move (value)) + BasicValue (Object value, Allocator& allocator) + : BasicValue (allocator) { + _data.template set (copyObject (value)); } /** * @brief copy constructor. * @param other object to copy. */ - constexpr Value (const Value& other) = default; + BasicValue (const BasicValue& other) + : BasicValue (nullptr) + { + copy (other); + } /** * @brief copy assignment. * @param other object to copy. * @return a reference of the current object. */ - Value& operator= (const Value& other) = default; + Value& operator= (const Value& other) + { + if (_owner) + { + return *this = BasicValue (other); + } + + copy (other); + + return *this; + } + + /** + * @brief constructs a copy of a value using an allocator owned by the caller. + * @param other value to copy. + * @param allocator allocator providing the memory of the value. + */ + template + requires std::same_as + BasicValue (const Other& other, Allocator& allocator) + : BasicValue (allocator) + { + copy (other); + } + + /** + * @brief assign a null value. + * @param value null value. + * @return a reference of the current object. + */ + 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); + return *this; + } + + /** + * @brief assign a real value. + * @param value real value. + * @return a reference of the current object. + */ + Value& operator= (double value) + { + reset (); + _data.template set (value); + return *this; + } + + /** + * @brief assign a string value from a string view. + * @param value string value. + * @return a reference of the current object. + */ + Value& operator= (std::string_view value) + { + if (isString () && (value.size () <= std::max (_capacity, getString ().size ()))) + { + char* data = const_cast (getString ().data ()); + _capacity = std::max (_capacity, getString ().size ()); + std::char_traits::move (data, value.data (), value.size ()); + data[value.size ()] = '\0'; + _data.template set (data, value.size ()); + return *this; + } + + if (_owner || (_allocator == nullptr)) + { + return *this = BasicValue (value); + } + + _data.template set (copyString (value)); + _capacity = 0; + + return *this; + } + + /** + * @brief assign a string value from a C-style string. + * @param value string value. + * @return a reference of the current object. + */ + Value& operator= (const char* value) + { + return *this = std::string_view (value); + } + + /** + * @brief assign a string value. + * @param value string value. + * @return a reference of the current object. + */ + Value& operator= (const std::string& value) + { + return *this = std::string_view (value); + } + + /** + * @brief assign an array value. + * @param value array value. + * @return a reference of the current object. + */ + Value& operator= (Array value) + { + if (_owner || (_allocator == nullptr)) + { + return *this = BasicValue (value); + } + + _data.template set (copyArray (value)); + _capacity = 0; + + return *this; + } + + /** + * @brief assign an object value. + * @param value object value. + * @return a reference of the current object. + */ + Value& operator= (Object value) + { + if (_owner || (_allocator == nullptr)) + { + return *this = BasicValue (value); + } + + _data.template set (copyObject (value)); + _capacity = 0; + + return *this; + } /** * @brief move constructor. * @param other object to move. */ - constexpr Value (Value&& other) = default; + BasicValue (BasicValue&& other) + : BasicValue (nullptr) + { + if (other._owner) + { + _data = other._data; + _allocator = other._allocator; + _capacity = other._capacity; + _owner = other._owner; + other._data.template set (); + other._allocator = nullptr; + other._capacity = 0; + other._owner = false; + } + else + { + copy (other); + other._data.template set (); + other._capacity = 0; + } + } /** * @brief move assignment. * @param other object to move. * @return a reference of the current object. */ - Value& operator= (Value&& other) = default; + Value& operator= (Value&& other) + { + if (other._owner && (_owner || (_allocator == nullptr))) + { + if (_owner) + { + delete _allocator; + } + _data = other._data; + _allocator = other._allocator; + _capacity = other._capacity; + _owner = other._owner; + other._data.template set (); + other._allocator = nullptr; + other._capacity = 0; + other._owner = false; + } + else if (_allocator == other._allocator) + { + _data = other._data; + _capacity = other._capacity; + other._data.template set (); + other._capacity = 0; + } + else + { + reset (); + copy (other); + other._data.template set (); + other._capacity = 0; + } + + return *this; + } /** * @brief destroy the Value instance. */ - ~Value () = default; + ~BasicValue () + { + if (_owner) + { + delete _allocator; + } + } /** * @brief get the index of the alternative in use. @@ -319,7 +694,7 @@ namespace join { if (_data.index () == BooleanValue) { - return _data.get (); + return _data.template get (); } return convertBool (); @@ -374,23 +749,31 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= + static_cast (std::numeric_limits::min ()) && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case UnsignedValue: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case Integer64Value: - return _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= + static_cast (std::numeric_limits::min ()) && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + 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; @@ -411,19 +794,19 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -449,24 +832,28 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case UnsignedValue: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case Integer64Value: - return _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return std::trunc (_data.template get ()) == _data.template get () && + _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); default: break; @@ -487,19 +874,19 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -525,25 +912,31 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= + static_cast (std::numeric_limits::min ()) && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case UnsignedValue: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case Integer64Value: - return _data.get () >= + return _data.template get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + 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; @@ -564,19 +957,19 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -602,24 +995,28 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case UnsignedValue: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case Integer64Value: - return _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return std::trunc (_data.template get ()) == _data.template get () && + _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); default: break; @@ -640,19 +1037,19 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -681,21 +1078,25 @@ namespace join return true; case UnsignedValue: - return _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () <= + static_cast (std::numeric_limits::max ()); case Integer64Value: - return _data.get () >= + return _data.template get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () <= static_cast (std::numeric_limits::max ()); + 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; @@ -713,7 +1114,7 @@ namespace join { if (_data.index () == IntegerValue) { - return _data.get (); + return _data.template get (); } return convertInt (); @@ -738,23 +1139,25 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= 0; + return _data.template get () >= 0; case UnsignedValue: return true; case Integer64Value: - return _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= 0 && - _data.get () <= static_cast (std::numeric_limits::max ()); + return std::trunc (_data.template get ()) == _data.template get () && + _data.template get () >= 0 && + _data.template get () <= + static_cast (std::numeric_limits::max ()); default: break; @@ -772,7 +1175,7 @@ namespace join { if (_data.index () == UnsignedValue) { - return _data.get (); + return _data.template get (); } return convertUint (); @@ -802,13 +1205,15 @@ namespace join return true; case Unsigned64Value: - return _data.get () <= + return _data.template get () <= static_cast (std::numeric_limits::max ()); case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= static_cast (std::numeric_limits::min ()) && - _data.get () < static_cast (std::numeric_limits::max ()); + 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; @@ -826,7 +1231,7 @@ namespace join { if (_data.index () == Integer64Value) { - return _data.get (); + return _data.template get (); } return convertInt64 (); @@ -851,21 +1256,22 @@ namespace join switch (_data.index ()) { case IntegerValue: - return _data.get () >= 0; + return _data.template get () >= 0; case UnsignedValue: return true; case Integer64Value: - return _data.get () >= 0; + return _data.template get () >= 0; case Unsigned64Value: return true; case RealValue: - return std::trunc (_data.get ()) == _data.get () && - _data.get () >= 0 && - _data.get () < static_cast (std::numeric_limits::max ()); + return std::trunc (_data.template get ()) == _data.template get () && + _data.template get () >= 0 && + _data.template get () < + static_cast (std::numeric_limits::max ()); default: break; @@ -883,7 +1289,7 @@ namespace join { if (_data.index () == Unsigned64Value) { - return _data.get (); + return _data.template get (); } return convertUint64 (); @@ -917,7 +1323,7 @@ namespace join { if (_data.index () == RealValue) { - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } return convertFloat (); @@ -951,7 +1357,7 @@ namespace join { if (_data.index () == RealValue) { - return _data.get (); + return _data.template get (); } return convertDouble (); @@ -978,12 +1384,13 @@ namespace join /** * @brief get variable held by value as a string value. - * @return variable held by value as a string value. + * @return view of a null-terminated string. * @throw std::bad_cast. */ constexpr std::string_view getString () const { - return _data.get (); + const String& value = _data.template get (); + return std::string_view (value.data (), value.size ()); } /** @@ -1012,17 +1419,7 @@ namespace join */ constexpr const Array& getArray () const { - return _data.get (); - } - - /** - * @brief get variable held by value as an array. - * @return variable held by value as an array. - * @throw std::bad_cast. - */ - constexpr Array& getArray () - { - return _data.get (); + return _data.template get (); } /** @@ -1041,17 +1438,7 @@ namespace join */ constexpr const Object& getObject () const { - return _data.get (); - } - - /** - * @brief get variable held by value as an object. - * @return variable held by value as an object. - * @throw std::bad_cast. - */ - constexpr Object& getObject () - { - return _data.get (); + return _data.template get (); } /** @@ -1062,7 +1449,7 @@ namespace join */ Value& at ([[maybe_unused]] std::nullptr_t key) { - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isNull ()) { @@ -1081,7 +1468,7 @@ namespace join */ Value& at (bool key) { - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isBool () && member.first.getBool () == key) { @@ -1102,10 +1489,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isInt () && member.first.getInt () == key) { @@ -1126,10 +1513,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isUint () && member.first.getUint () == key) { @@ -1150,10 +1537,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isInt64 () && member.first.getInt64 () == key) { @@ -1174,10 +1561,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isUint64 () && member.first.getUint64 () == key) { @@ -1196,7 +1583,7 @@ namespace join */ Value& at (double key) { - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isDouble () && member.first.getDouble () == key) { @@ -1215,7 +1602,7 @@ namespace join */ Value& at (std::string_view key) { - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isString () && member.first.getString () == key) { @@ -1237,6 +1624,32 @@ namespace join 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 + Value& at (const Key& key) + { + if (_data.index () == ArrayValue) + { + return elementAt (key.getUint64 ()); + } + + for (auto& 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. @@ -1245,7 +1658,7 @@ namespace join */ const Value& at ([[maybe_unused]] std::nullptr_t key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isNull ()) { @@ -1264,7 +1677,7 @@ namespace join */ const Value& at (bool key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isBool () && member.first.getBool () == key) { @@ -1285,10 +1698,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isInt () && member.first.getInt () == key) { @@ -1309,10 +1722,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isUint () && member.first.getUint () == key) { @@ -1333,10 +1746,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isInt64 () && member.first.getInt64 () == key) { @@ -1357,10 +1770,10 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ().at (key); + return elementAt (key); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isUint64 () && member.first.getUint64 () == key) { @@ -1379,7 +1792,7 @@ namespace join */ const Value& at (double key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isDouble () && member.first.getDouble () == key) { @@ -1398,7 +1811,7 @@ namespace join */ const Value& at (std::string_view key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isString () && member.first.getString () == key) { @@ -1421,29 +1834,29 @@ 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. + * @throw std::bad_cast, std::out_of_range. */ - Value& operator[] (std::nullptr_t key) + template + requires std::same_as + const Value& at (const Key& key) const { - if (_data.index () == NullValue) + if (_data.index () == ArrayValue) { - _data.set (); + return elementAt (key.getUint64 ()); } - for (auto& member : _data.get ()) + for (auto const& member : _data.template get ()) { - if (member.first.isNull ()) + if (member.first == key) { return member.second; } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + throwException ("invalid key"); } /** @@ -1452,24 +1865,46 @@ namespace join * @return a reference to the requested element. * @throw std::bad_cast. */ - Value& operator[] (bool key) + Value& operator[] (std::nullptr_t key) { if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { - if (member.first.isBool () && member.first.getBool () == key) + if (member.first.isNull ()) { return member.second; } } - _data.get ().emplace_back (key, nullptr); + 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 (); + } - return _data.get ().back ().second; + for (auto& member : _data.template get ()) + { + if (member.first.isBool () && member.first.getBool () == key) + { + return member.second; + } + } + + return appendMember (key); } /** @@ -1482,15 +1917,15 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ()[key]; + return _data.template get ()[key]; } if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isInt () && member.first.getInt () == key) { @@ -1498,9 +1933,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1513,15 +1946,15 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ()[key]; + return _data.template get ()[key]; } if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isUint () && member.first.getUint () == key) { @@ -1529,9 +1962,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1544,15 +1975,15 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ()[key]; + return _data.template get ()[key]; } if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isInt64 () && member.first.getInt64 () == key) { @@ -1560,9 +1991,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1575,15 +2004,15 @@ namespace join { if (_data.index () == ArrayValue) { - return _data.get ()[key]; + return _data.template get ()[key]; } if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isUint64 () && member.first.getUint64 () == key) { @@ -1591,9 +2020,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1606,10 +2033,10 @@ namespace join { if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isDouble () && member.first.getDouble () == key) { @@ -1617,9 +2044,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1632,10 +2057,10 @@ namespace join { if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - for (auto& member : _data.get ()) + for (auto& member : _data.template get ()) { if (member.first.isString () && member.first.getString () == key) { @@ -1643,9 +2068,7 @@ namespace join } } - _data.get ().emplace_back (key, nullptr); - - return _data.get ().back ().second; + return appendMember (key); } /** @@ -1659,6 +2082,37 @@ namespace join 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 ())); + } + /** * @brief check if the nested container is empty. * @return true if empty, false otherwise. @@ -1669,13 +2123,13 @@ namespace join switch (_data.index ()) { case StringValue: - return _data.get ().empty (); + return _data.template get ().empty (); case ArrayValue: - return _data.get ().empty (); + return _data.template get ().empty (); case ObjectValue: - return _data.get ().empty (); + return _data.template get ().empty (); default: break; @@ -1694,13 +2148,13 @@ namespace join switch (_data.index ()) { case StringValue: - return _data.get ().size (); + return _data.template get ().size (); case ArrayValue: - return _data.get ().size (); + return _data.template get ().size (); case ObjectValue: - return _data.get ().size (); + return _data.template get ().size (); default: break; @@ -1710,7 +2164,7 @@ namespace join } /** - * @brief increase the capacity of the nested container. + * @brief increase the capacity of the nested container or string. * @param cap new capacity. * @throw std::bad_cast. */ @@ -1719,15 +2173,26 @@ namespace join switch (_data.index ()) { case StringValue: - _data.get ().reserve (cap); + if (cap > std::max (_capacity, getString ().size ())) + { + if (JOIN_UNLIKELY (cap >= std::numeric_limits::max ())) + { + throwException (); + } + std::string_view str = getString (); + char* data = allocate (cap + 1); + std::copy_n (str.data (), str.size () + 1, data); + _data.template set (data, str.size ()); + _capacity = static_cast (cap); + } return; case ArrayValue: - _data.get ().reserve (cap); + grow (cap); return; case ObjectValue: - _data.get ().reserve (cap); + grow (cap); return; default: @@ -1746,15 +2211,15 @@ namespace join switch (_data.index ()) { case StringValue: - _data.get ().clear (); + *this = std::string_view (); return; case ArrayValue: - _data.get ().clear (); + _data.template set (_data.template get ().data (), 0); return; case ObjectValue: - _data.get ().clear (); + _data.template set (_data.template get ().data (), 0); return; default: @@ -1770,22 +2235,25 @@ namespace join * @return a reference to the inserted element. * @throw std::bad_cast. */ - Value& insert (const Member& member) + template + requires std::same_as + Value& insert (const M& member) { - _data.get ().push_back (member); - return _data.get ().back ().second; + return appendMember (Value (member.first, *allocator ()), Value (member.second, *allocator ())); } /** - * @brief insert element in the nested container. - * @param member the element to insert in the nested container. + * @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& insert (Member&& member) + template + Value& insert (K&& key, T&& value) { - _data.get ().emplace_back (std::move (member)); - return _data.get ().back ().second; + return appendMember (Value (std::forward (key), *allocator ()), + Value (std::forward (value), *allocator ())); } /** @@ -1796,14 +2264,14 @@ namespace join */ size_t erase ([[maybe_unused]] std::nullptr_t key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + auto beg = _data.template get ().begin (); + auto end = _data.template get ().end (); for (auto it = beg; it != end; ++it) { if (it->first.isNull ()) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1819,14 +2287,14 @@ namespace join */ size_t erase (bool key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1842,14 +2310,14 @@ namespace join */ size_t erase (int32_t key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1865,14 +2333,14 @@ namespace join */ size_t erase (uint32_t key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1888,14 +2356,14 @@ namespace join */ size_t erase (int64_t key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1911,14 +2379,14 @@ namespace join */ size_t erase (uint64_t key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1934,14 +2402,14 @@ namespace join */ size_t erase (double key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1957,14 +2425,14 @@ namespace join */ size_t erase (std::string_view key) { - auto beg = _data.get ().begin (); - auto end = _data.get ().end (); + 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) { - _data.get ().erase (it); + eraseMember (it); return 1; } } @@ -1983,6 +2451,31 @@ namespace join 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. @@ -1992,44 +2485,150 @@ namespace join template Value& emplaceBack (Args&&... args) { - if (_data.index () == NullValue) - { - _data.set (); - } - _data.get ().emplace_back (std::forward (args)...); - return _data.get ().back (); + return pushBack (Value (std::forward (args)..., *allocator ())); } /** - * @brief appends element at the end of the nested container. + * @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 (const Value& value) + Value& pushBack (std::nullptr_t value) { - if (_data.index () == NullValue) - { - _data.set (); - } - _data.get ().push_back (value); - return _data.get ().back (); + 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 ())); + } + + /** + * @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. + * @throw std::bad_cast. + */ + Value& pushBack (int32_t value) + { + return pushBack (Value (value, *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. + * @throw std::bad_cast. + */ + Value& pushBack (uint32_t value) + { + return pushBack (Value (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. + * @throw std::bad_cast. + */ + Value& pushBack (int64_t value) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @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. + * @throw std::bad_cast. + */ + Value& pushBack (uint64_t value) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @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. + * @throw std::bad_cast. + */ + Value& pushBack (double value) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @brief appends a string value from a C-style string 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) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @brief appends a string value from a string view 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::string_view value) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @brief appends an array 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 (Array value) + { + return pushBack (Value (value, *allocator ())); + } + + /** + * @brief appends an object 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 (Object value) + { + return pushBack (Value (value, *allocator ())); } /** - * @brief appends element at the end of the nested container. + * @brief appends a 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 (Value&& value) + template + requires std::same_as, BasicValue> + Value& pushBack (Other&& value) { + Value element (*allocator ()); + element = std::forward (value); if (_data.index () == NullValue) { - _data.set (); + _data.template set (); } - _data.get ().emplace_back (std::move (value)); - return _data.get ().back (); + Value& slot = append (); + ::new (&slot) Value (*_allocator); + slot = std::move (element); + return slot; } /** @@ -2038,7 +2637,12 @@ namespace join */ void popBack () { - _data.get ().pop_back (); + Array& array = _data.template get (); + if (array.empty ()) + { + return; + } + array = Array (array.data (), array.size () - 1); } /** @@ -2049,7 +2653,7 @@ namespace join */ bool contains ([[maybe_unused]] std::nullptr_t key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isNull ()) { @@ -2068,7 +2672,7 @@ namespace join */ bool contains (bool key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isBool () && member.first.getBool () == key) { @@ -2089,10 +2693,10 @@ namespace join { if (_data.index () == ArrayValue) { - return key >= 0 && static_cast (key) < _data.get ().size (); + return key >= 0 && static_cast (key) < _data.template get ().size (); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isInt () && member.first.getInt () == key) { @@ -2113,10 +2717,10 @@ namespace join { if (_data.index () == ArrayValue) { - return key < _data.get ().size (); + return key < _data.template get ().size (); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isUint () && member.first.getUint () == key) { @@ -2137,10 +2741,10 @@ namespace join { if (_data.index () == ArrayValue) { - return key >= 0 && static_cast (key) < _data.get ().size (); + return key >= 0 && static_cast (key) < _data.template get ().size (); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isInt64 () && member.first.getInt64 () == key) { @@ -2161,10 +2765,10 @@ namespace join { if (_data.index () == ArrayValue) { - return key < _data.get ().size (); + return key < _data.template get ().size (); } - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isUint64 () && member.first.getUint64 () == key) { @@ -2183,7 +2787,7 @@ namespace join */ bool contains (double key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isDouble () && member.first.getDouble () == key) { @@ -2202,7 +2806,7 @@ namespace join */ bool contains (std::string_view key) const { - for (auto const& member : _data.get ()) + for (auto const& member : _data.template get ()) { if (member.first.isString () && member.first.getString () == key) { @@ -2224,12 +2828,45 @@ namespace join return contains (std::string_view (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 at position pos or mapped to key, false otherwise. + * @throw std::bad_cast. + */ + template + requires std::same_as + bool contains (const Key& key) const + { + if (_data.index () == ArrayValue) + { + return key.getUint64 () < _data.template get ().size (); + } + + for (auto const& member : _data.template get ()) + { + if (member.first == key) + { + return true; + } + } + + return false; + } + /** * @brief exchanges the contents of the value with those of other. * @param other value to exchange the contents with. */ void swap (Value& other) { + if (_allocator == other._allocator) + { + std::swap (_data, other._data); + std::swap (_capacity, other._capacity); + return; + } + Value temp (std::move (*this)); *this = std::move (other); other = std::move (temp); @@ -2285,164 +2922,451 @@ namespace join } /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @param length the length of the json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal. + * @param other value to compare to. + * @return true if equal. */ - int jsonRead (const char* document, size_t length); + template + requires std::same_as> + constexpr bool operator== (const Other& other) const; /** - * @brief deserialize a json document. - * @param first the first character of the json document to deserialize. - * @param last the last character of the document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare values. + * @param other value to compare to. + * @return ordering of this value relative to other. */ - int jsonRead (const char* first, const char* last); + template + requires std::same_as> + constexpr std::partial_ordering operator<=> (const Other& other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a null value. + * @param other null value to compare to. + * @return true if equal. */ - int jsonRead (std::string_view document); + constexpr bool operator== (std::nullptr_t other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a null value. + * @param other null value to compare to. + * @return ordering of this value relative to other. */ - int jsonRead (std::stringstream& document); + constexpr std::partial_ordering operator<=> (std::nullptr_t other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a boolean value. + * @param other boolean value to compare to. + * @return true if equal. */ - int jsonRead (std::istringstream& document); + constexpr bool operator== (bool other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a boolean value. + * @param other boolean value to compare to. + * @return ordering of this value relative to other. */ - int jsonRead (std::fstream& document); + constexpr std::partial_ordering operator<=> (bool other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a integer value. + * @param other integer value to compare to. + * @return true if equal. */ - int jsonRead (std::ifstream& document); + constexpr bool operator== (int32_t other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a integer value. + * @param other integer value to compare to. + * @return ordering of this value relative to other. */ - int jsonRead (std::iostream& document); + constexpr std::partial_ordering operator<=> (int32_t other) const; /** - * @brief deserialize a json document. - * @param document json document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a unsigned integer value. + * @param other unsigned integer value to compare to. + * @return true if equal. */ - int jsonRead (std::istream& document); + constexpr bool operator== (uint32_t other) const; /** - * @brief serialize json data. - * @param document Document where to serialize json data. - * @param indentation number of spaces per indentation level. - * @return 0 on success, -1 otherwise. + * @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. */ - int jsonWrite (std::ostream& document, size_t indentation = 0) const; + constexpr std::partial_ordering operator<=> (uint32_t other) const; /** - * @brief serialize canonicalized json data. - * @param document Document where to serialize canonicalized json data. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a 64 bits integer value. + * @param other 64 bits integer value to compare to. + * @return true if equal. */ - int jsonCanonicalize (std::ostream& document) const; + constexpr bool operator== (int64_t other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @param length the length of the msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @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. */ - int packRead (const char* document, size_t length); + constexpr std::partial_ordering operator<=> (int64_t other) const; /** - * @brief deserialize a msgpack document. - * @param first the first character of the msgpack document to deserialize. - * @param last the last character of the document to deserialize. - * @return 0 on success, -1 otherwise. + * @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. */ - int packRead (const char* first, const char* last); + constexpr bool operator== (uint64_t other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @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. */ - int packRead (std::string_view document); + constexpr std::partial_ordering operator<=> (uint64_t other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a real value. + * @param other real value to compare to. + * @return true if equal. */ - int packRead (std::stringstream& document); + constexpr bool operator== (double other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a real value. + * @param other real value to compare to. + * @return ordering of this value relative to other. */ - int packRead (std::istringstream& document); + constexpr std::partial_ordering operator<=> (double other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a C-style string. + * @param other string to compare to. + * @return true if equal. */ - int packRead (std::fstream& document); + constexpr bool operator== (const char* other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a C-style string. + * @param other string to compare to. + * @return ordering of this value relative to other. */ - int packRead (std::ifstream& document); + constexpr std::partial_ordering operator<=> (const char* other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to a string view. + * @param other string to compare to. + * @return true if equal. */ - int packRead (std::iostream& document); + constexpr bool operator== (std::string_view other) const; /** - * @brief deserialize a msgpack document. - * @param document msgpack document to deserialize. - * @return 0 on success, -1 otherwise. + * @brief three-way compare to a string view. + * @param other string to compare to. + * @return ordering of this value relative to other. */ - int packRead (std::istream& document); + constexpr std::partial_ordering operator<=> (std::string_view other) const; /** - * @brief serialize msgpack data. - * @param document Document where to serialize msgpack data. - * @return 0 on success, -1 otherwise. + * @brief compare if equal to an array. + * @param other array to compare to. + * @return true if equal. */ - int packWrite (std::ostream& document) const; + constexpr bool operator== (const Array& other) const; - // friendship with equal operator. - friend constexpr bool operator== (const Value& lhs, const Value& rhs); + /** + * @brief three-way compare to an array. + * @param other array to compare to. + * @return ordering of this value relative to other. + */ + constexpr std::partial_ordering operator<=> (const Array& other) const; + + /** + * @brief compare if equal to an object. + * @param other object to compare to. + * @return true if equal. + */ + constexpr bool operator== (const Object& other) const; - // friendship with three-way comparison operator. - friend constexpr std::partial_ordering operator<=> (const Value& lhs, const Value& rhs); + /** + * @brief three-way compare to an object. + * @param other object to compare to. + * @return ordering of this value relative to other. + */ + constexpr std::partial_ordering operator<=> (const Object& other) const; private: + /// variant type holding the value. + using Data = Variant; + + // friendship with value builder. + friend class ValueBuilder; + + /** + * @brief get the allocator shared by the tree, created when the root has none. + * @return allocator. + */ + Allocator* allocator () + { + if (_allocator == nullptr) + { + _allocator = new Allocator (); + _owner = true; + } + return _allocator; + } + + /** + * @brief allocate uninitialized memory for elements. + * @param count number of elements. + * @return pointer to the memory. + * @throw std::bad_alloc. + */ + template + T* allocate (size_t count) + { + void* data = nullptr; + if (JOIN_LIKELY (count <= std::min (std::numeric_limits::max (), + std::numeric_limits::max () / sizeof (T)))) + { + data = allocator ()->allocate (count * sizeof (T)); + } + + if (JOIN_UNLIKELY (data == nullptr)) + { + throwException (); + } + + return static_cast (data); + } + + /** + * @brief reset to null, releasing the memory of the tree when the value owns the allocator. + */ + void reset () noexcept + { + if constexpr (requires { _allocator->reset (); }) + { + if (_owner) + { + _allocator->reset (); + } + } + _data.template set (); + _capacity = 0; + } + + /** + * @brief copy a string into the allocator. + * @param value string to copy. + * @return copied string. + */ + String copyString (std::string_view value) + { + char* data = allocate (value.size () + 1); + std::copy_n (value.data (), value.size (), data); + data[value.size ()] = '\0'; + return String (data, value.size ()); + } + + /** + * @brief move values of the open containers of a builder into the allocator. + * @param values values to move. + * @param count number of values. + * @return array holding the values. + */ + Array makeArray (const Data* values, size_t count) + { + Value* data = allocate (count); + for (size_t i = 0; i < count; ++i) + { + ::new (data + i) Value (*_allocator); + data[i]._data = values[i]; + } + return Array (data, count); + } + + /** + * @brief copy an array into the allocator. + * @param value array to copy. + * @return copied array. + */ + Array copyArray (const Array& value) + { + Value* data = allocate (value.size ()); + for (size_t i = 0; i < value.size (); ++i) + { + ::new (data + i) Value (value[i], *_allocator); + } + return Array (data, value.size ()); + } + + /** + * @brief move keys and values of the open containers of a builder into the allocator. + * @param values keys and values to move, alternated. + * @param count number of members. + * @return object holding the members. + */ + Object makeObject (const Data* values, size_t count) + { + Member* data = allocate (count); + for (size_t i = 0; i < count; ++i) + { + ::new (data + i) Member{Value (*_allocator), Value (*_allocator)}; + data[i].first._data = values[2 * i]; + data[i].second._data = values[2 * i + 1]; + } + return Object (data, count); + } + + /** + * @brief copy an object into the allocator. + * @param value object to copy. + * @return copied object. + */ + Object copyObject (const Object& value) + { + Member* data = allocate (value.size ()); + for (size_t i = 0; i < value.size (); ++i) + { + ::new (data + i) Member{Value (value[i].first, *_allocator), Value (value[i].second, *_allocator)}; + } + return Object (data, value.size ()); + } + + /** + * @brief copy a value into the allocator. + * @param other value to copy. + */ + void copy (const Value& other) + { + _capacity = 0; + + switch (other.index ()) + { + case StringValue: + _data.template set (copyString (other.getString ())); + break; + + case ArrayValue: + _data.template set (copyArray (other.getArray ())); + break; + + case ObjectValue: + _data.template set (copyObject (other.getObject ())); + break; + + default: + _data = other._data; + break; + } + } + + /** + * @brief move the elements of the nested container to a larger block. + * @param cap new capacity. + */ + template + void grow (size_t cap) + { + View& view = _data.template get> (); + if (cap > std::max (view.size (), _capacity)) + { + T* data = allocate (cap); + if (!view.empty ()) + { + std::memcpy (static_cast (data), static_cast (view.data ()), + view.size () * sizeof (T)); + } + view = View (data, view.size ()); + _capacity = static_cast (cap); + } + } + + /** + * @brief add an uninitialized element at the end of the nested container. + * @return a reference to the element. + */ + template + T& append () + { + View& view = _data.template get> (); + if (view.size () >= _capacity) + { + grow (std::max (view.size () * 2, 1)); + } + view = View (view.data (), view.size () + 1); + return view[view.size () - 1]; + } + + /** + * @brief add a member at the end of the object. + * @param key key of the member. + * @param value value of the member. + * @return a reference to the value of the member. + */ + Value& appendMember (Value&& key, Value&& value) + { + Member& slot = append (); + ::new (&slot) Member{Value (*_allocator), Value (*_allocator)}; + slot.first = std::move (key); + slot.second = std::move (value); + return slot.second; + } + + /** + * @brief add a member with a null value at the end of the object. + * @param key key of the member. + * @return a reference to the value of the member. + */ + template + Value& appendMember (Key key) + { + return appendMember (Value (key, *allocator ()), Value (*allocator ())); + } + + /** + * @brief remove a member of the object. + * @param it member to remove. + */ + void eraseMember (Member* it) + { + Object& object = _data.template get (); + std::memmove (static_cast (it), static_cast (it + 1), + (object.end () - it - 1) * sizeof (Member)); + object = Object (object.data (), object.size () - 1); + } + + /** + * @brief returns a reference to the array element at position pos. + * @param pos position of the element. + * @return a reference to the requested element. + * @throw std::out_of_range. + */ + Value& elementAt (size_t pos) + { + Array& array = _data.template get (); + if (pos >= array.size ()) + { + throwException ("invalid key"); + } + return array[pos]; + } + + /** + * @brief returns a reference to the array element at position pos. + * @param pos position of the element. + * @return a reference to the requested element. + * @throw std::out_of_range. + */ + const Value& elementAt (size_t pos) const + { + const Array& array = _data.template get (); + if (pos >= array.size ()) + { + throwException ("invalid key"); + } + return array[pos]; + } + /** * @brief set value. * @param value value to write. @@ -2595,16 +3519,16 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: break; @@ -2625,19 +3549,19 @@ namespace join return false; case IntegerValue: - return _data.get (); + return _data.template get (); case UnsignedValue: - return _data.get (); + return _data.template get (); case Integer64Value: - return _data.get (); + return _data.template get (); case Unsigned64Value: - return _data.get (); + return _data.template get (); case RealValue: - return _data.get (); + return _data.template get (); default: break; @@ -2657,16 +3581,16 @@ namespace join switch (_data.index ()) { case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -2684,16 +3608,16 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -2711,16 +3635,16 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -2738,16 +3662,16 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); } } @@ -2763,16 +3687,16 @@ namespace join switch (_data.index ()) { case IntegerValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case UnsignedValue: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Integer64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); case Unsigned64Value: - return static_cast (_data.get ()); + return static_cast (_data.template get ()); default: break; @@ -2783,69 +3707,348 @@ namespace join /// variant holding the value. Data _data; + + /// allocator shared by the tree. + Allocator* _allocator = nullptr; + + /// capacity of the nested container or string, 0 when it has no spare room. + uint32_t _capacity = 0; + + /// true when the value destroys the allocator. + bool _owner = false; }; /** * @brief compare if equal. - * @param lhs value to compare. - * @param rhs value to compare to. + * @param other value to compare to. * @return true if equal. */ - constexpr bool operator== (const Value& lhs, const Value& rhs) + template + template + requires std::same_as> + constexpr bool BasicValue::operator== (const Other& other) const { - if (lhs.isNumber () && rhs.isNumber () && (lhs.index () != rhs.index ())) + if (isNumber () && other.isNumber () && (index () != other.index ())) { - if (lhs.isInt64 () && rhs.isUint64 ()) + if (isInt64 () && other.isUint64 ()) { - return lhs.getInt64 () >= 0 && uint64_t (lhs.getInt64 ()) == rhs.getUint64 (); + return getInt64 () >= 0 && uint64_t (getInt64 ()) == other.getUint64 (); } - else if (lhs.isUint64 () && rhs.isInt64 ()) + else if (isUint64 () && other.isInt64 ()) { - return rhs.getInt64 () >= 0 && uint64_t (rhs.getInt64 ()) == lhs.getUint64 (); + return other.getInt64 () >= 0 && uint64_t (other.getInt64 ()) == getUint64 (); } else { - return lhs.getDouble () == rhs.getDouble (); + return getDouble () == other.getDouble (); } } - return lhs._data == rhs._data; + return _data == other._data; } /** * @brief three-way compare values. - * @param lhs value to compare. - * @param rhs value to compare to. - * @return ordering of lhs relative to rhs. + * @param other value to compare to. + * @return ordering of this value relative to other. */ - constexpr std::partial_ordering operator<=> (const Value& lhs, const Value& rhs) + template + template + requires std::same_as> + constexpr std::partial_ordering BasicValue::operator<=> (const Other& other) const { - if (lhs.isNumber () && rhs.isNumber () && (lhs.index () != rhs.index ())) + if (isNumber () && other.isNumber () && (index () != other.index ())) { - if (lhs.isInt64 () && rhs.isUint64 ()) + if (isInt64 () && other.isUint64 ()) { - if (lhs.getInt64 () < 0) + if (getInt64 () < 0) { return std::partial_ordering::less; } - return uint64_t (lhs.getInt64 ()) <=> rhs.getUint64 (); + return uint64_t (getInt64 ()) <=> other.getUint64 (); } - else if (lhs.isUint64 () && rhs.isInt64 ()) + else if (isUint64 () && other.isInt64 ()) { - if (rhs.getInt64 () < 0) + if (other.getInt64 () < 0) { return std::partial_ordering::greater; } - return lhs.getUint64 () <=> uint64_t (rhs.getInt64 ()); + return getUint64 () <=> uint64_t (other.getInt64 ()); } else { - return lhs.getDouble () <=> rhs.getDouble (); + return getDouble () <=> other.getDouble (); } } - return lhs._data <=> rhs._data; + return _data <=> other._data; + } + + /** + * @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. + * @return true if equal. + */ + template + constexpr bool BasicValue::operator== (uint32_t other) const + { + return *this == BasicValue (other); + } + + /** + * @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. + */ + template + constexpr std::partial_ordering BasicValue::operator<=> (uint32_t 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. + * @return true if equal. + */ + template + constexpr bool BasicValue::operator== (std::string_view other) const + { + return isString () && (getString () == other); + } + + /** + * @brief three-way compare to a string view. + * @param other string to compare to. + * @return ordering of this value relative to other. + */ + template + constexpr std::partial_ordering BasicValue::operator<=> (std::string_view other) const + { + if (!isString ()) + { + return index () <=> StringValue; + } + return getString () <=> other; + } + + /** + * @brief compare if equal to an array. + * @param other array to compare to. + * @return true if equal. + */ + template + constexpr bool BasicValue::operator== (const Array& other) const + { + return isArray () && (getArray () == other); + } + + /** + * @brief three-way compare to an array. + * @param other array to compare to. + * @return ordering of this value relative to other. + */ + template + constexpr std::partial_ordering BasicValue::operator<=> (const Array& other) const + { + if (!isArray ()) + { + return index () <=> ArrayValue; + } + return getArray () <=> other; + } + + /** + * @brief compare if equal to an object. + * @param other object to compare to. + * @return true if equal. + */ + template + constexpr bool BasicValue::operator== (const Object& other) const + { + return isObject () && (getObject () == other); + } + + /** + * @brief three-way compare to an object. + * @param other object to compare to. + * @return ordering of this value relative to other. + */ + template + constexpr std::partial_ordering BasicValue::operator<=> (const Object& other) const + { + if (!isObject ()) + { + return index () <=> ObjectValue; + } + return getObject () <=> other; + } + + /// value using the default allocator. + using Value = BasicValue<>; + + /// array. + using Array = View; + + /// object member. + using Member = BasicMember; + + /// object. + using Object = View; } #endif diff --git a/data/include/join/value_builder.hpp b/data/include/join/value_builder.hpp index 750ee7c6..ae4e82e4 100644 --- a/data/include/join/value_builder.hpp +++ b/data/include/join/value_builder.hpp @@ -32,9 +32,7 @@ // C++. #include -#include #include -#include #include // C. @@ -45,8 +43,18 @@ namespace join /** * @brief value builder class, filled by balanced SAX calls. */ + template class ValueBuilder { + /// array. + using Array = typename Value::Array; + + /// object. + using Object = typename Value::Object; + + /// value of the open containers. + using Data = typename Value::Data; + public: /** * @brief create instance. @@ -56,6 +64,7 @@ namespace join : _stack (std::move (cache ())) , _root (root) { + _root.reset (); } /** @@ -169,7 +178,7 @@ namespace join */ int setString (std::string_view value) { - return emplaceValue (std::string (value)); + return emplaceValue (_root.copyString (value)); } /** @@ -206,19 +215,12 @@ namespace join return -1; } - auto first = _stack.begin () + _starts[--_depth]; - Array array (std::make_move_iterator (first), std::make_move_iterator (_stack.end ())); - _stack.erase (first, _stack.end ()); - - if (_depth == 0) - { - _root = std::move (array); - return 0; - } + const size_t first = _starts[--_depth]; - _stack.emplace_back (std::move (array)); + Array array = _root.makeArray (_stack.data () + first, _stack.size () - first); + _stack.resize (first); - return 0; + return emplaceValue (array); } /** @@ -248,7 +250,8 @@ namespace join * @param object object to write. * @return object members in insertion order. */ - const Object& members (const Object& object) const noexcept + template + const View& members (const View& object) const noexcept { return object; } @@ -392,7 +395,7 @@ namespace join return -1; } - _stack.emplace_back (key); + _stack.emplace_back (_root.copyString (key)); return 0; } @@ -425,24 +428,12 @@ namespace join return -1; } - auto first = _stack.begin () + _starts[--_depth]; - Object object; - object.reserve ((_stack.end () - first) / 2); - for (auto it = first; it != _stack.end (); it += 2) - { - object.emplace_back (std::move (it[0]), std::move (it[1])); - } - _stack.erase (first, _stack.end ()); - - if (_depth == 0) - { - _root = std::move (object); - return 0; - } + const size_t first = _starts[--_depth]; - _stack.emplace_back (std::move (object)); + Object object = _root.makeObject (_stack.data () + first, (_stack.size () - first) / 2); + _stack.resize (first); - return 0; + return emplaceValue (object); } /** @@ -465,7 +456,8 @@ namespace join { if (JOIN_UNLIKELY (_depth == 0)) { - _root = Value (std::forward (value)); + _root._data = std::forward (value); + _root._capacity = 0; return 0; } @@ -478,9 +470,9 @@ namespace join * @brief get the stack kept by the calling thread between documents. * @return stack. */ - static std::vector& cache () noexcept + static std::vector& cache () noexcept { - thread_local std::vector stack; + thread_local std::vector stack; return stack; } @@ -491,7 +483,7 @@ namespace join size_t _depth = 0; /// stack of the values of the open containers. - std::vector _stack; + std::vector _stack; /// value receiving the document. Value& _root; diff --git a/data/src/value.cpp b/data/src/value.cpp deleted file mode 100644 index 189ae683..00000000 --- a/data/src/value.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 Mathieu Rabine - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include - -using join::Value; - -using join::JsonReader; -using join::JsonWriter; -using join::JsonCanonicalizer; - -using join::PackReader; -using join::PackWriter; - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (const char* document, size_t length) -{ - return deserialize (document, length); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (const char* first, const char* last) -{ - return deserialize (first, last); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::string_view document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::stringstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::istringstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::fstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::ifstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::iostream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonRead -// ========================================================================= -int Value::jsonRead (std::istream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonWrite -// ========================================================================= -int Value::jsonWrite (std::ostream& document, size_t indentation) const -{ - return serialize (document, indentation); -} - -// ========================================================================= -// CLASS : Value -// METHOD : jsonCanonicalize -// ========================================================================= -int Value::jsonCanonicalize (std::ostream& document) const -{ - return serialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (const char* document, size_t length) -{ - return deserialize (document, length); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (const char* first, const char* last) -{ - return deserialize (first, last); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::string_view document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::stringstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::istringstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::fstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::ifstream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::iostream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packRead -// ========================================================================= -int Value::packRead (std::istream& document) -{ - return deserialize (document); -} - -// ========================================================================= -// CLASS : Value -// METHOD : packWrite -// ========================================================================= -int Value::packWrite (std::ostream& document) const -{ - return serialize (document); -} diff --git a/data/tests/json_canonicalizer_test.cpp b/data/tests/json_canonicalizer_test.cpp index 637b8424..65430d65 100644 --- a/data/tests/json_canonicalizer_test.cpp +++ b/data/tests/json_canonicalizer_test.cpp @@ -40,7 +40,12 @@ using join::SaxErrc; */ TEST (JsonCanonicalizer, members) { - Object object{{"b", 1}, {"\u20ac", 2}, {"a", 3}, {"\U0001F600", 4}}; + Value members; + members["b"] = 1; + members["\u20ac"] = 2; + members["a"] = 3; + members["\U0001F600"] = 4; + const Object& object = members.getObject (); std::stringstream out; JsonCanonicalizer writer (out); @@ -52,7 +57,8 @@ TEST (JsonCanonicalizer, members) EXPECT_EQ (sorted[3].get ().first, "\U0001F600"); Value value; - value = Object{{"b", 1}, {"a", 2}}; + value["b"] = 1; + value["a"] = 2; ASSERT_EQ (value.serialize (writer), 0) << join::lastError.message (); EXPECT_EQ (out.str (), "{\"a\":2,\"b\":1}"); EXPECT_EQ (value.getObject ()[0].first, "b"); @@ -130,7 +136,10 @@ TEST (JsonCanonicalizer, array) { Value value; value.pushBack (56); - value.pushBack (Object{{"d", true}, {"10", nullptr}, {"1", Array{}}}); + Value& object = value.pushBack (Object ()); + object["d"] = true; + object["10"] = nullptr; + object["1"] = Array (); value.pushBack (-53.0); std::stringstream out; @@ -164,12 +173,16 @@ TEST (JsonCanonicalizer, french) TEST (JsonCanonicalizer, structures) { Value value; - value["1"] = Object{{"f", Object{{"f", "hi"}, {"F", 5}}}, {"\n", 56.0}}; - value["10"] = Object{}; + value["1"]["f"]["f"] = "hi"; + value["1"]["f"]["F"] = 5; + value["1"]["\n"] = 56.0; + value["10"] = Object (); value[""] = "empty"; - value["a"] = Object{}; - value["111"] = Array{Object{{"e", "yes"}, {"E", "no"}}}; - value["A"] = Object{}; + value["a"] = Object (); + Value& element = value["111"].pushBack (Object ()); + element["e"] = "yes"; + element["E"] = "no"; + value["A"] = Object (); std::stringstream out; JsonCanonicalizer writer (out); @@ -199,9 +212,15 @@ TEST (JsonCanonicalizer, unicode) TEST (JsonCanonicalizer, values) { Value value; - value["numbers"] = Array{333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001}; + value["numbers"].pushBack (333333333.33333329); + value["numbers"].pushBack (1E30); + value["numbers"].pushBack (4.50); + value["numbers"].pushBack (2e-3); + value["numbers"].pushBack (0.000000000000000000000000001); value["string"] = "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"/"; - value["literals"] = Array{nullptr, true, false}; + value["literals"].pushBack (nullptr); + value["literals"].pushBack (true); + value["literals"].pushBack (false); std::stringstream out; JsonCanonicalizer writer (out); @@ -250,12 +269,14 @@ TEST (JsonCanonicalizer, invalid) ASSERT_EQ (value.serialize (writer), -1); ASSERT_EQ (join::lastError, JsonErrc::InvalidEncoding); - value = Object{{"a", "\xF0"}}; + value = nullptr; + value["a"] = "\xF0"; out.str (""); ASSERT_EQ (value.serialize (writer), -1); ASSERT_EQ (join::lastError, JsonErrc::InvalidEncoding); - value = Array{"\xFF"}; + value = nullptr; + value.pushBack ("\xFF"); out.str (""); ASSERT_EQ (value.serialize (writer), -1); ASSERT_EQ (join::lastError, JsonErrc::InvalidEncoding); @@ -267,7 +288,8 @@ TEST (JsonCanonicalizer, invalid) TEST (JsonCanonicalizer, document) { Value value; - value = Object{{Value (1), "One"}, {"a", "Ascii"}}; + value[1] = "One"; + value["a"] = "Ascii"; std::stringstream out; JsonCanonicalizer writer (out); @@ -279,7 +301,9 @@ TEST (JsonCanonicalizer, document) EXPECT_EQ (writer.setNull (), 0); EXPECT_EQ (out.str (), "null"); - value = Object{{"b", 1}, {"a", Array{1}}}; + value = nullptr; + value["b"] = 1; + value["a"].pushBack (1); out.str (""); JsonCanonicalizer indented (out, 2); EXPECT_EQ (value.serialize (indented), 0) << join::lastError.message (); diff --git a/data/tests/json_reader_test.cpp b/data/tests/json_reader_test.cpp index 7f004635..f40adb24 100644 --- a/data/tests/json_reader_test.cpp +++ b/data/tests/json_reader_test.cpp @@ -126,8 +126,7 @@ TEST (JsonReader, deserialize) JsonReader reader; ASSERT_EQ (reader.deserialize (std::string ("[1, [2, "), value), -1); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value.empty ()); + ASSERT_TRUE (value.isNull ()); ASSERT_EQ (reader.deserialize (std::string ("[3]"), value), 0) << join::lastError.message (); ASSERT_TRUE (value.isArray ()); @@ -170,6 +169,18 @@ TEST (JsonReader, deserialize) ASSERT_THROW (reader.deserialize ("[\"" + std::string (2000, 'a') + "\"]", failingWriter), std::runtime_error); ASSERT_EQ (reader.deserialize (std::string ("[2]"), failingWriter), 0) << join::lastError.message (); ASSERT_EQ (buffer.written, "[2]"); + + join::ValueBuilder builder (value); + for (size_t depth = 0; depth < join::saxMaxDepth; ++depth) + { + builder.startArray (); + } + ASSERT_EQ (JsonReader ().deserialize (std::string ("[1]"), builder), -1); + for (size_t depth = 0; depth < join::saxMaxDepth; ++depth) + { + builder.startArray (); + } + ASSERT_EQ (JsonReader ().deserialize (std::string ("{}"), builder), -1); } /** diff --git a/data/tests/json_writer_test.cpp b/data/tests/json_writer_test.cpp index 82fd61b1..10a95273 100644 --- a/data/tests/json_writer_test.cpp +++ b/data/tests/json_writer_test.cpp @@ -319,7 +319,10 @@ TEST (JsonWriter, members) { std::stringstream stream; JsonWriter jsonWriter (stream); - Object object{{"b", 1}, {"a", 2}}; + Value members; + members["b"] = 1; + members["a"] = 2; + const Object& object = members.getObject (); EXPECT_EQ (&jsonWriter.members (object), &object); } @@ -456,7 +459,7 @@ TEST (JsonWriter, document) EXPECT_EQ (value.serialize (jsonWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), "[null,true,1,2,3,4,1.23456789e-13,\"test\"]"); - value = Array{}; + value = Array (); std::string expected = "["; for (int i = 0; i < 1000; ++i) { @@ -470,41 +473,49 @@ TEST (JsonWriter, document) EXPECT_EQ (value.serialize (jsonWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), expected); - value = Object{{Value (1), "One"}}; + value = nullptr; + value[1] = "One"; stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), -1); EXPECT_EQ (join::lastError, SaxErrc::InvalidKey); EXPECT_EQ (stream.str (), ""); - value = Object{{"a", Object{{Value (1), "One"}}}}; + value = nullptr; + value["a"][1] = "One"; stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), -1); EXPECT_EQ (join::lastError, SaxErrc::InvalidKey); - value = Array{1, 2}; + value = nullptr; + value.pushBack (1); + value.pushBack (2); stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), "[1,2]"); - value = Array{}; + value = Array (); + Value* current = &value; for (int i = 0; i < 256; ++i) { - value = Array{value}; + current = ¤t->pushBack (Array ()); } stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), -1); EXPECT_EQ (join::lastError, SaxErrc::StackOverflow); - value = Object{}; + value = Object (); + current = &value; for (int i = 0; i < 256; ++i) { - value = Object{{"a", value}}; + current = ¤t->insert ("a", Object ()); } stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), -1); EXPECT_EQ (join::lastError, SaxErrc::StackOverflow); - value = Array{1, 2}; + value = nullptr; + value.pushBack (1); + value.pushBack (2); stream.str (""); EXPECT_EQ (value.serialize (jsonWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), "[1,2]"); @@ -512,9 +523,12 @@ TEST (JsonWriter, document) FailingBuffer buffer; std::ostream failing (&buffer); JsonWriter failingWriter (failing); - value = Array{std::string (2000, 'a')}; + value = nullptr; + value.pushBack (std::string (2000, 'a')); EXPECT_THROW (value.serialize (failingWriter), std::runtime_error); - value = Array{1, 2}; + value = nullptr; + value.pushBack (1); + value.pushBack (2); EXPECT_EQ (value.serialize (failingWriter), 0) << join::lastError.message (); EXPECT_EQ (buffer.written, "[1,2]"); } diff --git a/data/tests/pack_reader_test.cpp b/data/tests/pack_reader_test.cpp index abf74043..bf21495f 100644 --- a/data/tests/pack_reader_test.cpp +++ b/data/tests/pack_reader_test.cpp @@ -188,13 +188,24 @@ TEST (PackReader, deserialize) PackReader reader; ASSERT_EQ (reader.deserialize (std::string ({'\x92', '\x01'}), value), -1); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value.empty ()); + ASSERT_TRUE (value.isNull ()); ASSERT_EQ (reader.deserialize (std::string ({'\x91', '\x03'}), value), 0) << join::lastError.message (); ASSERT_TRUE (value.isArray ()); ASSERT_EQ (value.size (), 1); ASSERT_EQ (value[0], 3); + + join::ValueBuilder builder (value); + for (size_t depth = 0; depth < join::saxMaxDepth; ++depth) + { + builder.startArray (); + } + ASSERT_EQ (PackReader ().deserialize (std::string ({'\x91', '\x01'}), builder), -1); + for (size_t depth = 0; depth < join::saxMaxDepth; ++depth) + { + builder.startArray (); + } + ASSERT_EQ (PackReader ().deserialize (std::string (1, '\x80'), builder), -1); } /** diff --git a/data/tests/pack_writer_test.cpp b/data/tests/pack_writer_test.cpp index c63bcc1d..48b2b47d 100644 --- a/data/tests/pack_writer_test.cpp +++ b/data/tests/pack_writer_test.cpp @@ -469,7 +469,10 @@ TEST (PackWriter, members) { std::stringstream stream; PackWriter packWriter (stream); - Object object{{"b", 1}, {"a", 2}}; + Value members; + members["b"] = 1; + members["a"] = 2; + const Object& object = members.getObject (); EXPECT_EQ (&packWriter.members (object), &object); } @@ -641,18 +644,23 @@ TEST (PackWriter, document) std::string ({'\x98', '\xC0', '\xC3', '\x01', '\x02', '\x03', '\x04', '\xCB', '\x3D', '\x41', '\x5F', '\xFF', '\xE5', '\x3A', '\x68', '\x5D', '\xA4', '\x74', '\x65', '\x73', '\x74'})); - value = Object{{"a", 1}}; + value = nullptr; + value["a"] = 1; stream.str (""); EXPECT_EQ (value.serialize (packWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), std::string ({'\x81', '\xA1', 'a', '\x01'})); - value = Object{{Array{1}, 1}}; + Value key; + key.pushBack (1); + value = Object (); + value.insert (key, 1); stream.str (""); EXPECT_EQ (value.serialize (packWriter), -1); EXPECT_EQ (join::lastError, SaxErrc::InvalidKey); EXPECT_EQ (stream.str (), ""); - value = Array{7}; + value = nullptr; + value.pushBack (7); EXPECT_EQ (value.serialize (packWriter), 0) << join::lastError.message (); EXPECT_EQ (stream.str (), std::string ({'\x91', '\x07'})); } diff --git a/data/tests/sax_handler_test.cpp b/data/tests/sax_handler_test.cpp index 5d57a7dc..8c570a8e 100644 --- a/data/tests/sax_handler_test.cpp +++ b/data/tests/sax_handler_test.cpp @@ -168,7 +168,10 @@ TEST (SaxHandler, startObject) TEST (SaxHandler, members) { SaxHandler handler; - Object object{{"b", 1}, {"a", 2}}; + Value members; + members["b"] = 1; + members["a"] = 2; + const Object& object = members.getObject (); EXPECT_EQ (&handler.members (object), &object); } diff --git a/data/tests/value_builder_test.cpp b/data/tests/value_builder_test.cpp index e8cc27f5..ff4179aa 100644 --- a/data/tests/value_builder_test.cpp +++ b/data/tests/value_builder_test.cpp @@ -49,9 +49,9 @@ using join::SaxErrc; /** * @brief value builder derived by a user. */ -struct Derived : public ValueBuilder +struct Derived : public ValueBuilder { - using ValueBuilder::ValueBuilder; + using ValueBuilder::ValueBuilder; }; /** @@ -86,18 +86,23 @@ TEST (ValueBuilder, create) ASSERT_EQ (innerBuilder.setInt (2), 0); ASSERT_EQ (innerBuilder.stopArray (), 0); } - ASSERT_EQ (inner, Array{2}); + ASSERT_EQ (inner.size (), 1U); + ASSERT_EQ (inner[0], 2); ASSERT_EQ (builder.setInt (3), 0); ASSERT_EQ (builder.stopArray (), 0); } - ASSERT_EQ (value, (Array{1, 3})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value[0], 1); + ASSERT_EQ (value[1], 3); Nested nested; ASSERT_EQ (JsonReader ().deserialize (std::string ("[\"[1,{\\\"a\\\":2}]\", \"3\"]"), nested), 0) << join::lastError.message (); ASSERT_EQ (nested.values.size (), 2U); - ASSERT_EQ (nested.values[0], (Array{1, Object{{"a", 2}}})); + ASSERT_EQ (nested.values[0].size (), 2U); + ASSERT_EQ (nested.values[0][0], 1); + ASSERT_EQ (nested.values[0][1].at ("a"), 2); ASSERT_EQ (nested.values[1], 3); } @@ -108,14 +113,15 @@ TEST (ValueBuilder, setNull) { Value value; ValueBuilder builder (value); - value = Array{}; + value = Array (); ASSERT_EQ (builder.setNull (), 0); ASSERT_TRUE (value.isNull ()); ASSERT_EQ (builder.startArray (), 0); ASSERT_EQ (builder.setNull (), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, Array{nullptr}); + ASSERT_EQ (value.size (), 1U); + ASSERT_TRUE (value[0].isNull ()); } /** @@ -132,7 +138,9 @@ TEST (ValueBuilder, setBool) ASSERT_EQ (builder.setBool (true), 0); ASSERT_EQ (builder.setBool (false), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, (Array{true, false})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value[0], true); + ASSERT_EQ (value[1], false); } /** @@ -219,7 +227,8 @@ TEST (ValueBuilder, setDouble) ASSERT_EQ (builder.startArray (), 0); ASSERT_EQ (builder.setDouble (1.5), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, Array{1.5}); + ASSERT_EQ (value.size (), 1U); + ASSERT_EQ (value[0], 1.5); } /** @@ -237,7 +246,9 @@ TEST (ValueBuilder, setString) ASSERT_EQ (builder.setString ("a"), 0); ASSERT_EQ (builder.setString (b), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, (Array{"a", "b"})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value[0], "a"); + ASSERT_EQ (value[1], "b"); } /** @@ -259,7 +270,9 @@ TEST (ValueBuilder, startArray) ASSERT_EQ (builder.startArray (), 0); ASSERT_EQ (builder.stopArray (), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, Array{Value (Array{})}); + ASSERT_EQ (value.size (), 1U); + ASSERT_TRUE (value[0].isArray ()); + ASSERT_TRUE (value[0].empty ()); } /** @@ -275,7 +288,19 @@ TEST (ValueBuilder, stopArray) ASSERT_EQ (builder.startArray (), 0); ASSERT_EQ (builder.setInt (1), 0); ASSERT_EQ (builder.stopArray (), 0); - ASSERT_EQ (value, Array{1}); + ASSERT_EQ (value.size (), 1U); + ASSERT_EQ (value[0], 1); + + value.pushBack (2); + value.pushBack (3); + ASSERT_EQ (builder.startArray (), 0); + ASSERT_EQ (builder.setInt (4), 0); + ASSERT_EQ (builder.stopArray (), 0); + const Value* first = &value[0]; + value.pushBack (5); + ASSERT_NE (&value[0], first); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value[1], 5); } /** @@ -299,7 +324,9 @@ TEST (ValueBuilder, startObject) ASSERT_EQ (builder.startObject (), 0); ASSERT_EQ (builder.stopObject (), 0); ASSERT_EQ (builder.stopObject (), 0); - ASSERT_EQ (value, (Object{{"a", Object{}}})); + ASSERT_EQ (value.size (), 1U); + ASSERT_TRUE (value.at ("a").isObject ()); + ASSERT_TRUE (value.at ("a").empty ()); } /** @@ -309,12 +336,17 @@ TEST (ValueBuilder, members) { Value value; ValueBuilder builder (value); - Object object{{"b", 1}, {"a", 2}}; + Value members; + members["b"] = 1; + members["a"] = 2; + const Object& object = members.getObject (); EXPECT_EQ (&builder.members (object), &object); Value copy; ValueBuilder copyBuilder (copy); - value = Object{{"b", 1}, {"a", Array{2}}}; + value = nullptr; + value["b"] = 1; + value["a"].pushBack (2); ASSERT_EQ (value.serialize (copyBuilder), 0) << join::lastError.message (); EXPECT_EQ (copy, value); @@ -399,13 +431,17 @@ TEST (ValueBuilder, stopObject) ASSERT_EQ (builder.setKey ("a"), 0); ASSERT_EQ (builder.setInt (1), 0); ASSERT_EQ (builder.stopObject (), 0); - ASSERT_EQ (value, (Object{{"a", 1}})); + ASSERT_EQ (value.size (), 1U); + ASSERT_EQ (value.at ("a"), 1); std::string pack; { std::stringstream out; PackWriter writer (out); - Value source = Object{{"a", Array{1, 2}}, {"b", nullptr}}; + Value source; + source["a"].pushBack (1); + source["a"].pushBack (2); + source["b"] = nullptr; ASSERT_EQ (source.serialize (writer), 0) << join::lastError.message (); pack = out.str (); } diff --git a/data/tests/value_test.cpp b/data/tests/value_test.cpp index a4600c52..3a0db4f5 100644 --- a/data/tests/value_test.cpp +++ b/data/tests/value_test.cpp @@ -129,6 +129,13 @@ struct Counter : public join::SaxHandler */ TEST (Value, create) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + + static_assert (std::is_nothrow_default_constructible_v); Value defaultValue; ASSERT_TRUE (defaultValue.isNull ()); @@ -217,21 +224,14 @@ TEST (Value, create) ASSERT_TRUE (viewStringValue.isString ()); ASSERT_EQ (viewStringValue.getString (), "quu"); - Value arrayValue (Array{1}); + Value arrayValue (array.getArray ()); ASSERT_TRUE (arrayValue.isArray ()); + ASSERT_EQ (arrayValue.size (), 1U); + ASSERT_EQ (arrayValue[0], 1); - const Array array{1, 2}; - Value copiedArrayValue (array); - ASSERT_TRUE (copiedArrayValue.isArray ()); - ASSERT_EQ (copiedArrayValue.size (), 2U); - - Value objectValue (Object ({{"i", 1}})); + Value objectValue (object.getObject ()); ASSERT_TRUE (objectValue.isObject ()); - - const Object object{{"a", 1}}; - Value copiedObjectValue (object); - ASSERT_TRUE (copiedObjectValue.isObject ()); - ASSERT_EQ (copiedObjectValue["a"], 1); + ASSERT_EQ (objectValue["i"], 1); } /** @@ -239,6 +239,12 @@ TEST (Value, create) */ TEST (Value, copy) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; Value defaultValue (value); ASSERT_TRUE (defaultValue.isNull ()); @@ -321,11 +327,11 @@ TEST (Value, copy) Value stringValue (value); ASSERT_TRUE (stringValue.isString ()); - value = Array{1}; + value = array.getArray (); Value arrayValue (value); ASSERT_TRUE (arrayValue.isArray ()); - value = Object{{"i", 1}}; + value = object.getObject (); Value objectValue (value); ASSERT_TRUE (objectValue.isObject ()); } @@ -335,6 +341,12 @@ TEST (Value, copy) */ TEST (Value, move) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; Value defaultValue (std::move (value)); ASSERT_TRUE (defaultValue.isNull ()); @@ -417,11 +429,11 @@ TEST (Value, move) Value stringValue (std::move (value)); ASSERT_TRUE (stringValue.isString ()); - value = Array{1}; + value = array.getArray (); Value arrayValue (std::move (value)); ASSERT_TRUE (arrayValue.isArray ()); - value = Object{{"i", 1}}; + value = object.getObject (); Value objectValue (std::move (value)); ASSERT_TRUE (objectValue.isObject ()); } @@ -431,6 +443,12 @@ TEST (Value, move) */ TEST (Value, isNull) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_TRUE (value.isNull ()); @@ -515,10 +533,10 @@ TEST (Value, isNull) value = "127.0.0.1"; ASSERT_FALSE (value.isNull ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isNull ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isNull ()); } @@ -527,6 +545,12 @@ TEST (Value, isNull) */ TEST (Value, isBool) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isBool ()); @@ -611,10 +635,10 @@ TEST (Value, isBool) value = "127.0.0.1"; ASSERT_FALSE (value.isBool ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isBool ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isBool ()); } @@ -623,6 +647,12 @@ TEST (Value, isBool) */ TEST (Value, isTrue) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isTrue ()); @@ -707,10 +737,10 @@ TEST (Value, isTrue) value = "127.0.0.1"; ASSERT_THROW (value.isTrue (), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.isTrue (), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.isTrue (), std::bad_cast); } @@ -719,6 +749,12 @@ TEST (Value, isTrue) */ TEST (Value, isFalse) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_TRUE (value.isFalse ()); @@ -803,10 +839,10 @@ TEST (Value, isFalse) value = "127.0.0.1"; ASSERT_THROW (value.isFalse (), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.isFalse (), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.isFalse (), std::bad_cast); } @@ -815,6 +851,12 @@ TEST (Value, isFalse) */ TEST (Value, isNumber) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isNumber ()); @@ -899,10 +941,10 @@ TEST (Value, isNumber) value = "127.0.0.1"; ASSERT_FALSE (value.isNumber ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isNumber ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isNumber ()); } @@ -911,6 +953,12 @@ TEST (Value, isNumber) */ TEST (Value, isInt8) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isInt8 ()); @@ -995,10 +1043,10 @@ TEST (Value, isInt8) value = "127.0.0.1"; ASSERT_FALSE (value.isInt8 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isInt8 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isInt8 ()); } @@ -1007,6 +1055,12 @@ TEST (Value, isInt8) */ TEST (Value, isUint8) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isUint8 ()); @@ -1091,10 +1145,10 @@ TEST (Value, isUint8) value = "127.0.0.1"; ASSERT_FALSE (value.isUint8 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isUint8 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isUint8 ()); } @@ -1103,6 +1157,12 @@ TEST (Value, isUint8) */ TEST (Value, isInt16) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isInt16 ()); @@ -1187,10 +1247,10 @@ TEST (Value, isInt16) value = "127.0.0.1"; ASSERT_FALSE (value.isInt16 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isInt16 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isInt16 ()); } @@ -1199,6 +1259,12 @@ TEST (Value, isInt16) */ TEST (Value, isUint16) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isUint16 ()); @@ -1283,10 +1349,10 @@ TEST (Value, isUint16) value = "127.0.0.1"; ASSERT_FALSE (value.isUint16 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isUint16 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isUint16 ()); } @@ -1295,6 +1361,12 @@ TEST (Value, isUint16) */ TEST (Value, isInt) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isInt ()); @@ -1379,10 +1451,10 @@ TEST (Value, isInt) value = "127.0.0.1"; ASSERT_FALSE (value.isInt ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isInt ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isInt ()); } @@ -1391,6 +1463,12 @@ TEST (Value, isInt) */ TEST (Value, isUint) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isUint ()); @@ -1475,10 +1553,10 @@ TEST (Value, isUint) value = "127.0.0.1"; ASSERT_FALSE (value.isUint ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isUint ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isUint ()); } @@ -1487,6 +1565,12 @@ TEST (Value, isUint) */ TEST (Value, isInt64) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isInt64 ()); @@ -1571,10 +1655,10 @@ TEST (Value, isInt64) value = "127.0.0.1"; ASSERT_FALSE (value.isInt64 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isInt64 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isInt64 ()); } @@ -1583,6 +1667,12 @@ TEST (Value, isInt64) */ TEST (Value, isUint64) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isUint64 ()); @@ -1667,10 +1757,10 @@ TEST (Value, isUint64) value = "127.0.0.1"; ASSERT_FALSE (value.isUint64 ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isUint64 ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isUint64 ()); } @@ -1679,6 +1769,12 @@ TEST (Value, isUint64) */ TEST (Value, isFloat) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isFloat ()); @@ -1763,10 +1859,10 @@ TEST (Value, isFloat) value = "127.0.0.1"; ASSERT_FALSE (value.isFloat ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isFloat ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isFloat ()); } @@ -1775,6 +1871,12 @@ TEST (Value, isFloat) */ TEST (Value, isDouble) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isDouble ()); @@ -1859,10 +1961,10 @@ TEST (Value, isDouble) value = "127.0.0.1"; ASSERT_FALSE (value.isDouble ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isDouble ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isDouble ()); } @@ -1871,6 +1973,12 @@ TEST (Value, isDouble) */ TEST (Value, isString) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isString ()); @@ -1955,10 +2063,10 @@ TEST (Value, isString) value = "127.0.0.1"; ASSERT_TRUE (value.isString ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isString ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isString ()); } @@ -1967,6 +2075,12 @@ TEST (Value, isString) */ TEST (Value, isArray) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isArray ()); @@ -2051,10 +2165,10 @@ TEST (Value, isArray) value = "127.0.0.1"; ASSERT_FALSE (value.isArray ()); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (value.isArray ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.isArray ()); } @@ -2063,6 +2177,12 @@ TEST (Value, isArray) */ TEST (Value, isObject) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.isObject ()); @@ -2147,10 +2267,10 @@ TEST (Value, isObject) value = "127.0.0.1"; ASSERT_FALSE (value.isObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.isObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (value.isObject ()); } @@ -2159,6 +2279,12 @@ TEST (Value, isObject) */ TEST (Value, getBool) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_FALSE (value.getBool ()); ASSERT_FALSE (static_cast (value)); @@ -2272,11 +2398,11 @@ TEST (Value, getBool) value = "127.0.0.1"; ASSERT_THROW (value.getBool (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getBool (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getBool (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2286,6 +2412,12 @@ TEST (Value, getBool) */ TEST (Value, getInt8) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + int8_t tmp = 0; (void)tmp; @@ -2413,11 +2545,11 @@ TEST (Value, getInt8) ASSERT_THROW (value.getInt8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getInt8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getInt8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2427,6 +2559,12 @@ TEST (Value, getInt8) */ TEST (Value, getUint8) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + uint8_t tmp = 0; (void)tmp; @@ -2554,11 +2692,11 @@ TEST (Value, getUint8) ASSERT_THROW (value.getUint8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getUint8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getUint8 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2568,6 +2706,12 @@ TEST (Value, getUint8) */ TEST (Value, getInt16) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + int16_t tmp = 0; (void)tmp; @@ -2695,11 +2839,11 @@ TEST (Value, getInt16) ASSERT_THROW (value.getInt16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getInt16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getInt16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2709,6 +2853,12 @@ TEST (Value, getInt16) */ TEST (Value, getUint16) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + uint16_t tmp = 0; (void)tmp; @@ -2836,11 +2986,11 @@ TEST (Value, getUint16) ASSERT_THROW (value.getUint16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getUint16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getUint16 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2850,6 +3000,12 @@ TEST (Value, getUint16) */ TEST (Value, getInt) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + int32_t tmp = 0; (void)tmp; @@ -2973,11 +3129,11 @@ TEST (Value, getInt) ASSERT_THROW (value.getInt (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getInt (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getInt (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -2987,6 +3143,12 @@ TEST (Value, getInt) */ TEST (Value, getUint) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + uint32_t tmp = 0; (void)tmp; @@ -3110,11 +3272,11 @@ TEST (Value, getUint) ASSERT_THROW (value.getUint (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getUint (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getUint (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3124,6 +3286,12 @@ TEST (Value, getUint) */ TEST (Value, getInt64) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + int64_t tmp = 0; (void)tmp; @@ -3243,11 +3411,11 @@ TEST (Value, getInt64) ASSERT_THROW (value.getInt64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getInt64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getInt64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3257,6 +3425,12 @@ TEST (Value, getInt64) */ TEST (Value, getUint64) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + uint64_t tmp = 0; (void)tmp; @@ -3376,11 +3550,11 @@ TEST (Value, getUint64) ASSERT_THROW (value.getUint64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getUint64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getUint64 (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3390,6 +3564,12 @@ TEST (Value, getUint64) */ TEST (Value, getFloat) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + float tmp = 0.0f; (void)tmp; @@ -3505,11 +3685,11 @@ TEST (Value, getFloat) ASSERT_THROW (value.getFloat (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getFloat (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getFloat (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3519,6 +3699,12 @@ TEST (Value, getFloat) */ TEST (Value, getDouble) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + double tmp = 0.0; (void)tmp; @@ -3634,11 +3820,11 @@ TEST (Value, getDouble) ASSERT_THROW (value.getDouble (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getDouble (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getDouble (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3648,6 +3834,12 @@ TEST (Value, getDouble) */ TEST (Value, getString) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + std::string_view tmp; (void)tmp; @@ -3763,11 +3955,11 @@ TEST (Value, getString) ASSERT_EQ (value.getString (), "127.0.0.1"); ASSERT_EQ (static_cast (value), "127.0.0.1"); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getString (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getString (), std::bad_cast); ASSERT_THROW ((tmp = static_cast (value)), std::bad_cast); } @@ -3777,6 +3969,12 @@ TEST (Value, getString) */ TEST (Value, getArray) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.getArray (), std::bad_cast); @@ -3861,10 +4059,10 @@ TEST (Value, getArray) value = "127.0.0.1"; ASSERT_THROW (value.getArray (), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_NO_THROW (value.getArray ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.getArray (), std::bad_cast); } @@ -3873,6 +4071,12 @@ TEST (Value, getArray) */ TEST (Value, getObject) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.getObject (), std::bad_cast); @@ -3957,10 +4161,10 @@ TEST (Value, getObject) value = "127.0.0.1"; ASSERT_THROW (value.getObject (), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.getObject (), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_NO_THROW (value.getObject ()); } @@ -3969,6 +4173,12 @@ TEST (Value, getObject) */ TEST (Value, index) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -4067,7 +4277,7 @@ TEST (Value, index) ASSERT_NE (value.index (), static_cast (Value::Index::ArrayValue)); ASSERT_NE (value.index (), static_cast (Value::Index::ObjectValue)); - value = Array{1}; + value = array.getArray (); ASSERT_NE (value.index (), static_cast (Value::Index::NullValue)); ASSERT_NE (value.index (), static_cast (Value::Index::BooleanValue)); ASSERT_NE (value.index (), static_cast (Value::Index::IntegerValue)); @@ -4079,7 +4289,7 @@ TEST (Value, index) ASSERT_EQ (value.index (), static_cast (Value::Index::ArrayValue)); ASSERT_NE (value.index (), static_cast (Value::Index::ObjectValue)); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_NE (value.index (), static_cast (Value::Index::NullValue)); ASSERT_NE (value.index (), static_cast (Value::Index::BooleanValue)); ASSERT_NE (value.index (), static_cast (Value::Index::IntegerValue)); @@ -4114,10 +4324,10 @@ TEST (Value, at) value.pushBack ("foobar"); ASSERT_TRUE (value.at (4).isString ()); - value.pushBack (Array ({1, 2, 3, 4})); + value.pushBack (Array ()); ASSERT_TRUE (value.at (5).isArray ()); - value.pushBack (Object ({{"foo", 1}, {"bar", 2}})); + value.pushBack (Object ()); ASSERT_TRUE (value.at (6).isObject ()); ASSERT_THROW (value.at (7), std::out_of_range); @@ -4139,16 +4349,23 @@ TEST (Value, at) value["string"] = "foobar"; ASSERT_TRUE (value.at ("string").isString ()); - value["array"] = Array{1, 2, 3, 4}; + value["array"] = Array (); ASSERT_TRUE (value.at ("array").isArray ()); - value["object"] = Object{{"foo", 1}, {"bar", 2}}; + value["object"] = Object (); ASSERT_TRUE (value.at ("object").isObject ()); ASSERT_THROW (value.at ("non existing path"), std::out_of_range); - value = Object{{nullptr, 0}, {true, 1}, {int32_t (-2), 2}, {uint32_t (3), 3}, - {int64_t (-4), 4}, {uint64_t (5), 5}, {6.5, 6}, {"seven", 7}}; + value = nullptr; + value[nullptr] = 0; + value[true] = 1; + value[int32_t (-2)] = 2; + value[uint32_t (3)] = 3; + value[int64_t (-4)] = 4; + value[uint64_t (5)] = 5; + value[6.5] = 6; + value["seven"] = 7; const Value& constant = value; ASSERT_EQ (value.at (nullptr), 0); ASSERT_EQ (constant.at (nullptr), 0); @@ -4174,7 +4391,8 @@ TEST (Value, at) ASSERT_THROW (constant.at (8), std::out_of_range); ASSERT_THROW (constant.at ("eight"), std::out_of_range); - value = Object{{"seven", 7}}; + value = nullptr; + value["seven"] = 7; ASSERT_THROW (value.at (nullptr), std::out_of_range); ASSERT_THROW (constant.at (nullptr), std::out_of_range); ASSERT_THROW (value.at (true), std::out_of_range); @@ -4188,7 +4406,11 @@ TEST (Value, at) ASSERT_THROW (value.at (6.5), std::out_of_range); ASSERT_THROW (constant.at (6.5), std::out_of_range); - value = Array{0, 1, 2, 3}; + value = nullptr; + value.pushBack (0); + value.pushBack (1); + value.pushBack (2); + value.pushBack (3); ASSERT_EQ (value.at (int32_t (0)), 0); ASSERT_EQ (constant.at (int32_t (0)), 0); ASSERT_EQ (value.at (uint32_t (1)), 1); @@ -4259,7 +4481,11 @@ TEST (Value, subscript) value[6.5] = 6; ASSERT_TRUE (value.isObject ()); - value = Array{0, 1, 2, 3}; + value = nullptr; + value.pushBack (0); + value.pushBack (1); + value.pushBack (2); + value.pushBack (3); ASSERT_EQ (value[int32_t (0)], 0); ASSERT_EQ (value[uint32_t (1)], 1); ASSERT_EQ (value[int64_t (2)], 2); @@ -4296,21 +4522,21 @@ TEST (Value, assign) value["string"] = "foobar"; ASSERT_TRUE (value["string"].isString ()); - value["array"] = Array{1, 2, 3, 4}; + value["array"] = Array (); ASSERT_TRUE (value["array"].isArray ()); - value["object"] = Object{{"foo", 1}, {"bar", 2}}; + value["object"] = Object (); ASSERT_TRUE (value["object"].isObject ()); - value["braced"] = {}; - ASSERT_TRUE (value["braced"].isNull ()); - - value["braced"] = {1}; - ASSERT_TRUE (value["braced"].isInt ()); - const std::string string ("foo"); value["braced"] = {string}; ASSERT_TRUE (value["braced"].isString ()); + + Value root; + root.pushBack (2); + value["moved"] = std::move (root); + ASSERT_EQ (value["moved"][0], 2); + ASSERT_TRUE (root.isNull ()); } /** @@ -4318,6 +4544,12 @@ TEST (Value, assign) */ TEST (Value, empty) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.empty (), std::bad_cast); @@ -4402,16 +4634,16 @@ TEST (Value, empty) value = "127.0.0.1"; ASSERT_FALSE (value.empty ()); - value = Array{}; + value = Array (); ASSERT_TRUE (value.empty ()); - value = Array{1, 2, 3, 4}; + value = array.getArray (); ASSERT_FALSE (value.empty ()); - value = Object ({}); + value = Object (); ASSERT_TRUE (value.empty ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.empty ()); } @@ -4420,6 +4652,12 @@ TEST (Value, empty) */ TEST (Value, size) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.size (), std::bad_cast); @@ -4504,10 +4742,10 @@ TEST (Value, size) value = "127.0.0.1"; ASSERT_EQ (value.size (), 9); - value = Array{1}; + value = array.getArray (); ASSERT_EQ (value.size (), 1); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_EQ (value.size (), 1); } @@ -4516,6 +4754,12 @@ TEST (Value, size) */ TEST (Value, reserve) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.reserve (12), std::bad_cast); @@ -4600,11 +4844,17 @@ TEST (Value, reserve) value = "127.0.0.1"; ASSERT_NO_THROW (value.reserve (12)); - value = Array{1}; + value = array.getArray (); ASSERT_NO_THROW (value.reserve (12)); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_NO_THROW (value.reserve (12)); + + value = "foo"; + ASSERT_THROW (value.reserve (std::numeric_limits::max ()), std::bad_alloc); + + value = array.getArray (); + ASSERT_THROW (value.reserve (size_t (std::numeric_limits::max ()) + 1), std::bad_alloc); } /** @@ -4612,6 +4862,12 @@ TEST (Value, reserve) */ TEST (Value, clear) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.clear (), std::bad_cast); @@ -4704,12 +4960,12 @@ TEST (Value, clear) ASSERT_NO_THROW (value.clear ()); ASSERT_TRUE (value.empty ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value.empty ()); ASSERT_NO_THROW (value.clear ()); ASSERT_TRUE (value.empty ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.empty ()); ASSERT_NO_THROW (value.clear ()); ASSERT_TRUE (value.empty ()); @@ -4720,6 +4976,12 @@ TEST (Value, clear) */ TEST (Value, insert) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.insert (Member{"i", 1}), std::bad_cast); @@ -4804,10 +5066,10 @@ TEST (Value, insert) value = "127.0.0.1"; ASSERT_THROW (value.insert (Member{"i", 1}), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.insert (Member{"i", 1}), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_NO_THROW (value.insert (Member{"i", 1})); } @@ -4816,6 +5078,12 @@ TEST (Value, insert) */ TEST (Value, erase) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.erase ("i"), std::bad_cast); @@ -4900,15 +5168,24 @@ TEST (Value, erase) value = "127.0.0.1"; ASSERT_THROW (value.erase ("i"), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_THROW (value.erase ("i"), std::bad_cast); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_EQ (value.erase ("i"), 1); ASSERT_EQ (value.erase ("j"), 0); - value = Object{{nullptr, 0}, {true, 1}, {int32_t (-2), 2}, {uint32_t (3), 3}, {int64_t (-4), 4}, - {uint64_t (5), 5}, {6.5, 6}, {"seven", 7}, {"eight", 8}, {"nine", 9}}; + value = nullptr; + value[nullptr] = 0; + value[true] = 1; + value[int32_t (-2)] = 2; + value[uint32_t (3)] = 3; + value[int64_t (-4)] = 4; + value[uint64_t (5)] = 5; + value[6.5] = 6; + value["seven"] = 7; + value["eight"] = 8; + value["nine"] = 9; ASSERT_EQ (value.erase (nullptr), 1); ASSERT_EQ (value.erase (nullptr), 0); ASSERT_EQ (value.erase (true), 1); @@ -4952,6 +5229,12 @@ TEST (Value, emplaceBack) */ TEST (Value, pushBack) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_NO_THROW (value.pushBack (1)); @@ -5036,10 +5319,10 @@ TEST (Value, pushBack) value = "127.0.0.1"; ASSERT_THROW (value.pushBack (1), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_NO_THROW (value.pushBack (1)); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.pushBack (1), std::bad_cast); } @@ -5048,6 +5331,12 @@ TEST (Value, pushBack) */ TEST (Value, popBack) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.popBack (), std::bad_cast); @@ -5132,10 +5421,13 @@ TEST (Value, popBack) value = "127.0.0.1"; ASSERT_THROW (value.popBack (), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_NO_THROW (value.popBack ()); + ASSERT_TRUE (value.empty ()); + ASSERT_NO_THROW (value.popBack ()); + ASSERT_TRUE (value.empty ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_THROW (value.popBack (), std::bad_cast); } @@ -5144,6 +5436,12 @@ TEST (Value, popBack) */ TEST (Value, contains) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; ASSERT_THROW (value.contains (0), std::bad_cast); ASSERT_THROW (value.contains ("i"), std::bad_cast); @@ -5256,24 +5554,31 @@ TEST (Value, contains) ASSERT_THROW (value.contains (0), std::bad_cast); ASSERT_THROW (value.contains ("i"), std::bad_cast); - value = Array{}; + value = Array (); ASSERT_FALSE (value.contains (0)); ASSERT_THROW (value.contains ("i"), std::bad_cast); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (value.contains (0)); ASSERT_THROW (value.contains ("i"), std::bad_cast); - value = Object ({}); + value = Object (); ASSERT_FALSE (value.contains (0)); ASSERT_FALSE (value.contains ("i")); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value.contains (0)); ASSERT_TRUE (value.contains ("i")); - value = Object{{nullptr, 0}, {true, 1}, {int32_t (-2), 2}, {uint32_t (3), 3}, - {int64_t (-4), 4}, {uint64_t (5), 5}, {6.5, 6}, {"seven", 7}}; + value = nullptr; + value[nullptr] = 0; + value[true] = 1; + value[int32_t (-2)] = 2; + value[uint32_t (3)] = 3; + value[int64_t (-4)] = 4; + value[uint64_t (5)] = 5; + value[6.5] = 6; + value["seven"] = 7; ASSERT_TRUE (value.contains (nullptr)); ASSERT_TRUE (value.contains (true)); ASSERT_TRUE (value.contains (int32_t (-2))); @@ -5287,14 +5592,17 @@ TEST (Value, contains) ASSERT_FALSE (value.contains (false)); ASSERT_FALSE (value.contains (std::string_view ("eight"))); - value = Object{{"seven", 7}}; + value = nullptr; + value["seven"] = 7; ASSERT_FALSE (value.contains (nullptr)); ASSERT_FALSE (value.contains (uint32_t (3))); ASSERT_FALSE (value.contains (int64_t (-4))); ASSERT_FALSE (value.contains (uint64_t (5))); ASSERT_FALSE (value.contains (6.5)); - value = Array{0, 1}; + value = nullptr; + value.pushBack (0); + value.pushBack (1); ASSERT_TRUE (value.contains (int32_t (1))); ASSERT_FALSE (value.contains (int32_t (2))); ASSERT_FALSE (value.contains (int32_t (-1))); @@ -5315,9 +5623,15 @@ TEST (Value, contains) */ TEST (Value, swap) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value = nullptr; - Value other = Array{1}; + Value other = array.getArray (); ASSERT_TRUE (value.isNull ()); ASSERT_TRUE (other.isArray ()); value.swap (other); @@ -5380,19 +5694,26 @@ TEST (Value, swap) ASSERT_TRUE (value.isString ()); ASSERT_TRUE (other.isDouble ()); - other = Array{1}; + other = array.getArray (); ASSERT_TRUE (value.isString ()); ASSERT_TRUE (other.isArray ()); value.swap (other); ASSERT_TRUE (value.isArray ()); ASSERT_TRUE (other.isString ()); - other = Object{{"i", 1}}; + other = object.getObject (); ASSERT_TRUE (value.isArray ()); ASSERT_TRUE (other.isObject ()); value.swap (other); ASSERT_TRUE (value.isObject ()); ASSERT_TRUE (other.isArray ()); + + value = nullptr; + value["a"] = 1; + value["b"] = "foo"; + value["a"].swap (value["b"]); + ASSERT_EQ (value["a"], "foo"); + ASSERT_EQ (value["b"], 1); } /** @@ -5400,8 +5721,18 @@ TEST (Value, swap) */ TEST (Value, serialize) { - Value keys = Object{{nullptr, 0}, {true, 1}, {int32_t (-2), 2}, {uint32_t (3), 3}, - {int64_t (-4), 4}, {uint64_t (5), 5}, {6.5, 6}, {"seven", 7}}; + Value array; + array.pushBack (1); + + Value keys; + keys[nullptr] = 0; + keys[true] = 1; + keys[int32_t (-2)] = 2; + keys[uint32_t (3)] = 3; + keys[int64_t (-4)] = 4; + keys[uint64_t (5)] = 5; + keys[6.5] = 6; + keys["seven"] = 7; Value copy; join::ValueBuilder builder (copy); ASSERT_EQ (keys.serialize (builder), 0) << join::lastError.message (); @@ -5445,10 +5776,16 @@ TEST (Value, serialize) ASSERT_EQ (value.serialize (counter), 0) << join::lastError.message (); EXPECT_EQ (counter.values, 5U); - value = Object{}; - value["numbers"] = Array{333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001}; + value = Object (); + value["numbers"].pushBack (333333333.33333329); + value["numbers"].pushBack (1E30); + value["numbers"].pushBack (4.50); + value["numbers"].pushBack (2e-3); + value["numbers"].pushBack (0.000000000000000000000000001); value["string"] = "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"/"; - value["literals"] = Array{nullptr, true, false}; + value["literals"].pushBack (nullptr); + value["literals"].pushBack (true); + value["literals"].pushBack (false); out.str (""); ASSERT_EQ (value.serialize (out), 0) << join::lastError.message (); @@ -5456,22 +5793,27 @@ TEST (Value, serialize) "{\"literals\":[null,true,false],\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27],\"string\":\"€$" "\\u000f\\nA'B\\\"\\\\\\\\\\\"/\"}"); - value = Object{{Array{1}, 1}}; + value = Object (); + value.insert (array, 1); out.str (""); ASSERT_EQ (value.serialize (packWriter), -1); ASSERT_EQ (join::lastError, SaxErrc::InvalidKey); ASSERT_EQ (out.str (), ""); - value = Array{7}; + value = nullptr; + value.pushBack (7); ASSERT_EQ (value.serialize (packWriter), 0) << join::lastError.message (); ASSERT_EQ (out.str (), std::string ({'\x91', '\x07'})); FailingBuffer buffer; std::ostream failing (&buffer); JsonWriter failingWriter (failing); - value = Array{std::string (2000, 'a')}; + value = nullptr; + value.pushBack (std::string (2000, 'a')); ASSERT_THROW (value.serialize (failingWriter), std::runtime_error); - value = Array{1, 2}; + value = nullptr; + value.pushBack (1); + value.pushBack (2); ASSERT_EQ (value.serialize (failingWriter), 0) << join::lastError.message (); ASSERT_EQ (buffer.written, "[1,2]"); } @@ -5483,14 +5825,21 @@ TEST (Value, deserialize) { Value value; ASSERT_EQ (value.deserialize (std::string ("[1,{\"a\":\"b\"}]")), 0) << join::lastError.message (); - ASSERT_EQ (value, (Array{1, Object{{"a", "b"}}})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value.at (0), 1); + ASSERT_EQ (value.at (1).at ("a"), "b"); const char json[] = "{\"c\":[true,null]}"; ASSERT_EQ (value.deserialize (json, sizeof (json) - 1), 0) << join::lastError.message (); - ASSERT_EQ (value, (Object{{"c", Array{true, nullptr}}})); + ASSERT_EQ (value.size (), 1U); + ASSERT_EQ (value.at ("c").size (), 2U); + ASSERT_EQ (value.at ("c").at (0), true); + ASSERT_EQ (value.at ("c").at (1), nullptr); ASSERT_EQ (value.deserialize (&json[5], &json[sizeof (json) - 2]), 0) << join::lastError.message (); - ASSERT_EQ (value, (Array{true, nullptr})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value.at (0), true); + ASSERT_EQ (value.at (1), nullptr); std::stringstream stream ("42"); ASSERT_EQ (value.deserialize (stream), 0) << join::lastError.message (); @@ -5501,349 +5850,17 @@ TEST (Value, deserialize) ASSERT_EQ (value, 1.5); ASSERT_EQ (value.deserialize (std::string ("[1, [2, ")), -1); - ASSERT_EQ (value, 1.5); + ASSERT_TRUE (value.isNull ()); ASSERT_EQ (value.deserialize (std::string ({'\x92', '\x01', '\xa1', '\x61'})), 0) << join::lastError.message (); - ASSERT_EQ (value, (Array{1, "a"})); + ASSERT_EQ (value.size (), 2U); + ASSERT_EQ (value.at (0), 1); + ASSERT_EQ (value.at (1), "a"); ASSERT_EQ (value.deserialize (std::string ({'\x92', '\x01'})), -1); ASSERT_EQ (join::lastError, SaxErrc::Truncated); - ASSERT_EQ (value, (Array{1, "a"})); -} - -/** - * @brief packRead method. - */ -TEST (Value, packRead) -{ - Value value; - - std::string str ({'\x95', '\x01', '\xc0', '\xc3', '\xa4', '\x74', '\x65', '\x73', '\x74', '\xcb', '\x3d', '\x41', - '\x5f', '\xff', '\xe5', '\x3a', '\x68', '\x5d'}); - - ASSERT_NE (value.packRead (str), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - ASSERT_NE (value.packRead (str.c_str (), str.size ()), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - ASSERT_NE (value.packRead (str.data (), str.data () + str.size ()), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::stringstream sstream (str); - ASSERT_NE (value.packRead (sstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::istringstream isstream (str); - ASSERT_NE (value.packRead (isstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::ofstream out ("/tmp/fstream.pack", std::ios::binary); - out << str; - out.close (); - - std::fstream fstream ("/tmp/fstream.pack", std::ios::in | std::ios::binary); - ASSERT_NE (value.packRead (fstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - fstream.close (); - - std::ifstream ifstream ("/tmp/fstream.pack", std::ios::in | std::ios::binary); - ASSERT_NE (value.packRead (ifstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - ifstream.close (); - - std::stringbuf iosbuf (str, std::ios::in); - std::iostream iostream (&iosbuf); - ASSERT_NE (value.packRead (iostream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::stringbuf isbuf (str); - std::istream istream (&isbuf); - ASSERT_NE (value.packRead (istream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); -} - -/** - * @brief packWrite method. - */ -TEST (Value, packWrite) -{ - Value value; - value.pushBack (1); - value.pushBack (nullptr); - value.pushBack (true); - value.pushBack ("test"); - value.pushBack (1.23456789e-13); - - std::stringstream out; - ASSERT_NE (value.packWrite (out), -1) << join::lastError.message (); - EXPECT_EQ (out.str (), std::string ({'\x95', '\x01', '\xc0', '\xc3', '\xa4', '\x74', '\x65', '\x73', '\x74', '\xcb', - '\x3d', '\x41', '\x5f', '\xff', '\xe5', '\x3a', '\x68', '\x5d'})); -} - -/** - * @brief jsonRead method. - */ -TEST (Value, jsonRead) -{ - Value value; - - std::string str = "[1,null,true,\"test\",1.23456789e-13]"; - ASSERT_NE (value.jsonRead (str), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - ASSERT_NE (value.jsonRead (str.c_str (), str.size ()), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - ASSERT_NE (value.jsonRead (str.data (), str.data () + str.size ()), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::stringstream sstream (str); - ASSERT_NE (value.jsonRead (sstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::istringstream isstream (str); - ASSERT_NE (value.jsonRead (isstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::ofstream out ("/tmp/fstream.json"); - out << str; - out.close (); - - std::fstream fstream ("/tmp/fstream.json", std::ios::in); - ASSERT_NE (value.jsonRead (fstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - fstream.close (); - - std::ifstream ifstream ("/tmp/fstream.json"); - ASSERT_NE (value.jsonRead (ifstream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - ifstream.close (); - - std::stringbuf iosbuf (str, std::ios::in); - std::iostream iostream (&iosbuf); - ASSERT_NE (value.jsonRead (iostream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); - - std::stringbuf isbuf (str); - std::istream istream (&isbuf); - ASSERT_NE (value.jsonRead (istream), -1) << join::lastError.message (); - ASSERT_TRUE (value.isArray ()); - ASSERT_TRUE (value[0].isInt ()); - ASSERT_EQ (value[0], 1); - ASSERT_TRUE (value[1].isNull ()); - ASSERT_EQ (value[1], nullptr); - ASSERT_TRUE (value[2].isBool ()); - ASSERT_EQ (value[2], true); - ASSERT_TRUE (value[3].isString ()); - ASSERT_EQ (value[3], "test"); - ASSERT_TRUE (value[4].isDouble ()); - ASSERT_EQ (value[4], 1.23456789e-13); -} - -/** - * @brief jsonWrite method. - */ -TEST (Value, jsonWrite) -{ - Value value; - value.pushBack (1); - value.pushBack (nullptr); - value.pushBack (true); - value.pushBack ("test"); - value.pushBack (1.23456789e-13); - - std::stringstream out; - ASSERT_NE (value.jsonWrite (out), -1) << join::lastError.message (); - EXPECT_EQ (out.str (), "[1,null,true,\"test\",1.23456789e-13]"); -} - -/** - * @brief jsonCanonicalize method. - */ -TEST (Value, jsonCanonicalize) -{ - Value value; - value["numbers"] = Array{333333333.33333329, 1E30, 4.50, 2e-3, 0.000000000000000000000000001}; - value["string"] = "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"/"; - value["literals"] = Array{nullptr, true, false}; - - std::stringstream out; - ASSERT_NE (value.jsonCanonicalize (out), -1) << join::lastError.message (); - EXPECT_EQ (out.str (), - "{\"literals\":[null,true,false],\"numbers\":[333333333.3333333,1e+30,4.5,0.002,1e-27],\"string\":\"€$" - "\\u000f\\nA'B\\\"\\\\\\\\\\\"/\"}"); + ASSERT_TRUE (value.isNull ()); } /** @@ -5851,6 +5868,12 @@ TEST (Value, jsonCanonicalize) */ TEST (Value, equal) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -5868,8 +5891,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = bool (true); ASSERT_FALSE (value == nullptr); @@ -5886,8 +5909,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (value == nullptr); @@ -5904,8 +5927,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = uint32_t (std::numeric_limits::max ()); ASSERT_FALSE (value == nullptr); @@ -5922,8 +5945,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = int64_t (std::numeric_limits::min ()); ASSERT_FALSE (value == nullptr); @@ -5940,8 +5963,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = uint64_t (std::numeric_limits::max ()); ASSERT_FALSE (value == nullptr); @@ -5958,8 +5981,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_FALSE (value == nullptr); @@ -5976,8 +5999,8 @@ TEST (Value, equal) ASSERT_TRUE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); value = std::string ("foo"); ASSERT_FALSE (value == nullptr); @@ -5995,10 +6018,10 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_TRUE (value == "foo"); ASSERT_FALSE (value == "bar"); - ASSERT_FALSE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value == nullptr); ASSERT_FALSE (value == true); ASSERT_FALSE (value == false); @@ -6013,10 +6036,10 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_TRUE (value == Array{1}); - ASSERT_FALSE (value == Object ({{"i", 1}})); + ASSERT_TRUE (value == array.getArray ()); + ASSERT_FALSE (value == object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value == nullptr); ASSERT_FALSE (value == true); ASSERT_FALSE (value == false); @@ -6031,8 +6054,8 @@ TEST (Value, equal) ASSERT_FALSE (value == std::numeric_limits::min ()); ASSERT_FALSE (value == std::numeric_limits::max ()); ASSERT_FALSE (value == "foo"); - ASSERT_FALSE (value == Array{1}); - ASSERT_TRUE (value == Object ({{"i", 1}})); + ASSERT_FALSE (value == array.getArray ()); + ASSERT_TRUE (value == object.getObject ()); value = nullptr; ASSERT_TRUE (nullptr == value); @@ -6049,8 +6072,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = bool (true); ASSERT_FALSE (nullptr == value); @@ -6067,8 +6090,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (nullptr == value); @@ -6085,8 +6108,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = uint32_t (std::numeric_limits::max ()); ASSERT_FALSE (nullptr == value); @@ -6103,8 +6126,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = int64_t (std::numeric_limits::min ()); ASSERT_FALSE (nullptr == value); @@ -6121,8 +6144,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = uint64_t (std::numeric_limits::max ()); ASSERT_FALSE (nullptr == value); @@ -6139,8 +6162,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = double (std::numeric_limits::min ()); ASSERT_FALSE (nullptr == value); @@ -6157,8 +6180,8 @@ TEST (Value, equal) ASSERT_TRUE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); value = std::string ("foo"); ASSERT_FALSE (nullptr == value); @@ -6176,10 +6199,10 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_TRUE ("foo" == value); ASSERT_FALSE ("bar" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (nullptr == value); ASSERT_FALSE (true == value); ASSERT_FALSE (false == value); @@ -6194,10 +6217,10 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_TRUE (Array{1} == value); - ASSERT_FALSE (Object ({{"i", 1}}) == value); + ASSERT_TRUE (array.getArray () == value); + ASSERT_FALSE (object.getObject () == value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (nullptr == value); ASSERT_FALSE (true == value); ASSERT_FALSE (false == value); @@ -6212,8 +6235,8 @@ TEST (Value, equal) ASSERT_FALSE (std::numeric_limits::min () == value); ASSERT_FALSE (std::numeric_limits::max () == value); ASSERT_FALSE ("foo" == value); - ASSERT_FALSE (Array{1} == value); - ASSERT_TRUE (Object ({{"i", 1}}) == value); + ASSERT_FALSE (array.getArray () == value); + ASSERT_TRUE (object.getObject () == value); } /** @@ -6221,6 +6244,12 @@ TEST (Value, equal) */ TEST (Value, notEqual) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -6238,8 +6267,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = bool (true); ASSERT_TRUE (value != nullptr); @@ -6256,8 +6285,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (value != nullptr); @@ -6274,8 +6303,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = uint32_t (std::numeric_limits::max ()); ASSERT_TRUE (value != nullptr); @@ -6292,8 +6321,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = int64_t (std::numeric_limits::min ()); ASSERT_TRUE (value != nullptr); @@ -6310,8 +6339,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = uint64_t (std::numeric_limits::max ()); ASSERT_TRUE (value != nullptr); @@ -6328,8 +6357,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_TRUE (value != nullptr); @@ -6346,8 +6375,8 @@ TEST (Value, notEqual) ASSERT_FALSE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); value = std::string ("foo"); ASSERT_TRUE (value != nullptr); @@ -6364,10 +6393,10 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_FALSE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (value != nullptr); ASSERT_TRUE (value != true); ASSERT_TRUE (value != false); @@ -6382,10 +6411,10 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_FALSE (value != Array{1}); - ASSERT_TRUE (value != Object ({{"i", 1}})); + ASSERT_FALSE (value != array.getArray ()); + ASSERT_TRUE (value != object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (value != nullptr); ASSERT_TRUE (value != true); ASSERT_TRUE (value != false); @@ -6400,8 +6429,8 @@ TEST (Value, notEqual) ASSERT_TRUE (value != std::numeric_limits::min ()); ASSERT_TRUE (value != std::numeric_limits::max ()); ASSERT_TRUE (value != "foo"); - ASSERT_TRUE (value != Array{1}); - ASSERT_FALSE (value != Object ({{"i", 1}})); + ASSERT_TRUE (value != array.getArray ()); + ASSERT_FALSE (value != object.getObject ()); value = nullptr; ASSERT_FALSE (nullptr != value); @@ -6418,8 +6447,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = bool (true); ASSERT_TRUE (nullptr != value); @@ -6436,8 +6465,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (nullptr != value); @@ -6454,8 +6483,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = uint32_t (std::numeric_limits::max ()); ASSERT_TRUE (nullptr != value); @@ -6472,8 +6501,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = int64_t (std::numeric_limits::min ()); ASSERT_TRUE (nullptr != value); @@ -6490,8 +6519,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = uint64_t (std::numeric_limits::max ()); ASSERT_TRUE (nullptr != value); @@ -6508,8 +6537,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = double (std::numeric_limits::min ()); ASSERT_TRUE (nullptr != value); @@ -6526,8 +6555,8 @@ TEST (Value, notEqual) ASSERT_FALSE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); value = std::string ("foo"); ASSERT_TRUE (nullptr != value); @@ -6545,10 +6574,10 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_FALSE ("foo" != value); ASSERT_TRUE ("bar" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (nullptr != value); ASSERT_TRUE (true != value); ASSERT_TRUE (false != value); @@ -6563,10 +6592,10 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_FALSE (Array{1} != value); - ASSERT_TRUE (Object ({{"i", 1}}) != value); + ASSERT_FALSE (array.getArray () != value); + ASSERT_TRUE (object.getObject () != value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (nullptr != value); ASSERT_TRUE (true != value); ASSERT_TRUE (false != value); @@ -6581,8 +6610,8 @@ TEST (Value, notEqual) ASSERT_TRUE (std::numeric_limits::min () != value); ASSERT_TRUE (std::numeric_limits::max () != value); ASSERT_TRUE ("foo" != value); - ASSERT_TRUE (Array{1} != value); - ASSERT_FALSE (Object ({{"i", 1}}) != value); + ASSERT_TRUE (array.getArray () != value); + ASSERT_FALSE (object.getObject () != value); } /** @@ -6590,6 +6619,12 @@ TEST (Value, notEqual) */ TEST (Value, lower) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -6607,8 +6642,8 @@ TEST (Value, lower) ASSERT_TRUE (value < std::numeric_limits::min ()); ASSERT_TRUE (value < std::numeric_limits::max ()); ASSERT_TRUE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); value = bool (true); ASSERT_FALSE (value < nullptr); @@ -6625,8 +6660,8 @@ TEST (Value, lower) ASSERT_TRUE (value < std::numeric_limits::min ()); ASSERT_TRUE (value < std::numeric_limits::max ()); ASSERT_TRUE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (value < nullptr); @@ -6643,8 +6678,8 @@ TEST (Value, lower) ASSERT_TRUE (value < std::numeric_limits::min ()); ASSERT_TRUE (value < std::numeric_limits::max ()); ASSERT_TRUE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); value = int64_t (std::numeric_limits::max ()); ASSERT_FALSE (value < nullptr); @@ -6661,8 +6696,8 @@ TEST (Value, lower) ASSERT_FALSE (value < std::numeric_limits::min ()); ASSERT_TRUE (value < std::numeric_limits::max ()); ASSERT_TRUE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_FALSE (value < nullptr); @@ -6679,8 +6714,8 @@ TEST (Value, lower) ASSERT_FALSE (value < std::numeric_limits::min ()); ASSERT_TRUE (value < std::numeric_limits::max ()); ASSERT_TRUE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); value = std::string ("foo"); ASSERT_FALSE (value < nullptr); @@ -6697,10 +6732,10 @@ TEST (Value, lower) ASSERT_FALSE (value < std::numeric_limits::min ()); ASSERT_FALSE (value < std::numeric_limits::max ()); ASSERT_FALSE (value < "foo"); - ASSERT_TRUE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_TRUE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value < nullptr); ASSERT_FALSE (value < true); ASSERT_FALSE (value < false); @@ -6715,10 +6750,10 @@ TEST (Value, lower) ASSERT_FALSE (value < std::numeric_limits::min ()); ASSERT_FALSE (value < std::numeric_limits::max ()); ASSERT_FALSE (value < "foo"); - ASSERT_FALSE (value < Array{1}); - ASSERT_TRUE (value < Object ({{"i", 1}})); + ASSERT_FALSE (value < array.getArray ()); + ASSERT_TRUE (value < object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value < nullptr); ASSERT_FALSE (value < true); ASSERT_FALSE (value < false); @@ -6733,8 +6768,8 @@ TEST (Value, lower) ASSERT_FALSE (value < std::numeric_limits::min ()); ASSERT_FALSE (value < std::numeric_limits::max ()); ASSERT_FALSE (value < "foo"); - ASSERT_FALSE (value < Array{1}); - ASSERT_FALSE (value < Object ({{"i", 1}})); + ASSERT_FALSE (value < array.getArray ()); + ASSERT_FALSE (value < object.getObject ()); value = nullptr; ASSERT_FALSE (nullptr < value); @@ -6751,8 +6786,8 @@ TEST (Value, lower) ASSERT_FALSE (std::numeric_limits::min () < value); ASSERT_FALSE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); value = bool (true); ASSERT_TRUE (nullptr < value); @@ -6769,8 +6804,8 @@ TEST (Value, lower) ASSERT_FALSE (std::numeric_limits::min () < value); ASSERT_FALSE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (nullptr < value); @@ -6787,8 +6822,8 @@ TEST (Value, lower) ASSERT_FALSE (std::numeric_limits::min () < value); ASSERT_FALSE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); value = int64_t (std::numeric_limits::max ()); ASSERT_TRUE (nullptr < value); @@ -6805,8 +6840,8 @@ TEST (Value, lower) ASSERT_TRUE (std::numeric_limits::min () < value); ASSERT_FALSE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); value = double (std::numeric_limits::min ()); ASSERT_TRUE (nullptr < value); @@ -6823,8 +6858,8 @@ TEST (Value, lower) ASSERT_FALSE (std::numeric_limits::min () < value); ASSERT_FALSE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); value = std::string ("foo"); ASSERT_TRUE (nullptr < value); @@ -6841,10 +6876,10 @@ TEST (Value, lower) ASSERT_TRUE (std::numeric_limits::min () < value); ASSERT_TRUE (std::numeric_limits::max () < value); ASSERT_FALSE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (nullptr < value); ASSERT_TRUE (true < value); ASSERT_TRUE (false < value); @@ -6859,10 +6894,10 @@ TEST (Value, lower) ASSERT_TRUE (std::numeric_limits::min () < value); ASSERT_TRUE (std::numeric_limits::max () < value); ASSERT_TRUE ("foo" < value); - ASSERT_FALSE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_FALSE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (nullptr < value); ASSERT_TRUE (true < value); ASSERT_TRUE (false < value); @@ -6877,8 +6912,8 @@ TEST (Value, lower) ASSERT_TRUE (std::numeric_limits::min () < value); ASSERT_TRUE (std::numeric_limits::max () < value); ASSERT_TRUE ("foo" < value); - ASSERT_TRUE (Array{1} < value); - ASSERT_FALSE (Object ({{"i", 1}}) < value); + ASSERT_TRUE (array.getArray () < value); + ASSERT_FALSE (object.getObject () < value); } /** @@ -6886,6 +6921,12 @@ TEST (Value, lower) */ TEST (Value, greater) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -6903,8 +6944,8 @@ TEST (Value, greater) ASSERT_FALSE (value > std::numeric_limits::min ()); ASSERT_FALSE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = bool (true); ASSERT_TRUE (value > nullptr); @@ -6921,8 +6962,8 @@ TEST (Value, greater) ASSERT_FALSE (value > std::numeric_limits::min ()); ASSERT_FALSE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (value > nullptr); @@ -6939,8 +6980,8 @@ TEST (Value, greater) ASSERT_FALSE (value > std::numeric_limits::min ()); ASSERT_FALSE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = int64_t (std::numeric_limits::max ()); ASSERT_TRUE (value > nullptr); @@ -6957,8 +6998,8 @@ TEST (Value, greater) ASSERT_TRUE (value > std::numeric_limits::min ()); ASSERT_FALSE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_TRUE (value > nullptr); @@ -6975,8 +7016,8 @@ TEST (Value, greater) ASSERT_FALSE (value > std::numeric_limits::min ()); ASSERT_FALSE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = std::string ("foo"); ASSERT_TRUE (value > nullptr); @@ -6993,10 +7034,10 @@ TEST (Value, greater) ASSERT_TRUE (value > std::numeric_limits::min ()); ASSERT_TRUE (value > std::numeric_limits::max ()); ASSERT_FALSE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (value > nullptr); ASSERT_TRUE (value > true); ASSERT_TRUE (value > false); @@ -7011,10 +7052,10 @@ TEST (Value, greater) ASSERT_TRUE (value > std::numeric_limits::min ()); ASSERT_TRUE (value > std::numeric_limits::max ()); ASSERT_TRUE (value > "foo"); - ASSERT_FALSE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_FALSE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (value > nullptr); ASSERT_TRUE (value > true); ASSERT_TRUE (value > false); @@ -7029,8 +7070,8 @@ TEST (Value, greater) ASSERT_TRUE (value > std::numeric_limits::min ()); ASSERT_TRUE (value > std::numeric_limits::max ()); ASSERT_TRUE (value > "foo"); - ASSERT_TRUE (value > Array{1}); - ASSERT_FALSE (value > Object ({{"i", 1}})); + ASSERT_TRUE (value > array.getArray ()); + ASSERT_FALSE (value > object.getObject ()); value = nullptr; ASSERT_FALSE (nullptr > value); @@ -7047,8 +7088,8 @@ TEST (Value, greater) ASSERT_TRUE (std::numeric_limits::min () > value); ASSERT_TRUE (std::numeric_limits::max () > value); ASSERT_TRUE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); value = bool (true); ASSERT_FALSE (nullptr > value); @@ -7065,8 +7106,8 @@ TEST (Value, greater) ASSERT_TRUE (std::numeric_limits::min () > value); ASSERT_TRUE (std::numeric_limits::max () > value); ASSERT_TRUE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (nullptr > value); @@ -7083,8 +7124,8 @@ TEST (Value, greater) ASSERT_TRUE (std::numeric_limits::min () > value); ASSERT_TRUE (std::numeric_limits::max () > value); ASSERT_TRUE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); value = int64_t (std::numeric_limits::max ()); ASSERT_FALSE (nullptr > value); @@ -7101,8 +7142,8 @@ TEST (Value, greater) ASSERT_FALSE (std::numeric_limits::min () > value); ASSERT_TRUE (std::numeric_limits::max () > value); ASSERT_TRUE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); value = double (std::numeric_limits::min ()); ASSERT_FALSE (nullptr > value); @@ -7119,8 +7160,8 @@ TEST (Value, greater) ASSERT_FALSE (std::numeric_limits::min () > value); ASSERT_TRUE (std::numeric_limits::max () > value); ASSERT_TRUE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); value = std::string ("foo"); ASSERT_FALSE (nullptr > value); @@ -7137,10 +7178,10 @@ TEST (Value, greater) ASSERT_FALSE (std::numeric_limits::min () > value); ASSERT_FALSE (std::numeric_limits::max () > value); ASSERT_FALSE ("foo" > value); - ASSERT_TRUE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_TRUE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (nullptr > value); ASSERT_FALSE (true > value); ASSERT_FALSE (false > value); @@ -7155,10 +7196,10 @@ TEST (Value, greater) ASSERT_FALSE (std::numeric_limits::min () > value); ASSERT_FALSE (std::numeric_limits::max () > value); ASSERT_FALSE ("foo" > value); - ASSERT_FALSE (Array{1} > value); - ASSERT_TRUE (Object ({{"i", 1}}) > value); + ASSERT_FALSE (array.getArray () > value); + ASSERT_TRUE (object.getObject () > value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (nullptr > value); ASSERT_FALSE (true > value); ASSERT_FALSE (false > value); @@ -7173,8 +7214,8 @@ TEST (Value, greater) ASSERT_FALSE (std::numeric_limits::min () > value); ASSERT_FALSE (std::numeric_limits::max () > value); ASSERT_FALSE ("foo" > value); - ASSERT_FALSE (Array{1} > value); - ASSERT_FALSE (Object ({{"i", 1}}) > value); + ASSERT_FALSE (array.getArray () > value); + ASSERT_FALSE (object.getObject () > value); } /** @@ -7182,6 +7223,12 @@ TEST (Value, greater) */ TEST (Value, lowerOrEqual) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -7199,8 +7246,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = bool (true); ASSERT_FALSE (value <= nullptr); @@ -7217,8 +7264,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (value <= nullptr); @@ -7235,8 +7282,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = uint32_t (std::numeric_limits::max ()); ASSERT_FALSE (value <= nullptr); @@ -7253,8 +7300,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = int64_t (std::numeric_limits::min ()); ASSERT_FALSE (value <= nullptr); @@ -7271,8 +7318,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = uint64_t (std::numeric_limits::max ()); ASSERT_FALSE (value <= nullptr); @@ -7289,8 +7336,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_FALSE (value <= nullptr); @@ -7307,8 +7354,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (value <= std::numeric_limits::min ()); ASSERT_TRUE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = std::string ("foo"); ASSERT_FALSE (value <= nullptr); @@ -7325,10 +7372,10 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (value <= std::numeric_limits::min ()); ASSERT_FALSE (value <= std::numeric_limits::max ()); ASSERT_TRUE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (value <= nullptr); ASSERT_FALSE (value <= true); ASSERT_FALSE (value <= false); @@ -7343,10 +7390,10 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (value <= std::numeric_limits::min ()); ASSERT_FALSE (value <= std::numeric_limits::max ()); ASSERT_FALSE (value <= "foo"); - ASSERT_TRUE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_TRUE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (value <= nullptr); ASSERT_FALSE (value <= true); ASSERT_FALSE (value <= false); @@ -7361,8 +7408,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (value <= std::numeric_limits::min ()); ASSERT_FALSE (value <= std::numeric_limits::max ()); ASSERT_FALSE (value <= "foo"); - ASSERT_FALSE (value <= Array{1}); - ASSERT_TRUE (value <= Object ({{"i", 1}})); + ASSERT_FALSE (value <= array.getArray ()); + ASSERT_TRUE (value <= object.getObject ()); value = nullptr; ASSERT_TRUE (nullptr <= value); @@ -7380,8 +7427,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = bool (true); ASSERT_TRUE (nullptr <= value); @@ -7398,8 +7445,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (nullptr <= value); @@ -7416,8 +7463,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = uint32_t (std::numeric_limits::max ()); ASSERT_TRUE (nullptr <= value); @@ -7434,8 +7481,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = int64_t (std::numeric_limits::min ()); ASSERT_TRUE (nullptr <= value); @@ -7452,8 +7499,8 @@ TEST (Value, lowerOrEqual) ASSERT_FALSE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = uint64_t (std::numeric_limits::max ()); ASSERT_TRUE (nullptr <= value); @@ -7470,8 +7517,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = double (std::numeric_limits::min ()); ASSERT_TRUE (nullptr <= value); @@ -7488,8 +7535,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_FALSE (std::numeric_limits::max () <= value); ASSERT_FALSE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); value = std::string ("foo"); ASSERT_TRUE (nullptr <= value); @@ -7506,10 +7553,10 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_TRUE (std::numeric_limits::max () <= value); ASSERT_TRUE ("foo" <= value); - ASSERT_FALSE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_FALSE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (nullptr <= value); ASSERT_TRUE (true <= value); ASSERT_TRUE (false <= value); @@ -7524,10 +7571,10 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_TRUE (std::numeric_limits::max () <= value); ASSERT_TRUE ("foo" <= value); - ASSERT_TRUE (Array{1} <= value); - ASSERT_FALSE (Object ({{"i", 1}}) <= value); + ASSERT_TRUE (array.getArray () <= value); + ASSERT_FALSE (object.getObject () <= value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (nullptr <= value); ASSERT_TRUE (true <= value); ASSERT_TRUE (false <= value); @@ -7542,8 +7589,8 @@ TEST (Value, lowerOrEqual) ASSERT_TRUE (std::numeric_limits::min () <= value); ASSERT_TRUE (std::numeric_limits::max () <= value); ASSERT_TRUE ("foo" <= value); - ASSERT_TRUE (Array{1} <= value); - ASSERT_TRUE (Object ({{"i", 1}}) <= value); + ASSERT_TRUE (array.getArray () <= value); + ASSERT_TRUE (object.getObject () <= value); value = std::numeric_limits::quiet_NaN (); ASSERT_FALSE (value <= value); @@ -7555,6 +7602,12 @@ TEST (Value, lowerOrEqual) */ TEST (Value, greaterOrEqual) { + Value array; + array.pushBack (1); + + Value object; + object["i"] = 1; + Value value; value = nullptr; @@ -7572,8 +7625,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = bool (true); ASSERT_TRUE (value >= nullptr); @@ -7590,8 +7643,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = int32_t (std::numeric_limits::min ()); ASSERT_TRUE (value >= nullptr); @@ -7608,8 +7661,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = uint32_t (std::numeric_limits::max ()); ASSERT_TRUE (value >= nullptr); @@ -7626,8 +7679,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = int64_t (std::numeric_limits::min ()); ASSERT_TRUE (value >= nullptr); @@ -7644,8 +7697,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = uint64_t (std::numeric_limits::max ()); ASSERT_TRUE (value >= nullptr); @@ -7662,8 +7715,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = double (std::numeric_limits::min ()); ASSERT_TRUE (value >= nullptr); @@ -7680,8 +7733,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_FALSE (value >= std::numeric_limits::max ()); ASSERT_FALSE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); value = std::string ("foo"); ASSERT_TRUE (value >= nullptr); @@ -7698,10 +7751,10 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_TRUE (value >= std::numeric_limits::max ()); ASSERT_TRUE (value >= "foo"); - ASSERT_FALSE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_FALSE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); - value = Array{1}; + value = array.getArray (); ASSERT_TRUE (value >= nullptr); ASSERT_TRUE (value >= true); ASSERT_TRUE (value >= false); @@ -7716,10 +7769,10 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_TRUE (value >= std::numeric_limits::max ()); ASSERT_TRUE (value >= "foo"); - ASSERT_TRUE (value >= Array{1}); - ASSERT_FALSE (value >= Object ({{"i", 1}})); + ASSERT_TRUE (value >= array.getArray ()); + ASSERT_FALSE (value >= object.getObject ()); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_TRUE (value >= nullptr); ASSERT_TRUE (value >= true); ASSERT_TRUE (value >= false); @@ -7734,8 +7787,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (value >= std::numeric_limits::min ()); ASSERT_TRUE (value >= std::numeric_limits::max ()); ASSERT_TRUE (value >= "foo"); - ASSERT_TRUE (value >= Array{1}); - ASSERT_TRUE (value >= Object ({{"i", 1}})); + ASSERT_TRUE (value >= array.getArray ()); + ASSERT_TRUE (value >= object.getObject ()); value = nullptr; ASSERT_TRUE (nullptr >= value); @@ -7752,8 +7805,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = bool (true); ASSERT_FALSE (nullptr >= value); @@ -7770,8 +7823,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = int32_t (std::numeric_limits::min ()); ASSERT_FALSE (nullptr >= value); @@ -7788,8 +7841,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = uint32_t (std::numeric_limits::max ()); ASSERT_FALSE (nullptr >= value); @@ -7806,8 +7859,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = int64_t (std::numeric_limits::min ()); ASSERT_FALSE (nullptr >= value); @@ -7824,8 +7877,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = uint64_t (std::numeric_limits::max ()); ASSERT_FALSE (nullptr >= value); @@ -7842,8 +7895,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = double (std::numeric_limits::min ()); ASSERT_FALSE (nullptr >= value); @@ -7860,8 +7913,8 @@ TEST (Value, greaterOrEqual) ASSERT_TRUE (std::numeric_limits::min () >= value); ASSERT_TRUE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); value = std::string ("foo"); ASSERT_FALSE (nullptr >= value); @@ -7878,10 +7931,10 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (std::numeric_limits::min () >= value); ASSERT_FALSE (std::numeric_limits::max () >= value); ASSERT_TRUE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); - value = Array{1}; + value = array.getArray (); ASSERT_FALSE (nullptr >= value); ASSERT_FALSE (true >= value); ASSERT_FALSE (false >= value); @@ -7896,10 +7949,10 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (std::numeric_limits::min () >= value); ASSERT_FALSE (std::numeric_limits::max () >= value); ASSERT_FALSE ("foo" >= value); - ASSERT_TRUE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_TRUE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); - value = Object{{"i", 1}}; + value = object.getObject (); ASSERT_FALSE (nullptr >= value); ASSERT_FALSE (true >= value); ASSERT_FALSE (false >= value); @@ -7914,8 +7967,8 @@ TEST (Value, greaterOrEqual) ASSERT_FALSE (std::numeric_limits::min () >= value); ASSERT_FALSE (std::numeric_limits::max () >= value); ASSERT_FALSE ("foo" >= value); - ASSERT_FALSE (Array{1} >= value); - ASSERT_TRUE (Object ({{"i", 1}}) >= value); + ASSERT_FALSE (array.getArray () >= value); + ASSERT_TRUE (object.getObject () >= value); } /**