source: mainline/uspace/lib/cpp/src/__bits/test/functional.cpp@ 15e0b4d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 15e0b4d was 69cc156, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: renamed aux::invoke to aux::INVOKE to match standard and avoid conflicts with std::invoke, added functional tests and fixed some bugs found by them

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <__bits/test/tests.hpp>
30#include <functional>
31#include <type_traits>
32#include <utility>
33
34using namespace std::placeholders;
35
36namespace std::test
37{
38 namespace aux
39 {
40 int f1(int a, int b)
41 {
42 return a + b;
43 }
44
45 int f2(int a, int b)
46 {
47 return a * 10 + b;
48 }
49
50 void f3(int& a, int& b)
51 {
52 a = 42;
53 b = 1337;
54 }
55
56 struct Foo
57 {
58 int add(int a)
59 {
60 return a + data;
61 }
62
63 int data;
64 };
65 }
66
67 bool functional_test::run(bool report)
68 {
69 report_ = report;
70 start();
71
72 test_reference_wrapper();
73 test_function();
74 test_bind();
75
76 return end();
77 }
78
79 const char* functional_test::name()
80 {
81 return "functional";
82 }
83
84 void functional_test::test_reference_wrapper()
85 {
86 int x{4};
87 auto ref = std::ref(x);
88
89 test("reference_wrapper equivalence after construction (cast)", (ref == x));
90 test("reference_wrapper equivalence after construction (get)", (ref.get() == x));
91
92 ref.get() = 5;
93 test_eq("reference_wrapper equivalence after modification pt1", ref.get(), 5);
94 test_eq("reference_wrapper equivalence after modification pt2", x, 5);
95
96 int y{10};
97 ref = y;
98 test_eq("reference_wrapper equivalence after assignment pt1", ref.get(), 10);
99 test_eq("reference_wrapper equivalence after assignment pt2", x, 5);
100
101 std::function<int(int, int)> wrapped_f1{&aux::f1};
102 auto fref = std::ref(wrapped_f1);
103 auto res = fref(2, 5);
104 test_eq("reference_wrapper function invoke", res, 7);
105 }
106
107 void functional_test::test_function()
108 {
109 std::function<int(int, int)> f1{&aux::f1};
110 auto res1 = f1(1, 2);
111
112 test_eq("function from function pointer", res1, 3);
113
114 int x{};
115 std::function<char(char)> f2{[&](auto c){ x = 42; return ++c; }};
116 auto res2 = f2('B');
117
118 test_eq("function from lambda", res2, 'C');
119 test_eq("function from lambda - capture", x, 42);
120
121 test("function operator bool", (bool)f2);
122 f2 = nullptr;
123 test("function nullptr assignment", !f2);
124 }
125
126 void functional_test::test_bind()
127 {
128 auto f1 = std::bind(aux::f1, _1, 1);
129 auto res1 = f1(3);
130
131 test_eq("bind placeholder", res1, 4);
132
133 auto f2 = std::bind(aux::f2, _2, _1);
134 auto res2 = f2(5, 6);
135
136 test_eq("bind reverse placeholder order", res2, 65);
137
138 int x{};
139 int y{};
140 auto f3 = std::bind(aux::f3, _1, std::ref(y));
141 f3(std::ref(x));
142
143 test_eq("bind std::ref as bound", y, 1337);
144 test_eq("bind std::ref as unbound", x, 42);
145
146 auto f4 = std::bind(aux::f2, x, y);
147 auto res3 = f4();
148
149 test_eq("bind all arguments bound", res3, 1757);
150
151 aux::Foo foo{5};
152 auto f5 = std::mem_fn(&aux::Foo::add);
153 auto res4 = f5(&foo, 4);
154
155 test_eq("mem_fn", res4, 9);
156
157 /* auto f5 = std::bind(&aux::Foo::add, _1, _2); */
158 /* auto res4 = f4(&foo, 10); */
159
160 /* test_eq("bind to member function", res4, 19); */
161 }
162}
Note: See TracBrowser for help on using the repository browser.