VCCC  2024.05
VisualCamp Common C++ library
rend.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2024/02/08.
3 //
4 
5 #ifndef VCCC_RANGES_REND_HPP_
6 #define VCCC_RANGES_REND_HPP_
7 
8 #include <iterator>
9 #include <type_traits>
10 
18 #include "vccc/__ranges/begin.hpp"
19 #include "vccc/__ranges/rbegin.hpp"
24 
25 namespace vccc {
26 namespace ranges {
27 namespace detail {
28 
29 using vccc::detail::tag_1;
30 using vccc::detail::tag_2;
31 using vccc::detail::tag_3;
32 
33 struct rend_niebloid {
34  private:
35 
37  struct rend_member_check : std::false_type {};
38  template<typename T>
39  struct rend_member_check<T,
40  true, void_t<decltype(vccc_decay_copy( std::declval<T>().rend() ))>>
41  : sentinel_for<decltype(vccc_decay_copy( std::declval<T>().rend() )),
42  decltype( ranges::rbegin(std::declval<T>()) )> {};
43 
44  template<typename T, bool = conjunction<
45  is_invocable<rbegin_niebloid, T&&>,
46  is_class_or_enum<remove_cvref_t<T>>>::value, typename = void>
47  struct rend_global_check : std::false_type {};
48  template<typename T>
49  struct rend_global_check<T,
50  true, void_t<decltype(vccc_decay_copy( rend(std::declval<T>()) ))>>
51  : sentinel_for<decltype(vccc_decay_copy( rend(std::declval<T>()) )),
52  decltype( ranges::rbegin(std::declval<T>()) )> {};
53 
55  struct common_bidi_check : std::false_type {};
56  template<typename T>
57  struct common_bidi_check<T, true> : bidirectional_iterator<decltype( ranges::begin(std::declval<T>()) )> {};
58 
59  template<typename T>
60  using rend_tag = conditional_tag<rend_member_check<T>, rend_global_check<T>, common_bidi_check<T>>;
61 
62  template<typename T>
63  constexpr auto run(T&& t, tag_1) const {
64  return vccc_decay_copy(t.rend());
65  }
66 
67  template<typename T>
68  constexpr auto run(T&& t, tag_2) const {
69  return vccc_decay_copy(rend(t));
70  }
71 
72  template<typename T>
73  constexpr auto run(T&& t, tag_3) const {
74  return std::make_reverse_iterator(ranges::begin(t));
75  }
76 
77  public:
78  template<typename T, std::enable_if_t<conjunction<
79  vccc::detail::not_incomplete_array<T>,
80  disjunction<
81  std::is_lvalue_reference<std::remove_cv_t<T>>,
82  enable_borrowed_range<std::remove_cv_t<T>>
83  >,
85  >::value, int> = 0>
86  constexpr auto operator()(T&& t) const {
87  return run(std::forward<T>(t), rend_tag<T>{});
88  }
89 };
90 
91 } // namespace detail
92 
93 namespace niebloid {
94 
97 
98 VCCC_INLINE_OR_STATIC constexpr detail::rend_niebloid rend{};
99 
101 
102 } // namespace niebloid
103 using namespace niebloid;
104 
105 } // namespace ranges
106 } // namespace vccc
107 
108 #endif // VCCC_RANGES_REND_HPP_
#define vccc_decay_copy(x)
Definition: decay_copy.hpp:12
constexpr VCCC_INLINE_OR_STATIC detail::rend_niebloid rend
Definition: rend.hpp:98
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
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