brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.9 KiB · 133eed4 Raw
352 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 11// <optional>12 13// template<class F> constexpr auto and_then(F&&) &;14// template<class F> constexpr auto and_then(F&&) &&;15// template<class F> constexpr auto and_then(F&&) const&;16// template<class F> constexpr auto and_then(F&&) const&&;17 18#include <cassert>19#include <concepts>20#include <optional>21 22#include "test_macros.h"23 24struct LVal {25  constexpr std::optional<int> operator()(int&) { return 1; }26  std::optional<int> operator()(const int&) = delete;27  std::optional<int> operator()(int&&) = delete;28  std::optional<int> operator()(const int&&) = delete;29};30 31struct CLVal {32  std::optional<int> operator()(int&) = delete;33  constexpr std::optional<int> operator()(const int&) { return 1; }34  std::optional<int> operator()(int&&) = delete;35  std::optional<int> operator()(const int&&) = delete;36};37 38struct RVal {39  std::optional<int> operator()(int&) = delete;40  std::optional<int> operator()(const int&) = delete;41  constexpr std::optional<int> operator()(int&&) { return 1; }42  std::optional<int> operator()(const int&&) = delete;43};44 45struct CRVal {46  std::optional<int> operator()(int&) = delete;47  std::optional<int> operator()(const int&) = delete;48  std::optional<int> operator()(int&&) = delete;49  constexpr std::optional<int> operator()(const int&&) { return 1; }50};51 52struct RefQual {53  constexpr std::optional<int> operator()(int) & { return 1; }54  std::optional<int> operator()(int) const& = delete;55  std::optional<int> operator()(int) && = delete;56  std::optional<int> operator()(int) const&& = delete;57};58 59struct CRefQual {60  std::optional<int> operator()(int) & = delete;61  constexpr std::optional<int> operator()(int) const& { return 1; }62  std::optional<int> operator()(int) && = delete;63  std::optional<int> operator()(int) const&& = delete;64};65 66struct RVRefQual {67  std::optional<int> operator()(int) & = delete;68  std::optional<int> operator()(int) const& = delete;69  constexpr std::optional<int> operator()(int) && { return 1; }70  std::optional<int> operator()(int) const&& = delete;71};72 73struct RVCRefQual {74  std::optional<int> operator()(int) & = delete;75  std::optional<int> operator()(int) const& = delete;76  std::optional<int> operator()(int) && = delete;77  constexpr std::optional<int> operator()(int) const&& { return 1; }78};79 80struct NOLVal {81  constexpr std::optional<int> operator()(int&) { return std::nullopt; }82  std::optional<int> operator()(const int&) = delete;83  std::optional<int> operator()(int&&) = delete;84  std::optional<int> operator()(const int&&) = delete;85};86 87struct NOCLVal {88  std::optional<int> operator()(int&) = delete;89  constexpr std::optional<int> operator()(const int&) { return std::nullopt; }90  std::optional<int> operator()(int&&) = delete;91  std::optional<int> operator()(const int&&) = delete;92};93 94struct NORVal {95  std::optional<int> operator()(int&) = delete;96  std::optional<int> operator()(const int&) = delete;97  constexpr std::optional<int> operator()(int&&) { return std::nullopt; }98  std::optional<int> operator()(const int&&) = delete;99};100 101struct NOCRVal {102  std::optional<int> operator()(int&) = delete;103  std::optional<int> operator()(const int&) = delete;104  std::optional<int> operator()(int&&) = delete;105  constexpr std::optional<int> operator()(const int&&) { return std::nullopt; }106};107 108struct NORefQual {109  constexpr std::optional<int> operator()(int) & { return std::nullopt; }110  std::optional<int> operator()(int) const& = delete;111  std::optional<int> operator()(int) && = delete;112  std::optional<int> operator()(int) const&& = delete;113};114 115struct NOCRefQual {116  std::optional<int> operator()(int) & = delete;117  constexpr std::optional<int> operator()(int) const& { return std::nullopt; }118  std::optional<int> operator()(int) && = delete;119  std::optional<int> operator()(int) const&& = delete;120};121 122struct NORVRefQual {123  std::optional<int> operator()(int) & = delete;124  std::optional<int> operator()(int) const& = delete;125  constexpr std::optional<int> operator()(int) && { return std::nullopt; }126  std::optional<int> operator()(int) const&& = delete;127};128 129struct NORVCRefQual {130  std::optional<int> operator()(int) & = delete;131  std::optional<int> operator()(int) const& = delete;132  std::optional<int> operator()(int) && = delete;133  constexpr std::optional<int> operator()(int) const&& { return std::nullopt; }134};135 136struct NoCopy {137  NoCopy() = default;138  NoCopy(const NoCopy&) { assert(false); }139  std::optional<int> operator()(const NoCopy&&) { return 1; }140};141 142struct NonConst {143  std::optional<int> non_const() { return 1; }144};145 146constexpr void test_val_types() {147  // Test & overload148  {149    // Without & qualifier on F's operator()150    {151      std::optional<int> i{0};152      assert(i.and_then(LVal{}) == 1);153      assert(i.and_then(NOLVal{}) == std::nullopt);154      ASSERT_SAME_TYPE(decltype(i.and_then(LVal{})), std::optional<int>);155    }156 157    //With & qualifier on F's operator()158    {159      std::optional<int> i{0};160      RefQual l{};161      assert(i.and_then(l) == 1);162      NORefQual nl{};163      assert(i.and_then(nl) == std::nullopt);164      ASSERT_SAME_TYPE(decltype(i.and_then(l)), std::optional<int>);165    }166  }167 168  // Test const& overload169  {170    // Without & qualifier on F's operator()171    {172      const std::optional<int> i{0};173      assert(i.and_then(CLVal{}) == 1);174      assert(i.and_then(NOCLVal{}) == std::nullopt);175      ASSERT_SAME_TYPE(decltype(i.and_then(CLVal{})), std::optional<int>);176    }177 178    //With & qualifier on F's operator()179    {180      const std::optional<int> i{0};181      const CRefQual l{};182      assert(i.and_then(l) == 1);183      const NOCRefQual nl{};184      assert(i.and_then(nl) == std::nullopt);185      ASSERT_SAME_TYPE(decltype(i.and_then(l)), std::optional<int>);186    }187  }188 189  // Test && overload190  {191    // Without & qualifier on F's operator()192    {193      std::optional<int> i{0};194      assert(std::move(i).and_then(RVal{}) == 1);195      assert(std::move(i).and_then(NORVal{}) == std::nullopt);196      ASSERT_SAME_TYPE(decltype(std::move(i).and_then(RVal{})), std::optional<int>);197    }198 199    //With & qualifier on F's operator()200    {201      std::optional<int> i{0};202      assert(i.and_then(RVRefQual{}) == 1);203      assert(i.and_then(NORVRefQual{}) == std::nullopt);204      ASSERT_SAME_TYPE(decltype(i.and_then(RVRefQual{})), std::optional<int>);205    }206  }207 208  // Test const&& overload209  {210    // Without & qualifier on F's operator()211    {212      const std::optional<int> i{0};213      assert(std::move(i).and_then(CRVal{}) == 1);214      assert(std::move(i).and_then(NOCRVal{}) == std::nullopt);215      ASSERT_SAME_TYPE(decltype(std::move(i).and_then(CRVal{})), std::optional<int>);216    }217 218    //With & qualifier on F's operator()219    {220      const std::optional<int> i{0};221      const RVCRefQual l{};222      assert(i.and_then(std::move(l)) == 1);223      const NORVCRefQual nl{};224      assert(i.and_then(std::move(nl)) == std::nullopt);225      ASSERT_SAME_TYPE(decltype(i.and_then(std::move(l))), std::optional<int>);226    }227  }228}229 230// check that the lambda body is not instantiated during overload resolution231constexpr void test_sfinae() {232  std::optional<NonConst> opt{};233  auto l = [](auto&& x) { return x.non_const(); };234  opt.and_then(l);235  std::move(opt).and_then(l);236}237 238constexpr bool test() {239  test_val_types();240  std::optional<int> opt{};241  const auto& copt = opt;242 243  const auto never_called = [](int) {244    assert(false);245    return std::optional<int>{};246  };247 248  opt.and_then(never_called);249  std::move(opt).and_then(never_called);250  copt.and_then(never_called);251  std::move(copt).and_then(never_called);252 253  std::optional<NoCopy> nc;254  const auto& cnc = nc;255  std::move(cnc).and_then(NoCopy{});256  std::move(nc).and_then(NoCopy{});257 258  return true;259}260 261#if TEST_STD_VER >= 26262constexpr bool test_ref() {263  // Test & overload264  {265    // Without & qualifier on F's operator()266    {267      int j = 42;268      std::optional<int&> i{j};269      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(LVal{});270 271      assert(r == 1);272      assert(i.and_then(NOLVal{}) == std::nullopt);273    }274 275    //With & qualifier on F's operator()276    {277      int j = 42;278      std::optional<int&> i{j};279      RefQual l{};280      NORefQual nl{};281      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l);282 283      assert(r == 1);284      assert(i.and_then(nl) == std::nullopt);285    }286  }287 288  // Test const& overload289  {290    // Without & qualifier on F's operator()291    {292      int j = 42;293      std::optional<const int&> i{j};294      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(CLVal{});295 296      assert(r == 1);297      assert(i.and_then(NOCLVal{}) == std::nullopt);298    }299 300    //With & qualifier on F's operator()301    {302      int j = 42;303      const std::optional<int&> i{j};304      const CRefQual l{};305      const NOCRefQual nl{};306      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(l);307 308      assert(r == 1);309      assert(i.and_then(nl) == std::nullopt);310    }311  }312  // Test && overload313  {314    //With & qualifier on F's operator()315    {316      int j = 42;317      std::optional<int&> i{j};318      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(RVRefQual{});319 320      assert(r == 1);321      assert(i.and_then(NORVRefQual{}) == std::nullopt);322    }323  }324 325  // Test const&& overload326  {327    //With & qualifier on F's operator()328    {329      int j = 42;330      const std::optional<int&> i{j};331      const RVCRefQual l{};332      const NORVCRefQual nl{};333      std::same_as<std::optional<int>> decltype(auto) r = i.and_then(std::move(l));334 335      assert(r == 1);336      assert(i.and_then(std::move(nl)) == std::nullopt);337    }338  }339  return true;340}341#endif342 343int main(int, char**) {344  test();345  static_assert(test());346#if TEST_STD_VER >= 26347  test_ref();348  static_assert(test_ref());349#endif350  return 0;351}352