@@ -135,59 +135,60 @@ inline constexpr CallType operator|(CallType LHS, CallType RHS) {
135
135
}
136
136
137
137
struct ForwardingCallObject {
138
+ struct State {
139
+ CallType last_call_type = CT_None;
140
+ TypeID const & (*last_call_args)() = nullptr ;
141
+
142
+ template <class ...Args>
143
+ constexpr void set_call (CallType type) {
144
+ assert (last_call_type == CT_None);
145
+ assert (last_call_args == nullptr );
146
+ last_call_type = type;
147
+ last_call_args = &makeArgumentID<Args...>;
148
+ }
149
+
150
+ template <class ...Args>
151
+ constexpr bool check_call (CallType type) {
152
+ bool result =
153
+ last_call_type == type
154
+ && last_call_args
155
+ && *last_call_args == &makeArgumentID<Args...>;
156
+ last_call_type = CT_None;
157
+ last_call_args = nullptr ;
158
+ return result;
159
+ }
160
+ };
161
+
162
+ State *st_;
163
+
164
+ explicit constexpr ForwardingCallObject (State& st) : st_(&st) {}
138
165
139
166
template <class ...Args>
140
- bool operator ()(Args&&...) & {
141
- set_call<Args&&...>(CT_NonConst | CT_LValue);
167
+ constexpr bool operator ()(Args&&...) & {
168
+ st_-> set_call <Args&&...>(CT_NonConst | CT_LValue);
142
169
return true ;
143
170
}
144
171
145
172
template <class ...Args>
146
- bool operator ()(Args&&...) const & {
147
- set_call<Args&&...>(CT_Const | CT_LValue);
173
+ constexpr bool operator ()(Args&&...) const & {
174
+ st_-> set_call <Args&&...>(CT_Const | CT_LValue);
148
175
return true ;
149
176
}
150
177
151
178
// Don't allow the call operator to be invoked as an rvalue.
152
179
template <class ...Args>
153
- bool operator ()(Args&&...) && {
154
- set_call<Args&&...>(CT_NonConst | CT_RValue);
180
+ constexpr bool operator ()(Args&&...) && {
181
+ st_-> set_call <Args&&...>(CT_NonConst | CT_RValue);
155
182
return true ;
156
183
}
157
184
158
185
template <class ...Args>
159
- bool operator ()(Args&&...) const && {
160
- set_call<Args&&...>(CT_Const | CT_RValue);
186
+ constexpr bool operator ()(Args&&...) const && {
187
+ st_-> set_call <Args&&...>(CT_Const | CT_RValue);
161
188
return true ;
162
189
}
163
-
164
- template <class ...Args>
165
- static void set_call (CallType type) {
166
- assert (last_call_type == CT_None);
167
- assert (last_call_args == nullptr );
168
- last_call_type = type;
169
- last_call_args = &makeArgumentID<Args...>();
170
- }
171
-
172
- template <class ...Args>
173
- static bool check_call (CallType type) {
174
- bool result =
175
- last_call_type == type
176
- && last_call_args
177
- && *last_call_args == makeArgumentID<Args...>();
178
- last_call_type = CT_None;
179
- last_call_args = nullptr ;
180
- return result;
181
- }
182
-
183
- static CallType last_call_type;
184
- static TypeID const * last_call_args;
185
190
};
186
191
187
- CallType ForwardingCallObject::last_call_type = CT_None;
188
- TypeID const * ForwardingCallObject::last_call_args = nullptr ;
189
-
190
-
191
192
192
193
// /////////////////////////////////////////////////////////////////////////////
193
194
// BOOL TEST TYPES
@@ -467,85 +468,86 @@ void call_operator_sfinae_test() {
467
468
void call_operator_forwarding_test ()
468
469
{
469
470
using Fn = ForwardingCallObject;
470
- auto obj = std::not_fn (Fn{});
471
+ Fn::State st;
472
+ auto obj = std::not_fn (Fn{st});
471
473
const auto & c_obj = obj;
472
474
{ // test zero args
473
475
obj ();
474
- assert (Fn:: check_call<>(CT_NonConst | CT_LValue));
476
+ assert (st. check_call <>(CT_NonConst | CT_LValue));
475
477
std::move (obj)();
476
- assert (Fn:: check_call<>(CT_NonConst | CT_RValue));
478
+ assert (st. check_call <>(CT_NonConst | CT_RValue));
477
479
c_obj ();
478
- assert (Fn:: check_call<>(CT_Const | CT_LValue));
480
+ assert (st. check_call <>(CT_Const | CT_LValue));
479
481
std::move (c_obj)();
480
- assert (Fn:: check_call<>(CT_Const | CT_RValue));
482
+ assert (st. check_call <>(CT_Const | CT_RValue));
481
483
}
482
484
{ // test value categories
483
485
int x = 42 ;
484
486
const int cx = 42 ;
485
487
obj (x);
486
- assert (Fn:: check_call<int &>(CT_NonConst | CT_LValue));
488
+ assert (st. check_call <int &>(CT_NonConst | CT_LValue));
487
489
obj (cx);
488
- assert (Fn:: check_call<const int &>(CT_NonConst | CT_LValue));
490
+ assert (st. check_call <const int &>(CT_NonConst | CT_LValue));
489
491
obj (std::move (x));
490
- assert (Fn:: check_call<int &&>(CT_NonConst | CT_LValue));
492
+ assert (st. check_call <int &&>(CT_NonConst | CT_LValue));
491
493
obj (std::move (cx));
492
- assert (Fn:: check_call<const int &&>(CT_NonConst | CT_LValue));
494
+ assert (st. check_call <const int &&>(CT_NonConst | CT_LValue));
493
495
obj (42 );
494
- assert (Fn:: check_call<int &&>(CT_NonConst | CT_LValue));
496
+ assert (st. check_call <int &&>(CT_NonConst | CT_LValue));
495
497
}
496
498
{ // test value categories - rvalue
497
499
int x = 42 ;
498
500
const int cx = 42 ;
499
501
std::move (obj)(x);
500
- assert (Fn:: check_call<int &>(CT_NonConst | CT_RValue));
502
+ assert (st. check_call <int &>(CT_NonConst | CT_RValue));
501
503
std::move (obj)(cx);
502
- assert (Fn:: check_call<const int &>(CT_NonConst | CT_RValue));
504
+ assert (st. check_call <const int &>(CT_NonConst | CT_RValue));
503
505
std::move (obj)(std::move (x));
504
- assert (Fn:: check_call<int &&>(CT_NonConst | CT_RValue));
506
+ assert (st. check_call <int &&>(CT_NonConst | CT_RValue));
505
507
std::move (obj)(std::move (cx));
506
- assert (Fn:: check_call<const int &&>(CT_NonConst | CT_RValue));
508
+ assert (st. check_call <const int &&>(CT_NonConst | CT_RValue));
507
509
std::move (obj)(42 );
508
- assert (Fn:: check_call<int &&>(CT_NonConst | CT_RValue));
510
+ assert (st. check_call <int &&>(CT_NonConst | CT_RValue));
509
511
}
510
512
{ // test value categories - const call
511
513
int x = 42 ;
512
514
const int cx = 42 ;
513
515
c_obj (x);
514
- assert (Fn:: check_call<int &>(CT_Const | CT_LValue));
516
+ assert (st. check_call <int &>(CT_Const | CT_LValue));
515
517
c_obj (cx);
516
- assert (Fn:: check_call<const int &>(CT_Const | CT_LValue));
518
+ assert (st. check_call <const int &>(CT_Const | CT_LValue));
517
519
c_obj (std::move (x));
518
- assert (Fn:: check_call<int &&>(CT_Const | CT_LValue));
520
+ assert (st. check_call <int &&>(CT_Const | CT_LValue));
519
521
c_obj (std::move (cx));
520
- assert (Fn:: check_call<const int &&>(CT_Const | CT_LValue));
522
+ assert (st. check_call <const int &&>(CT_Const | CT_LValue));
521
523
c_obj (42 );
522
- assert (Fn:: check_call<int &&>(CT_Const | CT_LValue));
524
+ assert (st. check_call <int &&>(CT_Const | CT_LValue));
523
525
}
524
526
{ // test value categories - const call rvalue
525
527
int x = 42 ;
526
528
const int cx = 42 ;
527
529
std::move (c_obj)(x);
528
- assert (Fn:: check_call<int &>(CT_Const | CT_RValue));
530
+ assert (st. check_call <int &>(CT_Const | CT_RValue));
529
531
std::move (c_obj)(cx);
530
- assert (Fn:: check_call<const int &>(CT_Const | CT_RValue));
532
+ assert (st. check_call <const int &>(CT_Const | CT_RValue));
531
533
std::move (c_obj)(std::move (x));
532
- assert (Fn:: check_call<int &&>(CT_Const | CT_RValue));
534
+ assert (st. check_call <int &&>(CT_Const | CT_RValue));
533
535
std::move (c_obj)(std::move (cx));
534
- assert (Fn:: check_call<const int &&>(CT_Const | CT_RValue));
536
+ assert (st. check_call <const int &&>(CT_Const | CT_RValue));
535
537
std::move (c_obj)(42 );
536
- assert (Fn:: check_call<int &&>(CT_Const | CT_RValue));
538
+ assert (st. check_call <int &&>(CT_Const | CT_RValue));
537
539
}
538
540
{ // test multi arg
539
541
const double y = 3.14 ;
540
542
std::string s = " abc" ;
541
543
obj (42 , std::move (y), s, std::string{" foo" });
542
- Fn:: check_call<int &&, const double &&, std::string&, std::string&&>(CT_NonConst | CT_LValue);
544
+ assert ((st. check_call <int &&, const double &&, std::string&, std::string&&>(CT_NonConst | CT_LValue)) );
543
545
std::move (obj)(42 , std::move (y), s, std::string{" foo" });
544
- Fn:: check_call<int &&, const double &&, std::string&, std::string&&>(CT_NonConst | CT_RValue);
546
+ assert ((st. check_call <int &&, const double &&, std::string&, std::string&&>(CT_NonConst | CT_RValue)) );
545
547
c_obj (42 , std::move (y), s, std::string{" foo" });
546
- Fn:: check_call<int &&, const double &&, std::string&, std::string&&>(CT_Const | CT_LValue);
548
+ assert ((st. check_call <int &&, const double &&, std::string&, std::string&&>(CT_Const | CT_LValue)) );
547
549
std::move (c_obj)(42 , std::move (y), s, std::string{" foo" });
548
- Fn:: check_call<int &&, const double &&, std::string&, std::string&&>(CT_Const | CT_RValue);
550
+ assert ((st. check_call <int &&, const double &&, std::string&, std::string&&>(CT_Const | CT_RValue)) );
549
551
}
550
552
}
551
553
0 commit comments