/***************************************************************************** * * CLIPP - command line interfaces for modern C++ * * released under MIT license * * (c) 2017-2018 André Müller; foss@andremueller-online.de * *****************************************************************************/ #include #include "testing.h" //------------------------------------------------------------------- #if defined(_MSC_VER) #if _MSC_VER < 1800 namespace std { template bool isinf(const T &x) { return !_finite(x); } } #endif #endif //------------------------------------------------------------------- template::value, bool = std::is_floating_point::value> struct equals { static bool result(const T& a, const T&b) { return a == b; } }; template struct equals { static bool result(const T& a, const T&b) { #if defined(_MSC_VER) bool ainf = a == std::numeric_limits::infinity(); bool binf = b == std::numeric_limits::infinity(); if(ainf && binf) return true; if(ainf || binf) return false; #else if(std::isinf(a) && std::isinf(b)) return true; if(std::isinf(a) || std::isinf(b)) return false; #endif return a == b; } }; template struct equals { static bool result(const T& a, const T&b) { if(std::isinf(a) && std::isinf(b)) return true; if(std::isinf(a) || std::isinf(b)) return false; return std::abs(a-b) < T(1e-4); } }; //------------------------------------------------------------------- template void test(int lineNo, T x, const std::string& arg, T expected) { using namespace clipp; auto cli = group( value("", x) ); // std::cout << lineNo << " " << x << " '" << arg << "' " << expected; run_test({ __FILE__, lineNo }, {arg.c_str()}, cli, [&]{ // std::cout << " -> " << x << std::endl; return equals::result(x,expected); } ); } //------------------------------------------------------------------- template void test_conv(int lineNo) { test(lineNo, T(0), "0", T(0) ); test(lineNo, T(0), "1", T(1) ); test(lineNo, T(0), "2", T(2) ); test(lineNo, T(0), "66", T(66) ); test(lineNo, T(0), " 0 ", T(0) ); test(lineNo, T(0), " 1 ", T(1) ); test(lineNo, T(0), " 2 ", T(2) ); test(lineNo, T(0), " 66 ", T(66) ); constexpr auto maxv = std::numeric_limits::max(); test(lineNo, T(0), std::to_string(maxv), maxv); test(lineNo, T(0), " " + std::to_string(maxv) + " ", maxv); if(std::is_signed::value) { constexpr auto minv = std::numeric_limits::lowest(); test(lineNo, T(0), std::to_string(minv), minv); test(lineNo, T(0), " " + std::to_string(minv) + " ", minv); } else { test(lineNo, T(0), "-1", T(0) ); test(lineNo, T(0), " -1 ", T(0) ); } } //------------------------------------------------------------------- template sizeof(T))> struct test_clamp { static void in(int lineNo) { constexpr auto maxv = std::numeric_limits::max(); test(lineNo, T(0), std::to_string(maxv), maxv); test(lineNo, T(0), " " + std::to_string(maxv) + " ", maxv); test(lineNo, T(0), std::to_string(Wide(maxv)+1), maxv); test(lineNo, T(0), " " + std::to_string(Wide(maxv)+1) + " ", maxv); if(std::is_signed::value) { constexpr auto minv = std::numeric_limits::lowest(); test(lineNo, T(0), std::to_string(Wide(minv)-1), minv); test(lineNo, T(0), " " + std::to_string(Wide(minv)-1) + " ", minv); } } }; template struct test_clamp { static void in(int) {} }; //------------------------------------------------------------------- int main() { try { test(__LINE__, false, "", false); test(__LINE__, false, " ", true); test(__LINE__, false, "0", true); test(__LINE__, false, "1", true); test(__LINE__, false, "a", true); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test_conv( __LINE__ ); test(__LINE__, 0, "", 0); test(__LINE__, 0, " ", ' '); test(__LINE__, 0, "0", '0'); test(__LINE__, 0, "1", '1'); test(__LINE__, 0, "a", 'a'); test(__LINE__, 0, "11", 11); test(__LINE__, 0, "65", 65); test(__LINE__, 0, "127", 127); test(__LINE__, 0, "128", 127); test(__LINE__, 0, "-1", -1); test(__LINE__, 0, "-128", -128); test(__LINE__, 0, "-129", -128); test(__LINE__, "", "", ""); test(__LINE__, "", " ", " "); test(__LINE__, "", "0", "0"); test(__LINE__, "", "1", "1"); test(__LINE__, "", "a", "a"); test(__LINE__, "", "ab", "ab"); test(__LINE__, "", "abc", "abc"); using wide_ui_t = unsigned long long int; test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); using wide_i_t = long long int; test_clamp::in(__LINE__); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); test_clamp::in( __LINE__ ); } catch(std::exception& e) { std::cerr << e.what() << std::endl; return 1; } }