Allowing casts instead of get_double, get_uint64 and get_int64 (#1705)
This commit is contained in:
parent
4afe7565b4
commit
b935ce2e06
|
@ -1238,10 +1238,9 @@ instance. Upon success, it returns an `ondemand::number` instance.
|
||||||
An `ondemand::number` instance may contain an integer value or a floating-point value.
|
An `ondemand::number` instance may contain an integer value or a floating-point value.
|
||||||
Thus it is a dynamically typed number. Before accessing the value, you must determine the detected type:
|
Thus it is a dynamically typed number. Before accessing the value, you must determine the detected type:
|
||||||
|
|
||||||
* `number.get_number_type()` has value `number_type::signed_integer` if we have a integer in [-9223372036854775808,9223372036854775808). You can recover the value by the `get_int64()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::signed_integer`, you also have that `number.is_int64()` is true. Calling `get_int64()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::signed_integer` is unsafe.
|
* `number.get_number_type()` has value `number_type::signed_integer` if we have a integer in [-9223372036854775808,9223372036854775808). You can recover the value by the `get_int64()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::signed_integer`, you also have that `number.is_int64()` is true. Calling `get_int64()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::signed_integer` is unsafe. You may replace `get_int64()` by a cast to a `int64_t` value.
|
||||||
* `number.get_number_type()` has value `number_type::unsigned_integer` if we have a integer in [9223372036854775808,18446744073709551616). You can recover the value by the `get_uint64()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::unsigned_integer`, you also have that `number.is_uint64()` is true. Calling `get_uint64()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::unsigned_integer` is unsafe.
|
* `number.get_number_type()` has value `number_type::unsigned_integer` if we have a integer in [9223372036854775808,18446744073709551616). You can recover the value by the `get_uint64()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::unsigned_integer`, you also have that `number.is_uint64()` is true. Calling `get_uint64()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::unsigned_integer` is unsafe. You may replace `get_uint64()` by a cast to a `uint64_t` value.
|
||||||
* `number.get_number_type()` has value `number_type::unsigned_integer` if we have a integer in [9223372036854775808,18446744073709551616). You can recover the value by the `get_uint64()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::unsigned_integer`, you also have that `number.is_uint64()` is true. Calling `get_uint64()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::unsigned_integer` is unsafe.
|
* `number.get_number_type()` has value `number_type::floating_point_number` if we have and we have a floating-point (binary64) number. You can recover the value by the `get_double()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::floating_point_number`, you also have that `number.is_double()` is true. Calling `get_double()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::floating_point_number` is unsafe. You may replace `get_double()` by a cast to a `double` value.
|
||||||
* `number.get_number_type()` has value `number_type::floating_point_number` if we have and we have a floating-point (binary64) number. You can recover the value by the `get_double()` method applied on the `ondemand::number` instance. When `number.get_number_type()` has value `number_type::floating_point_number`, you also have that `number.is_double()` is true. Calling `get_double()` on the `ondemand::number` instance when `number.get_number_type()` is not `number_type::floating_point_number` is unsafe.
|
|
||||||
|
|
||||||
|
|
||||||
You must check the type before accessing the value: it is an error to call `get_int64()` when `number.get_number_type()` is not `number_type::signed_integer` and when `number.is_int64()` is false. You are responsible for this check as the user of the library.
|
You must check the type before accessing the value: it is an error to call `get_int64()` when `number.get_number_type()` is not `number_type::signed_integer` and when `number.is_int64()` is false. You are responsible for this check as the user of the library.
|
||||||
|
@ -1262,12 +1261,15 @@ Consider the following example:
|
||||||
ondemand::number_type t = num.get_number_type();
|
ondemand::number_type t = num.get_number_type();
|
||||||
switch(t) {
|
switch(t) {
|
||||||
case ondemand::number_type::signed_integer:
|
case ondemand::number_type::signed_integer:
|
||||||
|
std::cout << "integer: " << int64_t(num) << " ";
|
||||||
std::cout << "integer: " << num.get_int64() << std::endl;
|
std::cout << "integer: " << num.get_int64() << std::endl;
|
||||||
break;
|
break;
|
||||||
case ondemand::number_type::unsigned_integer:
|
case ondemand::number_type::unsigned_integer:
|
||||||
|
std::cout << "large 64-bit integer: " << uint64_t(num) << " ";
|
||||||
std::cout << "large 64-bit integer: " << num.get_uint64() << std::endl;
|
std::cout << "large 64-bit integer: " << num.get_uint64() << std::endl;
|
||||||
break;
|
break;
|
||||||
case ondemand::number_type::floating_point_number:
|
case ondemand::number_type::floating_point_number:
|
||||||
|
std::cout << "float: " << double(num) << " ";
|
||||||
std::cout << "float: " << num.get_double() << std::endl;
|
std::cout << "float: " << num.get_double() << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1277,12 +1279,12 @@ Consider the following example:
|
||||||
It will output:
|
It will output:
|
||||||
|
|
||||||
```
|
```
|
||||||
1.0 negative: 0 is_integer: 0 float: 1
|
1.0 negative: 0 is_integer: 0 float: 1 float: 1
|
||||||
3 negative: 0 is_integer: 1 integer: 3
|
3 negative: 0 is_integer: 1 integer: 3 integer: 3
|
||||||
1 negative: 0 is_integer: 1 integer: 1
|
1 negative: 0 is_integer: 1 integer: 1 integer: 1
|
||||||
3.1415 negative: 0 is_integer: 0 float: 3.1415
|
3.1415 negative: 0 is_integer: 0 float: 3.1415 float: 3.1415
|
||||||
-13231232 negative: 1 is_integer: 1 integer: -13231232
|
-13231232 negative: 1 is_integer: 1 integer: -13231232 integer: -13231232
|
||||||
9999999999999999999 negative: 0 is_integer: 1 large 64-bit integer: 9999999999999999999
|
9999999999999999999 negative: 0 is_integer: 1 large 64-bit integer: 9999999999999999999 large 64-bit integer: 9999999999999999999
|
||||||
```
|
```
|
||||||
|
|
||||||
Thread Safety
|
Thread Safety
|
||||||
|
|
|
@ -44,6 +44,10 @@ simdjson_really_inline uint64_t number::get_uint64() const noexcept {
|
||||||
return payload.unsigned_integer;
|
return payload.unsigned_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline number::operator uint64_t() const noexcept {
|
||||||
|
return get_uint64();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
simdjson_really_inline bool number::is_int64() const noexcept {
|
simdjson_really_inline bool number::is_int64() const noexcept {
|
||||||
return get_number_type() == number_type::signed_integer;
|
return get_number_type() == number_type::signed_integer;
|
||||||
|
@ -53,6 +57,10 @@ simdjson_really_inline int64_t number::get_int64() const noexcept {
|
||||||
return payload.signed_integer;
|
return payload.signed_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline number::operator int64_t() const noexcept {
|
||||||
|
return get_int64();
|
||||||
|
}
|
||||||
|
|
||||||
simdjson_really_inline bool number::is_double() const noexcept {
|
simdjson_really_inline bool number::is_double() const noexcept {
|
||||||
return get_number_type() == number_type::floating_point_number;
|
return get_number_type() == number_type::floating_point_number;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +69,10 @@ simdjson_really_inline double number::get_double() const noexcept {
|
||||||
return payload.floating_point_number;
|
return payload.floating_point_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline number::operator double() const noexcept {
|
||||||
|
return get_double();
|
||||||
|
}
|
||||||
|
|
||||||
simdjson_really_inline double number::as_double() const noexcept {
|
simdjson_really_inline double number::as_double() const noexcept {
|
||||||
if(is_double()) {
|
if(is_double()) {
|
||||||
return payload.floating_point_number;
|
return payload.floating_point_number;
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct number {
|
||||||
* return the value as a uint64_t, only valid if is_uint64() is true.
|
* return the value as a uint64_t, only valid if is_uint64() is true.
|
||||||
*/
|
*/
|
||||||
simdjson_really_inline uint64_t get_uint64() const noexcept;
|
simdjson_really_inline uint64_t get_uint64() const noexcept;
|
||||||
|
simdjson_really_inline operator uint64_t() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return true if the automatically determined type of
|
* return true if the automatically determined type of
|
||||||
|
@ -57,6 +58,7 @@ struct number {
|
||||||
* return the value as a int64_t, only valid if is_int64() is true.
|
* return the value as a int64_t, only valid if is_int64() is true.
|
||||||
*/
|
*/
|
||||||
simdjson_really_inline int64_t get_int64() const noexcept;
|
simdjson_really_inline int64_t get_int64() const noexcept;
|
||||||
|
simdjson_really_inline operator int64_t() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +70,8 @@ struct number {
|
||||||
* return the value as a double, only valid if is_double() is true.
|
* return the value as a double, only valid if is_double() is true.
|
||||||
*/
|
*/
|
||||||
simdjson_really_inline double get_double() const noexcept;
|
simdjson_really_inline double get_double() const noexcept;
|
||||||
|
simdjson_really_inline operator double() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the number to a double. Though it always succeed, the conversion
|
* Convert the number to a double. Though it always succeed, the conversion
|
||||||
* may be lossy if the number cannot be represented exactly.
|
* may be lossy if the number cannot be represented exactly.
|
||||||
|
@ -75,8 +79,6 @@ struct number {
|
||||||
simdjson_really_inline double as_double() const noexcept;
|
simdjson_really_inline double as_double() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* The next block of declaration is designed so that we can call the number parsing
|
* The next block of declaration is designed so that we can call the number parsing
|
||||||
|
|
|
@ -237,16 +237,22 @@ namespace number_tests {
|
||||||
}
|
}
|
||||||
if(counter == 0) {
|
if(counter == 0) {
|
||||||
ASSERT_EQUAL(num.get_double(), 1.0);
|
ASSERT_EQUAL(num.get_double(), 1.0);
|
||||||
|
ASSERT_EQUAL((double)num, 1.0);
|
||||||
} else if(counter == 1) {
|
} else if(counter == 1) {
|
||||||
ASSERT_EQUAL(num.get_int64(), 3);
|
ASSERT_EQUAL(num.get_int64(), 3);
|
||||||
|
ASSERT_EQUAL((int64_t)num, 3);
|
||||||
} else if(counter == 2) {
|
} else if(counter == 2) {
|
||||||
ASSERT_EQUAL(num.get_int64(), 1);
|
ASSERT_EQUAL(num.get_int64(), 1);
|
||||||
|
ASSERT_EQUAL((int64_t)num, 1);
|
||||||
} else if(counter == 3) {
|
} else if(counter == 3) {
|
||||||
ASSERT_EQUAL(num.get_double(), 3.1415);
|
ASSERT_EQUAL(num.get_double(), 3.1415);
|
||||||
|
ASSERT_EQUAL((double)num, 3.1415);
|
||||||
} else if(counter == 4) {
|
} else if(counter == 4) {
|
||||||
ASSERT_EQUAL(num.get_int64(), -13231232);
|
ASSERT_EQUAL(num.get_int64(), -13231232);
|
||||||
|
ASSERT_EQUAL((int64_t)num, -13231232);
|
||||||
} else if(counter == 5) {
|
} else if(counter == 5) {
|
||||||
ASSERT_EQUAL(num.get_uint64(), UINT64_C(9999999999999999999));
|
ASSERT_EQUAL(num.get_uint64(), UINT64_C(9999999999999999999));
|
||||||
|
ASSERT_EQUAL((uint64_t)num, UINT64_C(9999999999999999999));
|
||||||
}
|
}
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,15 @@ using error_code=simdjson::error_code;
|
||||||
ondemand::number_type t = num.get_number_type();
|
ondemand::number_type t = num.get_number_type();
|
||||||
switch(t) {
|
switch(t) {
|
||||||
case ondemand::number_type::signed_integer:
|
case ondemand::number_type::signed_integer:
|
||||||
|
std::cout << "integer: " << int64_t(num) << " ";
|
||||||
std::cout << "integer: " << num.get_int64() << std::endl;
|
std::cout << "integer: " << num.get_int64() << std::endl;
|
||||||
break;
|
break;
|
||||||
case ondemand::number_type::unsigned_integer:
|
case ondemand::number_type::unsigned_integer:
|
||||||
|
std::cout << "large 64-bit integer: " << uint64_t(num) << " ";
|
||||||
std::cout << "large 64-bit integer: " << num.get_uint64() << std::endl;
|
std::cout << "large 64-bit integer: " << num.get_uint64() << std::endl;
|
||||||
break;
|
break;
|
||||||
case ondemand::number_type::floating_point_number:
|
case ondemand::number_type::floating_point_number:
|
||||||
|
std::cout << "float: " << double(num) << " ";
|
||||||
std::cout << "float: " << num.get_double() << std::endl;
|
std::cout << "float: " << num.get_double() << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue