mirror of
https://github.com/red0124/ssp.git
synced 2025-12-16 06:39:55 +01:00
Add ss::uint8 and ss::int8, add unit tests for them
This commit is contained in:
@@ -2,6 +2,16 @@
|
||||
#include <algorithm>
|
||||
#include <ss/extract.hpp>
|
||||
|
||||
template <typename T>
|
||||
struct std::numeric_limits<ss::numeric_wrapper<T>>
|
||||
: public std::numeric_limits<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct std::is_signed<ss::numeric_wrapper<T>> : public std::is_signed<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct std::is_unsigned<ss::numeric_wrapper<T>> : public std::is_unsigned<T> {};
|
||||
|
||||
TEST_CASE("testing extract functions for floating point values") {
|
||||
CHECK_FLOATING_CONVERSION(123.456, float);
|
||||
CHECK_FLOATING_CONVERSION(123.456, double);
|
||||
@@ -22,18 +32,18 @@ TEST_CASE("testing extract functions for floating point values") {
|
||||
#define CHECK_DECIMAL_CONVERSION(input, type) \
|
||||
{ \
|
||||
std::string s = #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_EQ(t.value(), type(input)); \
|
||||
type value; \
|
||||
bool valid = ss::extract(s.c_str(), s.c_str() + s.size(), value); \
|
||||
REQUIRE(valid); \
|
||||
CHECK_EQ(value, type(input)); \
|
||||
} \
|
||||
{ \
|
||||
/* check negative too */ \
|
||||
if (std::is_signed_v<type>) { \
|
||||
auto s = std::string("-") + #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_EQ(t.value(), type(-input)); \
|
||||
} \
|
||||
/* check negative too */ \
|
||||
if (std::is_signed_v<type>) { \
|
||||
std::string s = std::string("-") + #input; \
|
||||
type value; \
|
||||
bool valid = ss::extract(s.c_str(), s.c_str() + s.size(), value); \
|
||||
REQUIRE(valid); \
|
||||
CHECK_EQ(value, type(-input)); \
|
||||
}
|
||||
|
||||
using us = unsigned short;
|
||||
@@ -43,6 +53,8 @@ using ll = long long;
|
||||
using ull = unsigned long long;
|
||||
|
||||
TEST_CASE("extract test functions for decimal values") {
|
||||
CHECK_DECIMAL_CONVERSION(12, ss::int8);
|
||||
CHECK_DECIMAL_CONVERSION(12, ss::uint8);
|
||||
CHECK_DECIMAL_CONVERSION(1234, short);
|
||||
CHECK_DECIMAL_CONVERSION(1234, us);
|
||||
CHECK_DECIMAL_CONVERSION(1234, int);
|
||||
@@ -54,6 +66,9 @@ TEST_CASE("extract test functions for decimal values") {
|
||||
}
|
||||
|
||||
TEST_CASE("extract test functions for numbers with invalid inputs") {
|
||||
// negative unsigned value for numeric_wrapper
|
||||
CHECK_INVALID_CONVERSION("-12", ss::uint8);
|
||||
|
||||
// negative unsigned value
|
||||
CHECK_INVALID_CONVERSION("-1234", ul);
|
||||
|
||||
@@ -70,46 +85,38 @@ TEST_CASE("extract test functions for numbers with invalid inputs") {
|
||||
CHECK_INVALID_CONVERSION("", int);
|
||||
}
|
||||
|
||||
#define CHECK_OUT_OF_RANGE_CONVERSION(type) \
|
||||
{ \
|
||||
std::string s = std::to_string(std::numeric_limits<type>::max()); \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK(t.has_value()); \
|
||||
for (auto& i : s) { \
|
||||
if (i != '9' && i != '.') { \
|
||||
i = '9'; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK_FALSE(t.has_value()); \
|
||||
} \
|
||||
{ \
|
||||
std::string s = std::to_string(std::numeric_limits<type>::min()); \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK(t.has_value()); \
|
||||
for (auto& i : s) { \
|
||||
if (std::is_signed_v<type> && i != '9' && i != '.') { \
|
||||
i = '9'; \
|
||||
break; \
|
||||
} else if (std::is_unsigned_v<type>) { \
|
||||
s = "-1"; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK_FALSE(t.has_value()); \
|
||||
TEST_CASE_TEMPLATE(
|
||||
"extract test functions for numbers with out of range inputs", T, short, us,
|
||||
int, ui, long, ul, ll, ull, ss::uint8) {
|
||||
{
|
||||
std::string s = std::to_string(std::numeric_limits<T>::max());
|
||||
auto t = ss::to_num<T>(s.c_str(), s.c_str() + s.size());
|
||||
CHECK(t.has_value());
|
||||
for (auto& i : s) {
|
||||
if (i != '9' && i != '.') {
|
||||
i = '9';
|
||||
break;
|
||||
}
|
||||
}
|
||||
t = ss::to_num<T>(s.c_str(), s.c_str() + s.size());
|
||||
CHECK_FALSE(t.has_value());
|
||||
}
|
||||
{
|
||||
std::string s = std::to_string(std::numeric_limits<T>::min());
|
||||
auto t = ss::to_num<T>(s.c_str(), s.c_str() + s.size());
|
||||
CHECK(t.has_value());
|
||||
for (auto& i : s) {
|
||||
if (std::is_signed_v<T> && i != '9' && i != '.') {
|
||||
i = '9';
|
||||
break;
|
||||
} else if (std::is_unsigned_v<T>) {
|
||||
s = "-1";
|
||||
break;
|
||||
}
|
||||
}
|
||||
t = ss::to_num<T>(s.c_str(), s.c_str() + s.size());
|
||||
CHECK_FALSE(t.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("extract test functions for numbers with out of range inputs") {
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(short);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(us);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(int);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(ui);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(long);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(ul);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(ll);
|
||||
CHECK_OUT_OF_RANGE_CONVERSION(ull);
|
||||
}
|
||||
|
||||
TEST_CASE("extract test functions for boolean values") {
|
||||
@@ -142,12 +149,12 @@ TEST_CASE("extract test functions for char values") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("extract test functions for std::optional") {
|
||||
for (const auto& [i, s] :
|
||||
{std::pair<std::optional<int>, std::string>{1, "1"},
|
||||
{69, "69"},
|
||||
{-4, "-4"}}) {
|
||||
std::optional<int> v;
|
||||
TEST_CASE_TEMPLATE("extract test functions for std::optional", T, int,
|
||||
ss::int8) {
|
||||
for (const auto& [i, s] : {std::pair<std::optional<T>, std::string>{1, "1"},
|
||||
{69, "69"},
|
||||
{-4, "-4"}}) {
|
||||
std::optional<T> v;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), v));
|
||||
REQUIRE(v.has_value());
|
||||
CHECK_EQ(*v, i);
|
||||
@@ -164,7 +171,7 @@ TEST_CASE("extract test functions for std::optional") {
|
||||
}
|
||||
|
||||
for (const std::string s : {"aa", "xxx", ""}) {
|
||||
std::optional<int> v;
|
||||
std::optional<T> v;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), v));
|
||||
CHECK_FALSE(v.has_value());
|
||||
}
|
||||
@@ -176,56 +183,57 @@ TEST_CASE("extract test functions for std::optional") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("extract test functions for std::variant") {
|
||||
TEST_CASE_TEMPLATE("extract test functions for std::variant", T, int,
|
||||
ss::uint8) {
|
||||
{
|
||||
std::string s = "22";
|
||||
{
|
||||
std::variant<int, double, std::string> var;
|
||||
std::variant<T, double, std::string> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
CHECK_NOT_VARIANT(var, std::string);
|
||||
REQUIRE_VARIANT(var, 22, int);
|
||||
REQUIRE_VARIANT(var, 22, T);
|
||||
}
|
||||
{
|
||||
std::variant<double, int, std::string> var;
|
||||
std::variant<double, T, std::string> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, std::string);
|
||||
REQUIRE_VARIANT(var, 22, double);
|
||||
}
|
||||
{
|
||||
std::variant<std::string, double, int> var;
|
||||
std::variant<std::string, double, T> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
REQUIRE_VARIANT(var, "22", std::string);
|
||||
}
|
||||
{
|
||||
std::variant<int> var;
|
||||
std::variant<T> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
REQUIRE_VARIANT(var, 22, int);
|
||||
REQUIRE_VARIANT(var, 22, T);
|
||||
}
|
||||
}
|
||||
{
|
||||
std::string s = "22.2";
|
||||
{
|
||||
std::variant<int, double, std::string> var;
|
||||
std::variant<T, double, std::string> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, std::string);
|
||||
REQUIRE_VARIANT(var, 22.2, double);
|
||||
}
|
||||
{
|
||||
std::variant<double, int, std::string> var;
|
||||
std::variant<double, T, std::string> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, std::string);
|
||||
REQUIRE_VARIANT(var, 22.2, double);
|
||||
}
|
||||
{
|
||||
std::variant<std::string, double, int> var;
|
||||
std::variant<std::string, double, T> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
REQUIRE_VARIANT(var, "22.2", std::string);
|
||||
}
|
||||
@@ -233,45 +241,45 @@ TEST_CASE("extract test functions for std::variant") {
|
||||
{
|
||||
std::string s = "2.2.2";
|
||||
{
|
||||
std::variant<int, double, std::string> var;
|
||||
std::variant<T, double, std::string> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
REQUIRE_VARIANT(var, "2.2.2", std::string);
|
||||
}
|
||||
{
|
||||
std::variant<double, std::string, int> var;
|
||||
std::variant<double, std::string, T> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
REQUIRE_VARIANT(var, "2.2.2", std::string);
|
||||
}
|
||||
{
|
||||
std::variant<std::string, double, int> var;
|
||||
std::variant<std::string, double, T> var;
|
||||
REQUIRE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
REQUIRE_VARIANT(var, "2.2.2", std::string);
|
||||
}
|
||||
{
|
||||
std::variant<int, double> var;
|
||||
std::variant<T, double> var;
|
||||
REQUIRE_FALSE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
|
||||
REQUIRE_VARIANT(var, int{}, int);
|
||||
REQUIRE_VARIANT(var, T{}, T);
|
||||
CHECK_NOT_VARIANT(var, double);
|
||||
}
|
||||
{
|
||||
std::variant<double, int> var;
|
||||
std::variant<double, T> var;
|
||||
REQUIRE_FALSE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
|
||||
REQUIRE_VARIANT(var, double{}, double);
|
||||
CHECK_NOT_VARIANT(var, int);
|
||||
CHECK_NOT_VARIANT(var, T);
|
||||
}
|
||||
{
|
||||
std::variant<int> var;
|
||||
std::variant<T> var;
|
||||
REQUIRE_FALSE(ss::extract(s.c_str(), s.c_str() + s.size(), var));
|
||||
|
||||
REQUIRE_VARIANT(var, int{}, int);
|
||||
REQUIRE_VARIANT(var, T{}, T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user