summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/20_util/move_only_function/cons.cc
blob: 44e9681b694a43987cda2d85b2012c91c7a26c26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// { dg-options "-std=gnu++23" }
// { dg-do compile { target c++23 } }
// { dg-require-effective-target hosted }

#include <functional>

#ifndef __cpp_lib_move_only_function
# error "Feature-test macro for move_only_function missing in <functional>"
#elif __cpp_lib_move_only_function != 202110L
# error "Feature-test macro for move_only_function has wrong value in <functional>"
#endif

using std::move_only_function;

using std::is_constructible_v;
using std::is_copy_constructible_v;
using std::is_nothrow_default_constructible_v;
using std::is_nothrow_move_constructible_v;
using std::is_nothrow_constructible_v;
using std::nullptr_t;
using std::in_place_type_t;

static_assert( is_nothrow_default_constructible_v<move_only_function<void()>> );
static_assert( is_nothrow_constructible_v<move_only_function<void()>, nullptr_t> );
static_assert( is_nothrow_move_constructible_v<move_only_function<void()>> );
static_assert( ! is_copy_constructible_v<move_only_function<void()>> );

static_assert( is_constructible_v<move_only_function<void()>, void()> );
static_assert( is_constructible_v<move_only_function<void()>, void(&)()> );
static_assert( is_constructible_v<move_only_function<void()>, void(*)()> );
static_assert( is_constructible_v<move_only_function<void()>, int()> );
static_assert( is_constructible_v<move_only_function<void()>, int(&)()> );
static_assert( is_constructible_v<move_only_function<void()>, int(*)()> );
static_assert( ! is_constructible_v<move_only_function<void()>, void(int)> );
static_assert( is_constructible_v<move_only_function<void(int)>, void(int)> );

static_assert( is_constructible_v<move_only_function<void(int)>,
				  in_place_type_t<void(*)(int)>, void(int)> );

static_assert( is_constructible_v<move_only_function<void()>,
				  void() noexcept> );
static_assert( is_constructible_v<move_only_function<void() noexcept>,
				  void() noexcept> );
static_assert( ! is_constructible_v<move_only_function<void() noexcept>,
				    void() > );

struct Q
{
  void operator()() const &;
  void operator()() &&;
};

static_assert( is_constructible_v<move_only_function<void()>, Q> );
static_assert( is_constructible_v<move_only_function<void() const>, Q> );
static_assert( is_constructible_v<move_only_function<void() &>, Q> );
static_assert( is_constructible_v<move_only_function<void() const &>, Q> );
static_assert( is_constructible_v<move_only_function<void() &&>, Q> );
static_assert( is_constructible_v<move_only_function<void() const &&>, Q> );

struct R
{
  void operator()() &;
  void operator()() &&;
};

static_assert( is_constructible_v<move_only_function<void()>, R> );
static_assert( is_constructible_v<move_only_function<void()&>, R> );
static_assert( is_constructible_v<move_only_function<void()&&>, R> );
static_assert( ! is_constructible_v<move_only_function<void() const>, R> );
static_assert( ! is_constructible_v<move_only_function<void() const&>, R> );
static_assert( ! is_constructible_v<move_only_function<void() const&&>, R> );

// The following nothrow-constructible guarantees are a GCC extension,
// not required by the standard.

static_assert( is_nothrow_constructible_v<move_only_function<void()>, void()> );
static_assert( is_nothrow_constructible_v<move_only_function<void(int)>,
					  in_place_type_t<void(*)(int)>,
					  void(int)> );

// These types are all small and nothrow move constructible
struct F { void operator()(); };
struct G { void operator()() const; };
static_assert( is_nothrow_constructible_v<move_only_function<void()>, F> );
static_assert( is_nothrow_constructible_v<move_only_function<void()>, G> );
static_assert( is_nothrow_constructible_v<move_only_function<void() const>, G> );

struct H {
  H(int);
  H(int, int) noexcept;
  void operator()() noexcept;
};
static_assert( is_nothrow_constructible_v<move_only_function<void()>, H> );
static_assert( is_nothrow_constructible_v<move_only_function<void() noexcept>,
					  H> );
static_assert( ! is_nothrow_constructible_v<move_only_function<void() noexcept>,
					    in_place_type_t<H>, int> );
static_assert( is_nothrow_constructible_v<move_only_function<void() noexcept>,
					  in_place_type_t<H>, int, int> );

struct I {
  I(int, const char*);
  I(std::initializer_list<char>);
  int operator()() const noexcept;
};

static_assert( is_constructible_v<move_only_function<void()>,
				  std::in_place_type_t<I>,
				  int, const char*> );
static_assert( is_constructible_v<move_only_function<void()>,
				  std::in_place_type_t<I>,
				  std::initializer_list<char>> );

void
test_instantiation()
{
  // Instantiate the constructor bodies
  move_only_function<void()> f0;
  move_only_function<void()> f1(nullptr);
  move_only_function<void()> f2( I(1, "two") );
  move_only_function<void()> f3(std::in_place_type<I>, 3, "four");
  move_only_function<void()> f4(std::in_place_type<I>, // PR libstdc++/102825
				{ 'P', 'R', '1', '0', '2', '8', '2', '5'});
  auto f5 = std::move(f4);
  f4 = std::move(f5);
}