@@ -17,10 +17,29 @@ namespace {
1717 return i + 1 ;
1818 }
1919
20- class PlusOner {
20+ struct PlusOner {
21+ int operator ()(int i) const {
22+ return i + 1 ;
23+ }
24+ };
25+
26+ class MoveOnlyAdder {
27+ private:
28+ // unique_ptr is better for triggering asan than an int if there's a
29+ // dangling reference to the callable
30+ std::unique_ptr<int > add_amount_;
31+
2132 public:
33+ MoveOnlyAdder (int v) : add_amount_{std::make_unique<int >(v)} {}
34+
35+ MoveOnlyAdder (const MoveOnlyAdder&) = delete ;
36+ MoveOnlyAdder& operator =(const MoveOnlyAdder&) = delete ;
37+
38+ MoveOnlyAdder (MoveOnlyAdder&&) = default ;
39+ MoveOnlyAdder& operator =(MoveOnlyAdder&&) = default ;
40+
2241 int operator ()(int i) {
23- return i + 1 ;
42+ return i + *add_amount_ ;
2443 }
2544 };
2645
@@ -33,31 +52,48 @@ namespace {
3352 }
3453}
3554
36- TEST_CASE (" imap: works with lambda, callable, and function" , " [imap]" ) {
37- Vec ns = {10 , 20 , 30 };
55+ TEST_CASE (" imap: handles different callable types" , " [imap]" ) {
56+ Vec ns = {10 , 15 , 300 };
57+ Vec vc = {11 , 16 , 301 };
3858 std::vector<int > v;
39- SECTION (" with lambda " ) {
40- auto im = imap ([]( int i) { return i + 1 ; } , ns);
41- v. assign (std::begin (im ), std::end (im ));
59+ SECTION (" with function pointer " ) {
60+ auto m = imap (plusone , ns);
61+ v = Vec (std::begin (m ), std::end (m ));
4262 }
4363
44- SECTION (" with callable" ) {
45- SECTION (" Normal call" ) {
46- auto im = imap (PlusOner{}, ns);
47- v.assign (std::begin (im), std::end (im));
64+ SECTION (" with callable object" ) {
65+ auto m = imap (PlusOner{}, ns);
66+ v = Vec (std::begin (m), std::end (m));
67+ }
68+
69+ SECTION (" with lvalue callable object" ) {
70+ auto lt = PlusOner{};
71+ SECTION (" normal call" ) {
72+ auto m = imap (lt, ns);
73+ v = Vec (std::begin (m), std::end (m));
4874 }
49- SECTION (" Pipe " ) {
50- auto im = ns | imap (PlusOner{} );
51- v. assign (std::begin (im ), std::end (im ));
75+ SECTION (" pipe " ) {
76+ auto m = ns | imap (lt );
77+ v = Vec (std::begin (m ), std::end (m ));
5278 }
5379 }
5480
55- SECTION (" with function" ) {
56- auto im = imap (PlusOner{}, ns);
57- v.assign (std::begin (im), std::end (im));
81+ SECTION (" with move-only callable object" ) {
82+ SECTION (" normal call" ) {
83+ auto m = imap (MoveOnlyAdder{1 }, ns);
84+ v = Vec (std::begin (m), std::end (m));
85+ }
86+ SECTION (" pipe" ) {
87+ auto m = ns | imap (MoveOnlyAdder{1 });
88+ v = Vec (std::begin (m), std::end (m));
89+ }
5890 }
5991
60- Vec vc = {11 , 21 , 31 };
92+ SECTION (" with lambda" ) {
93+ auto ltf = [](int i) { return i + 1 ; };
94+ auto m = imap (ltf, ns);
95+ v = Vec (std::begin (m), std::end (m));
96+ }
6197 REQUIRE (v == vc);
6298}
6399
0 commit comments