File: CallableTest.cpp

package info (click to toggle)
audacity 3.7.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 125,252 kB
  • sloc: cpp: 358,238; ansic: 75,458; lisp: 7,761; sh: 3,410; python: 1,503; xml: 1,385; perl: 854; makefile: 122
file content (171 lines) | stat: -rw-r--r-- 4,532 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*  SPDX-License-Identifier: GPL-2.0-or-later */
/*!********************************************************************

  Audacity: A Digital Audio Editor

  CallableTest.cpp

  Paul Licameli

**********************************************************************/
#include <catch2/catch.hpp>
#include "Callable.h"
#include <variant>

// See also VariantTest for more exercise of OverloadSet

using namespace Callable;

namespace {
struct X {
   int member{ 0 };

   X() = default;
   explicit X(int value) : member{ value } {}
   explicit X(int value, std::shared_ptr<X>) : member{ value } {}
};

struct TestVisitor {
   static int x;
   int & operator () (std::monostate) const { return x; }
};

int TestVisitor::x{};

template<auto T> struct TakesNonTypeParameter {};
}

TEST_CASE("Compilation")
{
   {
      // Test contexpr-ness of OverloadSet constructor, and MemberInvoker too
      constexpr auto visitor = OverloadSet{ TestVisitor{}, &X::member },
         // and copy constructor
         visitor2{ visitor },
         // and move constructor
         visitor3{ OverloadSet{ TestVisitor{}, &X::member } };

      // OverloadSet can be default-constructed, when all the callables can be
      constexpr auto visitor4 = OverloadSet<TestVisitor>{};
   }
   
   {
      // These function objects are of literal types
      constexpr auto f1 = UniquePtrFactory<X>::Function;
      constexpr auto f2 = UniquePtrFactory<X, int>::Function;
      // How to get multiple signatures
      constexpr auto f3 = OverloadSet{ f1, f2 };
      constexpr auto f4 =
         UniquePtrFactory<X, int, std::unique_ptr<X>>::Function;

      {
         auto p1 = f1();
         REQUIRE(p1->member == 0);
         auto p2 = f2(1);
         REQUIRE(p2->member == 1);

         // Demonstrate move of argument
         auto p3 = f4(2, move(p2));
         REQUIRE(p3->member == 2);
         REQUIRE(!p2);
      }

      {
         auto p1 = f3();
         REQUIRE(p1->member == 0);
         auto p2 = f3(1);
         REQUIRE(p2->member == 1);
      }

      TakesNonTypeParameter<f1> t1{};
      TakesNonTypeParameter<f2> t2{};
      // Doesn't work with f3 in C++17
   }
   
   {
      // These function objects are of literal types
      constexpr auto f1 = SharedPtrFactory<X>::Function;
      constexpr auto f2 = SharedPtrFactory<X, int>::Function;
      // How to get multiple signatures
      constexpr auto f3 = OverloadSet{ f1, f2 };
      constexpr auto f4 =
         UniquePtrFactory<X, int, std::shared_ptr<X>>::Function;

      {
         auto p1 = f1();
         REQUIRE(p1->member == 0);
         auto p2 = f2(1);
         REQUIRE(p2->member == 1);

         // Demonstrate move of argument
         auto p3 = f4(2, move(p2));
         REQUIRE(p3->member == 2);
         REQUIRE(!p2);
      }

      {
         auto p1 = f3();
         REQUIRE(p1->member == 0);
         auto p2 = f3(1);
         REQUIRE(p2->member == 1);
      }

      TakesNonTypeParameter<f1> t1{};
      TakesNonTypeParameter<f2> t2{};
      // Doesn't work with f3 in C++17
   }
   
   {
      // These function objects are of literal types
      constexpr auto f1 = Constantly<0>::Function;
      constexpr auto f2 = Constantly<0, int>::Function;
      // How to get multiple signatures
      constexpr auto f3 = OverloadSet{ f1, f2 };

      REQUIRE(f1() == 0);
      REQUIRE(f2(1) == 0);

      REQUIRE(f3() == 0);
      REQUIRE(f3(1) == 0);

      TakesNonTypeParameter<f1> t1{};
      TakesNonTypeParameter<f2> t2{};
      // Doesn't work with f3 in C++17
   }

   {
      // These function objects are of literal types
      constexpr auto f1 = UniqueMaker<X>();
      constexpr auto f2 = UniqueMaker<X, int>();
      // How to get multiple signatures
      constexpr auto f3 = OverloadSet{ f1, f2 };
      constexpr auto f4 =
         UniqueMaker<X, int, std::shared_ptr<X>>();

      {
         auto p1 = f1();
         REQUIRE(p1->member == 0);
         auto p2 = f2(1);
         REQUIRE(p2->member == 1);

         // Demonstrate move of argument
         auto p3 = f4(2, move(p2));
         REQUIRE(p3->member == 2);
         REQUIRE(!p2);

         // Demonstrate how {} can work as an argument
         auto p4 = f2({});
         // auto p4 = f1({}); sorry
         auto p5 = f1(0); // But this works, f1 is still variadic
      }

      {
         auto p1 = f3();
         REQUIRE(p1->member == 0);
         auto p2 = f3(1);
         REQUIRE(p2->member == 1);
      }

      // generat3ed lambdas won't work as template arguments in C++17
   }
}