VCCC  2024.05
VisualCamp Common C++ library
iter_move.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/24.
3 //
4 
5 #ifndef VCCC_ITERATOR_ITER_MOVE_HPP_
6 #define VCCC_ITERATOR_ITER_MOVE_HPP_
7 
8 #include <type_traits>
9 #include <utility>
10 
17 
18 namespace vccc {
19 namespace ranges {
20 namespace detail_iter_move {
21 
23  private:
24  template<std::size_t N>
25  using return_category = vccc::detail::return_category<N>;
26 
27  template<
28  typename T,
30  typename = void
31  >
32  struct has_adl : std::false_type {
33  using category = return_category<0>;
34  };
35  template<typename T>
36  struct has_adl<T, true, void_t<decltype(iter_move(std::declval<T>()))>> : std::true_type {
37  using category = return_category<1>;
38  };
39 
40  template<typename I, template<typename, typename...> class Test, bool = dereferenceable<I>::value /* false */>
41  struct deref_is : std::false_type {};
42 
43  template<typename I, template<typename, typename...> class Test>
44  struct deref_is<I, Test, true> : Test<decltype(*std::declval<I>())> {};
45 
46  template<typename T>
47  struct category
48  : std::conditional_t<
49  has_adl<T>::value, return_category<1>,
50  std::conditional_t<
51  deref_is<T, std::is_lvalue_reference>::value, return_category<2>,
52  std::conditional_t<
53  dereferenceable<T>::value, return_category<3>,
54  return_category<0>
55  >>> {};
56 
57  template<typename T>
58  constexpr decltype(auto) call(T&& t, return_category<1>) const {
59  return iter_move(std::forward<T>(t));
60  }
61 
62  template<typename T>
63  constexpr decltype(auto) call(T&& t, return_category<2>) const {
64  return std::move(*std::forward<T>(t));
65  }
66 
67  template<typename T>
68  constexpr decltype(auto) call(T&& t, return_category<3>) const {
69  return *std::forward<T>(t);
70  }
71 
72  public:
73  template<typename T, std::enable_if_t<(category<T&&>::value > 0), int> = 0>
74  constexpr decltype(auto) operator()(T &&t) const {
75  return this->call(std::forward<T>(t), category<T&&>{});
76  }
77 };
78 
79 } // namespace detail_iter_move
80 
81 namespace niebloid {
82 
88 
93 
96 
97 } // inline namespace niebloid
98 using namespace niebloid;
99 
100 } // namespace ranges
101 } // namespace vccc
102 
103 #endif // VCCC_ITERATOR_ITER_MOVE_HPP_
constexpr VCCC_INLINE_OR_STATIC detail_iter_move::iter_move_niebloid iter_move
Definition: iter_move.hpp:92
void void_t
Definition: void_t.hpp:19
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
specifies that an object of a type can be dereferenced
Definition: dereferenceable.hpp:45
Definition: is_class_or_enum.hpp:20