VCCC  2024.05
VisualCamp Common C++ library
control_special.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2/1/24.
3 //
4 
5 #ifndef VCCC_TYPE_TRAITS_CORE_CONTROL_SPECIAL_HPP
6 #define VCCC_TYPE_TRAITS_CORE_CONTROL_SPECIAL_HPP
7 
8 #include <type_traits>
9 
11 
12 namespace vccc {
13 namespace detail {
14 
15 template<typename Base>
16 struct non_trivial_copy_ctor : Base {
17  using base = Base;
18  using base::base;
19 
20  non_trivial_copy_ctor() = default;
21  non_trivial_copy_ctor(const non_trivial_copy_ctor& other)
22  noexcept(noexcept(std::declval<Base&>().construct_from(static_cast<const Base&>(other))))
23  {
24  Base::construct_from(static_cast<const Base&>(other));
25  }
26  non_trivial_copy_ctor(non_trivial_copy_ctor&&) = default;
27  non_trivial_copy_ctor& operator=(const non_trivial_copy_ctor&) = default;
28  non_trivial_copy_ctor& operator=(non_trivial_copy_ctor&&) = default;
29 };
30 
31 template<typename Base>
32 struct deleted_copy_ctor : Base {
33  using base = Base;
34  using base::base;
35 
36  deleted_copy_ctor() = default;
37  deleted_copy_ctor(const deleted_copy_ctor&) = delete;
38  deleted_copy_ctor(deleted_copy_ctor&&) = default;
39  deleted_copy_ctor& operator=(const deleted_copy_ctor&) = default;
40  deleted_copy_ctor& operator=(deleted_copy_ctor&&) = default;
41 };
42 
43 template<typename Base, typename... T>
44 using control_copy_ctor =
45  std::conditional_t<
46  conjunction<std::is_trivially_copy_constructible<T>...>::value, Base,
47  std::conditional_t<
48  conjunction<std::is_copy_constructible<T>...>::value, non_trivial_copy_ctor<Base>,
49  deleted_copy_ctor<Base>
50  >>;
51 
52 template<typename Base, typename... T>
53 struct non_trivial_move_ctor : control_copy_ctor<Base, T...> {
54  using base = control_copy_ctor<Base, T...>;
55  using base::base;
56 
57  non_trivial_move_ctor() = default;
58  non_trivial_move_ctor(const non_trivial_move_ctor&) = default;
59  non_trivial_move_ctor(non_trivial_move_ctor&& other)
60  noexcept(noexcept(std::declval<Base&>().construct_from(static_cast<Base&&>(other))))
61  {
62  Base::construct_from(static_cast<Base&&>(other));
63  }
64  non_trivial_move_ctor& operator=(const non_trivial_move_ctor&) = default;
65  non_trivial_move_ctor& operator=(non_trivial_move_ctor&&) = default;
66 };
67 
68 template<typename Base, typename... T>
69 struct deleted_move_ctor : control_copy_ctor<Base, T...> {
70  using base = control_copy_ctor<Base, T...>;
71  using base::base;
72 
73  deleted_move_ctor() = default;
74  deleted_move_ctor(const deleted_move_ctor&) = default;
75  deleted_move_ctor(deleted_move_ctor&&) = delete;
76  deleted_move_ctor& operator=(const deleted_move_ctor&) = default;
77  deleted_move_ctor& operator=(deleted_move_ctor&&) = default;
78 };
79 
80 template<typename Base, typename... T>
81 using control_move_ctor =
82  std::conditional_t<
83  conjunction<std::is_trivially_move_constructible<T>...>::value, control_copy_ctor<Base, T...>,
84  std::conditional_t<
85  conjunction<std::is_move_constructible<T>...>::value, non_trivial_move_ctor<Base, T...>,
86  deleted_move_ctor<Base, T...>
87  >>;
88 
89 template<typename Base, typename... T>
90 struct non_trivial_copy_assign : control_move_ctor<Base, T...> {
91  using base = control_move_ctor<Base, T...>;
92  using base::base;
93 
94  non_trivial_copy_assign() = default;
95  non_trivial_copy_assign(const non_trivial_copy_assign& other) = default;
96  non_trivial_copy_assign(non_trivial_copy_assign&&) = default;
97  non_trivial_copy_assign& operator=(const non_trivial_copy_assign& other)
98  noexcept(noexcept(std::declval<Base&>().assign_from(static_cast<const Base&>(other))))
99  {
100  Base::assign_from(static_cast<const Base&>(other));
101  return *this;
102  }
103  non_trivial_copy_assign& operator=(non_trivial_copy_assign&&) = default;
104 };
105 
106 template<typename Base, typename... T>
107 struct deleted_copy_assign : control_move_ctor<Base, T...> {
108  using base = control_move_ctor<Base, T...>;
109  using base::base;
110 
111  deleted_copy_assign() = default;
112  deleted_copy_assign(const deleted_copy_assign&) = default;
113  deleted_copy_assign(deleted_copy_assign&&) = default;
114  deleted_copy_assign& operator=(const deleted_copy_assign&) = delete;
115  deleted_copy_assign& operator=(deleted_copy_assign&&) = default;
116 };
117 
118 template<typename Base, typename... T>
119 using control_copy_assign =
120  std::conditional_t<
121  conjunction<
122  std::is_trivially_copy_constructible<T>...,
123  std::is_trivially_copy_assignable<T>...,
124  std::is_trivially_destructible<T>...
125  >::value,
126  control_move_ctor<Base, T...>,
127  std::conditional_t<
128  conjunction<
129  std::is_copy_constructible<T>...,
130  std::is_copy_assignable<T>...
131  >::value,
132  non_trivial_copy_assign<Base, T...>,
133  deleted_copy_assign<Base, T...>
134  >>;
135 
136 template<typename Base, typename... T>
137 struct non_trivial_move_assign : control_copy_assign<Base, T...> {
138  using base = control_copy_assign<Base, T...>;
139  using base::base;
140 
141  non_trivial_move_assign() = default;
142  non_trivial_move_assign(const non_trivial_move_assign& other) = default;
143  non_trivial_move_assign(non_trivial_move_assign&&) = default;
144  non_trivial_move_assign& operator=(const non_trivial_move_assign&) = default;
145  non_trivial_move_assign& operator=(non_trivial_move_assign&& other)
146  noexcept(noexcept(std::declval<Base&>().assign_from(static_cast<Base&&>(other))))
147  {
148  Base::assign_from(static_cast<Base&&>(other));
149  return *this;
150  }
151 };
152 
153 template<typename Base, typename... T>
154 struct deleted_move_assign : control_copy_assign<Base, T...> {
155  using base = control_copy_assign<Base, T...>;
156  using base::base;
157 
158  deleted_move_assign() = default;
159  deleted_move_assign(const deleted_move_assign&) = default;
160  deleted_move_assign(deleted_move_assign&&) = default;
161  deleted_move_assign& operator=(const deleted_move_assign&) = default;
162  deleted_move_assign& operator=(deleted_move_assign&&) = delete;
163 };
164 
165 template<typename Base, typename... T>
166 using control_move_assign =
167  std::conditional_t<
168  conjunction<
169  std::is_trivially_move_constructible<T>...,
170  std::is_trivially_move_assignable<T>...,
171  std::is_trivially_destructible<T>...
172  >::value,
173  control_copy_assign<Base, T...>,
174  std::conditional_t<
175  conjunction<
176  std::is_move_constructible<T>...,
177  std::is_move_assignable<T>...
178  >::value,
179  non_trivial_move_assign<Base, T...>,
180  deleted_move_assign<Base, T...>
181  >>;
182 
183 // DtorBase must define construct_from and assign_from
184 template<typename DtorBase, typename... T>
185 using control_special = control_move_assign<DtorBase, T...>;
186 
187 } // namespace detail
188 } // namespace vccc
189 
190 #endif // VCCC_TYPE_TRAITS_CORE_CONTROL_SPECIAL_HPP
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35