From ce1a3d1af241376d358863beed3f603df80a46e8 Mon Sep 17 00:00:00 2001 From: Luc Grosheintz Date: Tue, 11 Jul 2023 09:12:40 +0200 Subject: [PATCH] Fix and test bug in a FixedLenStringArray ctor. --- include/highfive/bits/H5DataType_misc.hpp | 11 ++--- tests/unit/tests_high_five_base.cpp | 60 +++++++++++++++++++---- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/include/highfive/bits/H5DataType_misc.hpp b/include/highfive/bits/H5DataType_misc.hpp index 1b2e6a4f6..934d5f5e5 100644 --- a/include/highfive/bits/H5DataType_misc.hpp +++ b/include/highfive/bits/H5DataType_misc.hpp @@ -330,18 +330,15 @@ inline FixedLenStringArray::FixedLenStringArray(const char array[][N], std::s template inline FixedLenStringArray::FixedLenStringArray(const std::string* iter_begin, const std::string* iter_end) { - datavec.resize(static_cast(iter_end - iter_begin)); - for (auto& dst_array: datavec) { - const char* src = (iter_begin++)->c_str(); - const size_t length = std::min(N - 1, std::strlen(src)); - std::memcpy(dst_array.data(), src, length); - dst_array[length] = 0; + datavec.reserve(static_cast(iter_end - iter_begin)); + for (std::string const* it = iter_begin; it != iter_end; ++it) { + push_back(*it); } } template inline FixedLenStringArray::FixedLenStringArray(const std::vector& vec) - : FixedLenStringArray(&vec.front(), &vec.back()) {} + : FixedLenStringArray(vec.data(), vec.data() + vec.size()) {} template inline FixedLenStringArray::FixedLenStringArray( diff --git a/tests/unit/tests_high_five_base.cpp b/tests/unit/tests_high_five_base.cpp index 008f0cc74..429d10983 100644 --- a/tests/unit/tests_high_five_base.cpp +++ b/tests/unit/tests_high_five_base.cpp @@ -2943,8 +2943,6 @@ TEST_CASE("HighFiveFixedString") { { // Dedicated FixedLenStringArray FixedLenStringArray<10> arr{"0000000", "1111111"}; - // For completeness, test also the other constructor - FixedLenStringArray<10> arrx(std::vector{"0000", "1111"}); // More API: test inserting something arr.push_back("2222"); @@ -3030,6 +3028,16 @@ TEST_CASE("HighFiveFixedString") { } } +template +static void check_fixed_len_string_array_contents(const FixedLenStringArray& array, + const std::vector& expected) { + REQUIRE(array.size() == expected.size()); + + for (size_t i = 0; i < array.size(); ++i) { + CHECK(array[i] == expected[i]); + } +} + TEST_CASE("HighFiveFixedLenStringArrayStructure") { using fixed_array_t = FixedLenStringArray<10>; // increment the characters of a string written in a std::array @@ -3044,16 +3052,52 @@ TEST_CASE("HighFiveFixedLenStringArrayStructure") { return output; }; + SECTION("create from std::vector (onpoint)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<4>(expected); + check_fixed_len_string_array_contents(actual, expected); + } + + SECTION("create from std::vector (oversized)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<8>(expected); + check_fixed_len_string_array_contents(actual, expected); + } + + SECTION("create from pointers (onpoint)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<4>(expected.data(), expected.data() + expected.size()); + check_fixed_len_string_array_contents(actual, expected); + } + + SECTION("create from pointers (oversized)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<8>(expected.data(), expected.data() + expected.size()); + check_fixed_len_string_array_contents(actual, expected); + } + + + SECTION("create from std::initializer_list (onpoint)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<4>{"000", "111"}; + check_fixed_len_string_array_contents(actual, expected); + } + + SECTION("create from std::initializer_list (oversized)") { + auto expected = std::vector{"000", "111"}; + auto actual = FixedLenStringArray<8>{"000", "111"}; + check_fixed_len_string_array_contents(actual, expected); + } + // manipulate FixedLenStringArray with std::copy - { + SECTION("compatible with std::copy") { const fixed_array_t arr1{"0000000", "1111111"}; fixed_array_t arr2{"0000000", "1111111"}; std::copy(arr1.begin(), arr1.end(), std::back_inserter(arr2)); CHECK(arr2.size() == 4); } - // manipulate FixedLenStringArray with std::transform - { + SECTION("compatible with std::transform") { fixed_array_t arr; { const fixed_array_t arr1{"0000000", "1111111"}; @@ -3064,8 +3108,7 @@ TEST_CASE("HighFiveFixedLenStringArrayStructure") { CHECK(arr[1] == std::string("2222222")); } - // manipulate FixedLenStringArray with std::transform and reverse iterator - { + SECTION("compatible with std::transform (reverse iterator)") { fixed_array_t arr; { const fixed_array_t arr1{"0000000", "1111111"}; @@ -3076,8 +3119,7 @@ TEST_CASE("HighFiveFixedLenStringArrayStructure") { CHECK(arr[1] == std::string("0000000")); } - // manipulate FixedLenStringArray with std::remove_copy_if - { + SECTION("compatible with std::remove_copy_if") { fixed_array_t arr2; { const fixed_array_t arr1{"0000000", "1111111"};