VCCC  2024.05
VisualCamp Common C++ library
end.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2023/12/24.
3 //
4 
5 #ifndef VCCC_RANGES_END_HPP_
6 #define VCCC_RANGES_END_HPP_
7 
8 #include <cstddef>
9 #include <type_traits>
10 
22 
23 namespace vccc {
24 namespace ranges {
25 namespace detail {
26 
27 using vccc::detail::return_category;
28 
29 struct end_niebloid {
30  private:
31  template<typename T, bool = is_bounded_array<remove_cvref_t<T>>::value>
32  struct end_array_check : std::false_type {
33  using category = return_category<0>;
34  };
35  template<typename T>
36  struct end_array_check<T, true> : std::true_type {
37  using category = return_category<1, decltype(std::declval<T>() + std::extent<std::remove_reference_t<T>>::value)>;
38  };
39 
40  template<typename T, typename = void>
41  struct end_member_check : std::false_type {
42  using category = return_category<0>;
43  };
44  template<typename T>
45  struct end_member_check<T, void_t<decltype(vccc_decay_copy(std::declval<T>().end()))>>
46  : sentinel_for<decltype(vccc_decay_copy(std::declval<T>().end())), iterator_t<T>> {
47  using category = return_category<2, decltype(vccc_decay_copy(std::declval<T>().end()))>;
48  };
49 
50  template<typename T, typename = void>
51  struct end_global_check : std::false_type {
52  using category = return_category<0>;
53  };
54  template<typename T>
55  struct end_global_check<T, void_t<decltype(vccc_decay_copy(end(std::declval<T>())))>>
56  : sentinel_for<decltype(vccc_decay_copy(end(std::declval<T>()))), iterator_t<T>> {
57  using category = return_category<3, decltype(vccc_decay_copy(end(std::declval<T>())))>;
58  };
59 
61  struct end_category_impl_2 : end_global_check<T> {};
62  template<typename T>
63  struct end_category_impl_2<T, true> : end_member_check<T> {};
64 
66  struct end_category_impl : end_category_impl_2<T> {};
67  template<typename T>
68  struct end_category_impl<T, true> : end_array_check<T> {};
69 
70  template<typename T>
71  struct end_category
72  : std::conditional_t<
73  disjunction<
74  std::is_lvalue_reference<T>,
75  enable_borrowed_range<remove_cvref_t<T>>
76  >::value,
77  typename end_category_impl<T>::category,
78  return_category<0>
79  > {};
80 
81  template<typename T, typename R>
82  constexpr R operator()(T&& t, return_category<1, R>) const {
83  static_assert(is_complete<std::remove_all_extents_t<std::remove_reference_t<T>>>::value, "Array element must be complete type");
84  return t + std::extent<remove_cvref_t<T>>::value;
85  }
86 
87  template<typename T, typename R>
88  constexpr R operator()(T&& t, return_category<2, R>) const {
89  return vccc_decay_copy(t.end());
90  }
91 
92  template<typename T, typename R>
93  constexpr R operator()(T&& t, return_category<3, R>) const {
94  return vccc_decay_copy(end(t));
95  }
96 
97  public:
98  template<typename T>
99  constexpr typename end_category<T&&>::return_type
100  operator()(T&& t) const {
101  return (*this)(std::forward<T>(t), end_category<T&&>{});
102  }
103 };
104 
105 } // namespace detail
106 
107 namespace niebloid {
108 
111 
120 VCCC_INLINE_OR_STATIC constexpr detail::end_niebloid end{};
121 
123 
124 } // namespace niebloid
125 using namespace niebloid;
126 
127 } // namespace ranges
128 } // namespace vccc
129 
130 #endif // VCCC_RANGES_END_HPP_
#define vccc_decay_copy(x)
Definition: decay_copy.hpp:12
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
void void_t
Definition: void_t.hpp:19
decltype(detail::is_complete_impl(std::declval< T * >())) is_complete
Definition: is_complete.hpp:23
#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