From 54f2a6ef6f3503f7595625ac744c06a2294260c8 Mon Sep 17 00:00:00 2001 From: Alexis Placet Date: Tue, 27 Aug 2024 11:25:51 +0200 Subject: [PATCH] Fix endianess for bigendian archs (#178) --- .github/workflows/qemu.yaml | 97 ++++++++ CMakeLists.txt | 2 +- include/sparrow/buffer/buffer.hpp | 14 ++ include/sparrow/buffer/buffer_view.hpp | 14 ++ include/sparrow/layout/fixed_size_layout.hpp | 20 +- .../layout/list_layout/list_layout.hpp | 12 +- .../list_layout_value_iterator.hpp | 4 +- .../layout/variable_size_binary_layout.hpp | 76 ++++--- include/sparrow/utils/bit.hpp | 52 +++++ include/sparrow/utils/iterator.hpp | 7 + test/CMakeLists.txt | 5 +- test/test_array_data.cpp | 52 ++++- test/test_arrow_array.cpp | 33 ++- test/test_arrow_schema.cpp | 27 ++- test/test_bit.cpp | 107 +++++++++ test/test_buffer_adaptor.cpp | 211 +++++++++--------- test/test_iterator.cpp | 11 + 17 files changed, 560 insertions(+), 184 deletions(-) create mode 100644 .github/workflows/qemu.yaml create mode 100644 include/sparrow/utils/bit.hpp create mode 100644 test/test_bit.cpp diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml new file mode 100644 index 00000000..4da46c3a --- /dev/null +++ b/.github/workflows/qemu.yaml @@ -0,0 +1,97 @@ +name: Exotic architectures +on: + workflow_dispatch: + pull_request: + push: + branches: [main] + +jobs: + build_job: + runs-on: ubuntu-22.04 + name: Build on ${{ matrix.target.arch }} / ${{ matrix.target.distro }} / ${{ matrix.config.name }} / date-polyfill ${{ matrix.target.date-polyfill}} + + strategy: + matrix: + target: + - { arch: armv6, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: armv7, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: aarch64, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: aarch64, distro: alpine_latest, date-polyfill: 'OFF' } + - { arch: riscv64, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: s390x, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: s390x, distro: alpine_latest, date-polyfill: 'OFF' } + - { arch: ppc64le, distro: alpine_latest, date-polyfill: 'ON' } + - { arch: ppc64le, distro: alpine_latest, date-polyfill: 'OFF' } + + config: + - { name: Debug } + - { name: Release } + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - uses: uraimo/run-on-arch-action@v2 + name: Build artifact + id: build + with: + arch: ${{matrix.target.arch}} + distro: ${{matrix.target.distro}} + + # Not required, but speeds up builds + githubToken: ${{github.token}} + + # Create an artifacts directory + setup: | + mkdir -p "${PWD}/artifacts" + + # Mount the artifacts directory as /artifacts in the container + dockerRunArgs: | + --volume "${PWD}/artifacts:/artifacts" + + # The shell to run commands with in the container + shell: /bin/sh + + # Install some dependencies in the container. This speeds up builds if + # you are also using githubToken. Any dependencies installed here will + # be part of the container image that gets cached, so subsequent + # builds don't have to re-install them. The image layer is cached + # publicly in your project's package repository, so it is vital that + # no secrets are present in the container state or logs. + install: | + case "${{matrix.target.distro}}" in + ubuntu*|bookworm) + apt-get update -q -y + apt-get install -q -y git cmake make doctest-dev libhowardhinnant-date-dev tzdata g++ ninja-build build-essential + ;; + fedora*) + dnf -y update + dnf -y groupinstall "Development Tools" + dnf -y install git which cmake make doctest-devel date date-devel tzdata gcc-c++ ninja-build + ;; + alpine*) + apk update + apk add git cmake make doctest-dev date-dev tzdata g++ samurai + ;; + esac + + run: | + CC=gcc + export CC + CXX=g++ + export CXX + echo "Configuring" + cmake -G Ninja -Bbuild -DCMAKE_BUILD_TYPE:STRING=${{matrix.config.name}} -DUSE_DATE_POLYFILL=${{matrix.target.date-polyfill}} -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON + cd build + echo "Building" + cmake --build . --config ${{matrix.config.name}} --target test_sparrow_lib + echo "Running examples" + cmake --build . --config ${{matrix.config.name}} --target run_examples + echo "Running tests" + cmake --build . --config ${{matrix.config.name}} --target run_tests_with_junit_report + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: test_sparrow_lib_report_Linux_${{matrix.target.distro}}_${{matrix.target.arch}}_${{matrix.config.name}}_date-polyfill_${{matrix.target.date-polyfill}} + path: '**/test_sparrow_lib_report.xml' diff --git a/CMakeLists.txt b/CMakeLists.txt index 83f51d30..a1da6a48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.27) +cmake_minimum_required(VERSION 3.22) # This is better specified per target, but cmake keeps ignoring these language version # specification when building this project by itself, in particular the gnu extensions, diff --git a/include/sparrow/buffer/buffer.hpp b/include/sparrow/buffer/buffer.hpp index 412340f1..4246fcdb 100644 --- a/include/sparrow/buffer/buffer.hpp +++ b/include/sparrow/buffer/buffer.hpp @@ -580,14 +580,28 @@ namespace sparrow template constexpr U* buffer::data() noexcept { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(get_data().p_begin); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } template template constexpr const U* buffer::data() const noexcept { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(get_data().p_begin); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } template diff --git a/include/sparrow/buffer/buffer_view.hpp b/include/sparrow/buffer/buffer_view.hpp index 25c0a396..bffb08e9 100644 --- a/include/sparrow/buffer/buffer_view.hpp +++ b/include/sparrow/buffer/buffer_view.hpp @@ -189,14 +189,28 @@ namespace sparrow template U* buffer_view::data() noexcept { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(p_data); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } template template const U* buffer_view::data() const noexcept { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(p_data); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } template diff --git a/include/sparrow/layout/fixed_size_layout.hpp b/include/sparrow/layout/fixed_size_layout.hpp index 36789075..92561ddc 100644 --- a/include/sparrow/layout/fixed_size_layout.hpp +++ b/include/sparrow/layout/fixed_size_layout.hpp @@ -257,9 +257,7 @@ namespace sparrow template auto fixed_size_layout::value_end() -> value_iterator { - value_iterator it = value_begin(); - std::advance(it, size()); - return it; + return sparrow::next(value_begin(), size()); } template @@ -271,37 +269,31 @@ namespace sparrow template auto fixed_size_layout::value_cend() const -> const_value_iterator { - auto it = value_cbegin(); - std::advance(it, size()); - return it; + return sparrow::next(value_cbegin(), size()); } template auto fixed_size_layout::bitmap_begin() -> bitmap_iterator { - return sparrow::bitmap(storage()).begin() + offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).begin(), offset(storage())); } template auto fixed_size_layout::bitmap_end() -> bitmap_iterator { - bitmap_iterator it = bitmap_begin(); - std::advance(it, size()); - return it; + return sparrow::next(bitmap_begin(), size()); } template auto fixed_size_layout::bitmap_cbegin() const -> const_bitmap_iterator { - return sparrow::bitmap(storage()).cbegin() + offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).cbegin(), offset(storage())); } template auto fixed_size_layout::bitmap_cend() const -> const_bitmap_iterator { - const_bitmap_iterator it = bitmap_cbegin(); - std::advance(it, size()); - return it; + return sparrow::next(bitmap_cbegin(), size()); } template diff --git a/include/sparrow/layout/list_layout/list_layout.hpp b/include/sparrow/layout/list_layout/list_layout.hpp index 110c9923..9c2e4c09 100644 --- a/include/sparrow/layout/list_layout/list_layout.hpp +++ b/include/sparrow/layout/list_layout/list_layout.hpp @@ -101,8 +101,8 @@ namespace sparrow if(bitmap_ref){ return reference( inner_reference( - m_child_layout.begin() + element_offset(i), - m_child_layout.begin() + element_offset(i) + element_length(i) + sparrow::next(m_child_layout.begin(), element_offset(i)), + sparrow::next(m_child_layout.begin(), element_offset(i) + element_length(i)) ), bitmap_ref ); @@ -117,8 +117,8 @@ namespace sparrow if(bitmap_ref){ return const_reference( inner_const_reference( - m_child_layout.begin() + element_offset(i), - m_child_layout.begin() + element_offset(i) + element_length(i) + sparrow::next(m_child_layout.begin(), element_offset(i)), + sparrow::next(m_child_layout.begin(), element_offset(i) + element_length(i)) ), bitmap_ref ); @@ -178,7 +178,7 @@ namespace sparrow } bitmap_iterator bitmap_begin(){ - return sparrow::bitmap(storage()).begin() + sparrow::offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).begin(), sparrow::offset(storage())); } bitmap_iterator bitmap_end(){ @@ -186,7 +186,7 @@ namespace sparrow } const_bitmap_iterator bitmap_cbegin() const{ - return sparrow::bitmap(storage()).cbegin() + sparrow::offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).cbegin(), sparrow::offset(storage())); } const_bitmap_iterator bitmap_cend() const { return sparrow::bitmap(storage()).cend(); diff --git a/include/sparrow/layout/list_layout/list_layout_value_iterator.hpp b/include/sparrow/layout/list_layout/list_layout_value_iterator.hpp index 19a21021..9d11230b 100644 --- a/include/sparrow/layout/list_layout/list_layout_value_iterator.hpp +++ b/include/sparrow/layout/list_layout/list_layout_value_iterator.hpp @@ -74,8 +74,8 @@ namespace sparrow return list_value_type( - child_layout.begin() + offset, - child_layout.begin() + offset + length); + sparrow::next(child_layout.begin(), offset), + sparrow::next(child_layout.begin(), offset + length)); } bool equal(const self_type& rhs) const diff --git a/include/sparrow/layout/variable_size_binary_layout.hpp b/include/sparrow/layout/variable_size_binary_layout.hpp index 366eff5c..207aee35 100644 --- a/include/sparrow/layout/variable_size_binary_layout.hpp +++ b/include/sparrow/layout/variable_size_binary_layout.hpp @@ -18,8 +18,8 @@ #include #include -#include "sparrow/array/array_data_concepts.hpp" #include "sparrow/array/array_data.hpp" +#include "sparrow/array/array_data_concepts.hpp" #include "sparrow/layout/layout_iterator.hpp" #include "sparrow/utils/algorithm.hpp" #include "sparrow/utils/contracts.hpp" @@ -27,6 +27,7 @@ #include "sparrow/utils/mp_utils.hpp" #include "sparrow/utils/nullable.hpp" + namespace sparrow { /** @@ -107,14 +108,14 @@ namespace sparrow vs_binary_reference(vs_binary_reference&&) = default; template - requires mpl::convertible_ranges + requires mpl::convertible_ranges self_type& operator=(T&& rhs); // This is to avoid const char* from begin caught by the previous // operator= overload. It would convert const char* to const char[N], // including the null-terminating char. template - requires std::assignable_from + requires std::assignable_from self_type& operator=(const char* rhs); size_type size() const; @@ -128,19 +129,19 @@ namespace sparrow const_iterator cend() const; template - requires mpl::convertible_ranges + requires mpl::convertible_ranges bool operator==(const T& rhs) const; template - requires std::assignable_from + requires std::assignable_from bool operator==(const char* rhs) const; template - requires mpl::convertible_ranges + requires mpl::convertible_ranges auto operator<=>(const T& rhs) const; template - requires std::assignable_from + requires std::assignable_from auto operator<=>(const char* rhs) const; private: @@ -185,9 +186,9 @@ namespace sparrow using self_type = variable_size_binary_layout; using data_storage_type = DS; - constexpr static bool is_mutable = data_storage_type::is_mutable; + static constexpr bool is_mutable = data_storage_type::is_mutable; using offset_type = OT; - using inner_value_type = std::conditional_t; + using inner_value_type = std::conditional_t; using inner_reference = vs_binary_reference; using inner_const_reference = CR; using bitmap_type = typename data_storage_type::bitmap_type; @@ -248,7 +249,7 @@ namespace sparrow private: template - requires mpl::convertible_ranges + requires mpl::convertible_ranges void assign(U&& rhs, size_type index); value_iterator value_begin(); @@ -359,7 +360,7 @@ namespace sparrow template template - requires mpl::convertible_ranges + requires mpl::convertible_ranges auto vs_binary_reference::operator=(T&& rhs) -> self_type& { p_layout->assign(std::forward(rhs), m_index); @@ -368,13 +369,12 @@ namespace sparrow template template - requires std::assignable_from + requires std::assignable_from auto vs_binary_reference::operator=(const char* rhs) -> self_type& { return *this = std::string_view(rhs); } - template auto vs_binary_reference::size() const -> size_type { @@ -419,7 +419,7 @@ namespace sparrow template template - requires mpl::convertible_ranges + requires mpl::convertible_ranges bool vs_binary_reference::operator==(const T& rhs) const { return std::equal(cbegin(), cend(), std::cbegin(rhs), std::cend(rhs)); @@ -427,7 +427,7 @@ namespace sparrow template template - requires std::assignable_from + requires std::assignable_from bool vs_binary_reference::operator==(const char* rhs) const { return operator==(std::string_view(rhs)); @@ -435,7 +435,7 @@ namespace sparrow template template - requires mpl::convertible_ranges + requires mpl::convertible_ranges auto vs_binary_reference::operator<=>(const T& rhs) const { return lexicographical_compare_three_way(*this, rhs); @@ -443,7 +443,7 @@ namespace sparrow template template - requires std::assignable_from + requires std::assignable_from auto vs_binary_reference::operator<=>(const char* rhs) const { return operator<=>(std::string_view(rhs)); @@ -531,7 +531,7 @@ namespace sparrow template template - requires mpl::convertible_ranges + requires mpl::convertible_ranges void variable_size_binary_layout::assign(U&& rhs, size_type index) { typename data_storage_type::buffer_type& data_buffer = buffer_at(storage(), 1u); @@ -548,26 +548,48 @@ namespace sparrow typename data_storage_type::buffer_type tmp_data_buf; tmp_data_buf.resize(data_buffer.size() + shift_val); // Copy initial elements - std::copy(data_buffer.cbegin(), data_buffer.cbegin() + offset_beg, tmp_data_buf.begin()); + std::copy(data_buffer.cbegin(), sparrow::next(data_buffer.cbegin(), offset_beg), tmp_data_buf.begin()); // Copy new_inner_val - std::copy(std::ranges::cbegin(rhs), std::ranges::cend(rhs), tmp_data_buf.begin() + offset_beg); + std::copy(std::ranges::cbegin(rhs), std::ranges::cend(rhs), sparrow::next(tmp_data_buf.begin(), offset_beg)); // Copy the elements left - std::copy(data_buffer.cbegin() + offset_end, data_buffer.cend(), tmp_data_buf.begin() + offset_beg + static_cast(new_value_length)); + std::copy( + sparrow::next(data_buffer.cbegin(), offset_end), + data_buffer.cend(), + sparrow::next(tmp_data_buf.begin(), offset_beg + static_cast(new_value_length)) + ); std::swap(data_buffer, tmp_data_buf); // Update offsets - std::for_each(offset(index + 1), offset(layout_data_length + 1), [shift_val](auto& offset){ offset += static_cast(shift_val); }); + std::for_each( + offset(index + 1), + offset(layout_data_length + 1), + [shift_val](auto& offset) + { + offset += static_cast(shift_val); + } + ); } else { - std::copy(std::ranges::cbegin(rhs), std::ranges::cend(rhs), data_buffer.begin() + offset_beg); + std::copy(std::ranges::cbegin(rhs), std::ranges::cend(rhs), sparrow::next(data_buffer.begin(), offset_beg)); if (new_value_length < initial_value_length) { const std::size_t shift_val = initial_value_length - new_value_length; // Shift values - std::copy(data_buffer.cbegin() + offset_end, data_buffer.cend(), data_buffer.begin() + offset_beg + static_cast(new_value_length)); + std::copy( + sparrow::next(data_buffer.cbegin(), offset_end), + data_buffer.cend(), + sparrow::next(data_buffer.begin(), offset_beg + static_cast(new_value_length)) + ); // Update offsets - std::for_each(offset(index+1), offset(layout_data_length + 1), [shift_val](auto& offset){ offset -= static_cast(shift_val); }); + std::for_each( + offset(index + 1), + offset(layout_data_length + 1), + [shift_val](auto& offset) + { + offset -= static_cast(shift_val); + } + ); } } } @@ -581,7 +603,7 @@ namespace sparrow template auto variable_size_binary_layout::bitmap_begin() -> bitmap_iterator { - return sparrow::bitmap(storage()).begin() + sparrow::offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).begin(), sparrow::offset(storage())); } template @@ -593,7 +615,7 @@ namespace sparrow template auto variable_size_binary_layout::bitmap_cbegin() const -> const_bitmap_iterator { - return sparrow::bitmap(storage()).cbegin() + sparrow::offset(storage()); + return sparrow::next(sparrow::bitmap(storage()).cbegin(), sparrow::offset(storage())); } template diff --git a/include/sparrow/utils/bit.hpp b/include/sparrow/utils/bit.hpp new file mode 100644 index 00000000..d494363a --- /dev/null +++ b/include/sparrow/utils/bit.hpp @@ -0,0 +1,52 @@ +// Copyright 2024 Man Group Operations Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include +#include +#include + +namespace sparrow +{ + /** + * Reverses the bytes in the given integer value. + * \tparam T The type of the integer value. + * \param value The integer value to reverse. + * \return The integer value with the bytes reversed. + * \note Implementation comes from https://en.cppreference.com/w/cpp/numeric/byteswap + */ + template + constexpr T byteswap(T value) noexcept + { + static_assert(std::has_unique_object_representations_v, "T may not have padding bits"); + auto value_representation = std::bit_cast>(value); + std::ranges::reverse(value_representation); + return std::bit_cast(value_representation); + } + + template + constexpr auto to_native_endian(std::integral auto value) noexcept + { + if constexpr (std::endian::native != input_value_endianess) + { + return byteswap(value); + } + else + { + return value; + } + } +} diff --git a/include/sparrow/utils/iterator.hpp b/include/sparrow/utils/iterator.hpp index e1a78a74..1bbb4490 100644 --- a/include/sparrow/utils/iterator.hpp +++ b/include/sparrow/utils/iterator.hpp @@ -498,4 +498,11 @@ namespace sparrow { return pointer_iterator(t); } + + template + constexpr InputIt next(InputIt it, Distance n) + { + std::advance(it, n); + return it; + } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 60261cdc..196bf870 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -42,18 +42,19 @@ set(SPARROW_TESTS_SOURCES test_array_data_creation.cpp test_array_data_factory.cpp test_array.cpp - test_array_data.cpp test_array_data_to_arrow_array_converters.cpp + test_array_data.cpp test_arrow_array_schema_utils.cpp test_arrow_array.cpp test_arrow_schema.cpp + test_bit.cpp test_buffer_adaptor.cpp test_buffer.cpp test_dictionary_encoded_layout.cpp test_list_layout.cpp test_dynamic_bitset.cpp - test_external_array.cpp test_external_array_data.cpp + test_external_array.cpp test_fixed_size_layout.cpp test_iterator.cpp test_memory.cpp diff --git a/test/test_array_data.cpp b/test/test_array_data.cpp index f52fb58c..11e2576c 100644 --- a/test/test_array_data.cpp +++ b/test/test_array_data.cpp @@ -13,10 +13,12 @@ // limitations under the License. #include + #include "sparrow/array/array_data.hpp" #include "doctest/doctest.h" + namespace sparrow { namespace test @@ -34,27 +36,41 @@ namespace sparrow using base_type::size; using base_type::operator[]; using base_type::begin; - using base_type::end; using base_type::cbegin; using base_type::cend; + using base_type::end; template U* data() { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(base_type::data()); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } template const U* data() const { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-align" +#endif return reinterpret_cast(base_type::data()); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif } }; }; struct test_array_data { - constexpr static bool is_mutable = false; + static constexpr bool is_mutable = false; using block_type = std::uint8_t; using bitmap_type = dynamic_bitset_view; using buffer_type = test::cast_vector; @@ -164,9 +180,24 @@ namespace sparrow TEST_CASE("variable_size_binary_layout") { - std::vector words = - {"once", "upon", "a", "time", "I", "was", "writing", "clean", - "code", "now", "I'm", "only", "drawing", "flowcharts", "Bonnie", "Compyler" }; + std::vector words = { + "once", + "upon", + "a", + "time", + "I", + "was", + "writing", + "clean", + "code", + "now", + "I'm", + "only", + "drawing", + "flowcharts", + "Bonnie", + "Compyler" + }; test_array_data td; { td.type = data_descriptor(data_type::STRING); @@ -195,9 +226,10 @@ namespace sparrow }; for (size_t i = 0; i < words.size(); ++i) { - offset_func( - )[i + 1] = offset_func()[i] - + static_cast(words[i].size()); + offset_func()[i + 1] = offset_func()[i] + + static_cast( + words[i].size() + ); std::ranges::copy(words[i], iter); iter += static_cast(words[i].size()); } @@ -212,11 +244,11 @@ namespace sparrow { CHECK_EQ(layout[i], words[i]); } - + auto iter = layout.cbegin(); auto words_iter = words.cbegin(); auto words_end = words.cend(); - while(words_iter != words_end) + while (words_iter != words_end) { CHECK_EQ(*words_iter++, *iter++); } diff --git a/test/test_arrow_array.cpp b/test/test_arrow_array.cpp index 3a3ec8ec..1baa6c21 100644 --- a/test/test_arrow_array.cpp +++ b/test/test_arrow_array.cpp @@ -57,7 +57,8 @@ void check_common( CHECK_EQ(array->children[i], children_ptr[i]); } CHECK_EQ(array->dictionary, dictionary_pointer); - CHECK_EQ(array->release, sparrow::release_arrow_array); + const bool is_release_arrow_array = array->release == &sparrow::release_arrow_array; + CHECK(is_release_arrow_array); CHECK_NE(array->private_data, nullptr); } @@ -77,7 +78,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(array->n_children, 0); CHECK_EQ(array->buffers, nullptr); CHECK_EQ(array->children, nullptr); - CHECK_EQ(array->release, nullptr); + const bool is_release_nullptr = array->release == nullptr; + CHECK(is_release_nullptr); CHECK_EQ(array->private_data, nullptr); } @@ -111,7 +113,8 @@ TEST_SUITE("C Data Interface") const sparrow::arrow_array_shared_ptr array; CHECK_FALSE(array); const auto deleter = array.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = deleter == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } SUBCASE("from arrow_array_unique_ptr") @@ -123,7 +126,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(shared_array->length, 99); CHECK_EQ(shared_array->null_count, 42); const auto del_p = shared_array.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const auto is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } SUBCASE("move") @@ -136,7 +140,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(shared_array_2->length, 99); CHECK_EQ(shared_array_2->null_count, 42); const auto del_p = shared_array_2.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } SUBCASE("copy") @@ -149,7 +154,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(shared_array_2->length, 99); CHECK_EQ(shared_array_2->null_count, 42); const auto del_p = shared_array_2.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } SUBCASE("nullptr") @@ -157,7 +163,8 @@ TEST_SUITE("C Data Interface") const sparrow::arrow_array_shared_ptr shared_array(nullptr); CHECK_FALSE(shared_array); const auto del_p = shared_array.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } } @@ -174,7 +181,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(shared_array_2->null_count, 42); // obtain pointer to the deleter: const auto del_p = shared_array_2.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } SUBCASE("copy") @@ -188,7 +196,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(shared_array_2->length, 99); CHECK_EQ(shared_array_2->null_count, 42); const auto del_p = shared_array_2.get_deleter(); - CHECK_EQ(*del_p, &sparrow::arrow_array_custom_deleter); + const bool is_release_arrow_array_custom_deleter = *del_p == &sparrow::arrow_array_custom_deleter; + CHECK(is_release_arrow_array_custom_deleter); } } } @@ -252,7 +261,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(array->n_children, 0); CHECK_EQ(array->buffers, nullptr); CHECK_EQ(array->children, nullptr); - CHECK_EQ(array->release, nullptr); + const bool is_release_nullptr = array->release == nullptr; + CHECK(is_release_nullptr); CHECK_EQ(array->private_data, nullptr); } @@ -269,7 +279,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(array->n_children, 0); CHECK_EQ(array->buffers, nullptr); CHECK_EQ(array->children, nullptr); - CHECK_EQ(array->release, nullptr); + const bool is_release_nullptr = array->release == nullptr; + CHECK(is_release_nullptr); CHECK_EQ(array->private_data, nullptr); } } diff --git a/test/test_arrow_schema.cpp b/test/test_arrow_schema.cpp index 1102ec15..46ff41bb 100644 --- a/test/test_arrow_schema.cpp +++ b/test/test_arrow_schema.cpp @@ -35,7 +35,8 @@ TEST_SUITE("C Data Interface") sparrow::arrow_schema_shared_ptr schema; CHECK_EQ(schema.get(), nullptr); const auto deleter = schema.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_schema_custom_deleter); + const auto is_arrow_schema_custom_deleter = *deleter == &sparrow::arrow_schema_custom_deleter; + CHECK(is_arrow_schema_custom_deleter); } SUBCASE("from arrow_schema_unique_ptr") @@ -48,7 +49,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema_shared->n_children, 99); CHECK_EQ(schema_shared->flags, 1); const auto deleter = schema_shared.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_schema_custom_deleter); + const auto is_arrow_schema_custom_deleter = *deleter == &sparrow::arrow_schema_custom_deleter; + CHECK(is_arrow_schema_custom_deleter); } SUBCASE("copy") @@ -62,7 +64,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema_shared_2->n_children, 99); CHECK_EQ(schema_shared_2->flags, 1); const auto deleter = schema_shared.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_schema_custom_deleter); + const bool is_arrow_schema_custom_deleter = *deleter == &sparrow::arrow_schema_custom_deleter; + CHECK(is_arrow_schema_custom_deleter); } } @@ -80,7 +83,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema_shared_2->n_children, 99); CHECK_EQ(schema_shared_2->flags, 1); const auto deleter = schema_shared_2.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_schema_custom_deleter); + const bool is_arrow_schema_custom_deleter = *deleter == &sparrow::arrow_schema_custom_deleter; + CHECK(is_arrow_schema_custom_deleter); } SUBCASE("copy") @@ -95,7 +99,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema_shared_2->n_children, 99); CHECK_EQ(schema_shared_2->flags, 1); const auto deleter = schema_shared.get_deleter(); - CHECK_EQ(*deleter, &sparrow::arrow_schema_custom_deleter); + const bool is_arrow_schema_custom_deleter = *deleter == &sparrow::arrow_schema_custom_deleter; + CHECK(is_arrow_schema_custom_deleter); } } } @@ -142,7 +147,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema->children[0], children_1_ptr); CHECK_EQ(schema->children[1], children_2_ptr); CHECK_EQ(schema->dictionary, dictionary_ptr); - CHECK_EQ(schema->release, sparrow::release_arrow_schema); + const bool is_release_arrow_schema = schema->release == &sparrow::release_arrow_schema; + CHECK(is_release_arrow_schema); CHECK_NE(schema->private_data, nullptr); } @@ -167,7 +173,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema->n_children, 0); CHECK_EQ(schema->children, nullptr); CHECK_EQ(schema->dictionary, nullptr); - CHECK_EQ(schema->release, sparrow::release_arrow_schema); + const bool is_release_arrow_schema = schema->release == &sparrow::release_arrow_schema; + CHECK(is_release_arrow_schema); CHECK_NE(schema->private_data, nullptr); } @@ -196,7 +203,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema->metadata, nullptr); CHECK_EQ(schema->children, nullptr); CHECK_EQ(schema->dictionary, nullptr); - CHECK_EQ(schema->release, nullptr); + const bool is_nullptr = schema->release == nullptr; + CHECK(is_nullptr); CHECK_EQ(schema->private_data, nullptr); } @@ -218,7 +226,8 @@ TEST_SUITE("C Data Interface") CHECK_EQ(schema->metadata, nullptr); CHECK_EQ(schema->children, nullptr); CHECK_EQ(schema->dictionary, nullptr); - CHECK_EQ(schema->release, nullptr); + const bool is_nullptr = schema->release == nullptr; + CHECK(is_nullptr); CHECK_EQ(schema->private_data, nullptr); } } diff --git a/test/test_bit.cpp b/test/test_bit.cpp new file mode 100644 index 00000000..07e27ccd --- /dev/null +++ b/test/test_bit.cpp @@ -0,0 +1,107 @@ +// Copyright 2024 Man Group Operations Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "sparrow/utils/bit.hpp" + +#include "doctest/doctest.h" + +namespace sparrow +{ + TEST_SUITE("bit") + { + TEST_CASE("byteswap") + { + SUBCASE("uint8_t") + { + constexpr uint8_t x = 0x12u; + CHECK_EQ(byteswap(x), 0x12u); + } + + SUBCASE("uint16_t") + { + constexpr uint16_t x = 0x1234u; + CHECK_EQ(byteswap(x), 0x3412u); + } + + SUBCASE("uint32_t") + { + constexpr uint32_t x = 0x12345678u; + CHECK_EQ(byteswap(x), 0x78563412u); + } + + SUBCASE("uint64_t") + { + constexpr uint64_t x = 0x123456789abcdef0ull; + CHECK_EQ(byteswap(x), 0xf0debc9a78563412ull); + } + } + + TEST_CASE("to_native_endian") + { + SUBCASE("uint8_t") + { + constexpr uint8_t x = 0x12u; + CHECK_EQ(to_native_endian(x), 0x12u); + CHECK_EQ(to_native_endian(x), 0x12u); + } + + SUBCASE("uint16_t") + { + constexpr uint16_t x = 0x1234u; + if constexpr (std::endian::native == std::endian::little) + { + CHECK_EQ(to_native_endian(x), 0x1234u); + CHECK_EQ(to_native_endian(x), 0x3412u); + } + else + { + CHECK_EQ(to_native_endian(x), 0x3412u); + CHECK_EQ(to_native_endian(x), 0x1234u); + } + } + + SUBCASE("uint32_t") + { + constexpr uint32_t x = 0x12345678u; + if constexpr (std::endian::native == std::endian::little) + { + CHECK_EQ(to_native_endian(x), 0x12345678u); + CHECK_EQ(to_native_endian(x), 0x78563412u); + } + else + { + CHECK_EQ(to_native_endian(x), 0x78563412u); + CHECK_EQ(to_native_endian(x), 0x12345678u); + } + } + + SUBCASE("uint64_t") + { + constexpr uint64_t x = 0x123456789abcdef0ull; + if constexpr (std::endian::native == std::endian::little) + { + CHECK_EQ(to_native_endian(x), 0x123456789abcdef0ull); + CHECK_EQ(to_native_endian(x), 0xf0debc9a78563412ull); + } + else + { + CHECK_EQ(to_native_endian(x), 0xf0debc9a78563412ull); + CHECK_EQ(to_native_endian(x), 0x123456789abcdef0ull); + } + } + } + } +} \ No newline at end of file diff --git a/test/test_buffer_adaptor.cpp b/test/test_buffer_adaptor.cpp index d53dd399..8eeceeb5 100644 --- a/test/test_buffer_adaptor.cpp +++ b/test/test_buffer_adaptor.cpp @@ -13,14 +13,20 @@ // limitations under the License. #include +#include #include #include #include "sparrow/buffer/buffer.hpp" #include "sparrow/buffer/buffer_adaptor.hpp" +#include "sparrow/utils/bit.hpp" #include "doctest/doctest.h" +constexpr uint8_t operator"" _u8(unsigned long long int value) { + return static_cast(value); +} + namespace sparrow { TEST_SUITE("buffer_adaptor") @@ -77,8 +83,8 @@ namespace sparrow buffer buf(input); buffer_adaptor buffer_adapt(buf); auto data = buffer_adapt.data(); - CHECK_EQ(data[0], 0x04030201); - CHECK_EQ(data[1], 0x08070605); + CHECK_EQ(data[0], to_native_endian(0x04030201u)); + CHECK_EQ(data[1], to_native_endian(0x08070605u)); } SUBCASE("from const data") @@ -86,8 +92,8 @@ namespace sparrow const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); auto data = const_buffer_adapt.data(); - CHECK_EQ(data[0], 0x04030201); - CHECK_EQ(data[1], 0x08070605); + CHECK_EQ(data[0], to_native_endian(0x04030201u)); + CHECK_EQ(data[1], to_native_endian(0x08070605u)); } } @@ -98,8 +104,8 @@ namespace sparrow buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); auto data = const_buffer_adapt.data(); - CHECK_EQ(data[0], 0x04030201); - CHECK_EQ(data[1], 0x08070605); + CHECK_EQ(data[0], to_native_endian(0x04030201u)); + CHECK_EQ(data[1], to_native_endian(0x08070605u)); } SUBCASE("from const data") @@ -107,8 +113,8 @@ namespace sparrow const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); auto data = const_buffer_adapt.data(); - CHECK_EQ(data[0], 0x04030201); - CHECK_EQ(data[1], 0x08070605); + CHECK_EQ(data[0], to_native_endian(0x04030201u)); + CHECK_EQ(data[1], to_native_endian(0x08070605u)); } } @@ -118,10 +124,10 @@ namespace sparrow { buffer buf(input); buffer_adaptor buffer_adapt(buf); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); - buffer_adapt[0] = 0x11111111; + buffer_adapt[0] = 0x11111111u; CHECK_EQ(buf[0], 0x11); } @@ -129,8 +135,8 @@ namespace sparrow { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt[0], 0x04030201); - CHECK_EQ(const_buffer_adapt[1], 0x08070605); + CHECK_EQ(const_buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(const_buffer_adapt[1], to_native_endian(0x08070605u)); } } @@ -140,16 +146,16 @@ namespace sparrow { buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt[0], 0x04030201); - CHECK_EQ(const_buffer_adapt[1], 0x08070605); + CHECK_EQ(const_buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(const_buffer_adapt[1], to_native_endian(0x08070605u)); } SUBCASE("from const data") { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt[0], 0x04030201); - CHECK_EQ(const_buffer_adapt[1], 0x08070605); + CHECK_EQ(const_buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(const_buffer_adapt[1], to_native_endian(0x08070605u)); } } @@ -159,14 +165,14 @@ namespace sparrow { buffer buf(input); buffer_adaptor buffer_adapt(buf); - CHECK_EQ(buffer_adapt.front(), 0x04030201); + CHECK_EQ(buffer_adapt.front(), to_native_endian(0x04030201u)); } SUBCASE("from const data") { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.front(), 0x04030201); + CHECK_EQ(const_buffer_adapt.front(), to_native_endian(0x04030201u)); } } @@ -176,14 +182,14 @@ namespace sparrow { buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.front(), 0x04030201); + CHECK_EQ(const_buffer_adapt.front(), to_native_endian(0x04030201u)); } SUBCASE("from const data") { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.front(), 0x04030201); + CHECK_EQ(const_buffer_adapt.front(), to_native_endian(0x04030201u)); } } @@ -193,14 +199,14 @@ namespace sparrow { buffer buf(input); buffer_adaptor buffer_adapt(buf); - CHECK_EQ(buffer_adapt.back(), 0x08070605); + CHECK_EQ(buffer_adapt.back(), to_native_endian(0x08070605u)); } SUBCASE("from const data") { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.back(), 0x08070605); + CHECK_EQ(const_buffer_adapt.back(), to_native_endian(0x08070605u)); } } @@ -210,14 +216,14 @@ namespace sparrow { buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.back(), 0x08070605); + CHECK_EQ(const_buffer_adapt.back(), to_native_endian(0x08070605u)); } SUBCASE("from const data") { const buffer buf(input); const buffer_adaptor const_buffer_adapt(buf); - CHECK_EQ(const_buffer_adapt.back(), 0x08070605); + CHECK_EQ(const_buffer_adapt.back(), to_native_endian(0x08070605u)); } } @@ -230,7 +236,7 @@ namespace sparrow { buffer_adaptor buffer_adapt(buf); auto it = buffer_adapt.begin(); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); } SUBCASE("end") @@ -244,7 +250,7 @@ namespace sparrow { const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.begin(); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); } SUBCASE("const end") @@ -258,7 +264,7 @@ namespace sparrow { const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.cbegin(); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); } SUBCASE("const cend") @@ -272,9 +278,9 @@ namespace sparrow { buffer_adaptor buffer_adapt(buf); auto it = buffer_adapt.rbegin(); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); std::advance(it, 1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, 1); CHECK_EQ(it, buffer_adapt.rend()); } @@ -284,9 +290,9 @@ namespace sparrow buffer_adaptor buffer_adapt(buf); auto it = buffer_adapt.rend(); std::advance(it, -1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, -1); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); CHECK_EQ(it, buffer_adapt.rbegin()); } @@ -294,9 +300,9 @@ namespace sparrow { const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.rbegin(); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); std::advance(it, 1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, 1); CHECK_EQ(it, const_buffer_adapt.rend()); } @@ -306,9 +312,9 @@ namespace sparrow const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.rend(); std::advance(it, -1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, -1); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); CHECK_EQ(it, const_buffer_adapt.rbegin()); } @@ -316,9 +322,9 @@ namespace sparrow { const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.crbegin(); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); std::advance(it, 1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, 1); CHECK_EQ(it, const_buffer_adapt.crend()); } @@ -328,9 +334,9 @@ namespace sparrow const buffer_adaptor const_buffer_adapt(buf); auto it = const_buffer_adapt.crend(); std::advance(it, -1); - CHECK_EQ(*it, 0x04030201); + CHECK_EQ(*it, to_native_endian(0x04030201u)); std::advance(it, -1); - CHECK_EQ(*it, 0x08070605); + CHECK_EQ(*it, to_native_endian(0x08070605u)); CHECK_EQ(it, const_buffer_adapt.crbegin()); } } @@ -418,8 +424,8 @@ namespace sparrow CHECK_EQ(result, buffer_adapt.begin()); REQUIRE_EQ(buffer_adapt.size(), 3); CHECK_EQ(buffer_adapt[0], to_insert); - CHECK_EQ(buffer_adapt[1], 0x04030201); - CHECK_EQ(buffer_adapt[2], 0x08070605); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 12); } @@ -428,7 +434,7 @@ namespace sparrow buffer buf(input); buffer_adaptor buffer_adapt(buf); const auto it = std::next(buffer_adapt.cbegin()); - constexpr uint32_t to_insert = 0x09999999; + constexpr uint32_t to_insert = to_native_endian(0x09999999u); const buffer_adaptor::iterator result = buffer_adapt.insert( it, to_insert @@ -436,9 +442,9 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::next(buffer_adapt.begin())); REQUIRE_EQ(buffer_adapt.size(), 3); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); CHECK_EQ(buffer_adapt[1], to_insert); - CHECK_EQ(buffer_adapt[2], 0x08070605); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 12); } @@ -455,8 +461,8 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::prev(buffer_adapt.end())); REQUIRE_EQ(buffer_adapt.size(), 3); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buffer_adapt[2], to_insert); CHECK_EQ(buf.size(), 12); } @@ -480,8 +486,8 @@ namespace sparrow REQUIRE_EQ(buffer_adapt.size(), 4); CHECK_EQ(buffer_adapt[0], to_insert); CHECK_EQ(buffer_adapt[1], to_insert); - CHECK_EQ(buffer_adapt[2], 0x04030201); - CHECK_EQ(buffer_adapt[3], 0x08070605); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[3], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 16); } @@ -499,10 +505,10 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::next(buffer_adapt.begin())); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); CHECK_EQ(buffer_adapt[1], to_insert); CHECK_EQ(buffer_adapt[2], to_insert); - CHECK_EQ(buffer_adapt[3], 0x08070605); + CHECK_EQ(buffer_adapt[3], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 16); } @@ -520,8 +526,8 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::prev(buffer_adapt.end(), 2)); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buffer_adapt[2], to_insert); CHECK_EQ(buffer_adapt[3], to_insert); CHECK_EQ(buf.size(), 16); @@ -546,8 +552,8 @@ namespace sparrow REQUIRE_EQ(buffer_adapt.size(), 4); CHECK_EQ(buffer_adapt[0], to_insert[0]); CHECK_EQ(buffer_adapt[1], to_insert[1]); - CHECK_EQ(buffer_adapt[2], 0x04030201); - CHECK_EQ(buffer_adapt[3], 0x08070605); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[3], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 16); } @@ -565,10 +571,10 @@ namespace sparrow CHECK_EQ(*result, to_insert[0]); CHECK_EQ(result, std::next(buffer_adapt.begin())); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); CHECK_EQ(buffer_adapt[1], to_insert[0]); CHECK_EQ(buffer_adapt[2], to_insert[1]); - CHECK_EQ(buffer_adapt[3], 0x08070605); + CHECK_EQ(buffer_adapt[3], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 16); } @@ -586,8 +592,8 @@ namespace sparrow CHECK_EQ(*result, to_insert[0]); CHECK_EQ(result, std::prev(buffer_adapt.end(), 2)); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buffer_adapt[2], to_insert[0]); CHECK_EQ(buffer_adapt[3], to_insert[1]); CHECK_EQ(buf.size(), 16); @@ -611,8 +617,8 @@ namespace sparrow CHECK_EQ(result, buffer_adapt.begin()); REQUIRE_EQ(buffer_adapt.size(), 3); CHECK_EQ(buffer_adapt[0], to_insert); - CHECK_EQ(buffer_adapt[1], 0x04030201); - CHECK_EQ(buffer_adapt[2], 0x08070605); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 12); } @@ -621,7 +627,7 @@ namespace sparrow buffer buf(input); buffer_adaptor buffer_adapt(buf); auto it = std::next(buffer_adapt.cbegin()); - constexpr uint32_t to_insert = 0x09999999; + constexpr uint32_t to_insert = 0x09999999u; const buffer_adaptor::iterator result = buffer_adapt.emplace( it, to_insert @@ -629,9 +635,9 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::next(buffer_adapt.begin())); REQUIRE_EQ(buffer_adapt.size(), 3); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); CHECK_EQ(buffer_adapt[1], to_insert); - CHECK_EQ(buffer_adapt[2], 0x08070605); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 12); } @@ -640,7 +646,7 @@ namespace sparrow buffer buf(input); buffer_adaptor buffer_adapt(buf); auto it = buffer_adapt.cend(); - constexpr uint32_t to_insert = 0x09999999; + constexpr uint32_t to_insert = 0x09999999u; const buffer_adaptor::iterator result = buffer_adapt.emplace( it, to_insert @@ -648,8 +654,8 @@ namespace sparrow CHECK_EQ(*result, to_insert); CHECK_EQ(result, std::prev(buffer_adapt.end())); REQUIRE_EQ(buffer_adapt.size(), 3); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buffer_adapt[2], to_insert); CHECK_EQ(buf.size(), 12); } @@ -669,12 +675,12 @@ namespace sparrow const buffer_adaptor::iterator result = buffer_adapt.erase(it); CHECK_EQ(result, buffer_adapt.begin()); REQUIRE_EQ(buffer_adapt.size(), 1); - CHECK_EQ(buffer_adapt[0], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 4); - CHECK_EQ(buf[0], 0x05); - CHECK_EQ(buf[1], 0x06); - CHECK_EQ(buf[2], 0x07); - CHECK_EQ(buf[3], 0x08); + CHECK_EQ(buf[0], 0x05_u8); + CHECK_EQ(buf[1], 0x06_u8); + CHECK_EQ(buf[2], 0x07_u8); + CHECK_EQ(buf[3], 0x08_u8); } SUBCASE("in the middle") @@ -685,12 +691,12 @@ namespace sparrow const buffer_adaptor::iterator result = buffer_adapt.erase(it); CHECK_EQ(result, std::next(buffer_adapt.begin())); REQUIRE_EQ(buffer_adapt.size(), 1); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); REQUIRE_EQ(buf.size(), 4); - CHECK_EQ(buf[0], 0x01); - CHECK_EQ(buf[1], 0x02); - CHECK_EQ(buf[2], 0x03); - CHECK_EQ(buf[3], 0x04); + CHECK_EQ(buf[0], 0x01_u8); + CHECK_EQ(buf[1], 0x02_u8); + CHECK_EQ(buf[2], 0x03_u8); + CHECK_EQ(buf[3], 0x04_u8); } SUBCASE("at the end") @@ -701,12 +707,12 @@ namespace sparrow const buffer_adaptor::iterator result = buffer_adapt.erase(it); CHECK_EQ(result, buffer_adapt.end()); REQUIRE_EQ(buffer_adapt.size(), 1); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); REQUIRE_EQ(buf.size(), 4); - CHECK_EQ(buf[0], 0x01); - CHECK_EQ(buf[1], 0x02); - CHECK_EQ(buf[2], 0x03); - CHECK_EQ(buf[3], 0x04); + CHECK_EQ(buf[0], 0x01_u8); + CHECK_EQ(buf[1], 0x02_u8); + CHECK_EQ(buf[2], 0x03_u8); + CHECK_EQ(buf[3], 0x04_u8); } } @@ -753,8 +759,8 @@ namespace sparrow ); CHECK_EQ(result, std::prev(buffer_adapt.end())); REQUIRE_EQ(buffer_adapt.size(), 2); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x0C0B0A09); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x0C0B0A09u)); CHECK_EQ(buf.size(), 8); } @@ -770,8 +776,8 @@ namespace sparrow ); CHECK_EQ(result, buffer_adapt.end()); REQUIRE_EQ(buffer_adapt.size(), 2); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buf.size(), 8); } } @@ -796,16 +802,17 @@ namespace sparrow { buffer buf(input); buffer_adaptor buffer_adapt(buf); - buffer_adapt.push_back(0x05040302); + constexpr uint32_t to_push = to_native_endian(0x05040302u); + buffer_adapt.push_back(to_push); REQUIRE_EQ(buffer_adapt.size(), 3); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); - CHECK_EQ(buffer_adapt[2], 0x05040302); - - CHECK_EQ(buf[8], 0x02); - CHECK_EQ(buf[9], 0x03); - CHECK_EQ(buf[10], 0x04); - CHECK_EQ(buf[11], 0x05); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); + CHECK_EQ(buffer_adapt[2], to_push); + + CHECK_EQ(buf[8], 0x02u); + CHECK_EQ(buf[9], 0x03u); + CHECK_EQ(buf[10], 0x04u); + CHECK_EQ(buf[11], 0x05u); } TEST_CASE("pop_back") @@ -814,7 +821,7 @@ namespace sparrow buffer_adaptor buffer_adapt(buf); buffer_adapt.pop_back(); REQUIRE_EQ(buffer_adapt.size(), 1); - CHECK_EQ(buffer_adapt[0], 0x04030201); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); CHECK_EQ(buf.size(), 4); } @@ -826,10 +833,10 @@ namespace sparrow { buffer_adapt.resize(4); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); - CHECK_EQ(buffer_adapt[2], 0x00000000); - CHECK_EQ(buffer_adapt[3], 0x00000000); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); + CHECK_EQ(buffer_adapt[2], to_native_endian(0x00000000u)); + CHECK_EQ(buffer_adapt[3], to_native_endian(0x00000000u)); CHECK_EQ(buf.size(), 16); } @@ -838,8 +845,8 @@ namespace sparrow constexpr uint32_t value = 0x0999999; buffer_adapt.resize(4, value); REQUIRE_EQ(buffer_adapt.size(), 4); - CHECK_EQ(buffer_adapt[0], 0x04030201); - CHECK_EQ(buffer_adapt[1], 0x08070605); + CHECK_EQ(buffer_adapt[0], to_native_endian(0x04030201u)); + CHECK_EQ(buffer_adapt[1], to_native_endian(0x08070605u)); CHECK_EQ(buffer_adapt[2], value); CHECK_EQ(buffer_adapt[3], value); CHECK_EQ(buf.size(), 16); diff --git a/test/test_iterator.cpp b/test/test_iterator.cpp index 08054e3a..0c1b1fb2 100644 --- a/test/test_iterator.cpp +++ b/test/test_iterator.cpp @@ -270,4 +270,15 @@ namespace sparrow CHECK_EQ(a[0], 3); } } + + TEST_SUITE("misc") + { + TEST_CASE("next") + { + const std::array a = {2, 4, 6}; + const auto iter = make_pointer_iterator(&a[0]); + const auto iter2 = next(iter, 2); + CHECK_EQ(*iter2, a[2]); + } + } }