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