Skip to content

Commit 2cb9f4f

Browse files
Add some constexpr tests
1 parent da37e7b commit 2cb9f4f

File tree

7 files changed

+71
-4
lines changed

7 files changed

+71
-4
lines changed

include/beman/any_view/detail/any_iterator.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ class any_iterator {
152152
constexpr auto operator-=(difference_type offset) -> any_iterator&
153153
requires random_access
154154
{
155-
*iterator_ptr -= offset;
155+
// TODO: should virtual function for operator-= be provided to avoid signed overflow for max difference type?
156+
*this += -offset;
156157
return *this;
157158
}
158159

include/beman/any_view/detail/concepts.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ concept contiguous_iterator_compatible_with =
3434
random_access_iterator_compatible_with<IterT, IterConceptT> and
3535
(not std::derived_from<IterConceptT, std::contiguous_iterator_tag> or std::contiguous_iterator<IterT>);
3636

37-
template <class RangeRefT, class TraitsRefT, class IterConceptT>
37+
template <class RangeRefT, class TraitsRefT, class IterConceptT = std::contiguous_iterator_tag>
3838
concept contiguous_reference_convertible_to =
3939
std::convertible_to<RangeRefT, TraitsRefT> and
4040
(not std::derived_from<IterConceptT, std::contiguous_iterator_tag> or

include/beman/any_view/detail/intrusive_small_ptr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class intrusive_small_ptr {
7777
if (index == index_type::is_inplace) {
7878
other.get_inplace()->copy_to(&inplace);
7979
} else {
80-
pointer = other.pointer->copy();
80+
pointer = other ? other.pointer->copy() : nullptr;
8181
}
8282
}
8383

include/beman/any_view/detail/iterator_adaptor.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#ifndef BEMAN_ANY_VIEW_DETAIL_ITERATOR_ADAPTOR_HPP
44
#define BEMAN_ANY_VIEW_DETAIL_ITERATOR_ADAPTOR_HPP
55

6+
#include <beman/any_view/detail/concepts.hpp>
67
#include <beman/any_view/detail/iterator_interface.hpp>
78
#include <beman/any_view/detail/utility.hpp>
89

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

7374
[[nodiscard]] constexpr auto operator->() const -> pointer override {
74-
if constexpr (contiguous) {
75+
if constexpr (contiguous and contiguous_reference_convertible_to<std::iter_reference_t<IteratorT>, RefT>) {
7576
return std::to_address(iterator);
7677
} else {
7778
unreachable();
@@ -129,6 +130,9 @@ class iterator_adaptor : public iterator_interface<ElementT, RefT, RValueRefT, D
129130
[[nodiscard]] constexpr auto operator==(std::default_sentinel_t) const -> bool override {
130131
return iterator == sentinel;
131132
}
133+
134+
// ICE workaround for GCC
135+
constexpr ~iterator_adaptor() noexcept override {}
132136
};
133137

134138
} // namespace beman::any_view::detail

include/beman/any_view/detail/view_adaptor.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueR
2323
public:
2424
constexpr view_adaptor(ViewT&& view) noexcept(get_noexcept()) : view(std::move(view)) {}
2525

26+
constexpr view_adaptor(const view_adaptor&) = default;
27+
28+
constexpr view_adaptor(view_adaptor&&) noexcept = default;
29+
2630
auto copy_to(void* destination) const -> void override {
2731
if constexpr (std::copy_constructible<ViewT>) {
2832
::new (destination) view_adaptor(*this);
@@ -62,6 +66,9 @@ class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueR
6266
unreachable();
6367
}
6468
}
69+
70+
// ICE workaround for GCC
71+
constexpr ~view_adaptor() noexcept override {}
6572
};
6673

6774
} // namespace beman::any_view::detail

tests/beman/any_view/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ function(beman_add_test)
1010
endfunction()
1111

1212
beman_add_test(TARGET concepts SOURCES concepts.test.cpp)
13+
beman_add_test(TARGET constexpr SOURCES constexpr.test.cpp)
1314
beman_add_test(TARGET sfinae SOURCES sfinae.test.cpp)
1415
beman_add_test(TARGET type_traits SOURCES type_traits.test.cpp)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2+
3+
#include <beman/any_view/any_view.hpp>
4+
5+
#include <gtest/gtest.h>
6+
7+
#include <vector>
8+
9+
using beman::any_view::any_view;
10+
11+
#if BEMAN_ANY_VIEW_USE_ENUM()
12+
using enum beman::any_view::any_view_options;
13+
14+
template <class ValueT>
15+
using proxy_any_view = any_view<ValueT, input, ValueT>;
16+
#elif BEMAN_ANY_VIEW_USE_TRAITS()
17+
template <class ValueT>
18+
struct proxy_traits {
19+
using reference_type = ValueT;
20+
};
21+
22+
template <class ValueT>
23+
using proxy_any_view = any_view<ValueT, proxy_traits<ValueT>>;
24+
#elif BEMAN_ANY_VIEW_USE_NAMED()
25+
using beman::any_view::type;
26+
27+
template <class ValueT>
28+
using proxy_any_view = any_view<ValueT, {.reference_type = type<ValueT>}>;
29+
#endif
30+
31+
constexpr auto sum(proxy_any_view<proxy_any_view<int>> views) {
32+
auto result = 0;
33+
34+
for (auto view : views) {
35+
for (const auto value : view) {
36+
result += value;
37+
}
38+
}
39+
40+
return result;
41+
}
42+
43+
TEST(ConstexprTest, sum_vector_of_vector) {
44+
static_assert(15 == sum(std::vector{std::vector{1, 2}, std::vector{3, 4}, std::vector{5}}));
45+
EXPECT_EQ(15, sum(std::vector{std::vector{1, 2}, std::vector{3, 4}, std::vector{5}}));
46+
}
47+
48+
TEST(ConstexprTest, sum_transform_view_of_iota) {
49+
constexpr auto iota = [](int n) { return std::views::iota(1) | std::views::take(n); };
50+
constexpr auto view = iota(5) | std::views::transform(iota);
51+
52+
static_assert(35 == sum(view));
53+
EXPECT_EQ(35, sum(view));
54+
}

0 commit comments

Comments
 (0)