On Tue, 22 Jul 2025, Tomasz Kamiński wrote: > All functions in testsuite_iterators.h are now marked constexpr, > targeting the earliest possible standard. Most functions use C++14 due > to multi-statement bodies, with exceptions: > > * BoundsContainer and some constructors are C++11 compatible. > * OutputContainer is C++20 due to operator new/delete usage. > > Before C++23, each constexpr templated function requires a constexpr > -suitable instantiation. Functions delegating to _GLIBCXX14_CONSTEXPR > must also be _GLIBCXX14_CONSTEXPR; e.g., forward_iterator_wrapper's > constructor calling input_iterator_wrapper's constructor, or > operator-> calling operator*. > > For classes defined C++20 or later (e.g., test_range), constexpr is > applied unconditionally.
LGTM > > PR libstdc++/119137 > > libstdc++-v3/ChangeLog: > > * testsuite/23_containers/inplace_vector/cons/from_range.cc: Run > iterators and range test at compile-time. > * testsuite/23_containers/inplace_vector/modifiers/assign.cc: > Likewise. > * testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc: > Likewise. > * testsuite/util/testsuite_iterators.h (__gnu_test::BoundsContainer) > (__gnu_test::OutputContainer, __gnu_test::WritableObject) > (__gnu_test::output_iterator_wrapper, > __gnu_test::input_iterator_wrapper) > (__gnu_test::forward_iterator_wrapper) > (__gnu_test::bidirectional_iterator_wrapper) > (__gnu_test::random_access_iterator_wrapper) > (__gnu_test::test_container): Add appropriate _GLIBCXXNN_CONSTEXPR > macros to member functions. > (__gnu_test::contiguous_iterator_wrapper) > (__gnu_test::input_iterator_wrapper_rval) > (__gnu_test::test_range, __gnu_test::test_range_nocopy) > (__gnu_test::test_sized_range_sized_sent) > (__gnu_test::test_sized_range): Add constexpr specifier to member > functions. > --- > This commit only extents the testsuite. > Tested on x86-64-linux. > > .../inplace_vector/cons/from_range.cc | 33 ++-- > .../inplace_vector/modifiers/assign.cc | 43 ++--- > .../inplace_vector/modifiers/multi_insert.cc | 47 +++-- > .../testsuite/util/testsuite_iterators.h | 173 +++++++++++++----- > 4 files changed, 179 insertions(+), 117 deletions(-) > > diff --git > a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc > b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc > index 5fa8a5de312..4a2f193e4a5 100644 > --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc > +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc > @@ -70,7 +70,7 @@ do_test_it() > #endif > } > > -bool > +constexpr bool > test_iterators() > { > using namespace __gnu_test; > @@ -131,7 +131,7 @@ do_test_r() > #endif > } > > -bool > +constexpr bool > test_ranges() > { > using namespace __gnu_test; > @@ -152,9 +152,9 @@ test_ranges() > > // Not lvalue-convertible to int > struct C { > - C(int v) : val(v) { } > - operator int() && { return val; } > - bool operator==(int b) const { return b == val; } > + constexpr C(int v) : val(v) { } > + constexpr operator int() && { return val; } > + constexpr bool operator==(int b) const { return b == val; } > int val; > }; > using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>; > @@ -163,22 +163,15 @@ test_ranges() > return true; > } > > -constexpr bool > -test_constexpr() > -{ > - // XXX: this doesn't test the non-forward_range code paths are constexpr. > - std::initializer_list<int> il{1, 2, 3, 4}; > - std::inplace_vector<int, 6> v(il.begin(), il.end()); > - eq<int>(v, il); > - > - do_test_r<std::span<short>>(); > - return true; > -} > - > int main() > { > - test_iterators(); > - test_ranges(); > - static_assert( test_constexpr() ); > + auto test_all = [] { > + test_iterators(); > + test_ranges(); > + return true; > + }; > + > + test_all(); > + static_assert( test_all() ); > } > > diff --git > a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc > b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc > index 91132be550e..65b505e7f37 100644 > --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc > +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc > @@ -204,14 +204,10 @@ template<size_t N, typename T> > constexpr void > test_assign_empty() > { > - // TODO make test iterators consteval > - if !consteval > - { > - using namespace __gnu_test; > - test_assign_empty_it<N, T, input_iterator_wrapper>(); > - test_assign_empty_it<N, T, forward_iterator_wrapper>(); > - test_assign_empty_it<N, T, random_access_iterator_wrapper>(); > - } > + using namespace __gnu_test; > + test_assign_empty_it<N, T, input_iterator_wrapper>(); > + test_assign_empty_it<N, T, forward_iterator_wrapper>(); > + test_assign_empty_it<N, T, random_access_iterator_wrapper>(); > > test_assign_empty_other<N, T>; > } > @@ -339,23 +335,20 @@ constexpr void > test_assigns() > { > using namespace __gnu_test; > - // TODO make test iterators consteval > - if !consteval { > - test_assign_range<test_forward_range<int>>(); > - test_assign_range<test_sized_range_sized_sent<int, > forward_iterator_wrapper>>(); > - > - test_assign_range<test_input_range<int>>(); > - test_assign_range<test_input_sized_range<int>>(); > - test_assign_range<test_sized_range_sized_sent<int, > input_iterator_wrapper>>(); > - > - test_assign_range<test_range<int, input_iterator_wrapper_nocopy>>(); > - test_assign_range<test_sized_range<int, > input_iterator_wrapper_nocopy>>(); > - test_assign_range<test_sized_range_sized_sent<int, > input_iterator_wrapper_nocopy>>(); > - > - test_assign_iterators<T, input_iterator_wrapper>(); > - test_assign_iterators<T, forward_iterator_wrapper>(); > - test_assign_iterators<T, random_access_iterator_wrapper>(); > - } > + test_assign_range<test_forward_range<int>>(); > + test_assign_range<test_sized_range_sized_sent<int, > forward_iterator_wrapper>>(); > + > + test_assign_range<test_input_range<int>>(); > + test_assign_range<test_input_sized_range<int>>(); > + test_assign_range<test_sized_range_sized_sent<int, > input_iterator_wrapper>>(); > + > + test_assign_range<test_range<int, input_iterator_wrapper_nocopy>>(); > + test_assign_range<test_sized_range<int, input_iterator_wrapper_nocopy>>(); > + test_assign_range<test_sized_range_sized_sent<int, > input_iterator_wrapper_nocopy>>(); > + > + test_assign_iterators<T, input_iterator_wrapper>(); > + test_assign_iterators<T, forward_iterator_wrapper>(); > + test_assign_iterators<T, random_access_iterator_wrapper>(); > > test_assign_initializer_list<T>(); > test_assign_repeated<T>(); > diff --git > a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc > > b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc > index 072f0b3e095..6a5b62f0aff 100644 > --- > a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc > +++ > b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc > @@ -227,12 +227,10 @@ constexpr void > test_add_to_full() > { > using namespace __gnu_test; > - // TODO make test iterators consteval > - if !consteval { > - test_add_to_full_it<N, T, input_iterator_wrapper>(); > - test_add_to_full_it<N, T, forward_iterator_wrapper>(); > - test_add_to_full_it<N, T, random_access_iterator_wrapper>(); > - } > + test_add_to_full_it<N, T, input_iterator_wrapper>(); > + test_add_to_full_it<N, T, forward_iterator_wrapper>(); > + test_add_to_full_it<N, T, random_access_iterator_wrapper>(); > + > test_add_to_full_other<N, T>(); > } > > @@ -566,34 +564,31 @@ constexpr void > test_inserts() > { > using namespace __gnu_test; > - // TODO make test iterators consteval > - if !consteval { > - do_test_ranges<test_forward_range<int>>(); > - do_test_ranges<test_sized_range_sized_sent<int, > forward_iterator_wrapper>>(); > + do_test_ranges<test_forward_range<int>>(); > + do_test_ranges<test_sized_range_sized_sent<int, > forward_iterator_wrapper>>(); > > - do_test_ranges<test_input_range<int>>(); > - do_test_ranges<test_input_sized_range<int>>(); > - do_test_ranges<test_sized_range_sized_sent<int, > input_iterator_wrapper>>(); > + do_test_ranges<test_input_range<int>>(); > + do_test_ranges<test_input_sized_range<int>>(); > + do_test_ranges<test_sized_range_sized_sent<int, input_iterator_wrapper>>(); > > - do_test_ranges<test_range<int, input_iterator_wrapper_nocopy>>(); > - do_test_ranges<test_sized_range<int, input_iterator_wrapper_nocopy>>(); > - do_test_ranges<test_sized_range_sized_sent<int, > input_iterator_wrapper_nocopy>>(); > + do_test_ranges<test_range<int, input_iterator_wrapper_nocopy>>(); > + do_test_ranges<test_sized_range<int, input_iterator_wrapper_nocopy>>(); > + do_test_ranges<test_sized_range_sized_sent<int, > input_iterator_wrapper_nocopy>>(); > > - test_insert_iterators<T, input_iterator_wrapper>(); > - test_insert_iterators<T, forward_iterator_wrapper>(); > - test_insert_iterators<T, random_access_iterator_wrapper>(); > - } > + test_insert_iterators<T, input_iterator_wrapper>(); > + test_insert_iterators<T, forward_iterator_wrapper>(); > + test_insert_iterators<T, random_access_iterator_wrapper>(); > > - test_insert_initializer_list<T>(); > - test_insert_repeated<T>(); > +test_insert_initializer_list<T>(); > +test_insert_repeated<T>(); > } > > int main() > { > - auto test_all = []{ > - test_add_to_full<0, int>(); > - test_add_to_full<0, X>(); > - test_add_to_full<4, int>(); > +auto test_all = []{ > + test_add_to_full<0, int>(); > + test_add_to_full<0, X>(); > + test_add_to_full<4, int>(); > > test_inserts<int>(); > #ifdef __cpp_lib_constexpr_inplace_vector > diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h > b/libstdc++-v3/testsuite/util/testsuite_iterators.h > index e9f8f56eb27..acd412af0f2 100644 > --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h > +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h > @@ -61,10 +61,12 @@ namespace __gnu_test > T* first; > T* last; > > + _GLIBCXX_CONSTEXPR > BoundsContainer(T* _first, T* _last) : first(_first), last(_last) > { } > > - std::size_t size() const { return last - first; } > + _GLIBCXX_CONSTEXPR std::size_t > + size() const { return last - first; } > }; > > // Simple container for holding state of a set of output iterators. > @@ -74,11 +76,13 @@ namespace __gnu_test > T* incrementedto; > bool* writtento; > > + _GLIBCXX20_CONSTEXPR > OutputContainer(T* _first, T* _last) > : BoundsContainer<T>(_first, _last), incrementedto(_first), > writtento(new bool[this->size()]()) > { } > > + _GLIBCXX20_CONSTEXPR > ~OutputContainer() > { delete[] writtento; } > }; > @@ -92,12 +96,14 @@ namespace __gnu_test > public: > OutputContainer<T>* SharedInfo; > > + _GLIBCXX_CONSTEXPR > WritableObject(T* ptr_in, OutputContainer<T>* SharedInfo_in): > ptr(ptr_in), SharedInfo(SharedInfo_in) > { } > > #if __cplusplus >= 201103L > template<class U> > + _GLIBCXX14_CONSTEXPR > typename std::enable_if<std::is_assignable<T&, U>::value>::type > operator=(U&& new_val) const > { > @@ -107,6 +113,7 @@ namespace __gnu_test > } > #else > template<class U> > + _GLIBCXX14_CONSTEXPR > void > operator=(const U& new_val) > { > @@ -128,6 +135,7 @@ namespace __gnu_test > struct output_iterator_wrapper > { > protected: > + _GLIBCXX_CONSTEXPR > output_iterator_wrapper() : ptr(0), SharedInfo(0) > { } > > @@ -142,6 +150,7 @@ namespace __gnu_test > T* ptr; > ContainerType* SharedInfo; > > + _GLIBCXX14_CONSTEXPR > output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) > : ptr(_ptr), SharedInfo(SharedInfo_in) > { > @@ -155,6 +164,7 @@ namespace __gnu_test > operator=(const output_iterator_wrapper&) = default; > #endif > > + _GLIBCXX14_CONSTEXPR > WritableObject<T> > operator*() const > { > @@ -163,6 +173,7 @@ namespace __gnu_test > return WritableObject<T>(ptr, SharedInfo); > } > > + _GLIBCXX14_CONSTEXPR > output_iterator_wrapper& > operator++() > { > @@ -173,6 +184,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > output_iterator_wrapper > operator++(int) > { > @@ -224,13 +236,19 @@ namespace __gnu_test > struct deref_proxy > { > T* ptr; > - operator const T&() const { return *ptr; } > + > + _GLIBCXX_CONSTEXPR > + operator const T&() const > + { return *ptr; } > } p; > > - deref_proxy operator*() const { return p; } > + _GLIBCXX_CONSTEXPR > + deref_proxy operator*() const > + { return p; } > }; > > protected: > + _GLIBCXX_CONSTEXPR > input_iterator_wrapper() : ptr(0), SharedInfo(0) > { } > > @@ -245,6 +263,7 @@ namespace __gnu_test > T* ptr; > ContainerType* SharedInfo; > > + _GLIBCXX14_CONSTEXPR > input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) > : ptr(_ptr), SharedInfo(SharedInfo_in) > { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); } > @@ -256,6 +275,7 @@ namespace __gnu_test > operator=(const input_iterator_wrapper&) = default; > #endif > > + _GLIBCXX14_CONSTEXPR > bool > operator==(const input_iterator_wrapper& in) const > { > @@ -264,32 +284,34 @@ namespace __gnu_test > return ptr == in.ptr; > } > > + _GLIBCXX14_CONSTEXPR > bool > operator!=(const input_iterator_wrapper& in) const > { > return !(*this == in); > } > > - T* > - base() const > + _GLIBCXX_CONSTEXPR > + T* base() const > { > return ptr; > } > > - T& > - operator*() const > + _GLIBCXX14_CONSTEXPR > + T& operator*() const > { > ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last); > ITERATOR_VERIFY(ptr >= SharedInfo->first); > return *ptr; > } > > - T* > - operator->() const > + _GLIBCXX14_CONSTEXPR > + T* operator->() const > { > return &**this; > } > > + _GLIBCXX14_CONSTEXPR > input_iterator_wrapper& > operator++() > { > @@ -300,6 +322,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > post_inc_proxy > operator++(int) > { > @@ -340,10 +363,12 @@ namespace __gnu_test > typedef BoundsContainer<T> ContainerType; > typedef std::forward_iterator_tag iterator_category; > > + _GLIBCXX14_CONSTEXPR > forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) > : input_iterator_wrapper<T>(_ptr, SharedInfo_in) > { } > > + _GLIBCXX14_CONSTEXPR > forward_iterator_wrapper() > { } > > @@ -354,17 +379,18 @@ namespace __gnu_test > operator=(const forward_iterator_wrapper&) = default; > #endif > > - T& > - operator*() const > + _GLIBCXX14_CONSTEXPR > + T& operator*() const > { > ITERATOR_VERIFY(this->SharedInfo && this->ptr < > this->SharedInfo->last); > return *(this->ptr); > } > > - T* > - operator->() const > + _GLIBCXX14_CONSTEXPR > + T* operator->() const > { return &**this; } > > + _GLIBCXX14_CONSTEXPR > forward_iterator_wrapper& > operator++() > { > @@ -373,6 +399,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > forward_iterator_wrapper > operator++(int) > { > @@ -382,8 +409,8 @@ namespace __gnu_test > } > > #if __cplusplus >= 201402L > - bool > - operator==(const forward_iterator_wrapper& it) const noexcept > + constexpr > + bool operator==(const forward_iterator_wrapper& it) const noexcept > { > // Since C++14 value-initialized forward iterators are comparable. > if (this->SharedInfo == nullptr || it.SharedInfo == nullptr) > @@ -394,8 +421,8 @@ namespace __gnu_test > return base_this == base_that; > } > > - bool > - operator!=(const forward_iterator_wrapper& it) const noexcept > + constexpr > + bool operator!=(const forward_iterator_wrapper& it) const noexcept > { > return !(*this == it); > } > @@ -415,10 +442,12 @@ namespace __gnu_test > typedef BoundsContainer<T> ContainerType; > typedef std::bidirectional_iterator_tag iterator_category; > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) > : forward_iterator_wrapper<T>(_ptr, SharedInfo_in) > { } > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper() > : forward_iterator_wrapper<T>() > { } > @@ -431,6 +460,7 @@ namespace __gnu_test > operator=(const bidirectional_iterator_wrapper&) = default; > #endif > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper& > operator++() > { > @@ -439,6 +469,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper > operator++(int) > { > @@ -447,6 +478,7 @@ namespace __gnu_test > return tmp; > } > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper& > operator--() > { > @@ -455,6 +487,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > bidirectional_iterator_wrapper > operator--(int) > { > @@ -478,10 +511,12 @@ namespace __gnu_test > typedef BoundsContainer<T> ContainerType; > typedef std::random_access_iterator_tag iterator_category; > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in) > : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in) > { } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper() > : bidirectional_iterator_wrapper<T>() > { } > @@ -494,6 +529,7 @@ namespace __gnu_test > operator=(const random_access_iterator_wrapper&) = default; > #endif > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper& > operator++() > { > @@ -502,6 +538,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper > operator++(int) > { > @@ -510,6 +547,7 @@ namespace __gnu_test > return tmp; > } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper& > operator--() > { > @@ -518,6 +556,7 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper > operator--(int) > { > @@ -526,6 +565,7 @@ namespace __gnu_test > return tmp; > } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper& > operator+=(std::ptrdiff_t n) > { > @@ -542,10 +582,12 @@ namespace __gnu_test > return *this; > } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper& > operator-=(std::ptrdiff_t n) > { return *this += -n; } > > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper > operator-(std::ptrdiff_t n) const > { > @@ -553,6 +595,7 @@ namespace __gnu_test > return tmp -= n; > } > > + _GLIBCXX14_CONSTEXPR > std::ptrdiff_t > operator-(const random_access_iterator_wrapper<T>& in) const > { > @@ -560,42 +603,44 @@ namespace __gnu_test > return this->ptr - in.ptr; > } > > - T& > - operator[](std::ptrdiff_t n) const > + _GLIBCXX14_CONSTEXPR > + T& operator[](std::ptrdiff_t n) const > { return *(*this + n); } > > - bool > - operator<(const random_access_iterator_wrapper<T>& in) const > + _GLIBCXX14_CONSTEXPR > + bool operator<(const random_access_iterator_wrapper<T>& in) const > { > ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo); > return this->ptr < in.ptr; > } > > - bool > - operator>(const random_access_iterator_wrapper<T>& in) const > + _GLIBCXX14_CONSTEXPR > + bool operator>(const random_access_iterator_wrapper<T>& in) const > { > return in < *this; > } > > - bool > - operator>=(const random_access_iterator_wrapper<T>& in) const > + _GLIBCXX14_CONSTEXPR > + bool operator>=(const random_access_iterator_wrapper<T>& in) const > { > return !(*this < in); > } > > - bool > - operator<=(const random_access_iterator_wrapper<T>& in) const > + _GLIBCXX14_CONSTEXPR > + bool operator<=(const random_access_iterator_wrapper<T>& in) const > { > return !(*this > in); > } > }; > > template<typename T> > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper<T> > operator+(random_access_iterator_wrapper<T> it, std::ptrdiff_t n) > { return it += n; } > > template<typename T> > + _GLIBCXX14_CONSTEXPR > random_access_iterator_wrapper<T> > operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it) > { return it += n; } > @@ -613,14 +658,17 @@ namespace __gnu_test > { > typename ItType<T>::ContainerType bounds; > > + _GLIBCXX_CONSTEXPR > test_container(T* _first, T* _last) : bounds(_first, _last) > { } > > template<std::size_t N> > explicit > + _GLIBCXX_CONSTEXPR > test_container(T (&arr)[N]) : bounds(arr, arr+N) > { } > > + _GLIBCXX14_CONSTEXPR > ItType<T> > it(int pos) > { > @@ -628,6 +676,7 @@ namespace __gnu_test > return ItType<T>(bounds.first + pos, &bounds); > } > > + _GLIBCXX14_CONSTEXPR > ItType<T> > it(T* pos) > { > @@ -635,18 +684,22 @@ namespace __gnu_test > return ItType<T>(pos, &bounds); > } > > + _GLIBCXX_CONSTEXPR > const T& > val(int pos) > { return (bounds.first)[pos]; } > > + _GLIBCXX14_CONSTEXPR > ItType<T> > begin() > { return it(bounds.first); } > > + _GLIBCXX14_CONSTEXPR > ItType<T> > end() > { return it(bounds.last); } > > + _GLIBCXX_CONSTEXPR > std::size_t > size() const > { return bounds.size(); } > @@ -686,6 +739,7 @@ namespace __gnu_test > // Use an integer-class type to try and break the library code. > using difference_type = std::ranges::__detail::__max_diff_type; > > + constexpr > contiguous_iterator_wrapper& > operator++() > { > @@ -693,6 +747,7 @@ namespace __gnu_test > return *this; > } > > + constexpr > contiguous_iterator_wrapper& > operator--() > { > @@ -700,6 +755,7 @@ namespace __gnu_test > return *this; > } > > + constexpr > contiguous_iterator_wrapper > operator++(int) > { > @@ -708,6 +764,7 @@ namespace __gnu_test > return tmp; > } > > + constexpr > contiguous_iterator_wrapper > operator--(int) > { > @@ -716,6 +773,7 @@ namespace __gnu_test > return tmp; > } > > + constexpr > contiguous_iterator_wrapper& > operator+=(difference_type n) > { > @@ -724,23 +782,28 @@ namespace __gnu_test > return *this; > } > > - friend contiguous_iterator_wrapper > + friend constexpr > + contiguous_iterator_wrapper > operator+(contiguous_iterator_wrapper iter, difference_type n) > { return iter += n; } > > - friend contiguous_iterator_wrapper > + friend constexpr > + contiguous_iterator_wrapper > operator+(difference_type n, contiguous_iterator_wrapper iter) > { return iter += n; } > > + constexpr > contiguous_iterator_wrapper& > operator-=(difference_type n) > { return *this += -n; } > > - friend contiguous_iterator_wrapper > + friend constexpr > + contiguous_iterator_wrapper > operator-(contiguous_iterator_wrapper iter, difference_type n) > { return iter -= n; } > > - friend difference_type > + friend constexpr > + difference_type > operator-(contiguous_iterator_wrapper l, contiguous_iterator_wrapper r) > { > const random_access_iterator_wrapper<T>& lbase = l; > @@ -748,6 +811,7 @@ namespace __gnu_test > return static_cast<difference_type>(lbase - rbase); > } > > + constexpr > decltype(auto) operator[](difference_type n) const > { > auto d = static_cast<std::ptrdiff_t>(n); > @@ -765,6 +829,7 @@ namespace __gnu_test > { > using input_iterator_wrapper<T>::input_iterator_wrapper; > > + constexpr > input_iterator_wrapper_nocopy() > : input_iterator_wrapper<T>(nullptr, nullptr) > { } > @@ -779,6 +844,7 @@ namespace __gnu_test > > using input_iterator_wrapper<T>::operator++; > > + constexpr > input_iterator_wrapper_nocopy& > operator++() > { > @@ -795,6 +861,7 @@ namespace __gnu_test > > using input_iterator_wrapper<T>::operator++; > > + constexpr > input_iterator_wrapper_rval& > operator++() > { > @@ -802,8 +869,8 @@ namespace __gnu_test > return *this; > } > > - T&& > - operator*() const > + constexpr > + T&& operator*() const > { return std::move(input_iterator_wrapper<T>::operator*()); } > }; > > @@ -821,7 +888,9 @@ namespace __gnu_test > > using Iter<T>::operator++; > > - iterator& operator++() { Iter<T>::operator++(); return *this; } > + constexpr > + iterator& operator++() > + { Iter<T>::operator++(); return *this; } > }; > > template<typename I> > @@ -829,21 +898,24 @@ namespace __gnu_test > { > T* end; > > - friend bool operator==(const sentinel& s, const I& i) noexcept > + friend constexpr bool > + operator==(const sentinel& s, const I& i) noexcept > { return s.end == i.ptr; } > > - friend auto operator-(const sentinel& s, const I& i) noexcept > + friend constexpr > + auto operator-(const sentinel& s, const I& i) noexcept > requires std::random_access_iterator<I> > { return std::iter_difference_t<I>(s.end - i.ptr); } > > - friend auto operator-(const I& i, const sentinel& s) noexcept > + friend constexpr auto > + operator-(const I& i, const sentinel& s) noexcept > requires std::random_access_iterator<I> > { return std::iter_difference_t<I>(i.ptr - s.end); } > }; > > protected: > - auto > - get_iterator(T* p) > + constexpr > + auto get_iterator(T* p) > { > if constexpr (std::default_initializable<Iter<T>>) > return Iter<T>(p, &bounds); > @@ -852,17 +924,19 @@ namespace __gnu_test > } > > public: > + constexpr > test_range(T* first, T* last) : bounds(first, last) > { } > > template<std::size_t N> > - explicit > + explicit constexpr > test_range(T (&arr)[N]) : test_range(arr, arr+N) > { } > > - auto begin() & { return get_iterator(bounds.first); } > + constexpr auto begin() & > + { return get_iterator(bounds.first); } > > - auto end() & > + constexpr auto end() & > { > using I = decltype(get_iterator(bounds.last)); > return sentinel<I>{bounds.last}; > @@ -875,7 +949,9 @@ namespace __gnu_test > template<typename T, template<typename> class Iter> > struct test_range_nocopy : test_range<T, Iter> > { > - test_range_nocopy(T* first, T* last) : test_range<T, Iter>(first, last) > + constexpr > + test_range_nocopy(T* first, T* last) > + : test_range<T, Iter>(first, last) > {} > > test_range_nocopy(test_range_nocopy&&) = default; > @@ -910,6 +986,7 @@ namespace __gnu_test > { > using test_range<T, Iter>::test_range; > > + constexpr > std::size_t size() const noexcept > { return this->bounds.size(); } > }; > @@ -945,18 +1022,22 @@ namespace __gnu_test > { > T* end; > > - friend bool operator==(const sentinel& s, const I& i) noexcept > + friend constexpr > + bool operator==(const sentinel& s, const I& i) noexcept > { return s.end == i.ptr; } > > - friend std::iter_difference_t<I> > + friend constexpr > + std::iter_difference_t<I> > operator-(const sentinel& s, const I& i) noexcept > { return std::iter_difference_t<I>(s.end - i.ptr); } > > - friend std::iter_difference_t<I> > + friend constexpr > + std::iter_difference_t<I> > operator-(const I& i, const sentinel& s) noexcept > { return std::iter_difference_t<I>(i.ptr - s.end); } > }; > > + constexpr > auto end() & > { > using I = decltype(this->get_iterator(this->bounds.last)); > -- > 2.49.0 > >