Create a new `__capacity_aware_iterator` iterator type which wraps an existing iterator, takes its container as a template parameter, and encodes the maximum amount of elements the container can hold. The main objective is to prevent iterator mixups between different containers (e.g. `vector`).
101 lines
2.4 KiB
C++
101 lines
2.4 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// REQUIRES: std-at-least-c++26
|
|
// UNSUPPORTED: libcpp-has-no-experimental-optional-iterator
|
|
|
|
// <optional>
|
|
|
|
// template <class T> class optional::iterator::operator<=>;
|
|
// template <class T> class optional::const_iterator::operator<=>;
|
|
|
|
#include <cassert>
|
|
#include <compare>
|
|
#include <concepts>
|
|
#include <optional>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
template <typename T>
|
|
constexpr bool test() {
|
|
using Opt = std::optional<T>;
|
|
|
|
static_assert(std::three_way_comparable<typename Opt::iterator>);
|
|
|
|
if constexpr (std::is_object_v<T>) {
|
|
static_assert(std::three_way_comparable<typename Opt::const_iterator>);
|
|
}
|
|
|
|
std::remove_reference_t<T> t{};
|
|
Opt opt{t};
|
|
|
|
// [container.reqmts] tests for comparison operators of optional::iterator and optional::const_iterator
|
|
auto it1 = opt.begin();
|
|
|
|
{
|
|
auto it2 = opt.begin();
|
|
assert(it1 == it2);
|
|
assert(!(it1 != it2));
|
|
|
|
std::same_as<std::strong_ordering> decltype(auto) spaceship = it1 <=> it2;
|
|
assert(spaceship == std::strong_ordering::equal);
|
|
}
|
|
|
|
{
|
|
auto it3 = opt.end();
|
|
assert(it1 != it3);
|
|
assert(it1 <= it3);
|
|
assert(it1 < it3);
|
|
assert(it3 >= it1);
|
|
assert(it3 > it1);
|
|
|
|
assert(it1 <=> it3 == std::strong_ordering::less);
|
|
assert(it3 <=> it1 == std::strong_ordering::greater);
|
|
}
|
|
|
|
auto cit1 = std::as_const(opt).begin();
|
|
|
|
{
|
|
auto cit2 = std::as_const(opt).begin();
|
|
assert(cit1 == cit2);
|
|
assert(!(cit1 != cit2));
|
|
|
|
std::same_as<std::strong_ordering> decltype(auto) spaceship = cit1 <=> cit2;
|
|
assert(spaceship == std::strong_ordering::equal);
|
|
}
|
|
|
|
{
|
|
auto cit3 = std::as_const(opt).end();
|
|
|
|
assert(cit1 <= cit3);
|
|
assert(cit1 < cit3);
|
|
assert(cit3 >= cit1);
|
|
assert(cit3 > cit1);
|
|
|
|
assert(cit1 <=> cit3 == std::strong_ordering::less);
|
|
assert(cit3 <=> cit1 == std::strong_ordering::greater);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
constexpr bool test() {
|
|
test<int>();
|
|
test<char>();
|
|
test<int&>();
|
|
|
|
return true;
|
|
}
|
|
|
|
int main(int, char**) {
|
|
test();
|
|
static_assert(test());
|
|
|
|
return 0;
|
|
}
|