function.h
Go to the documentation of this file.
1 //
2 // Created by Eduard Valeyev on 5/12/20.
3 //
4 
5 #ifndef TILEDARRAY_SRC_TILEDARRAY_UTIL_FUNCTION_H
6 #define TILEDARRAY_SRC_TILEDARRAY_UTIL_FUNCTION_H
7 
8 #include <functional>
9 #include <memory>
10 #include <type_traits>
11 
12 namespace TiledArray {
13 
15 template <typename F>
17  public:
18  static_assert(std::is_same_v<std::remove_reference_t<F>, F>);
19  shared_function() = default;
20  shared_function(F &&f) : f_(std::make_shared<F>(std::move(f))) {}
21  shared_function(shared_function const &other) { f_ = other.f_; }
25 
26  explicit operator bool() const { return f_; }
27 
28  template <typename... As, typename = std::void_t<decltype(
29  (std::declval<F &>())(std::declval<As>()...))>>
30  auto operator()(As &&...as) const {
31  return (*f_)(std::forward<As>(as)...);
32  }
33 
34  private:
35  std::shared_ptr<F> f_;
36 };
37 
38 template <class F>
40  return {std::forward<F>(f)};
41 }
42 
43 template <class F>
45 
47 template <class R, class... Args>
48 class function_ref<R(Args...)> {
49  public:
50  constexpr function_ref() noexcept = default;
51 
53  constexpr function_ref(const function_ref<R(Args...)> &rhs) noexcept =
54  default;
55 
59  template <typename F,
60  std::enable_if_t<
61  !std::is_same<std::decay_t<F>, function_ref>::value &&
62  std::is_invocable_r<R, F &&, Args...>::value> * = nullptr>
63  constexpr function_ref(F &&f) noexcept
64  : obj_(const_cast<void *>(
65  reinterpret_cast<const void *>(std::addressof(f)))) {
66  callback_ = [](void *obj, Args... args) -> R {
67  return std::invoke(
68  *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
69  std::forward<Args>(args)...);
70  };
71  }
72 
74  constexpr function_ref<R(Args...)> &operator=(
75  const function_ref<R(Args...)> &rhs) noexcept = default;
76 
81  template <typename F,
82  std::enable_if_t<
83  !std::is_same<std::decay_t<F>, function_ref>::value &&
84  std::is_invocable_r<R, F &&, Args...>::value> * = nullptr>
85  constexpr function_ref<R(Args...)> &operator=(F &&f) noexcept {
86  obj_ = reinterpret_cast<void *>(std::addressof(f));
87  callback_ = [](void *obj, Args... args) {
88  return std::invoke(
89  *reinterpret_cast<typename std::add_pointer<F>::type>(obj),
90  std::forward<Args>(args)...);
91  };
92 
93  return *this;
94  }
95 
97  constexpr void swap(function_ref<R(Args...)> &rhs) noexcept {
98  std::swap(obj_, rhs.obj_);
99  std::swap(callback_, rhs.callback_);
100  }
101 
103  R operator()(Args... args) const {
104  return callback_(obj_, std::forward<Args>(args)...);
105  }
106 
108  explicit operator bool() const { return obj_; }
109 
111  bool operator==(const function_ref& other) const { return obj_ == other.obj_; }
112 
113  private:
114  void *obj_ = nullptr;
115  R (*callback_)(void *, Args...) = nullptr;
116 };
117 
119 template <typename R, typename... Args>
120 constexpr void swap(function_ref<R(Args...)> &lhs,
121  function_ref<R(Args...)> &rhs) noexcept {
122  lhs.swap(rhs);
123 }
124 
128 template <typename Op>
130  constexpr const bool op_has_external_owner = std::is_reference_v<Op>;
131  using Op_ = std::remove_reference_t<Op>;
132  using result_t =
133  std::conditional_t<op_has_external_owner, std::reference_wrapper<Op_>,
135  if constexpr (op_has_external_owner)
136  return result_t(op);
137  else
138  return make_shared_function<Op_>(std::forward<Op>(op));
139  abort(); // unreachable
140 }
141 
142 } // namespace TiledArray
143 
144 #endif // TILEDARRAY_SRC_TILEDARRAY_UTIL_FUNCTION_H
typename make_void< Ts... >::type void_t
Definition: type_traits.h:55
::blas::Op Op
Definition: blas.h:46
constexpr function_ref() noexcept=default
shared_function< std::decay_t< F > > make_shared_function(F &&f)
Definition: function.h:39
auto make_op_shared_handle(Op &&op)
Definition: function.h:129
constexpr function_ref< R(Args...)> & operator=(F &&f) noexcept
Definition: function.h:85
analogous to std::function, but has shallow-copy semantics
Definition: function.h:16
R operator()(Args... args) const
Call the stored callable with the given arguments.
Definition: function.h:103
constexpr void swap(function_ref< R(Args...)> &lhs, function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of lhs and rhs.
Definition: function.h:120
constexpr function_ref< R(Args...)> & operator=(const function_ref< R(Args...)> &rhs) noexcept=default
Makes *this refer to the same callable as rhs.
shared_function & operator=(shared_function const &)=default
constexpr void swap(function_ref< R(Args...)> &rhs) noexcept
Swaps the referred callables of *this and rhs.
Definition: function.h:97
auto invoke(Function &&fn, Args &&... args) -> typename std::enable_if< !or_reduce< false, madness::is_future< std::decay_t< Args >>::value... >::value, decltype(fn(args...))>::type
Definition: meta.h:52
shared_function(shared_function &&)=default
shared_function(shared_function const &other)
Definition: function.h:21
shared_function & operator=(shared_function &&)=default
bool operator==(const function_ref &other) const
Definition: function.h:111
auto operator()(As &&...as) const
Definition: function.h:30
void swap(Range &r0, Range &r1)
Exchange the values of the give two ranges.
Definition: range.h:1233