brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · de0a67c Raw
100 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// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010// <optional>11 12// template<class F> constexpr optional or_else(F&&) &&;13// template<class F> constexpr optional or_else(F&&) const&;14 15#include "MoveOnly.h"16 17#include <cassert>18#include <optional>19 20struct NonMovable {21  NonMovable() = default;22  NonMovable(NonMovable&&) = delete;23};24 25template <class Opt, class F>26concept has_or_else = requires(Opt&& opt, F&& f) {27  {std::forward<Opt>(opt).or_else(std::forward<F>(f))};28};29 30template <class T>31std::optional<T> return_optional() {}32 33static_assert(has_or_else<std::optional<int>&, decltype(return_optional<int>)>);34static_assert(has_or_else<std::optional<int>&&, decltype(return_optional<int>)>);35static_assert(!has_or_else<std::optional<MoveOnly>&, decltype(return_optional<MoveOnly>)>);36static_assert(has_or_else<std::optional<MoveOnly>&&, decltype(return_optional<MoveOnly>)>);37static_assert(!has_or_else<std::optional<NonMovable>&, decltype(return_optional<NonMovable>)>);38static_assert(!has_or_else<std::optional<NonMovable>&&, decltype(return_optional<NonMovable>)>);39 40std::optional<int> take_int(int) { return 0; }41void take_int_return_void(int) {}42 43static_assert(!has_or_else<std::optional<int>, decltype(take_int)>);44static_assert(!has_or_else<std::optional<int>, decltype(take_int_return_void)>);45static_assert(!has_or_else<std::optional<int>, int>);46 47constexpr bool test() {48  {49    std::optional<int> opt;50    assert(opt.or_else([] { return std::optional<int>{0}; }) == 0);51    opt = 1;52    opt.or_else([] {53      assert(false);54      return std::optional<int>{};55    });56  }57  {58    std::optional<MoveOnly> opt;59    opt = std::move(opt).or_else([] { return std::optional<MoveOnly>{MoveOnly{}}; });60    std::move(opt).or_else([] {61      assert(false);62      return std::optional<MoveOnly>{};63    });64  }65#if TEST_STD_VER >= 2666  {67    int i = 2;68    std::optional<int&> opt;69    assert(opt.or_else([&] { return std::optional<int&>{i}; }) == i);70    int j = 3;71    opt   = j;72    opt.or_else([] {73      assert(false);74      return std::optional<int&>{};75    });76    assert(opt == j);77  }78  {79    int i = 2;80    std::optional<int&> opt;81    assert(std::move(opt).or_else([&] { return std::optional<int&>{i}; }) == i);82    int j = 3;83    opt   = j;84    std::move(opt).or_else([] {85      assert(false);86      return std::optional<int&>{};87    });88    assert(opt == j);89  }90#endif91 92  return true;93}94 95int main(int, char**) {96  test();97  static_assert(test());98  return 0;99}100