brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.6 KiB · ad2713f Raw
313 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 transform(F&&) &;14// template<class F> constexpr auto transform(F&&) &&;15// template<class F> constexpr auto transform(F&&) const&;16// template<class F> constexpr auto transform(F&&) const&&;17 18#include "test_macros.h"19#include <cassert>20#include <concepts>21#include <optional>22#include <type_traits>23#include <utility>24 25struct LVal {26  constexpr int operator()(int&) { return 1; }27  int operator()(const int&)  = delete;28  int operator()(int&&)       = delete;29  int operator()(const int&&) = delete;30};31 32struct CLVal {33  int operator()(int&) = delete;34  constexpr int operator()(const int&) { return 1; }35  int operator()(int&&)       = delete;36  int operator()(const int&&) = delete;37};38 39struct RVal {40  int operator()(int&)       = delete;41  int operator()(const int&) = delete;42  constexpr int operator()(int&&) { return 1; }43  int operator()(const int&&) = delete;44};45 46struct CRVal {47  int operator()(int&)       = delete;48  int operator()(const int&) = delete;49  int operator()(int&&)      = delete;50  constexpr int operator()(const int&&) { return 1; }51};52 53struct RefQual {54  constexpr int operator()(int) & { return 1; }55  int operator()(int) const&  = delete;56  int operator()(int) &&      = delete;57  int operator()(int) const&& = delete;58};59 60struct CRefQual {61  int operator()(int) & = delete;62  constexpr int operator()(int) const& { return 1; }63  int operator()(int) &&      = delete;64  int operator()(int) const&& = delete;65};66 67struct RVRefQual {68  int operator()(int) &      = delete;69  int operator()(int) const& = delete;70  constexpr int operator()(int) && { return 1; }71  int operator()(int) const&& = delete;72};73 74struct RVCRefQual {75  int operator()(int) &      = delete;76  int operator()(int) const& = delete;77  int operator()(int) &&     = delete;78  constexpr int operator()(int) const&& { return 1; }79};80 81struct NoCopy {82  NoCopy() = default;83  NoCopy(const NoCopy&) { assert(false); }84  int operator()(const NoCopy&&) { return 1; }85};86 87struct NoMove {88  NoMove()         = default;89  NoMove(NoMove&&) = delete;90  NoMove operator()(const NoCopy&&) { return NoMove{}; }91};92 93constexpr void test_val_types() {94  // Test & overload95  {96    // Without & qualifier on F's operator()97    {98      std::optional<int> i{0};99      assert(i.transform(LVal{}) == 1);100      ASSERT_SAME_TYPE(decltype(i.transform(LVal{})), std::optional<int>);101    }102 103    //With & qualifier on F's operator()104    {105      std::optional<int> i{0};106      RefQual l{};107      assert(i.transform(l) == 1);108      ASSERT_SAME_TYPE(decltype(i.transform(l)), std::optional<int>);109    }110  }111 112  // Test const& overload113  {114    // Without & qualifier on F's operator()115    {116      const std::optional<int> i{0};117      assert(i.transform(CLVal{}) == 1);118      ASSERT_SAME_TYPE(decltype(i.transform(CLVal{})), std::optional<int>);119    }120 121    //With & qualifier on F's operator()122    {123      const std::optional<int> i{0};124      const CRefQual l{};125      assert(i.transform(l) == 1);126      ASSERT_SAME_TYPE(decltype(i.transform(l)), std::optional<int>);127    }128  }129 130  // Test && overload131  {132    // Without & qualifier on F's operator()133    {134      std::optional<int> i{0};135      assert(std::move(i).transform(RVal{}) == 1);136      ASSERT_SAME_TYPE(decltype(std::move(i).transform(RVal{})), std::optional<int>);137    }138 139    //With & qualifier on F's operator()140    {141      std::optional<int> i{0};142      assert(i.transform(RVRefQual{}) == 1);143      ASSERT_SAME_TYPE(decltype(i.transform(RVRefQual{})), std::optional<int>);144    }145  }146 147  // Test const&& overload148  {149    // Without & qualifier on F's operator()150    {151      const std::optional<int> i{0};152      assert(std::move(i).transform(CRVal{}) == 1);153      ASSERT_SAME_TYPE(decltype(std::move(i).transform(CRVal{})), std::optional<int>);154    }155 156    //With & qualifier on F's operator()157    {158      const std::optional<int> i{0};159      const RVCRefQual l{};160      assert(i.transform(std::move(l)) == 1);161      ASSERT_SAME_TYPE(decltype(i.transform(std::move(l))), std::optional<int>);162    }163  }164}165 166struct NonConst {167  int non_const() { return 1; }168};169 170// check that the lambda body is not instantiated during overload resolution171constexpr void test_sfinae() {172  std::optional<NonConst> opt{};173  auto l = [](auto&& x) { return x.non_const(); };174  opt.transform(l);175  std::move(opt).transform(l);176}177 178constexpr bool test() {179  test_sfinae();180  test_val_types();181  std::optional<int> opt;182  const auto& copt = opt;183 184  const auto never_called = [](int) {185    assert(false);186    return 0;187  };188 189  opt.transform(never_called);190  std::move(opt).transform(never_called);191  copt.transform(never_called);192  std::move(copt).transform(never_called);193 194  std::optional<NoCopy> nc;195  const auto& cnc = nc;196  std::move(nc).transform(NoCopy{});197  std::move(cnc).transform(NoCopy{});198 199  std::move(nc).transform(NoMove{});200  std::move(cnc).transform(NoMove{});201 202  return true;203}204 205#if TEST_STD_VER >= 26206constexpr bool test_ref() {207  {208    std::optional<int&> opt1;209    std::same_as<std::optional<int>> decltype(auto) opt1r = opt1.transform([](int i) { return i + 2; });210    assert(!opt1);211    assert(!opt1r);212  }213 214  {215    int i = 42;216    std::optional<int&> opt{i};217    std::same_as<std::optional<int>> decltype(auto) o2 = opt.transform([](int j) { return j + 2; });218 219    assert(*o2 == 44);220  }221  // Test & overload222  {223    // Without & qualifier on F's operator()224    {225      int i = 42;226      std::optional<int&> opt{i};227      std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(LVal{});228 229      assert(*o3 == 1);230    }231 232    //With & qualifier on F's operator()233    {234      int i = 42;235      std::optional<int&> opt{i};236      RefQual l{};237      std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l);238 239      assert(*o3 == 1);240    }241  }242  // const& overload243  {244    // Without & qualifier on F's operator()245    {246      int i = 42;247      std::optional<const int&> opt{i};248      std::same_as<std::optional<int>> decltype(auto) o3 = std::as_const(opt).transform(CLVal{});249 250      assert(*o3 == 1);251    }252 253    //With & qualifier on F's operator()254    {255      int i = 42;256      const std::optional<int&> opt{i};257      const CRefQual l{};258      std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(l);259 260      assert(*o3 == 1);261    }262  }263 264  // Test && overload265  {266    // Without & qualifier on F's operator()267    {268      int i = 42;269      std::optional<int> opt{i};270      std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVal{});271 272      assert(*o3 == 1);273    }274 275    //With & qualifier on F's operator()276    {277      int i = 42;278      std::optional<int&> opt{i};279      std::same_as<std::optional<int>> decltype(auto) o3 = std::move(opt).transform(RVRefQual{});280      assert(*o3 == 1);281    }282  }283 284  // const&& overload285  {286    //With & qualifier on F's operator()287    {288      int i = 42;289      std::optional<int&> opt{i};290      const RVCRefQual rvc{};291      std::same_as<std::optional<int>> decltype(auto) o3 = opt.transform(std::move(rvc));292      assert(*o3 == 1);293    }294  }295  {296    std::optional<int&> o6 = std::nullopt;297    auto o6r               = o6.transform([](int) { return 42; });298    assert(!o6r);299  }300  return true;301}302#endif303 304int main(int, char**) {305  test();306  static_assert(test());307#if TEST_STD_VER >= 26308  test_ref();309  static_assert(test_ref());310#endif311  return 0;312}313