VCCC  2024.05
VisualCamp Common C++ library
is_swappable.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/09/29.
3 //
4 
5 #ifndef VCCC_TYPE_TRAITS_IS_SWAPPABLE_HPP
6 #define VCCC_TYPE_TRAITS_IS_SWAPPABLE_HPP
7 
8 #include <utility>
9 #include <type_traits>
10 
16 
17 namespace vccc {
18 
21 
22 template<typename T> struct is_swappable;
23 template<typename T> struct is_nothrow_swappable;
24 
25 namespace internal {
26 
27 namespace swappable_test_std {
28 
29 # if __cplusplus < 201703L
30 
31 template<typename T, typename U>
32 struct is_swappable_with_impl : conjunction<
33  std::is_convertible<decltype(std::declval<U>()), decltype(std::declval<T>())>,
34  std::is_convertible<decltype(std::declval<T>()), decltype(std::declval<U>())>,
35  std::is_move_constructible<std::remove_reference_t<T>>, std::is_move_assignable<std::remove_reference_t<T>>,
36  std::is_move_constructible<std::remove_reference_t<U>>, std::is_move_assignable<std::remove_reference_t<U>>
37  > {
38  static constexpr bool nothrow =
39  std::is_nothrow_move_constructible<std::remove_reference_t<T>>::value && std::is_nothrow_move_assignable<std::remove_reference_t<T>>::value &&
40  std::is_nothrow_move_constructible<std::remove_reference_t<U>>::value && std::is_nothrow_move_assignable<std::remove_reference_t<U>>::value;
41 };
42 
43 template<typename T, std::size_t N>
44 struct is_swappable_with_impl<T(&)[N], T(&)[N]> : is_swappable<T> {
45  static constexpr bool nothrow = is_nothrow_swappable<T>::value;
46 };
47 
48 # else
49 using std::swap;
50 template<typename T, typename U, typename = void>
51 struct is_swappable_with_impl : std::false_type {};
52 
53 template<typename T, typename U>
54 struct is_swappable_with_impl<T, U, void_t<
55  decltype((swap(std::declval<T>(), std::declval<U>()),
56  swap(std::declval<U>(), std::declval<T>()))
57  )>
58  > : std::true_type {
59  static constexpr bool nothrow
60  = noexcept(swap(std::declval<T>(), std::declval<U>())) &&
61  noexcept(swap(std::declval<U>(), std::declval<T>()));
62 
63 };
64 
65 # endif
66 
67 } // namespace swappable_test_std
68 
69 namespace swappable_test_adl {
70 
71 template<typename T, typename U, typename = void>
72 struct is_swappable_with_impl : std::false_type {};
73 
74 template<typename T, typename U>
75 struct is_swappable_with_impl<T, U, void_t<
76  decltype((swap(std::declval<T>(), std::declval<U>()),
77  swap(std::declval<U>(), std::declval<T>())))>> : std::true_type {
78  static constexpr bool nothrow
79  = noexcept(swap(std::declval<T>(), std::declval<U>())) &&
80  noexcept(swap(std::declval<U>(), std::declval<T>()));
81 };
82 
83 } // namespace swappable_test_adl
84 
85 #if __cplusplus < 201703L
86 
87 template<typename T, typename U>
88 struct is_swappable_with_impl :
89  disjunction<swappable_test_adl::is_swappable_with_impl<T, U>,
90  swappable_test_std::is_swappable_with_impl<T, U>> {};
91 
93 struct is_nothrow_swappable_with_impl : bool_constant<is_swappable_with_impl<T, U>::nothrow> {};
94 
95 template<typename T, typename U>
96 struct is_nothrow_swappable_with_impl<T, U, false> : std::false_type {};
97 
98 #else
99 
100 template<typename T, typename U>
101 struct is_swappable_with_impl : std::is_swappable_with<T, U> {};
102 
103 template<typename T, typename U>
104 struct is_nothrow_swappable_with_impl : std::is_nothrow_swappable_with<T, U> {};
105 
106 #endif
107 
108 } // namespace internal
109 
110 template<typename T, typename U>
111 struct is_swappable_with : internal::is_swappable_with_impl<T, U> {};
112 
113 template<typename T>
114 struct is_swappable :
115  std::conditional_t<
116  !is_referencable<T>::value,
117  std::false_type,
118  is_swappable_with<std::add_lvalue_reference_t<T>, std::add_lvalue_reference_t<T>>
119  > {};
120 
121 template<typename T, typename U>
122 struct is_nothrow_swappable_with : internal::is_nothrow_swappable_with_impl<T, U> {};
123 
124 template<typename T>
126 
128 
129 } // namespace vccc
130 
131 
132 # if __cplusplus < 201703L
133 
135 
136 # endif
137 
138 #endif // VCCC_TYPE_TRAITS_IS_SWAPPABLE_HPP
void swap(::vccc::optional< T > &lhs, ::vccc::optional< T > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition: swap.h:30
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
void void_t
Definition: void_t.hpp:19
constexpr std::enable_if_t< conjunction< is_swappable< T >, is_swappable< U > >::value > swap(compressed_pair< T, U > &lhs, compressed_pair< T, U > &rhs) noexcept(conjunction< is_nothrow_swappable< T >, is_nothrow_swappable< U >>::value)
Definition: compressed_pair.hpp:108
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: is_swappable.hpp:122
Definition: is_swappable.hpp:125
Definition: is_swappable.hpp:111
Definition: is_swappable.hpp:119