diff --git a/CMakeLists.txt b/CMakeLists.txt index 68a3f663..c0c87c1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,7 +133,7 @@ if (USE_DATE_POLYFILL) endif() if(USE_LARGE_INT_PLACEHOLDERS) - + message(STATUS "Using large int placeholders") add_compile_definitions(SPARROW_USE_LARGE_INT_PLACEHOLDERS) endif() diff --git a/include/sparrow/types/data_type.hpp b/include/sparrow/types/data_type.hpp index 00fd1903..f17520ba 100644 --- a/include/sparrow/types/data_type.hpp +++ b/include/sparrow/types/data_type.hpp @@ -764,8 +764,14 @@ namespace std return "Sparse union"; case RUN_ENCODED: return "Run encoded"; - case DECIMAL: - return "Decimal"; + case DECIMAL32: + return "Decimal32"; + case DECIMAL64: + return "Decimal64"; + case DECIMAL128: + return "Decimal128"; + case DECIMAL256: + return "Decimal256"; case FIXED_WIDTH_BINARY: return "Fixed width binary"; case STRING_VIEW: diff --git a/include/sparrow/utils/decimal.hpp b/include/sparrow/utils/decimal.hpp index 020b8ee5..38852b92 100644 --- a/include/sparrow/utils/decimal.hpp +++ b/include/sparrow/utils/decimal.hpp @@ -5,6 +5,10 @@ #include #include +#if defined(__cpp_lib_format) +# include +#endif + #include "sparrow/utils/large_int.hpp" #include "sparrow/utils/mp_utils.hpp" @@ -187,4 +191,18 @@ namespace sparrow } } -} // namespace sparrow \ No newline at end of file +} // namespace sparrow + +template +struct std::formatter> +{ + constexpr auto parse(std::format_parse_context& ctx) + { + return ctx.begin(); + } + + auto format(const sparrow::decimal& d, std::format_context& ctx) const + { + return std::format_to(ctx.out(), "Decimal({}, {})", d.storage(), d.scale()); + } +}; diff --git a/include/sparrow/utils/format.hpp b/include/sparrow/utils/format.hpp index b1458ecc..51e52346 100644 --- a/include/sparrow/utils/format.hpp +++ b/include/sparrow/utils/format.hpp @@ -158,7 +158,7 @@ namespace sparrow # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wsign-conversion" #endif - widths[i] = std::max(widths[i], static_cast +#endif + #ifndef SPARROW_USE_LARGE_INT_PLACEHOLDERS // disabe warnings -Wold-style-cast sign-conversion for clang and gcc -#if defined(__clang__) || defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#endif -#include -#include - -#if defined(__clang__) || defined(__GNUC__) -#pragma GCC diagnostic pop -#endif +# if defined(__clang__) || defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wold-style-cast" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# pragma GCC diagnostic ignored "-Wshadow" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# endif +# include +# include + +# if defined(__clang__) || defined(__GNUC__) +# pragma GCC diagnostic pop +# endif #endif @@ -23,52 +41,55 @@ namespace sparrow { - - - #ifdef SPARROW_USE_LARGE_INT_PLACEHOLDERS +#ifdef SPARROW_USE_LARGE_INT_PLACEHOLDERS constexpr bool large_int_placeholders = true; - struct int128_t { int128_t() = default; std::uint64_t words[2]; - bool operator == (const int128_t& other) const + + bool operator==(const int128_t& other) const { return words[0] == other.words[0] && words[1] == other.words[1]; } - bool operator != (const int128_t& other) const + + bool operator!=(const int128_t& other) const { return !(*this == other); } }; + struct int256_t { int256_t() = default; std::uint64_t words[4]; - bool operator == (const int256_t& other) const + + bool operator==(const int256_t& other) const { - return words[0] == other.words[0] && words[1] == other.words[1] && words[2] == other.words[2] && words[3] == other.words[3]; + return words[0] == other.words[0] && words[1] == other.words[1] && words[2] == other.words[2] + && words[3] == other.words[3]; } - bool operator != (const int256_t& other) const + + bool operator!=(const int256_t& other) const { return !(*this == other); } }; - template + template constexpr bool is_int_placeholder_v = std::is_same_v || std::is_same_v; - #else - - template +#else + + template constexpr bool is_int_placeholder_v = false; constexpr bool large_int_placeholders = false; using int128_t = primesum::int128_t; using int256_t = primesum::int256_t; - template - requires (std::is_same_v || std::is_same_v) + template + requires(std::is_same_v || std::is_same_v) inline std::ostream& operator<<(std::ostream& stream, T n) { std::string str; @@ -93,5 +114,37 @@ namespace sparrow return stream; } - #endif -} // namespace sparrow \ No newline at end of file +#endif +} // namespace sparrow + +#if defined(__cpp_lib_format) && defined(SPARROW_USE_LARGE_INT_PLACEHOLDERS) + +template <> +struct std::formatter +{ + constexpr auto parse(std::format_parse_context& ctx) + { + return ctx.begin(); // Simple implementation + } + + auto format(const sparrow::int128_t& n, std::format_context& ctx) const + { + return std::format_to(ctx.out(), "{}", n); + } +}; + +template <> +struct std::formatter +{ + constexpr auto parse(std::format_parse_context& ctx) + { + return ctx.begin(); // Simple implementation + } + + auto format(const sparrow::int256_t& n, std::format_context& ctx) const + { + return std::format_to(ctx.out(), "{}", n); + } +}; + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1493f56f..1ba6dfcf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -228,3 +228,4 @@ add_custom_target(run_tests_with_junit_report ) set_target_properties(run_tests_with_junit_report PROPERTIES FOLDER "Tests utilities") + \ No newline at end of file diff --git a/test/test_decimal.cpp b/test/test_decimal.cpp index e12bc685..90d3dd81 100644 --- a/test/test_decimal.cpp +++ b/test/test_decimal.cpp @@ -12,21 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "doctest/doctest.h" - -#include -#include #include +#include #include +#include -#include #include +#include + +#include "doctest/doctest.h" + // ignore -Wdouble-promotion #ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdouble-promotion" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -34,13 +35,14 @@ namespace sparrow { using testing_types = std::tuple< - int32_t - ,int64_t - #ifndef SPARROW_USE_LARGE_INT_PLACEHOLDERS - ,int128_t - ,int256_t - #endif - >; + int32_t, + int64_t +#ifndef SPARROW_USE_LARGE_INT_PLACEHOLDERS + , + int128_t, + int256_t +#endif + >; TEST_SUITE("decimals") @@ -56,18 +58,18 @@ namespace sparrow decimal_type d; auto storage = d.storage(); CHECK_EQ(static_cast(storage), 0); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); // cast to double: CHECK_EQ(as_float, doctest::Approx(0.0)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(0.0)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "0"); } @@ -76,17 +78,17 @@ namespace sparrow decimal_type d(42, 0); auto storage = d.storage(); CHECK_EQ(static_cast(storage), 42); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); CHECK_EQ(as_float, doctest::Approx(42.0)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(42.0)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "42"); } @@ -97,17 +99,17 @@ namespace sparrow decimal_type d(42, 1); auto storage = d.storage(); CHECK_EQ(static_cast(storage), 42); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); CHECK_EQ(as_float, doctest::Approx(4.2)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(4.20)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "4.2"); } SUBCASE("neg") @@ -115,17 +117,17 @@ namespace sparrow decimal_type d(-42, 1); auto storage = d.storage(); CHECK_EQ(static_cast(storage), -42); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); CHECK_EQ(as_float, doctest::Approx(-4.2)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(-4.20)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "-4.2"); } } @@ -136,17 +138,17 @@ namespace sparrow decimal_type d(42, -1); auto storage = d.storage(); CHECK_EQ(static_cast(storage), 42); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); CHECK_EQ(as_float, doctest::Approx(420.0)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(420.0)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "420"); } SUBCASE("neg") @@ -154,42 +156,48 @@ namespace sparrow decimal_type d(-42, -1); auto storage = d.storage(); CHECK_EQ(static_cast(storage), -42); - + // float - auto as_float = static_cast(d); + auto as_float = static_cast(d); CHECK_EQ(as_float, doctest::Approx(-420.0)); // double - auto as_double = static_cast(d); + auto as_double = static_cast(d); CHECK_EQ(as_double, doctest::Approx(-420.0)); // string - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, "-420"); } } SUBCASE("generic") { - std::vector values = {-123,-122, -111, -100, -99, 10, 11, 100, 101, 110, 111, 122, 123}; - std::vector scales = {-3, -2, -1, 0, 1, 2, -4}; + std::vector values = {-123, -122, -111, -100, -99, 10, 11, 100, 101, 110, 111, 122, 123}; + std::vector scales = {-3, -2, -1, 0, 1, 2, -4}; // cross product - for(auto value : values) + for (auto value : values) { - for(auto scale : scales) + for (auto scale : scales) { decimal_type d(value, scale); auto storage = d.storage(); CHECK_EQ(static_cast(storage), value); - + // float - auto as_float = static_cast(d); - CHECK_EQ(as_float, doctest::Approx(static_cast(value) / static_cast(std::pow(10, scale)))); + auto as_float = static_cast(d); + CHECK_EQ( + as_float, + doctest::Approx(static_cast(value) / static_cast(std::pow(10, scale))) + ); // double - auto as_double = static_cast(d); - CHECK_EQ(as_double, doctest::Approx(static_cast(value) / static_cast(std::pow(10, scale)))); + auto as_double = static_cast(d); + CHECK_EQ( + as_double, + doctest::Approx(static_cast(value) / static_cast(std::pow(10, scale))) + ); } } } @@ -215,7 +223,7 @@ namespace sparrow {decimal_type(-1, 3), "-0.001"}, {decimal_type(-1, -1), "-10"}, {decimal_type(-1, -2), "-100"}, - {decimal_type(-1, -3), "-1000"}, + {decimal_type(-1, -3), "-1000"}, {decimal_type(123456789, 0), "123456789"}, {decimal_type(123456789, 1), "12345678.9"}, {decimal_type(123456789, 2), "1234567.89"}, @@ -260,18 +268,17 @@ namespace sparrow {decimal_type(-123456789, 20), "-0.00000000000123456789"}, }; - for(auto [d, expected] : data) + for (const auto& [d, expected] : data) { - auto as_string = std::string(d); + auto as_string = std::string(d); CHECK_EQ(as_string, expected); } } - } TEST_CASE_TEMPLATE_APPLY(decimal_test_id, testing_types); } } #ifdef __GNUC__ -#pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif \ No newline at end of file diff --git a/test/test_dictionary_encoded_array.cpp b/test/test_dictionary_encoded_array.cpp index 6b9a9840..f05750c9 100644 --- a/test/test_dictionary_encoded_array.cpp +++ b/test/test_dictionary_encoded_array.cpp @@ -238,9 +238,10 @@ namespace sparrow #if defined(__cpp_lib_format) TEST_CASE("formatter") { - const layout_type dict(make_arrow_proxy()); + const layout_type dict(make_dictionary()); const std::string formatted = std::format("{}", dict); - constexpr std::string_view expected = "Dictionary [size=10] "; + constexpr std::string_view + expected = "Dictionary [size=10] "; CHECK_EQ(formatted, expected); } #endif