VCCC  2024.05
VisualCamp Common C++ library
swap.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/21.
3 //
4 
5 #ifndef VCCC_CONCEPTS_SWAP_HPP
6 #define VCCC_CONCEPTS_SWAP_HPP
7 
8 #include <type_traits>
9 #include <utility>
10 
11 #include "vccc/core.hpp"
19 
20 namespace vccc {
21 namespace ranges {
22 namespace detail_ranges_swap {
23 
24 using std::swap;
25 
26 template<typename T>
27 constexpr void swap(T&, T&) = delete;
28 
29 template<typename T, typename U>
30 constexpr auto test_swap(int) -> decltype(swap(std::declval<T>(), std::declval<U>()), std::true_type{});
31 
32 template<typename T, typename U>
33 constexpr auto test_swap(...) -> std::false_type;
34 
35 template<typename T, typename U, bool = disjunction<
38 struct adl_swappable : std::false_type {};
39 
40 template<typename T, typename U>
41 struct adl_swappable<T, U, true> : decltype(test_swap<T, U>(0)) {};
42 
43 template<typename T, typename U, typename = void>
44 struct swappable_array : std::false_type {};
45 
46 struct swap_niebloid {
47  template<typename T, typename U, std::enable_if_t<
49  ::value, int> = 0>
50  constexpr void operator()(T&& t, U&& u) const noexcept(noexcept(swap(std::forward<T>(t), std::forward<U>(u)))) {
51  swap(std::forward<T>(t), std::forward<U>(u));
52  }
53 
54  template<typename T, typename U, std::size_t N, std::enable_if_t<conjunction<
55  negation< adl_swappable<T(&)[N], U(&)[N]> >,
56  swappable_array<T(&)[N], U(&)[N]>
57  >::value, int> = 0>
58  constexpr void operator()(T(&t)[N], U(&u)[N]) const noexcept(noexcept((*this)(*t, *u))) {
59  // TODO: Use swap_ranges
60  for (std::size_t i = 0; i < N; ++i) {
61  (*this)(t[i], u[i]);
62  }
63  }
64 
65  template<typename V, std::enable_if_t<conjunction<
67  move_constructible<V>,
69  >::value, int> = 0>
70  constexpr void operator()(V& t, V& u) const
72  {
73  V temp(std::move(t));
74  t = std::move(u);
75  u = std::move(temp);
76  }
77 };
78 
79 } // namespace detail_ranges_swap
80 
82 namespace niebloid {
83 
86 
87 
100 
102 
103 } // namespace niebloid
104 using namespace niebloid;
105 
106 namespace detail_ranges_swap {
107 
108 template<typename T, typename U, std::size_t N>
109 struct swappable_array<T(&)[N], U(&)[N], void_t<decltype(ranges::swap(*std::declval<T(&)[N]>(), *std::declval<U(&)[N]>()))>>
110  : std::true_type {};
111 
112 } // namespace detail
113 
114 } // namespace ranges
115 } // namespace vccc
116 
117 #endif // VCCC_CONCEPTS_SWAP_HPP
constexpr VCCC_INLINE_OR_STATIC detail_ranges_swap::swap_niebloid swap
swaps the values of two objects
Definition: swap.hpp:99
void swap(::vccc::optional< T > &lhs, ::vccc::optional< T > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Definition: swap.h:30
void void_t
Definition: void_t.hpp:19
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
constexpr void swap(T &, T &)=delete
constexpr auto test_swap(int) -> decltype(swap(std::declval< T >(), std::declval< U >()), std::true_type{})
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Models std::assignable_from
Definition: assignable_from.hpp:66
Definition: conjunction.hpp:22
Definition: disjunction.hpp:22
Definition: is_class_or_enum.hpp:20
Definition: negation.hpp:23
constexpr void operator()(V &t, V &u) const noexcept(std::is_nothrow_move_constructible< V >::value &&std::is_nothrow_move_assignable< V >::value)
Definition: swap.hpp:70
constexpr void operator()(T &&t, U &&u) const noexcept(noexcept(swap(std::forward< T >(t), std::forward< U >(u))))
Definition: swap.hpp:50
constexpr void operator()(T(&t)[N], U(&u)[N]) const noexcept(noexcept((*this)(*t, *u)))
Definition: swap.hpp:58