brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 671fac3 Raw
117 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// template <class T> class optional::iterator;14// template <class T> class optional::const_iterator;15 16#include <cassert>17#include <optional>18#include <ranges>19#include <type_traits>20#include <utility>21 22template <typename T>23constexpr bool test_range_concept() {24  return std::ranges::range<std::optional<T>>;25}26 27template <typename T, std::remove_reference_t<T> __val>28constexpr bool test() {29  std::remove_reference_t<T> v{__val};30  std::optional<T> opt{v};31  {32    assert(test_range_concept<T>());33  }34 35  { // Dereferencing an iterator of an engaged optional will return the same value that the optional holds.36    auto it  = opt.begin();37    auto it2 = std::as_const(opt).begin();38    assert(*it == *opt);39    assert(*it2 == *std::as_const(opt));40  }41 42  { // optional::iterator and optional::const_iterator satisfy the Cpp17RandomAccessIterator and contiguous iterator.43    auto it  = opt.begin();44    auto it2 = std::as_const(opt).begin();45    assert(std::contiguous_iterator<decltype(it)>);46    assert(std::contiguous_iterator<decltype(it2)>);47 48    assert(std::random_access_iterator<decltype(it)>);49    assert(std::random_access_iterator<decltype(it2)>);50  }51 52  { // const_iterator::value_type == std::remove_cvref_t<T>, const_iterator::reference == const T&, iterator::value_type = std::remove_cvref_t<T>, iterator::reference == T&53    // std::remove_cv_t is impossible for optional<T&>54    auto it  = opt.begin();55    auto it2 = std::as_const(opt).begin();56    assert((std::is_same_v<typename decltype(it)::value_type, std::remove_cvref_t<T>>));57    assert((std::is_same_v<typename decltype(it)::reference, std::remove_reference_t<T>&>));58    assert((std::is_same_v<typename decltype(it2)::value_type, std::remove_cvref_t<T>>));59    assert((std::is_same_v<typename decltype(it2)::reference, const std::remove_reference_t<T>&>));60  }61 62  { // std::ranges::size for an engaged optional<T> == 1, disengaged optional<T> == 063    const std::optional<T> disengaged{std::nullopt};64    std::optional<T> disengaged2{std::nullopt};65    assert(std::ranges::size(opt) == 1);66    assert(std::ranges::size(std::as_const(opt)) == 1);67 68    assert(std::ranges::size(disengaged) == 0);69    assert(std::ranges::size(disengaged2) == 0);70  }71 72  { // std::ranges::enable_view<optional<T>> == true, and std::format_kind<optional<T>> == true73    static_assert(std::ranges::enable_view<std::optional<T>> == true);74    static_assert(std::format_kind<std::optional<T>> == std::range_format::disabled);75  }76 77  // An optional with value that is reset will have a begin() == end(), then when it is reassigned a value,78  // begin() != end(), and *begin() will contain the new value.79  {80    std::optional<T> val{v};81    assert(val.begin() != val.end());82    val.reset();83    assert(val.begin() == val.end());84    val.emplace(v);85    assert(val.begin() != val.end());86    assert(*(val.begin()) == v);87  }88 89  return true;90}91 92constexpr bool tests() {93  assert((test<int, 1>()));94  assert((test<char, 'a'>()));95  assert((test<bool, true>()));96  assert((test<const int, 2>()));97  assert((test<const char, 'b'>()));98  assert((test<int&, 1>()));99  assert((test<char&, 'a'>()));100  assert((test<bool&, true>()));101  assert((test<const int&, 2>()));102  assert((test<const char&, 'b'>()));103 104  assert(!test_range_concept<int (&)()>());105  assert(!test_range_concept<int (&)[]>());106  assert(!test_range_concept<int (&)[42]>());107 108  return true;109}110 111int main(int, char**) {112  assert(tests());113  static_assert(tests());114 115  return 0;116}117