VCCC  2024.05
VisualCamp Common C++ library
range_adaptor.hpp
Go to the documentation of this file.
1 //
2 // Created by YongGyu Lee on 3/25/24.
3 //
4 
5 #ifndef VCCC_RANGES_RANGE_ADAPTOR_HPP_
6 #define VCCC_RANGES_RANGE_ADAPTOR_HPP_
7 
8 #include <tuple>
9 #include <type_traits>
10 #include <utility>
11 
17 
18 namespace vccc {
19 namespace ranges {
20 
23 
24 template<typename Niebloid, typename... Args>
25 class range_adaptor : public range_adaptor_closure<range_adaptor<Niebloid, Args...>> {
26  public:
27  static_assert(std::is_default_constructible<Niebloid>::value, "Constraints not satisfied");
28  static_assert(std::is_empty<Niebloid>::value, "Constraints not satisfied");
29 
30  template<typename... T, std::enable_if_t<conjunction<
32  bool_constant<(sizeof...(Args) == sizeof...(T))>
33  >::value, int> = 0>
34  constexpr explicit range_adaptor(T&&... args)
35  noexcept(conjunction<std::is_nothrow_constructible<Args, T>...>::value)
36  : args_(std::forward<T>(args)...) {}
37 
38  template<typename R, std::enable_if_t<is_invocable<Niebloid, R, Args&...>::value, int> = 0>
39  constexpr decltype(auto) operator()(R&& r) & {
40  return call(*this, std::forward<R>(r), std::index_sequence_for<Args...>{});
41  }
42 
43  template<typename R, std::enable_if_t<is_invocable<Niebloid, R, const Args&...>::value, int> = 0>
44  constexpr decltype(auto) operator()(R&& r) const & {
45  return call(*this, std::forward<R>(r), std::index_sequence_for<Args...>{});
46  }
47 
48  template<typename R, std::enable_if_t<is_invocable<Niebloid, R, Args&&...>::value, int> = 0>
49  constexpr decltype(auto) operator()(R&& r) && {
50  return call(std::move(*this), std::forward<R>(r), std::index_sequence_for<Args...>{});
51  }
52 
53  template<typename R, std::enable_if_t<is_invocable<Niebloid, R, const Args&&...>::value, int> = 0>
54  constexpr decltype(auto) operator()(R&& r) const && {
55  return call(std::move(*this), std::forward<R>(r), std::index_sequence_for<Args...>{});
56  }
57 
58  private:
59  template<typename This, typename R, std::size_t... I>
60  static constexpr decltype(auto) call(This&& thiz, R&& r, std::index_sequence<I...>) {
61  return Niebloid{}(std::forward<R>(r), std::get<I>(std::forward<This>(thiz).args_)...);
62  }
63 
64  std::tuple<Args...> args_;
65 };
66 
68 
69 } // namespace ranges
70 } // namespace vccc
71 
72 #endif // VCCC_RANGES_RANGE_ADAPTOR_HPP_
Definition: range_adaptor.hpp:25
constexpr range_adaptor(T &&... args) noexcept(conjunction< std::is_nothrow_constructible< Args, T >... >::value)
Definition: range_adaptor.hpp:34
std::integral_constant< bool, v > bool_constant
Definition: bool_constant.hpp:19
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35
Definition: conjunction.hpp:22
Definition: different_from.hpp:21
Determines whether INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...) is well formed when treate...
Definition: is_invocable.hpp:77
helper base class template for defining a range adaptor closure object
Definition: range_adaptor_closure.hpp:96