-
-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update Catch to 2.13.2 and nlohmann_json to 3.9.1
- Loading branch information
Showing
5 changed files
with
2,508 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#pragma once | ||
|
||
#include <cstdint> // uint8_t | ||
#include <tuple> // tie | ||
#include <utility> // move | ||
|
||
namespace nlohmann | ||
{ | ||
|
||
/*! | ||
@brief an internal type for a backed binary type | ||
This type extends the template parameter @a BinaryType provided to `basic_json` | ||
with a subtype used by BSON and MessagePack. This type exists so that the user | ||
does not have to specify a type themselves with a specific naming scheme in | ||
order to override the binary type. | ||
@tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by | ||
default) | ||
@since version 3.8.0 | ||
*/ | ||
template<typename BinaryType> | ||
class byte_container_with_subtype : public BinaryType | ||
{ | ||
public: | ||
/// the type of the underlying container | ||
using container_type = BinaryType; | ||
|
||
byte_container_with_subtype() noexcept(noexcept(container_type())) | ||
: container_type() | ||
{} | ||
|
||
byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) | ||
: container_type(b) | ||
{} | ||
|
||
byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) | ||
: container_type(std::move(b)) | ||
{} | ||
|
||
byte_container_with_subtype(const container_type& b, std::uint8_t subtype) noexcept(noexcept(container_type(b))) | ||
: container_type(b) | ||
, m_subtype(subtype) | ||
, m_has_subtype(true) | ||
{} | ||
|
||
byte_container_with_subtype(container_type&& b, std::uint8_t subtype) noexcept(noexcept(container_type(std::move(b)))) | ||
: container_type(std::move(b)) | ||
, m_subtype(subtype) | ||
, m_has_subtype(true) | ||
{} | ||
|
||
bool operator==(const byte_container_with_subtype& rhs) const | ||
{ | ||
return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) == | ||
std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype); | ||
} | ||
|
||
bool operator!=(const byte_container_with_subtype& rhs) const | ||
{ | ||
return !(rhs == *this); | ||
} | ||
|
||
/*! | ||
@brief sets the binary subtype | ||
Sets the binary subtype of the value, also flags a binary JSON value as | ||
having a subtype, which has implications for serialization. | ||
@complexity Constant. | ||
@exceptionsafety No-throw guarantee: this member function never throws | ||
exceptions. | ||
@sa @ref subtype() -- return the binary subtype | ||
@sa @ref clear_subtype() -- clears the binary subtype | ||
@sa @ref has_subtype() -- returns whether or not the binary value has a | ||
subtype | ||
@since version 3.8.0 | ||
*/ | ||
void set_subtype(std::uint8_t subtype) noexcept | ||
{ | ||
m_subtype = subtype; | ||
m_has_subtype = true; | ||
} | ||
|
||
/*! | ||
@brief return the binary subtype | ||
Returns the numerical subtype of the value if it has a subtype. If it does | ||
not have a subtype, this function will return size_t(-1) as a sentinel | ||
value. | ||
@return the numerical subtype of the binary value | ||
@complexity Constant. | ||
@exceptionsafety No-throw guarantee: this member function never throws | ||
exceptions. | ||
@sa @ref set_subtype() -- sets the binary subtype | ||
@sa @ref clear_subtype() -- clears the binary subtype | ||
@sa @ref has_subtype() -- returns whether or not the binary value has a | ||
subtype | ||
@since version 3.8.0 | ||
*/ | ||
constexpr std::uint8_t subtype() const noexcept | ||
{ | ||
return m_subtype; | ||
} | ||
|
||
/*! | ||
@brief return whether the value has a subtype | ||
@return whether the value has a subtype | ||
@complexity Constant. | ||
@exceptionsafety No-throw guarantee: this member function never throws | ||
exceptions. | ||
@sa @ref subtype() -- return the binary subtype | ||
@sa @ref set_subtype() -- sets the binary subtype | ||
@sa @ref clear_subtype() -- clears the binary subtype | ||
@since version 3.8.0 | ||
*/ | ||
constexpr bool has_subtype() const noexcept | ||
{ | ||
return m_has_subtype; | ||
} | ||
|
||
/*! | ||
@brief clears the binary subtype | ||
Clears the binary subtype and flags the value as not having a subtype, which | ||
has implications for serialization; for instance MessagePack will prefer the | ||
bin family over the ext family. | ||
@complexity Constant. | ||
@exceptionsafety No-throw guarantee: this member function never throws | ||
exceptions. | ||
@sa @ref subtype() -- return the binary subtype | ||
@sa @ref set_subtype() -- sets the binary subtype | ||
@sa @ref has_subtype() -- returns whether or not the binary value has a | ||
subtype | ||
@since version 3.8.0 | ||
*/ | ||
void clear_subtype() noexcept | ||
{ | ||
m_subtype = 0; | ||
m_has_subtype = false; | ||
} | ||
|
||
private: | ||
std::uint8_t m_subtype = 0; | ||
bool m_has_subtype = false; | ||
}; | ||
|
||
} // namespace nlohmann |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#pragma once | ||
|
||
#include <cstddef> // size_t, uint8_t | ||
#include <functional> // hash | ||
|
||
namespace nlohmann | ||
{ | ||
namespace detail | ||
{ | ||
|
||
// boost::hash_combine | ||
inline std::size_t combine(std::size_t seed, std::size_t h) noexcept | ||
{ | ||
seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); | ||
return seed; | ||
} | ||
|
||
/*! | ||
@brief hash a JSON value | ||
The hash function tries to rely on std::hash where possible. Furthermore, the | ||
type of the JSON value is taken into account to have different hash values for | ||
null, 0, 0U, and false, etc. | ||
@tparam BasicJsonType basic_json specialization | ||
@param j JSON value to hash | ||
@return hash value of j | ||
*/ | ||
template<typename BasicJsonType> | ||
std::size_t hash(const BasicJsonType& j) | ||
{ | ||
using string_t = typename BasicJsonType::string_t; | ||
using number_integer_t = typename BasicJsonType::number_integer_t; | ||
using number_unsigned_t = typename BasicJsonType::number_unsigned_t; | ||
using number_float_t = typename BasicJsonType::number_float_t; | ||
|
||
const auto type = static_cast<std::size_t>(j.type()); | ||
switch (j.type()) | ||
{ | ||
case BasicJsonType::value_t::null: | ||
case BasicJsonType::value_t::discarded: | ||
{ | ||
return combine(type, 0); | ||
} | ||
|
||
case BasicJsonType::value_t::object: | ||
{ | ||
auto seed = combine(type, j.size()); | ||
for (const auto& element : j.items()) | ||
{ | ||
const auto h = std::hash<string_t> {}(element.key()); | ||
seed = combine(seed, h); | ||
seed = combine(seed, hash(element.value())); | ||
} | ||
return seed; | ||
} | ||
|
||
case BasicJsonType::value_t::array: | ||
{ | ||
auto seed = combine(type, j.size()); | ||
for (const auto& element : j) | ||
{ | ||
seed = combine(seed, hash(element)); | ||
} | ||
return seed; | ||
} | ||
|
||
case BasicJsonType::value_t::string: | ||
{ | ||
const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>()); | ||
return combine(type, h); | ||
} | ||
|
||
case BasicJsonType::value_t::boolean: | ||
{ | ||
const auto h = std::hash<bool> {}(j.template get<bool>()); | ||
return combine(type, h); | ||
} | ||
|
||
case BasicJsonType::value_t::number_integer: | ||
{ | ||
const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>()); | ||
return combine(type, h); | ||
} | ||
|
||
case nlohmann::detail::value_t::number_unsigned: | ||
{ | ||
const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>()); | ||
return combine(type, h); | ||
} | ||
|
||
case nlohmann::detail::value_t::number_float: | ||
{ | ||
const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>()); | ||
return combine(type, h); | ||
} | ||
|
||
case nlohmann::detail::value_t::binary: | ||
{ | ||
auto seed = combine(type, j.get_binary().size()); | ||
const auto h = std::hash<bool> {}(j.get_binary().has_subtype()); | ||
seed = combine(seed, h); | ||
seed = combine(seed, j.get_binary().subtype()); | ||
for (const auto byte : j.get_binary()) | ||
{ | ||
seed = combine(seed, std::hash<std::uint8_t> {}(byte)); | ||
} | ||
return seed; | ||
} | ||
|
||
default: // LCOV_EXCL_LINE | ||
JSON_ASSERT(false); // LCOV_EXCL_LINE | ||
} | ||
} | ||
|
||
} // namespace detail | ||
} // namespace nlohmann |
Oops, something went wrong.