Add translations for various sub-directories
[binutils-gdb.git] / gdb / unittests / function-view-selftests.c
blobdc1a6304eb683ca142621f0b82226ecd1da91ecf
1 /* Self tests for function_view for GDB, the GNU debugger.
3 Copyright (C) 2017-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "gdbsupport/selftest.h"
21 #include "gdbsupport/function-view.h"
23 namespace selftests {
24 namespace function_view {
26 static int
27 plus_one_fn_int (int val)
29 return ++val;
32 static short
33 plus_one_fn_short (short val)
35 return ++val;
38 static int
39 call_callback_int (int val, gdb::function_view <int (int)> callback)
41 return callback (val);
44 static void
45 call_callback_void (int val, gdb::function_view <void (int)> callback)
47 callback (val);
50 struct plus_one_int_func_obj
52 int operator () (int val)
54 ++call_count;
55 return ++val;
58 /* Number of times called. */
59 int call_count = 0;
62 static void
63 test_function_view ()
65 /* A simple lambda. */
66 auto plus_one_lambda = [] (int val) { return ++val; };
68 /* A function_view that references the lambda. */
69 gdb::function_view<int (int)> plus_one_func_view (plus_one_lambda);
71 /* Check calling the lambda directly. */
72 SELF_CHECK (plus_one_lambda (0) == 1);
73 SELF_CHECK (plus_one_lambda (1) == 2);
75 /* Check calling lambda via the view. */
76 SELF_CHECK (plus_one_func_view (2) == 3);
77 SELF_CHECK (plus_one_func_view (3) == 4);
79 /* Check calling a function that takes a function_view as argument,
80 by value. Pass a lambda, making sure a function_view is properly
81 constructed implicitly. */
82 SELF_CHECK (call_callback_int (1, [] (int val)
84 return val + 2;
85 }) == 3);
87 /* Same, passing a named/lvalue lambda. */
88 SELF_CHECK (call_callback_int (1, plus_one_lambda) == 2);
89 /* Same, passing a named/lvalue function_view (should copy). */
90 SELF_CHECK (call_callback_int (1, plus_one_func_view) == 2);
92 /* Check constructing a function view over a function-object
93 callable, and calling it. */
94 plus_one_int_func_obj func_obj;
95 SELF_CHECK (func_obj (0) == 1);
96 SELF_CHECK (call_callback_int (1, func_obj) == 2);
97 /* Check that the callable was referenced, not copied. */
98 SELF_CHECK (func_obj.call_count == 2);
100 /* Check constructing a function_view over a free-function callable,
101 and calling it. */
102 SELF_CHECK (call_callback_int (1, plus_one_fn_int) == 2);
104 /* Check calling a function with a
105 compatible-but-not-exactly-the-same prototype. */
106 SELF_CHECK (call_callback_int (1, [] (short val) -> short
108 return val + 2;
109 }) == 3);
110 /* Same, but passing a function pointer. */
111 SELF_CHECK (call_callback_int (1, plus_one_fn_short) == 2);
113 /* Like std::function, a function_view that expects a void return
114 can reference callables with non-void return type. The result is
115 simply discarded. Check a lambda, function object and a function
116 pointer. */
117 call_callback_void (1, [] (int val) -> int
119 return val + 2;
121 call_callback_void (1, func_obj);
122 call_callback_void (1, plus_one_fn_int);
124 /* Check that the main ctor doesn't hijack the copy ctor. */
125 auto plus_one_func_view2 (plus_one_func_view);
126 auto plus_one_func_view3 (plus_one_func_view2);
127 static_assert (std::is_same<decltype (plus_one_func_view),
128 decltype (plus_one_func_view2)>::value, "");
129 static_assert (std::is_same<decltype (plus_one_func_view),
130 decltype (plus_one_func_view3)>::value, "");
132 SELF_CHECK (plus_one_func_view3 (1) == 2);
134 /* Likewise, but propagate a NULL callable. If this calls the main
135 function_view ctor instead of the copy ctor by mistake, then
136 null_func_2 ends up non-NULL (because it'd instead reference
137 null_func_1 as just another callable). */
138 constexpr gdb::function_view<int (int)> null_func_view_1 = nullptr;
139 constexpr auto null_func_view_2 (null_func_view_1);
141 /* While at it, check whether the function_view is bound using
142 various forms, op==, op!= and op bool. */
144 /* op== */
145 static_assert (null_func_view_2 == nullptr, "");
146 static_assert (nullptr == null_func_view_2, "");
147 static_assert (null_func_view_2 == NULL, "");
148 static_assert (NULL == null_func_view_2, "");
150 /* op!= */
151 static_assert (!(null_func_view_2 != nullptr), "");
152 static_assert (!(nullptr != null_func_view_2), "");
153 static_assert (!(null_func_view_2 != NULL), "");
154 static_assert (!(NULL != null_func_view_2), "");
156 /* op bool */
157 static_assert (!null_func_view_2, "");
159 /* Check the nullptr_t ctor. */
160 constexpr gdb::function_view<int (int)> check_ctor_nullptr (nullptr);
161 static_assert (!check_ctor_nullptr, "");
163 /* Check the nullptr_t op= */
164 gdb::function_view<int (int)> check_op_eq_null (plus_one_fn_int);
165 SELF_CHECK (check_op_eq_null);
166 check_op_eq_null = nullptr;
167 SELF_CHECK (!check_op_eq_null);
170 /* A template function where the function_view type is dependent on a
171 template parameter. */
173 template<typename T>
174 static int
175 tmpl_func (T val, gdb::function_view<T (T)> callback)
177 return callback (val) + 1;
180 static int
181 make_fv_test_func (int val)
183 return val + 1;
186 /* A function object with const operator(). */
188 struct func_obj_const_op
190 int operator() (int val) const
192 return val + 1;
196 /* A function object with non-const operator(). */
198 struct func_obj_non_const_op
200 int operator() (int val)
202 return val + 1;
206 static void
207 test_make_function_view ()
209 /* Function reference. */
210 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (make_fv_test_func)));
212 /* Function pointer. */
213 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (&make_fv_test_func)));
215 /* Reference to const and non-const function pointers. */
216 typedef int (*func_ptr) (int);
217 func_ptr ptr = make_fv_test_func;
218 const func_ptr cptr = make_fv_test_func;
219 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (ptr)));
220 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (cptr)));
222 /* Lambdas. */
224 auto lambda = [] (int val) -> int { return val + 1; };
226 /* This wouldn't compile, since tmpl_func is a template and its
227 function_view argument's callable type is a dependent type. The
228 passed argument must be of the exact type of the function's
229 parameter. */
230 // SELF_CHECK (3 == tmpl_func (1, lambda));
232 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (lambda)));
234 /* Regular function objects. */
236 func_obj_non_const_op fobj;
237 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (fobj)));
239 func_obj_const_op cfobj;
240 SELF_CHECK (3 == tmpl_func (1, gdb::make_function_view (cfobj)));
243 static void
244 run_tests ()
246 test_function_view ();
247 test_make_function_view ();
250 } /* namespace function_view */
251 } /* namespace selftests */
253 void _initialize_function_view_selftests ();
254 void
255 _initialize_function_view_selftests ()
257 selftests::register_test ("function_view",
258 selftests::function_view::run_tests);