diff --git a/src/utils/CastArray.hpp b/src/utils/CastArray.hpp index 5e1b366e233e07cdcfff9940e38bbe6bc1c80d5a..d329b4ef35f70f3a612ca430c45d0ec23bb7ed9d 100644 --- a/src/utils/CastArray.hpp +++ b/src/utils/CastArray.hpp @@ -8,7 +8,7 @@ #include <iostream> template <typename DataType, typename CastDataType> -class CastArray +class [[nodiscard]] CastArray { public: using data_type = CastDataType; @@ -20,15 +20,13 @@ class CastArray public: PUGS_INLINE - const size_t& - size() const + const size_t& size() const { return m_size; } PUGS_INLINE - CastDataType& - operator[](size_t i) const + CastDataType& operator[](size_t i) const { Assert(i < m_size); return m_values[i]; @@ -40,11 +38,10 @@ class CastArray PUGS_INLINE CastArray& operator=(CastArray&&) = default; - PUGS_INLINE - CastArray(const Array<DataType>& array) + explicit CastArray(const Array<DataType>& array) : m_array(array), m_size(sizeof(DataType) * array.size() / sizeof(CastDataType)), - m_values((array.size() == 0) ? nullptr : reinterpret_cast<CastDataType*>(&(array[0]))) + m_values((array.size() == 0) ? nullptr : reinterpret_cast<CastDataType*>(&(static_cast<DataType&>(array[0])))) { static_assert((std::is_const_v<CastDataType> and std::is_const_v<DataType>) or (not std::is_const_v<DataType>), "CastArray cannot remove const attribute"); @@ -54,9 +51,8 @@ class CastArray } } - PUGS_INLINE - CastArray(DataType& value) - : m_size(sizeof(DataType) / sizeof(CastDataType)), m_values(reinterpret_cast<CastDataType*>(&(value))) + explicit CastArray(DataType & value) + : m_size(sizeof(DataType) / sizeof(CastDataType)), m_values(reinterpret_cast<CastDataType*>(&value)) { static_assert((std::is_const_v<CastDataType> and std::is_const_v<DataType>) or (not std::is_const_v<DataType>), "CastArray cannot remove const attribute"); @@ -65,13 +61,13 @@ class CastArray } PUGS_INLINE - CastArray(DataType&& value) = delete; + CastArray(DataType && value) = delete; PUGS_INLINE CastArray(const CastArray&) = default; PUGS_INLINE - CastArray(CastArray&&) = default; + CastArray(CastArray &&) = default; PUGS_INLINE ~CastArray() = default; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ff217a345d59a413ec999a2c3a96dd13f47a439d..f776b803d439452058cf5e76ccddbc2d7512f918 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -49,6 +49,7 @@ add_executable (unit_tests test_BuiltinFunctionEmbedder.cpp test_BuiltinFunctionEmbedderTable.cpp test_BuiltinFunctionProcessor.cpp + test_CastArray.cpp test_CG.cpp test_ContinueProcessor.cpp test_ConcatExpressionProcessor.cpp diff --git a/tests/test_CastArray.cpp b/tests/test_CastArray.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ea3899ce84c95fa70f6a301cc7e1ec2eb701eb51 --- /dev/null +++ b/tests/test_CastArray.cpp @@ -0,0 +1,93 @@ +#ifndef TEST_CAST_ARRAY_HPP +#define TEST_CAST_ARRAY_HPP + +#include <catch2/catch.hpp> + +#include <utils/ArrayUtils.hpp> +#include <utils/CastArray.hpp> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("CastArray", "[utils]") +{ + SECTION("explicit cast Array -> CastArray") + { + Array<double> x_double{5}; + x_double[0] = 1; + x_double[1] = 2; + x_double[2] = 3; + x_double[3] = 4; + x_double[4] = 5; + + CastArray<double, char> x_char{x_double}; + + REQUIRE(x_char.size() * sizeof(char) == x_double.size() * sizeof(double)); + + Array<char> y_char{x_char.size()}; + for (size_t i = 0; i < x_char.size(); ++i) { + y_char[i] = x_char[i]; + } + + CastArray<char, double> y_double{y_char}; + REQUIRE(y_char.size() * sizeof(char) == y_double.size() * sizeof(double)); + + REQUIRE(&(y_double[0]) != &(x_double[0])); + + for (size_t i = 0; i < y_double.size(); ++i) { + REQUIRE(y_double[i] == x_double[i]); + } + } + + SECTION("explicit cast value -> CastArray") + { + double x = 3; + + CastArray<double, char> x_char(x); + + REQUIRE(x_char.size() * sizeof(char) == sizeof(double)); + } + + SECTION("invalid cast array") + { + Array<char> x_char{13}; + + REQUIRE_THROWS_WITH((CastArray<char, double>{x_char}), + "unexpected error: cannot cast array to the chosen data type"); + } + + SECTION("cast array utilities") + { + SECTION("Array -> CastArray") + { + Array<double> x_double{5}; + x_double[0] = 1.3; + x_double[1] = 3.2; + x_double[2] = -4; + x_double[3] = 6.2; + x_double[4] = -1.6; + + CastArray<double, short> x_short{x_double}; + auto x_short_from = cast_array_to<short>::from(x_double); + + REQUIRE(x_short_from.size() == x_short.size()); + for (size_t i = 0; i < x_short_from.size(); ++i) { + REQUIRE(x_short_from[i] == x_short[i]); + } + } + + SECTION("Value -> CastArray") + { + double x = 3.14; + + CastArray<double, short> x_short{x}; + auto x_short_from = cast_value_to<short>::from(x); + + REQUIRE(x_short_from.size() == x_short.size()); + for (size_t i = 0; i < x_short_from.size(); ++i) { + REQUIRE(x_short_from[i] == x_short[i]); + } + } + } +} + +#endif // TEST_CAST_ARRAY_HPP