Skip to content

Commit 285ef66

Browse files
committed
New macros MEM_RETURN, MEM_WITH, MEM_SIDE_EFFECT, MEM_THROW, etc.
1 parent cc040f8 commit 285ef66

File tree

5 files changed

+189
-29
lines changed

5 files changed

+189
-29
lines changed

include/trompeloeil/coro.hpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,13 @@ namespace trompeloeil
318318

319319
}
320320

321-
#define TROMPELOEIL_CO_RETURN(...) TROMPELOEIL_CO_RETURN_(=, __VA_ARGS__)
322-
#define TROMPELOEIL_LR_CO_RETURN(...) TROMPELOEIL_CO_RETURN_(&, __VA_ARGS__)
321+
#define TROMPELOEIL_CO_RETURN(...) TROMPELOEIL_CO_RETURN_((=), __VA_ARGS__)
322+
#define TROMPELOEIL_LR_CO_RETURN(...) TROMPELOEIL_CO_RETURN_((&), __VA_ARGS__)
323+
#define TROMPELOEIL_MEM_CO_RETURN(...) TROMPELOEIL_CO_RETURN_((&,this), __VA_ARGS__)
323324

324325
#define TROMPELOEIL_CO_RETURN_(capture, ...) \
325-
template action<trompeloeil::handle_co_return>([capture](auto& trompeloeil_x)\
326-
-> decltype(auto) { \
326+
template action<trompeloeil::handle_co_return>( \
327+
[TROMPELOEIL_IDENTITY capture] (auto& trompeloeil_x) -> decltype(auto) { \
327328
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
328329
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
329330
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -343,11 +344,13 @@ namespace trompeloeil
343344
return ::trompeloeil::decay_return_type(__VA_ARGS__); \
344345
})
345346

346-
#define TROMPELOEIL_CO_THROW(...) TROMPELOEIL_CO_THROW_(=, __VA_ARGS__)
347-
#define TROMPELOEIL_LR_CO_THROW(...) TROMPELOEIL_CO_THROW_(&, __VA_ARGS__)
347+
#define TROMPELOEIL_CO_THROW(...) TROMPELOEIL_CO_THROW_((=), __VA_ARGS__)
348+
#define TROMPELOEIL_LR_CO_THROW(...) TROMPELOEIL_CO_THROW_((&), __VA_ARGS__)
349+
#define TROMPELOEIL_MEM_CO_THROW(...) TROMPELOEIL_CO_THROW_((&,this), __VA_ARGS__)
348350

349351
#define TROMPELOEIL_CO_THROW_(capture, ...) \
350-
template action<trompeloeil::handle_co_throw>([capture](auto& trompeloeil_x){\
352+
template action<trompeloeil::handle_co_throw>( \
353+
[TROMPELOEIL_IDENTITY capture](auto& trompeloeil_x){ \
351354
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
352355
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
353356
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -367,12 +370,14 @@ namespace trompeloeil
367370
throw __VA_ARGS__; \
368371
})
369372

370-
#define TROMPELOEIL_CO_YIELD(...) TROMPELOEIL_CO_YIELD_(=, __VA_ARGS__)
371-
#define TROMPELOEIL_LR_CO_YIELD(...) TROMPELOEIL_CO_YIELD_(&, __VA_ARGS__)
373+
#define TROMPELOEIL_CO_YIELD(...) TROMPELOEIL_CO_YIELD_((=), __VA_ARGS__)
374+
#define TROMPELOEIL_LR_CO_YIELD(...) TROMPELOEIL_CO_YIELD_((&), __VA_ARGS__)
375+
#define TROMPELOEIL_MEM_CO_YIELD(...) TROMPELOEIL_CO_YIELD_((&,this), __VA_ARGS__)
372376

373377

374378
#define TROMPELOEIL_CO_YIELD_(capture, ...) \
375-
template action<trompeloeil::handle_co_yield>([capture](auto& trompeloeil_x){\
379+
template action<trompeloeil::handle_co_yield>( \
380+
[TROMPELOEIL_IDENTITY capture](auto& trompeloeil_x){ \
376381
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
377382
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
378383
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -396,10 +401,13 @@ namespace trompeloeil
396401

397402
#define CO_RETURN TROMPELOEIL_CO_RETURN
398403
#define LR_CO_RETURN TROMPELOEIL_LR_CO_RETURN
404+
#define MEM_CO_RETURN TROMPELOEIL_MEM_CO_RETURN
399405
#define CO_THROW TROMPELOEIL_CO_THROW
400406
#define LR_CO_THROW TROMPELOEIL_LR_CO_THROW
407+
#define MEM_CO_THROW TROMPELOEIL_MEM_CO_THROW
401408
#define CO_YIELD TROMPELOEIL_CO_YIELD
402409
#define LR_CO_YIELD TROMPELOEIL_LR_CO_YIELD
410+
#define MEM_CO_YIELD TROMPELOEIL_MEM_CO_YIELD
403411

404412
#endif
405413

include/trompeloeil/cpp11_shenanigans.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ using index_sequence_for = make_index_sequence<sizeof...(T)>;
269269
#define TROMPELOEIL_WITH_(capture, arg_s, ...) \
270270
template action<trompeloeil::with>( \
271271
arg_s, \
272-
[capture] \
272+
[TROMPELOEIL_IDENTITY capture] \
273273
(typename trompeloeil_e_t::trompeloeil_call_params_type_t const& trompeloeil_x)\
274274
{ \
275275
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
@@ -294,7 +294,7 @@ using index_sequence_for = make_index_sequence<sizeof...(T)>;
294294

295295
#define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
296296
template action<trompeloeil::sideeffect>( \
297-
[capture] \
297+
[TROMPELOEIL_IDENTITY capture] \
298298
(typename trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
299299
{ \
300300
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
@@ -319,7 +319,7 @@ using index_sequence_for = make_index_sequence<sizeof...(T)>;
319319

320320
#define TROMPELOEIL_RETURN_(capture, ...) \
321321
template action<trompeloeil::handle_return>( \
322-
[capture] \
322+
[TROMPELOEIL_IDENTITY capture] \
323323
(typename trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
324324
-> typename trompeloeil_e_t::trompeloeil_return_of_t \
325325
{ \
@@ -344,7 +344,7 @@ using index_sequence_for = make_index_sequence<sizeof...(T)>;
344344
})
345345
#define TROMPELOEIL_THROW_(capture, ...) \
346346
template action<trompeloeil::handle_throw>( \
347-
[capture] \
347+
[TROMPELOEIL_IDENTITY capture] \
348348
(typename trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
349349
{ \
350350
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \

include/trompeloeil/mock.hpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,15 +4089,17 @@ template <typename T>
40894089
#endif /* (TROMPELOEIL_CPLUSPLUS > 201103L) */
40904090

40914091

4092-
#define TROMPELOEIL_WITH(...) TROMPELOEIL_WITH_(=,#__VA_ARGS__, __VA_ARGS__)
4093-
#define TROMPELOEIL_LR_WITH(...) TROMPELOEIL_WITH_(&,#__VA_ARGS__, __VA_ARGS__)
4092+
#define TROMPELOEIL_WITH(...) TROMPELOEIL_WITH_((=),#__VA_ARGS__, __VA_ARGS__)
4093+
#define TROMPELOEIL_LR_WITH(...) TROMPELOEIL_WITH_((&),#__VA_ARGS__, __VA_ARGS__)
4094+
#define TROMPELOEIL_MEM_WITH(...) TROMPELOEIL_WITH_((&,this),#__VA_ARGS__, __VA_ARGS__)
40944095

40954096

40964097
#if (TROMPELOEIL_CPLUSPLUS != 201103L)
40974098

40984099
#define TROMPELOEIL_WITH_(capture, arg_s, ...) \
4099-
template action<trompeloeil::with>(arg_s, \
4100-
[capture](auto const& trompeloeil_x) { \
4100+
template action<trompeloeil::with>( \
4101+
arg_s, \
4102+
[TROMPELOEIL_IDENTITY capture](auto const& trompeloeil_x) { \
41014103
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
41024104
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
41034105
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -4120,14 +4122,16 @@ template <typename T>
41204122
#endif /* !(TROMPELOEIL_CPLUSPLUS != 201103L) */
41214123

41224124

4123-
#define TROMPELOEIL_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(=, __VA_ARGS__)
4124-
#define TROMPELOEIL_LR_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_(&, __VA_ARGS__)
4125+
#define TROMPELOEIL_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_((=), __VA_ARGS__)
4126+
#define TROMPELOEIL_LR_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_((&), __VA_ARGS__)
4127+
#define TROMPELOEIL_MEM_SIDE_EFFECT(...) TROMPELOEIL_SIDE_EFFECT_((&,this), __VA_ARGS__)
41254128

41264129

41274130
#if (TROMPELOEIL_CPLUSPLUS != 201103L)
41284131

41294132
#define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
4130-
template action<trompeloeil::sideeffect>([capture](auto& trompeloeil_x) { \
4133+
template action<trompeloeil::sideeffect>( \
4134+
[TROMPELOEIL_IDENTITY capture](auto& trompeloeil_x) { \
41314135
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
41324136
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
41334137
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -4150,15 +4154,16 @@ template <typename T>
41504154
#endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */
41514155

41524156

4153-
#define TROMPELOEIL_RETURN(...) TROMPELOEIL_RETURN_(=, __VA_ARGS__)
4154-
#define TROMPELOEIL_LR_RETURN(...) TROMPELOEIL_RETURN_(&, __VA_ARGS__)
4157+
#define TROMPELOEIL_RETURN(...) TROMPELOEIL_RETURN_((=), __VA_ARGS__)
4158+
#define TROMPELOEIL_LR_RETURN(...) TROMPELOEIL_RETURN_((&), __VA_ARGS__)
4159+
#define TROMPELOEIL_MEM_RETURN(...) TROMPELOEIL_RETURN_((&,this), __VA_ARGS__)
41554160

41564161

41574162
#if (TROMPELOEIL_CPLUSPLUS != 201103L)
41584163

41594164
#define TROMPELOEIL_RETURN_(capture, ...) \
4160-
template action<trompeloeil::handle_return>([capture](auto& trompeloeil_x) \
4161-
-> decltype(auto) { \
4165+
template action<trompeloeil::handle_return>( \
4166+
[TROMPELOEIL_IDENTITY capture](auto& trompeloeil_x) -> decltype(auto) { \
41624167
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
41634168
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
41644169
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -4181,14 +4186,16 @@ template <typename T>
41814186
#endif /* !(TROMPELOEIL_CPLUSPLUS != 201103L) */
41824187

41834188

4184-
#define TROMPELOEIL_THROW(...) TROMPELOEIL_THROW_(=, __VA_ARGS__)
4185-
#define TROMPELOEIL_LR_THROW(...) TROMPELOEIL_THROW_(&, __VA_ARGS__)
4189+
#define TROMPELOEIL_THROW(...) TROMPELOEIL_THROW_((=), __VA_ARGS__)
4190+
#define TROMPELOEIL_LR_THROW(...) TROMPELOEIL_THROW_((&), __VA_ARGS__)
4191+
#define TROMPELOEIL_MEM_THROW(...) TROMPELOEIL_THROW_((&,this), __VA_ARGS__)
41864192

41874193

41884194
#if (TROMPELOEIL_CPLUSPLUS != 201103L)
41894195

41904196
#define TROMPELOEIL_THROW_(capture, ...) \
4191-
template action<trompeloeil::handle_throw>([capture](auto& trompeloeil_x) { \
4197+
template action<trompeloeil::handle_throw>( \
4198+
[TROMPELOEIL_IDENTITY capture](auto& trompeloeil_x) { \
41924199
auto&& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
41934200
auto&& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
41944201
auto&& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \
@@ -4345,12 +4352,16 @@ template <typename T>
43454352

43464353
#define WITH TROMPELOEIL_WITH
43474354
#define LR_WITH TROMPELOEIL_LR_WITH
4355+
#define MEM_WITH TROMPELOEIL_MEM_WITH
43484356
#define SIDE_EFFECT TROMPELOEIL_SIDE_EFFECT
43494357
#define LR_SIDE_EFFECT TROMPELOEIL_LR_SIDE_EFFECT
4358+
#define MEM_SIDE_EFFECT TROMPELOEIL_MEM_SIDE_EFFECT
43504359
#define RETURN TROMPELOEIL_RETURN
43514360
#define LR_RETURN TROMPELOEIL_LR_RETURN
4361+
#define MEM_RETURN TROMPELOEIL_MEM_RETURN
43524362
#define THROW TROMPELOEIL_THROW
43534363
#define LR_THROW TROMPELOEIL_LR_THROW
4364+
#define MEM_THROW TROMPELOEIL_MEM_THROW
43544365
#define TIMES TROMPELOEIL_TIMES
43554366
#define RT_TIMES TROMPELOEIL_RT_TIMES
43564367
#define AT_LEAST TROMPELOEIL_AT_LEAST

test/compiling_tests_14.cpp

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,13 @@ and has.* obj\.func\(_, _\).* as first required):";
526526
INFO(first.file << ':' << first.line << "\n" << first.msg);
527527
}
528528
}
529-
// SIDE_EFFECT and LR_SIDE_EFFECT tests
529+
530+
struct mem_fixture : Fixture
531+
{
532+
int member_variable = 1;
533+
};
534+
535+
// SIDE_EFFECT, LR_SIDE_EFFECT and MEM_SIDE_EFFECT tests
530536

531537
TEST_CASE_METHOD(
532538
Fixture,
@@ -584,6 +590,24 @@ TEST_CASE_METHOD(
584590
REQUIRE(s == "3_3_");
585591
}
586592

593+
#if TROMPELOEIL_CPLUSPLUS >= 202003L
594+
595+
TEST_CASE_METHOD(
596+
mem_fixture,
597+
"C++20: MEM_SIDE_EFFECT has access to member variables",
598+
"[C++20][side_effects]")
599+
{
600+
mock_c obj;
601+
REQUIRE_CALL(obj, getter(ANY(int)))
602+
.MEM_SIDE_EFFECT(member_variable = _1)
603+
.RETURN(_1);
604+
605+
obj.getter(3);
606+
REQUIRE(member_variable == 3);
607+
}
608+
609+
#endif
610+
587611
// RETURN and LR_RETURN tests
588612

589613
TEST_CASE_METHOD(
@@ -804,6 +828,24 @@ TEST_CASE_METHOD(
804828
REQUIRE(reports.empty());
805829
}
806830

831+
#if TROMPELOEIL_CPLUSPLUS >= 202003L
832+
833+
TEST_CASE_METHOD(
834+
mem_fixture,
835+
"C++20: MEM_RETURN has access to member variables",
836+
"[C++20][side_effects]")
837+
{
838+
mock_c obj;
839+
REQUIRE_CALL(obj, getter(ANY(int)))
840+
.MEM_RETURN(member_variable + _1);
841+
842+
auto x = obj.getter(3);
843+
REQUIRE(x == 4);
844+
}
845+
846+
#endif
847+
848+
807849
TEST_CASE_METHOD(
808850
Fixture,
809851
"C++14: THROW access copy of local object",
@@ -892,6 +934,30 @@ TEST_CASE_METHOD(
892934
REQUIRE(s == "8");
893935
}
894936

937+
#if TROMPELOEIL_CPLUSPLUS >= 202003L
938+
939+
TEST_CASE_METHOD(
940+
mem_fixture,
941+
"C++20: MEM_THROW has access to member variables",
942+
"[C++20][side_effects]")
943+
{
944+
mock_c obj;
945+
REQUIRE_CALL(obj, getter(ANY(int)))
946+
.MEM_THROW(member_variable + _1);
947+
948+
try {
949+
obj.getter(3);
950+
FAIL("didn't thriw");
951+
}
952+
catch (int x)
953+
{
954+
REQUIRE(x == 4);
955+
}
956+
}
957+
958+
#endif
959+
960+
895961
// WITH and LR_WITH tests
896962

897963
TEST_CASE_METHOD(
@@ -968,6 +1034,30 @@ TEST_CASE_METHOD(
9681034
REQUIRE(reports.empty());
9691035
}
9701036

1037+
#if TROMPELOEIL_CPLUSPLUS >= 202003L
1038+
1039+
TEST_CASE_METHOD(
1040+
mem_fixture,
1041+
"C++20: MEM_WIITH has access to member variables",
1042+
"[C++20][side_effects]")
1043+
{
1044+
mock_c obj;
1045+
{
1046+
REQUIRE_CALL(obj, getter(ANY(int)))
1047+
.MEM_WITH(member_variable == _1)
1048+
.RETURN(0);
1049+
REQUIRE(obj.getter(1) == 0);
1050+
}
1051+
{
1052+
REQUIRE_CALL(obj, getter(ANY(int)))
1053+
.MEM_WITH(member_variable > _1)
1054+
.RETURN(1);
1055+
1056+
REQUIRE(obj.getter(0) == 1);
1057+
}
1058+
}
1059+
1060+
#endif
9711061

9721062
TEST_CASE_METHOD(
9731063
Fixture,

test/test_co_mock.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,57 @@ TEST_CASE_METHOD(
208208
REQUIRE(reports.empty());
209209
}
210210

211+
struct co_member_fixture : Fixture
212+
{
213+
int member_variable = 1;
214+
};
215+
216+
TEST_CASE_METHOD(
217+
co_member_fixture,
218+
"MEM_CO_RETURN can access member variables",
219+
"[coro]")
220+
{
221+
co_mock m;
222+
REQUIRE_CALL(m, intret())
223+
.MEM_CO_RETURN(member_variable++);
224+
auto p = m.intret();
225+
int v = 0;
226+
std::invoke([&]() -> coro::task<void> { v = co_await p;});
227+
REQUIRE(v == 1);
228+
REQUIRE(this->member_variable == 2);
229+
}
230+
231+
TEST_CASE_METHOD(
232+
co_member_fixture,
233+
"MEM_CO_YIELD can access member variables",
234+
"[coro]")
235+
{
236+
co_mock m;
237+
REQUIRE_CALL(m, intret())
238+
.MEM_CO_YIELD(member_variable++)
239+
.CO_RETURN(0);
240+
auto p = m.intret();
241+
int v = 0;
242+
std::invoke([&]() -> coro::task<void> { v = co_await p;});
243+
REQUIRE(v == 1);
244+
REQUIRE(this->member_variable == 2);
245+
std::invoke([&]() -> coro::task<void> { v = co_await p;});
246+
REQUIRE(v == 0);
247+
}
248+
249+
TEST_CASE_METHOD(
250+
co_member_fixture,
251+
"MEM_CO_THROW can access member variables",
252+
"[coro]")
253+
{
254+
co_mock m;
255+
REQUIRE_CALL(m, intret())
256+
.MEM_CO_THROW(member_variable++);
257+
auto p = m.intret();
258+
std::invoke([&]() -> coro::task<void> { REQUIRE_THROWS(co_await p); });
259+
REQUIRE(member_variable == 2);
260+
}
261+
211262
#ifdef __cpp_lib_generator
212263
TEST_CASE_METHOD(
213264
Fixture,

0 commit comments

Comments
 (0)