-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Closed as not planned
Labels
kind: bugstate: please discussplease discuss the issue or vote for your favorite optionplease discuss the issue or vote for your favorite optionstate: stalethe issue has not been updated in a while and will be closed automatically soon unless it is updatedthe issue has not been updated in a while and will be closed automatically soon unless it is updated
Description
Description
Converting from "value": true
or "value": false
behaves unexpectedly and differently for certain integer types.
I was expecting all conversions from a boolean true/false to integer value to fail, however it is stored as a 1 or 0.
Reproduction steps
Given:
template<typename T>
class Value {
public:
T value;
private:
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Value<T>, value);
};
This will result in a 1
in value
.
auto v = R"({
"value" : true
})"_json.get<Value<int>>();
Using uint64_t
will throw a type_error
.
auto v = R"({
"value" : true
})"_json.get<Value<uint64_t>>();
Expected vs. actual results
I expected all boolean to integer conversions to fail. Instead a true
-> 1
and false
-> 0
for certain integer values.
Various integer conversions - https://godbolt.org/z/7Wrh6EanW
The uint64_t
case is taking the path through get_arithmetic_value
template<typename BasicJsonType>
inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
{
get_arithmetic_value(j, val);
}
The int
case is taking the path through
struct from_json_fn
{
template<typename BasicJsonType, typename T>
auto operator()(const BasicJsonType& j, T&& val) const
noexcept(noexcept(from_json(j, std::forward<T>(val))))
-> decltype(from_json(j, std::forward<T>(val)))
{
return from_json(j, std::forward<T>(val));
}
};
// which calls
template < typename BasicJsonType, typename ArithmeticType,
enable_if_t <
std::is_arithmetic<ArithmeticType>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
!std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
int > = 0 >
inline void from_json(const BasicJsonType& j, ArithmeticType& val)
{
//...
case value_t::boolean:
{
val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
break;
}
//...
}
Minimal code example
https://godbolt.org/z/fs4frqz7G
#include <cassert>
#include <iostream>
#include <nlohmann/json.hpp>
template<typename T>
class Value {
public:
T value;
private:
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Value<T>, value);
};
int main() {
try {
std::cout << "uint64_t" << std::endl;
auto v = R"({
"value" : true
})"_json.get<Value<uint64_t>>();
assert(false);
} catch (const nlohmann::detail::type_error& e) {
std::cout << e.what() << std::endl;
std::cout << "ok - exception expected" << std::endl;
}
try {
std::cout << "int" << std::endl;
auto v = R"({
"value" : true
})"_json.get<Value<int>>();
assert(false);
} catch (const nlohmann::detail::type_error& e) {
std::cout << e.what() << std::endl;
std::cout << "ok - exception expected" << std::endl;
}
}
Error messages
No response
Compiler and operating system
Latest MSVC & Clang
Library version
3.11.3
Validation
- The bug also occurs if the latest version from the
develop
branch is used. - I can successfully compile and run the unit tests.
Metadata
Metadata
Assignees
Labels
kind: bugstate: please discussplease discuss the issue or vote for your favorite optionplease discuss the issue or vote for your favorite optionstate: stalethe issue has not been updated in a while and will be closed automatically soon unless it is updatedthe issue has not been updated in a while and will be closed automatically soon unless it is updated