70 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: std-at-least-c++2610 11// <optional>12 13// constexpr iterator optional::begin() noexcept;14// constexpr const_iterator optional::begin() const noexcept;15 16#include <cassert>17#include <iterator>18#include <optional>19#include <type_traits>20#include <utility>21 22template <typename T>23constexpr bool test() {24 std::remove_reference_t<T> t = std::remove_reference_t<T>{};25 std::optional<T> opt{t};26 27 { // begin() is marked noexcept28 static_assert(noexcept(opt.begin()));29 static_assert(noexcept(std::as_const(opt).begin()));30 }31 32 { // Dereferencing an iterator at the beginning == indexing the 0th element, and that calling begin() again return the same iterator.33 auto iter1 = opt.begin();34 auto iter2 = std::as_const(opt).begin();35 assert(*iter1 == iter1[0]);36 assert(*iter2 == iter2[0]);37 assert(iter1 == opt.begin());38 assert(iter2 == std::as_const(opt).begin());39 }40 41 { // Calling begin() multiple times on a disengaged optional returns the same iterator.42 std::optional<T> disengaged{std::nullopt};43 auto iter1 = disengaged.begin();44 auto iter2 = std::as_const(disengaged).begin();45 assert(iter1 == disengaged.begin());46 assert(iter2 == std::as_const(disengaged).begin());47 }48 49 return true;50}51 52constexpr bool tests() {53 assert(test<int>());54 assert(test<char>());55 assert(test<const int>());56 assert(test<const char>());57 assert(test<int&>());58 assert(test<char&>());59 assert(test<const int&>());60 assert(test<const char&>());61 return true;62}63 64int main(int, char**) {65 assert(tests());66 static_assert(tests());67 68 return 0;69}70