#pragma once #include #include #include #ifdef CMAKE_GITHUB_CI #include #else #include #endif struct buffer { char* data_{nullptr}; char* operator()(const char* data) { if (data_) { delete[] data_; } data_ = new char[strlen(data) + 1]; strcpy(data_, data); return 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_overwrite_last(const char* data, size_t size) { data_[strlen(data_) - size] = '\0'; return append(data); } ~buffer() { if (data_) { delete[] data_; } } }; [[maybe_unused]] inline buffer buff; #define CHECK_FLOATING_CONVERSION(input, type) \ { \ auto eps = std::numeric_limits::min(); \ std::string s = #input; \ auto t = ss::to_num(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::min(); \ auto s = std::string("-") + #input; \ auto t = ss::to_num(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(s.c_str(), s.c_str() + s.size()); \ CHECK_FALSE(t.has_value()); \ } #define REQUIRE_VARIANT(var, el, type) \ { \ auto ptr = std::get_if(&var); \ REQUIRE(ptr); \ REQUIRE_EQ(el, *ptr); \ } #define CHECK_NOT_VARIANT(var, type) CHECK(!std::holds_alternative(var)); #define REQUIRE_EXCEPTION(...) \ try { \ __VA_ARGS__; \ FAIL("Expected exception"); \ } catch (ss::exception & e) { \ CHECK_FALSE(std::string{e.what()}.empty()); \ } template std::vector> vector_combinations( const std::vector& v, size_t n) { std::vector> ret; if (n <= 1) { for (const auto& i : v) { ret.push_back({i}); } return ret; } auto inner_combinations = vector_combinations(v, n - 1); for (const auto& i : v) { for (auto j : inner_combinations) { j.insert(j.begin(), i); ret.push_back(move(j)); } } return ret; }