brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · d1bc36d Raw
158 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef SUPPORT_VARIANT_TEST_HELPERS_H11#define SUPPORT_VARIANT_TEST_HELPERS_H12 13#include <type_traits>14#include <utility>15#include <cassert>16 17#include "test_macros.h"18#include "type_id.h"19 20#if TEST_STD_VER <= 1421#error This file requires C++1722#endif23 24#ifndef TEST_HAS_NO_EXCEPTIONS25struct CopyThrows {26  CopyThrows() = default;27  CopyThrows(CopyThrows const&) { throw 42; }28  CopyThrows& operator=(CopyThrows const&) { throw 42; }29};30 31struct MoveThrows {32  static int alive;33  MoveThrows() { ++alive; }34  MoveThrows(MoveThrows const&) {++alive;}35  MoveThrows(MoveThrows&&) {  throw 42; }36  MoveThrows& operator=(MoveThrows const&) { return *this; }37  MoveThrows& operator=(MoveThrows&&) { throw 42; }38  ~MoveThrows() { --alive; }39};40 41int MoveThrows::alive = 0;42 43struct MakeEmptyT {44  static int alive;45  MakeEmptyT() { ++alive; }46  MakeEmptyT(MakeEmptyT const&) {47      ++alive;48      // Don't throw from the copy constructor since variant's assignment49      // operator performs a copy before committing to the assignment.50  }51  MakeEmptyT(MakeEmptyT &&) {52      throw 42;53  }54  MakeEmptyT& operator=(MakeEmptyT const&) {55      throw 42;56  }57  MakeEmptyT& operator=(MakeEmptyT&&) {58      throw 42;59  }60   ~MakeEmptyT() { --alive; }61};62static_assert(std::is_swappable_v<MakeEmptyT>, ""); // required for test63 64int MakeEmptyT::alive = 0;65 66template <class Variant>67void makeEmpty(Variant& v) {68    Variant v2(std::in_place_type<MakeEmptyT>);69    try {70        v = std::move(v2);71        assert(false);72    } catch (...) {73        assert(v.valueless_by_exception());74    }75}76#endif // TEST_HAS_NO_EXCEPTIONS77 78enum CallType : unsigned {79  CT_None,80  CT_NonConst = 1,81  CT_Const = 2,82  CT_LValue = 4,83  CT_RValue = 884};85 86inline constexpr CallType operator|(CallType LHS, CallType RHS) {87  return static_cast<CallType>(static_cast<unsigned>(LHS) |88                               static_cast<unsigned>(RHS));89}90 91struct ForwardingCallObject {92 93  template <class... Args>94  ForwardingCallObject& operator()(Args&&...) & {95    set_call<Args &&...>(CT_NonConst | CT_LValue);96    return *this;97  }98 99  template <class... Args>100  const ForwardingCallObject& operator()(Args&&...) const & {101    set_call<Args &&...>(CT_Const | CT_LValue);102    return *this;103  }104 105  template <class... Args>106  ForwardingCallObject&& operator()(Args&&...) && {107    set_call<Args &&...>(CT_NonConst | CT_RValue);108    return std::move(*this);109  }110 111  template <class... Args>112  const ForwardingCallObject&& operator()(Args&&...) const && {113    set_call<Args &&...>(CT_Const | CT_RValue);114    return std::move(*this);115  }116 117  template <class... Args> static void set_call(CallType type) {118    assert(last_call_type == CT_None);119    assert(last_call_args == nullptr);120    last_call_type = type;121    last_call_args = std::addressof(makeArgumentID<Args...>());122  }123 124  template <class... Args> static bool check_call(CallType type) {125    bool result = last_call_type == type && last_call_args &&126                  *last_call_args == makeArgumentID<Args...>();127    last_call_type = CT_None;128    last_call_args = nullptr;129    return result;130  }131 132  // To check explicit return type for visit<R>133  constexpr operator int() const134  {135    return 0;136  }137 138  static CallType last_call_type;139  static const TypeID *last_call_args;140};141 142CallType ForwardingCallObject::last_call_type = CT_None;143const TypeID *ForwardingCallObject::last_call_args = nullptr;144 145struct ReturnFirst {146  template <class... Args> constexpr int operator()(int f, Args &&...) const {147    return f;148  }149};150 151struct ReturnArity {152  template <class... Args> constexpr int operator()(Args &&...) const {153    return sizeof...(Args);154  }155};156 157#endif // SUPPORT_VARIANT_TEST_HELPERS_H158