William Tran-Viet 7b6f1235b9
[libc++] Implement a type-safe iterator for optional (#154239)
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`).
2026-02-02 16:18:39 -05:00

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;
}