1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LIBCXX_TEST_STD_UTILITIES_TUPLE_ASSIGN_TYPES_H
9 #define LIBCXX_TEST_STD_UTILITIES_TUPLE_ASSIGN_TYPES_H
10 
11 #include "test_allocator.h"
12 #include <type_traits>
13 
14 struct CopyAssign {
15   int val;
16 
17   constexpr CopyAssign() = default;
CopyAssignCopyAssign18   constexpr CopyAssign(int v) : val(v) {}
19 
20   constexpr CopyAssign& operator=(const CopyAssign&) = default;
21 
22   constexpr const CopyAssign& operator=(const CopyAssign&) const = delete;
23   constexpr CopyAssign& operator=(CopyAssign&&) = delete;
24   constexpr const CopyAssign& operator=(CopyAssign&&) const = delete;
25 };
26 
27 struct ConstCopyAssign {
28   mutable int val;
29 
30   constexpr ConstCopyAssign() = default;
ConstCopyAssignConstCopyAssign31   constexpr ConstCopyAssign(int v) : val(v) {}
32 
33   constexpr const ConstCopyAssign& operator=(const ConstCopyAssign& other) const {
34     val = other.val;
35     return *this;
36   }
37 
38   constexpr ConstCopyAssign& operator=(const ConstCopyAssign&) = delete;
39   constexpr ConstCopyAssign& operator=(ConstCopyAssign&&) = delete;
40   constexpr const ConstCopyAssign& operator=(ConstCopyAssign&&) const = delete;
41 };
42 
43 struct MoveAssign {
44   int val;
45 
46   constexpr MoveAssign() = default;
MoveAssignMoveAssign47   constexpr MoveAssign(int v) : val(v) {}
48 
49   constexpr MoveAssign& operator=(MoveAssign&&) = default;
50 
51   constexpr MoveAssign& operator=(const MoveAssign&) = delete;
52   constexpr const MoveAssign& operator=(const MoveAssign&) const = delete;
53   constexpr const MoveAssign& operator=(MoveAssign&&) const = delete;
54 };
55 
56 struct ConstMoveAssign {
57   mutable int val;
58 
59   constexpr ConstMoveAssign() = default;
ConstMoveAssignConstMoveAssign60   constexpr ConstMoveAssign(int v) : val(v) {}
61 
62   constexpr const ConstMoveAssign& operator=(ConstMoveAssign&& other) const {
63     val = other.val;
64     return *this;
65   }
66 
67   constexpr ConstMoveAssign& operator=(const ConstMoveAssign&) = delete;
68   constexpr const ConstMoveAssign& operator=(const ConstMoveAssign&) const = delete;
69   constexpr ConstMoveAssign& operator=(ConstMoveAssign&&) = delete;
70 };
71 
72 template <class T>
73 struct AssignableFrom {
74   T v;
75 
76   constexpr AssignableFrom() = default;
77 
78   template <class U>
AssignableFromAssignableFrom79   constexpr AssignableFrom(U&& u)
80     requires std::is_constructible_v<T, U&&>
81   : v(std::forward<U>(u)) {}
82 
83   constexpr AssignableFrom& operator=(const T& t)
84     requires std::is_copy_assignable_v<T>
85   {
86     v = t;
87     return *this;
88   }
89 
90   constexpr AssignableFrom& operator=(T&& t)
91     requires std::is_move_assignable_v<T>
92   {
93     v = std::move(t);
94     return *this;
95   }
96 
97   constexpr const AssignableFrom& operator=(const T& t) const
98     requires std::is_assignable_v<const T&, const T&>
99   {
100     v = t;
101     return *this;
102   }
103 
104   constexpr const AssignableFrom& operator=(T&& t) const
105     requires std::is_assignable_v<const T&, T&&>
106   {
107     v = std::move(t);
108     return *this;
109   }
110 };
111 
112 struct TracedAssignment {
113   int copyAssign = 0;
114   mutable int constCopyAssign = 0;
115   int moveAssign = 0;
116   mutable int constMoveAssign = 0;
117 
118   constexpr TracedAssignment() = default;
119 
120   constexpr TracedAssignment& operator=(const TracedAssignment&) {
121     copyAssign++;
122     return *this;
123   }
124   constexpr const TracedAssignment& operator=(const TracedAssignment&) const {
125     constCopyAssign++;
126     return *this;
127   }
128   constexpr TracedAssignment& operator=(TracedAssignment&&) {
129     moveAssign++;
130     return *this;
131   }
132   constexpr const TracedAssignment& operator=(TracedAssignment&&) const {
133     constMoveAssign++;
134     return *this;
135   }
136 };
137 
138 #endif
139