VCCC  2024.05
VisualCamp Common C++ library
max.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 01/27/24.
3 //
4 
5 #ifndef VCCC_ALGORITHM_RANGES_MAX_HPP
6 #define VCCC_ALGORITHM_RANGES_MAX_HPP
7 
8 #include <functional>
9 #include <initializer_list>
10 
25 
26 namespace vccc {
27 namespace ranges {
28 namespace detail {
29 
30 struct max_niebloid {
31  private:
32  template<typename R, typename Proj, typename Comp, bool = projectable<iterator_t<R>, Proj>::value /* false */>
33  struct check_range_2 : std::false_type {};
34  template<typename R, typename Proj, typename Comp>
35  struct check_range_2<R, Proj, Comp, true>
36  : conjunction<
37  indirect_strict_weak_order<Comp, projected<iterator_t<R>, Proj>>,
38  indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*>
39  > {};
40 
42  struct check_range : std::false_type {};
43  template<typename R, typename Proj, typename Comp>
44  struct check_range<R, Proj, Comp, true> : check_range_2<R, Proj, Comp> {};
45 
46  template<typename R, typename Proj, typename Comp>
47  constexpr range_value_t<R>
48  max_range(R&& r, Comp comp, Proj proj, std::true_type /* forward_range */) const {
49  return static_cast<range_value_t<R>>(*ranges::max_element(r, std::ref(comp), std::ref(proj)));
50  }
51 
52  template<typename R, typename Proj, typename Comp>
53  constexpr range_value_t<R>
54  max_range(R&& r, Comp comp, Proj proj, std::false_type /* forward_range */) const {
55  auto i = ranges::begin(r);
56  auto s = ranges::end(r);
57  range_value_t<R> m(*i);
58  while (++i != s) {
59  if (!vccc::invoke(comp, vccc::invoke(proj, m), vccc::invoke(proj, *i)))
60  m = *i;
61  }
62  return m;
63  }
64 
65  public:
66  template<typename T, typename Proj = identity, typename Comp = less, std::enable_if_t<
67  indirect_strict_weak_order<Comp, projected<const T*, Proj>>::value, int> = 0>
68  constexpr const T&
69  operator()(const T& a, const T& b, Comp comp = {}, Proj proj = {}) const {
70  return vccc::invoke(comp, vccc::invoke(proj, a), vccc::invoke(proj, b)) ? b : a;
71  }
72 
73  template<typename T, typename Proj = identity, typename Comp = less,
74  std::enable_if_t<conjunction<
75  copyable<T>,
76  indirect_strict_weak_order<Comp, projected<const T*, Proj>>
77  >::value, int> = 0>
78  constexpr T
79  operator()(std::initializer_list<T> r, Comp comp = {}, Proj proj = {}) const {
80  return *ranges::max_element(r, std::ref(comp), std::ref(proj));
81  }
82 
83  template<typename R, typename Proj = identity, typename Comp = less,
85  constexpr range_value_t<R>
86  operator()(R&& r, Comp comp = {}, Proj proj = {}) const {
87  return this->max_range(std::forward<R>(r), std::ref(comp), std::ref(proj), forward_range<R>{});
88  }
89 };
90 } // namespace detail
91 
94 
95 VCCC_INLINE_OR_STATIC constexpr detail::max_niebloid max{};
96 
98 
99 } // namespace ranges
100 } // namespace vccc
101 
102 #endif // VCCC_ALGORITHM_RANGES_MAX_HPP
constexpr VCCC_INLINE_OR_STATIC detail::max_niebloid max
Definition: max.hpp:95
constexpr VCCC_INLINE_OR_STATIC detail::max_element_niebloid max_element
Definition: max_element.hpp:61
constexpr invoke_result_t< F, Args... > invoke(F &&f, Args &&... args) noexcept(is_nothrow_invocable< F, Args... >::value)
Definition: invoke.hpp:38
constexpr VCCC_INLINE_OR_STATIC detail::begin_niebloid begin
returns an iterator to the beginning of a range
Definition: begin.hpp:116
constexpr VCCC_INLINE_OR_STATIC detail::end_niebloid end
returns a sentinel indicating the end of a range
Definition: end.hpp:120
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35