1 /* Self tests for function_view for GDB, the GNU debugger.
3 Copyright (C) 2017-2022 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/>. */
21 #include "gdbsupport/selftest.h"
22 #include "gdbsupport/function-view.h"
25 namespace function_view
{
28 plus_one_fn_int (int val
)
34 plus_one_fn_short (short val
)
40 call_callback_int (int val
, gdb::function_view
<int (int)> callback
)
42 return callback (val
);
46 call_callback_void (int val
, gdb::function_view
<void (int)> callback
)
51 struct plus_one_int_func_obj
53 int operator () (int val
)
59 /* Number of times called. */
66 /* A simple lambda. */
67 auto plus_one_lambda
= [] (int val
) { return ++val
; };
69 /* A function_view that references the lambda. */
70 gdb::function_view
<int (int)> plus_one_func_view (plus_one_lambda
);
72 /* Check calling the lambda directly. */
73 SELF_CHECK (plus_one_lambda (0) == 1);
74 SELF_CHECK (plus_one_lambda (1) == 2);
76 /* Check calling lambda via the view. */
77 SELF_CHECK (plus_one_func_view (2) == 3);
78 SELF_CHECK (plus_one_func_view (3) == 4);
80 /* Check calling a function that takes a function_view as argument,
81 by value. Pass a lambda, making sure a function_view is properly
82 constructed implicitly. */
83 SELF_CHECK (call_callback_int (1, [] (int val
)
88 /* Same, passing a named/lvalue lambda. */
89 SELF_CHECK (call_callback_int (1, plus_one_lambda
) == 2);
90 /* Same, passing a named/lvalue function_view (should copy). */
91 SELF_CHECK (call_callback_int (1, plus_one_func_view
) == 2);
93 /* Check constructing a function view over a function-object
94 callable, and calling it. */
95 plus_one_int_func_obj func_obj
;
96 SELF_CHECK (func_obj (0) == 1);
97 SELF_CHECK (call_callback_int (1, func_obj
) == 2);
98 /* Check that the callable was referenced, not copied. */
99 SELF_CHECK (func_obj
.call_count
== 2);
101 /* Check constructing a function_view over a free-function callable,
103 SELF_CHECK (call_callback_int (1, plus_one_fn_int
) == 2);
105 /* Check calling a function with a
106 compatible-but-not-exactly-the-same prototype. */
107 SELF_CHECK (call_callback_int (1, [] (short val
) -> short
111 /* Same, but passing a function pointer. */
112 SELF_CHECK (call_callback_int (1, plus_one_fn_short
) == 2);
114 /* Like std::function, a function_view that expects a void return
115 can reference callables with non-void return type. The result is
116 simply discarded. Check a lambda, function object and a function
118 call_callback_void (1, [] (int val
) -> int
122 call_callback_void (1, func_obj
);
123 call_callback_void (1, plus_one_fn_int
);
125 /* Check that the main ctor doesn't hijack the copy ctor. */
126 auto plus_one_func_view2 (plus_one_func_view
);
127 auto plus_one_func_view3 (plus_one_func_view2
);
128 static_assert (std::is_same
<decltype (plus_one_func_view
),
129 decltype (plus_one_func_view2
)>::value
, "");
130 static_assert (std::is_same
<decltype (plus_one_func_view
),
131 decltype (plus_one_func_view3
)>::value
, "");
133 SELF_CHECK (plus_one_func_view3 (1) == 2);
135 /* Likewise, but propagate a NULL callable. If this calls the main
136 function_view ctor instead of the copy ctor by mistake, then
137 null_func_2 ends up non-NULL (because it'd instead reference
138 null_func_1 as just another callable). */
139 constexpr gdb::function_view
<int (int)> null_func_view_1
= nullptr;
140 constexpr auto null_func_view_2 (null_func_view_1
);
142 /* While at it, check whether the function_view is bound using
143 various forms, op==, op!= and op bool. */
146 static_assert (null_func_view_2
== nullptr, "");
147 static_assert (nullptr == null_func_view_2
, "");
148 static_assert (null_func_view_2
== NULL
, "");
149 static_assert (NULL
== null_func_view_2
, "");
152 static_assert (!(null_func_view_2
!= nullptr), "");
153 static_assert (!(nullptr != null_func_view_2
), "");
154 static_assert (!(null_func_view_2
!= NULL
), "");
155 static_assert (!(NULL
!= null_func_view_2
), "");
158 static_assert (!null_func_view_2
, "");
160 /* Check the nullptr_t ctor. */
161 constexpr gdb::function_view
<int (int)> check_ctor_nullptr (nullptr);
162 static_assert (!check_ctor_nullptr
, "");
164 /* Check the nullptr_t op= */
165 gdb::function_view
<int (int)> check_op_eq_null (plus_one_fn_int
);
166 SELF_CHECK (check_op_eq_null
);
167 check_op_eq_null
= nullptr;
168 SELF_CHECK (!check_op_eq_null
);
171 } /* namespace function_view */
172 } /* namespace selftests */
174 void _initialize_function_view_selftests ();
176 _initialize_function_view_selftests ()
178 selftests::register_test ("function_view",
179 selftests::function_view::run_tests
);