VCCC  2024.05
VisualCamp Common C++ library
bind_base.hpp
Go to the documentation of this file.
1 #ifndef VCCC_FUNCTIONAL_DETAIL_BIND_BASE_HPP_
2 #define VCCC_FUNCTIONAL_DETAIL_BIND_BASE_HPP_
3 
4 #include <tuple>
5 #include <utility>
6 
9 
10 namespace vccc {
11 namespace detail {
12 
13 struct bind_object_ctor_tag{};
14 
15 template<typename Derived, typename F, typename... Args>
16 class bind_object_base {
17  template<typename DerivedRef, typename... U>
18  struct bind_invoke_result : Derived::template bind_invoke_result<DerivedRef, U&&...> {};
19 
20  template<typename DerivedRef, typename... U>
21  struct bind_nothrow_invocable : Derived::template bind_nothrow_invocable<DerivedRef, U&&...> {};
22 
23  using index_sequence = std::index_sequence_for<Args...>;
24 
25  public:
26  template<typename F2, typename... Args2>
27  constexpr bind_object_base(bind_object_ctor_tag, F2&& func, Args2&&... args)
28  : func_(std::forward<F2>(func))
29  , args_(std::forward<Args2>(args)...) {}
30 
31  template<typename... U>
32  constexpr typename bind_invoke_result<Derived&, U&&...>::type
33  operator()(U&&... args) & noexcept(bind_nothrow_invocable<Derived&, U&&...>::value) {
34  return call(*this, std::forward<U>(args)...);
35  return Derived::call(derived(), index_sequence{}, std::forward<U>(args)...);
36  }
37 
38  template<typename... U>
39  constexpr typename bind_invoke_result<const Derived&, U&&...>::type
40  operator()(U&&... args) const & noexcept(bind_nothrow_invocable<const Derived&, U&&...>::value) {
41  return call(*this, std::forward<U>(args)...);
42  }
43 
44  template<typename... U>
45  constexpr typename bind_invoke_result<Derived&&, U&&...>::type
46  operator()(U&&... args) && noexcept(bind_nothrow_invocable<Derived&&, U&&...>::value) {
47  return call(std::move(*this), std::forward<U>(args)...);
48  }
49 
50  template<typename... U>
51  constexpr typename bind_invoke_result<const Derived&&, U&&...>::type
52  operator()(U&&... args) const && noexcept(bind_nothrow_invocable<const Derived&&, U&&...>::value) {
53  return call(std::move(*this), std::forward<U>(args)...);
54  }
55 
56  protected:
57  F func_;
58  std::tuple<Args...> args_;
59 
60  private:
61  template<typename Self, typename... U>
62  static constexpr typename bind_invoke_result<copy_cvref_t<Self&&, Derived>, U&&...>::type
63  call(Self&& self, U&&... args) noexcept(bind_nothrow_invocable<copy_cvref_t<Self&&, Derived>, U&&...>::value) {
64  return Derived::call(std::forward<Self>(self).derived(), index_sequence{}, std::forward<U>(args)...);
65  }
66 
67  Derived& derived() & { return static_cast<Derived&>(*this); }
68  const Derived& derived() const & { return static_cast<const Derived&>(*this); }
69  Derived&& derived() && { return static_cast<Derived&&>(*this); }
70  const Derived&& derived() const && { return static_cast<const Derived&&>(*this); }
71 };
72 
73 } // namespace detail
74 } // namespace vccc
75 
76 #endif // VCCC_FUNCTIONAL_DETAIL_BIND_BASE_HPP_
Definition: matrix.hpp:495
Definition: directory.h:12
constexpr VCCC_INLINE_OR_STATIC detail::element_niebloid< 1 > value
Definition: key_value.hpp:35