mirror of
https://github.com/red0124/ssp.git
synced 2025-12-14 21:59:55 +01:00
Merge with master
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef CMAKE_GITHUB_CI
|
||||
#include <doctest/doctest.h>
|
||||
@@ -10,74 +9,56 @@
|
||||
#endif
|
||||
|
||||
struct buffer {
|
||||
char* data_{nullptr};
|
||||
std::string data_;
|
||||
|
||||
char* operator()(const char* data) {
|
||||
if (data_) {
|
||||
delete[] data_;
|
||||
}
|
||||
data_ = new char[strlen(data) + 1];
|
||||
strcpy(data_, data);
|
||||
return data_;
|
||||
}
|
||||
char *operator()(const std::string &data) {
|
||||
data_ = data;
|
||||
return data_.data();
|
||||
}
|
||||
|
||||
char* append(const char* data) {
|
||||
if (data_) {
|
||||
char* new_data_ = new char[strlen(data_) + strlen(data) + 1];
|
||||
strcpy(new_data_, data_);
|
||||
strcat(new_data_, data);
|
||||
delete[] data_;
|
||||
data_ = new_data_;
|
||||
return data_;
|
||||
} else {
|
||||
return operator()(data);
|
||||
}
|
||||
}
|
||||
char *append(const std::string &data) {
|
||||
data_ += data;
|
||||
return data_.data();
|
||||
}
|
||||
|
||||
char* append_overwrite_last(const char* data, size_t size) {
|
||||
data_[strlen(data_) - size] = '\0';
|
||||
return append(data);
|
||||
}
|
||||
|
||||
~buffer() {
|
||||
if (data_) {
|
||||
delete[] data_;
|
||||
}
|
||||
}
|
||||
char *append_overwrite_last(const std::string &data, size_t size) {
|
||||
data_.resize(data_.size() - size);
|
||||
return append(data);
|
||||
}
|
||||
};
|
||||
|
||||
[[maybe_unused]] inline buffer buff;
|
||||
|
||||
#define CHECK_FLOATING_CONVERSION(input, type) \
|
||||
{ \
|
||||
auto eps = std::numeric_limits<type>::min(); \
|
||||
std::string s = #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_LT(std::abs(t.value() - type(input)), eps); \
|
||||
} \
|
||||
{ \
|
||||
/* check negative too */ \
|
||||
auto eps = std::numeric_limits<type>::min(); \
|
||||
auto s = std::string("-") + #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_LT(std::abs(t.value() - type(-input)), eps); \
|
||||
}
|
||||
{ \
|
||||
auto eps = std::numeric_limits<type>::min(); \
|
||||
std::string s = #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_LT(std::abs(t.value() - type(input)), eps); \
|
||||
} \
|
||||
{ \
|
||||
/* check negative too */ \
|
||||
auto eps = std::numeric_limits<type>::min(); \
|
||||
auto s = std::string("-") + #input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
REQUIRE(t.has_value()); \
|
||||
CHECK_LT(std::abs(t.value() - type(-input)), eps); \
|
||||
}
|
||||
|
||||
#define CHECK_INVALID_CONVERSION(input, type) \
|
||||
{ \
|
||||
std::string s = input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK_FALSE(t.has_value()); \
|
||||
}
|
||||
{ \
|
||||
std::string s = input; \
|
||||
auto t = ss::to_num<type>(s.c_str(), s.c_str() + s.size()); \
|
||||
CHECK_FALSE(t.has_value()); \
|
||||
}
|
||||
|
||||
#define REQUIRE_VARIANT(var, el, type) \
|
||||
{ \
|
||||
auto ptr = std::get_if<type>(&var); \
|
||||
REQUIRE(ptr); \
|
||||
REQUIRE_EQ(el, *ptr); \
|
||||
}
|
||||
{ \
|
||||
auto ptr = std::get_if<type>(&var); \
|
||||
REQUIRE(ptr); \
|
||||
REQUIRE_EQ(el, *ptr); \
|
||||
}
|
||||
|
||||
#define CHECK_NOT_VARIANT(var, type) CHECK(!std::holds_alternative<type>(var));
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ TEST_CASE("parser test various cases") {
|
||||
}
|
||||
|
||||
std::copy_if(data.begin(), data.end(), expected.begin(),
|
||||
[](const X& x) { return x.i != excluded; });
|
||||
[&](const X& x) { return x.i != excluded; });
|
||||
CHECK_EQ(i, expected);
|
||||
CHECK_EQ(i2, expected);
|
||||
}
|
||||
@@ -383,7 +383,7 @@ TEST_CASE("parser test composite conversion") {
|
||||
p.try_next<int, int, double>(fail)
|
||||
.or_else<test_struct>(fail)
|
||||
.or_else<int, char, double>(
|
||||
[](auto&& data) { CHECK_EQ(data, expectedData); })
|
||||
[&](auto&& data) { CHECK_EQ(data, expectedData); })
|
||||
.on_error(fail)
|
||||
.or_else<test_tuple>(fail)
|
||||
.values();
|
||||
@@ -401,7 +401,7 @@ TEST_CASE("parser test composite conversion") {
|
||||
constexpr static auto expectedData = std::tuple{10, 20, 11.1};
|
||||
|
||||
auto [d1, d2, d3, d4] =
|
||||
p.try_next<int, int, double>([](auto& i1, auto i2, double d) {
|
||||
p.try_next<int, int, double>([&](auto& i1, auto i2, double d) {
|
||||
CHECK_EQ(std::tie(i1, i2, d), expectedData);
|
||||
})
|
||||
.on_error(fail)
|
||||
@@ -569,8 +569,6 @@ TEST_CASE("parser test composite conversion") {
|
||||
CHECK(p.eof());
|
||||
}
|
||||
|
||||
size_t move_called = 0;
|
||||
|
||||
struct my_string {
|
||||
char* data{nullptr};
|
||||
|
||||
@@ -585,12 +583,10 @@ struct my_string {
|
||||
my_string& operator=(const my_string&) = delete;
|
||||
|
||||
my_string(my_string&& other) : data{other.data} {
|
||||
move_called++;
|
||||
other.data = nullptr;
|
||||
}
|
||||
|
||||
my_string& operator=(my_string&& other) {
|
||||
move_called++;
|
||||
data = other.data;
|
||||
return *this;
|
||||
}
|
||||
@@ -614,49 +610,6 @@ struct xyz {
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("parser test the moving of parsed values") {
|
||||
{
|
||||
unique_file_name f;
|
||||
{
|
||||
std::ofstream out{f.name};
|
||||
out << "x" << std::endl;
|
||||
}
|
||||
|
||||
ss::parser p{f.name, ","};
|
||||
auto x = p.get_next<my_string>();
|
||||
CHECK_LE(move_called, 1);
|
||||
move_called = 0;
|
||||
}
|
||||
|
||||
unique_file_name f;
|
||||
{
|
||||
std::ofstream out{f.name};
|
||||
out << "a,b,c" << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
ss::parser p{f.name, ","};
|
||||
auto x = p.get_next<my_string, my_string, my_string>();
|
||||
CHECK_LE(move_called, 3);
|
||||
move_called = 0;
|
||||
}
|
||||
|
||||
{
|
||||
ss::parser p{f.name, ","};
|
||||
auto x = p.get_object<xyz, my_string, my_string, my_string>();
|
||||
CHECK_LE(move_called, 6);
|
||||
move_called = 0;
|
||||
}
|
||||
|
||||
{
|
||||
ss::parser p{f.name, ","};
|
||||
auto x = p.get_next<xyz>();
|
||||
CHECK_LE(move_called, 6);
|
||||
move_called = 0;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("parser test the moving of parsed composite values") {
|
||||
// to compile is enough
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user