Skip to content

Commit

Permalink
Add some constexpr tests
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickroberts committed Feb 8, 2025
1 parent da37e7b commit 2cb9f4f
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 4 deletions.
3 changes: 2 additions & 1 deletion include/beman/any_view/detail/any_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ class any_iterator {
constexpr auto operator-=(difference_type offset) -> any_iterator&
requires random_access
{
*iterator_ptr -= offset;
// TODO: should virtual function for operator-= be provided to avoid signed overflow for max difference type?
*this += -offset;
return *this;
}

Expand Down
2 changes: 1 addition & 1 deletion include/beman/any_view/detail/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ concept contiguous_iterator_compatible_with =
random_access_iterator_compatible_with<IterT, IterConceptT> and
(not std::derived_from<IterConceptT, std::contiguous_iterator_tag> or std::contiguous_iterator<IterT>);

template <class RangeRefT, class TraitsRefT, class IterConceptT>
template <class RangeRefT, class TraitsRefT, class IterConceptT = std::contiguous_iterator_tag>
concept contiguous_reference_convertible_to =
std::convertible_to<RangeRefT, TraitsRefT> and
(not std::derived_from<IterConceptT, std::contiguous_iterator_tag> or
Expand Down
2 changes: 1 addition & 1 deletion include/beman/any_view/detail/intrusive_small_ptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class intrusive_small_ptr {
if (index == index_type::is_inplace) {
other.get_inplace()->copy_to(&inplace);
} else {
pointer = other.pointer->copy();
pointer = other ? other.pointer->copy() : nullptr;
}
}

Expand Down
6 changes: 5 additions & 1 deletion include/beman/any_view/detail/iterator_adaptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef BEMAN_ANY_VIEW_DETAIL_ITERATOR_ADAPTOR_HPP
#define BEMAN_ANY_VIEW_DETAIL_ITERATOR_ADAPTOR_HPP

#include <beman/any_view/detail/concepts.hpp>
#include <beman/any_view/detail/iterator_interface.hpp>
#include <beman/any_view/detail/utility.hpp>

Expand Down Expand Up @@ -71,7 +72,7 @@ class iterator_adaptor : public iterator_interface<ElementT, RefT, RValueRefT, D
[[nodiscard]] constexpr auto iter_move() const -> RValueRefT override { return std::ranges::iter_move(iterator); }

[[nodiscard]] constexpr auto operator->() const -> pointer override {
if constexpr (contiguous) {
if constexpr (contiguous and contiguous_reference_convertible_to<std::iter_reference_t<IteratorT>, RefT>) {
return std::to_address(iterator);
} else {
unreachable();
Expand Down Expand Up @@ -129,6 +130,9 @@ class iterator_adaptor : public iterator_interface<ElementT, RefT, RValueRefT, D
[[nodiscard]] constexpr auto operator==(std::default_sentinel_t) const -> bool override {
return iterator == sentinel;
}

// ICE workaround for GCC
constexpr ~iterator_adaptor() noexcept override {}
};

} // namespace beman::any_view::detail
Expand Down
7 changes: 7 additions & 0 deletions include/beman/any_view/detail/view_adaptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueR
public:
constexpr view_adaptor(ViewT&& view) noexcept(get_noexcept()) : view(std::move(view)) {}

constexpr view_adaptor(const view_adaptor&) = default;

constexpr view_adaptor(view_adaptor&&) noexcept = default;

auto copy_to(void* destination) const -> void override {
if constexpr (std::copy_constructible<ViewT>) {
::new (destination) view_adaptor(*this);
Expand Down Expand Up @@ -62,6 +66,9 @@ class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueR
unreachable();
}
}

// ICE workaround for GCC
constexpr ~view_adaptor() noexcept override {}
};

} // namespace beman::any_view::detail
Expand Down
1 change: 1 addition & 0 deletions tests/beman/any_view/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ function(beman_add_test)
endfunction()

beman_add_test(TARGET concepts SOURCES concepts.test.cpp)
beman_add_test(TARGET constexpr SOURCES constexpr.test.cpp)
beman_add_test(TARGET sfinae SOURCES sfinae.test.cpp)
beman_add_test(TARGET type_traits SOURCES type_traits.test.cpp)
54 changes: 54 additions & 0 deletions tests/beman/any_view/constexpr.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <beman/any_view/any_view.hpp>

#include <gtest/gtest.h>

#include <vector>

using beman::any_view::any_view;

#if BEMAN_ANY_VIEW_USE_ENUM()
using enum beman::any_view::any_view_options;

template <class ValueT>
using proxy_any_view = any_view<ValueT, input, ValueT>;
#elif BEMAN_ANY_VIEW_USE_TRAITS()
template <class ValueT>
struct proxy_traits {
using reference_type = ValueT;
};

template <class ValueT>
using proxy_any_view = any_view<ValueT, proxy_traits<ValueT>>;
#elif BEMAN_ANY_VIEW_USE_NAMED()
using beman::any_view::type;

template <class ValueT>
using proxy_any_view = any_view<ValueT, {.reference_type = type<ValueT>}>;
#endif

constexpr auto sum(proxy_any_view<proxy_any_view<int>> views) {
auto result = 0;

for (auto view : views) {
for (const auto value : view) {
result += value;
}
}

return result;
}

TEST(ConstexprTest, sum_vector_of_vector) {
static_assert(15 == sum(std::vector{std::vector{1, 2}, std::vector{3, 4}, std::vector{5}}));
EXPECT_EQ(15, sum(std::vector{std::vector{1, 2}, std::vector{3, 4}, std::vector{5}}));
}

TEST(ConstexprTest, sum_transform_view_of_iota) {
constexpr auto iota = [](int n) { return std::views::iota(1) | std::views::take(n); };
constexpr auto view = iota(5) | std::views::transform(iota);

static_assert(35 == sum(view));
EXPECT_EQ(35, sum(view));
}

0 comments on commit 2cb9f4f

Please sign in to comment.