VCCC  2024.05
VisualCamp Common C++ library
join_with.hpp
Go to the documentation of this file.
1 //
2 // Created by yonggyulee on 2/13/24.
3 //
4 
5 #ifndef VCCC_RANGES_VIEWS_JOIN_WITH_HPP_
6 #define VCCC_RANGES_VIEWS_JOIN_WITH_HPP_
7 
8 #include <type_traits>
9 #include <utility>
10 
13 #include "vccc/__ranges/range.hpp"
17 #include "vccc/__ranges/view.hpp"
24 
25 namespace vccc {
26 namespace ranges {
27 namespace views {
28 namespace detail {
29 
30 template<typename T>
32 template<template<typename T, typename...> class Class, typename T1, typename... Ts>
33 struct first_template_arg<Class<T1, Ts...>> {
34  static_assert(derived_from_single_crtp<Class<T1, Ts...>, view_interface>::value, "Class must be view");
35  using type = T1;
36 };
37 
38 template<typename T>
40 
41 // Using its own implementation to support lazy pattern evaluation
42 template<typename Pattern>
43 class join_with_adaptor : public range_adaptor_closure<join_with_adaptor<Pattern>> {
45 
46  public:
48  constexpr explicit join_with_adaptor(U&& pattern)
49  : pattern_(std::forward<U>(pattern)) {}
50 
52  constexpr auto operator()(R&& r) & {
53  return call(*this, std::forward<R>(r), is_implicitly_constructible<range_value_t<range_reference_t<R>>, prv&>{});
54  }
55 
57  constexpr auto operator()(R&& r) const& {
58  return call(*this, std::forward<R>(r), is_implicitly_constructible<range_value_t<range_reference_t<R>>, const prv&>{});
59  }
60 
62  constexpr auto operator()(R&& r) && {
63  return call(std::move(*this), std::forward<R>(r), is_implicitly_constructible<range_value_t<range_reference_t<R>>, prv&&>{});
64  }
65 
67  constexpr auto operator()(R&& r) const&& {
68  return call(std::move(*this), std::forward<R>(r), is_implicitly_constructible<range_value_t<range_reference_t<R>>, const prv&&>{});
69  }
70 
71  private:
72  constexpr decltype(auto) value_ref() & { return *pattern_.begin(); }
73  constexpr decltype(auto) value_ref() const& { return *pattern_.begin(); }
74  constexpr decltype(auto) value_ref() && { return std::move(*pattern_.begin()); }
75  constexpr decltype(auto) value_ref() const&& { return std::move(*pattern_.begin()); }
76 
77  template<typename This, typename R>
78  constexpr static auto call(This&& thiz, R&& r, std::true_type) {
79  return join_with_view<all_t<R>, single_view<range_value_t<range_reference_t<R>>>>(
80  std::forward<R>(r), std::forward<This>(thiz).value_ref());
81  }
82 
83  template<typename This, typename R>
84  constexpr static auto call(This&& thiz, R&& r, std::false_type) {
85  return join_with_view<all_t<R>, Pattern>{std::forward<R>(r), std::forward<This>(thiz).pattern_};
86  }
87 
88  Pattern pattern_;
89 };
90 
92  template<typename R, typename Pattern, std::enable_if_t<conjunction<
96  >::value, int> = 0>
97  constexpr auto operator()(R&& r, Pattern&& pattern) const {
98  return join_with_view<all_t<R>, all_t<Pattern>>{std::forward<R>(r), std::forward<Pattern>(pattern)};
99  }
100 
101  template<typename R, std::enable_if_t<conjunction<
103  >::value, int> = 0>
104  constexpr auto operator()(R&& r, range_value_t<range_reference_t<R>> pattern) const {
106  std::forward<R>(r), std::move(pattern)};
107  }
108 
109  template<typename Pattern>
110  constexpr auto operator()(Pattern&& pattern) const {
111  return create_closure(std::forward<Pattern>(pattern), has_typename_type<all_t_impl<Pattern>>{});
112  }
113 
114  private:
115  template<typename Pattern>
116  constexpr auto create_closure(Pattern&& pattern, std::true_type /* all */) const {
117  return join_with_adaptor<views::all_t<Pattern>>(std::forward<Pattern>(pattern));
118  }
119 
120  template<typename Pattern>
121  constexpr auto create_closure(Pattern&& pattern, std::false_type /* all */) const {
122  return join_with_adaptor<decltype(views::single(std::forward<Pattern>(pattern)))>(std::forward<Pattern>(pattern));
123  }
124 };
125 
126 } // namespace detail
127 
130 
132 
134 
135 } // namespace views
136 } // namespace ranges
137 } // namespace vccc
138 
139 #endif // VCCC_RANGES_VIEWS_JOIN_WITH_HPP_
Definition: join_with_view.hpp:173
Definition: single.hpp:38
helper class template for defining a view, using the curiously recurring template pattern
Definition: view_interface.hpp:78
constexpr join_with_adaptor(U &&pattern)
Definition: join_with.hpp:48
constexpr auto operator()(R &&r) &&
Definition: join_with.hpp:62
constexpr auto operator()(R &&r) const &
Definition: join_with.hpp:57
constexpr auto operator()(R &&r) const &&
Definition: join_with.hpp:67
constexpr auto operator()(R &&r) &
Definition: join_with.hpp:52
constexpr VCCC_INLINE_OR_STATIC detail::join_with_niebloid join_with
Definition: join_with.hpp:131
typename detail::all_t_impl< R >::type all_t
Calculates the suitable view type of a viewable_range type.
Definition: all.hpp:107
typename range_reference< R >::type range_reference_t
Used to obtain the reference type of the iterator type of range type R.
Definition: range_reference_t.hpp:42
typename range_value< R >::type range_value_t
Used to obtain the value type of the iterator type of range type R.
Definition: range_value_t.hpp:42
#define VCCC_INLINE_OR_STATIC
Definition: inline_or_static.hpp:9
Definition: matrix.hpp:495
typename first_template_arg< T >::type first_template_arg_t
Definition: join_with.hpp:39
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
specifies that a type is derived from single specialization of CRTP base
Definition: derived_from_single_crtp.hpp:51
Definition: has_typename_type.hpp:18
Definition: is_implicitly_constructible.hpp:23
Definition: negation.hpp:23
helper base class template for defining a range adaptor closure object
Definition: range_adaptor_closure.hpp:96
specifies the requirements for a range to be safely convertible to a view
Definition: viewable_range.hpp:59
constexpr auto operator()(R &&r, range_value_t< range_reference_t< R >> pattern) const
Definition: join_with.hpp:104
constexpr auto operator()(R &&r, Pattern &&pattern) const
Definition: join_with.hpp:97
constexpr auto operator()(Pattern &&pattern) const
Definition: join_with.hpp:110