actor-framework
behavior.hpp
1 // This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
2 // the main distribution directory for license terms and copyright or visit
3 // https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
4 
5 #pragma once
6 
7 #include "caf/detail/behavior_impl.hpp"
8 #include "caf/detail/core_export.hpp"
9 #include "caf/detail/type_traits.hpp"
10 #include "caf/none.hpp"
11 #include "caf/timeout_definition.hpp"
12 #include "caf/timespan.hpp"
13 #include "caf/unsafe_behavior_init.hpp"
14 
15 #include <functional>
16 #include <type_traits>
17 
18 namespace caf {
19 
20 class message_handler;
21 
24 class CAF_CORE_EXPORT behavior {
25 public:
26  friend class message_handler;
27 
28  behavior() = default;
29  behavior(behavior&&) = default;
30  behavior(const behavior&) = default;
31  behavior& operator=(behavior&&) = default;
32  behavior& operator=(const behavior&) = default;
33 
34  // Convenience overload to allow "unsafe" initialization of any behavior_type.
35  behavior(unsafe_behavior_init_t, behavior from) : behavior(std::move(from)) {
36  // nop
37  }
38 
40  behavior(const message_handler& mh);
41 
44  template <class T, class... Ts>
45  behavior(T arg, Ts&&... args) {
46  if constexpr (is_timeout_definition_v<T>
47  || (is_timeout_definition_v<Ts> || ...)) {
48  legacy_assign(std::move(arg), std::forward<Ts>(args)...);
49  } else {
50  impl_ = detail::make_behavior(std::move(arg), std::forward<Ts>(args)...);
51  }
52  }
53 
55  template <class F>
56  [[deprecated("use idle timeouts instead of 'after >> ...'")]]
58  : impl_(detail::make_behavior(tdef)) {
59  // nop
60  }
61 
63  template <class... Ts>
64  [[deprecated("use idle timeouts instead of 'after >> ...'")]]
65  void legacy_assign(Ts&&... xs) {
66  static_assert(sizeof...(Ts) > 0, "assign() called without arguments");
67  impl_ = detail::make_behavior(std::forward<Ts>(xs)...);
68  }
69 
71  template <class T, class... Ts>
72  void assign(T&& arg, Ts&&... args) {
73  if constexpr (is_timeout_definition_v<T>
74  || (is_timeout_definition_v<Ts> || ...)) {
75  legacy_assign(std::forward<T>(arg), std::forward<Ts>(args)...);
76  } else {
77  impl_ = detail::make_behavior(std::forward<T>(arg),
78  std::forward<Ts>(args)...);
79  }
80  }
81 
82  void swap(behavior& other) {
83  impl_.swap(other.impl_);
84  }
85 
86  void assign(intrusive_ptr<detail::behavior_impl> ptr) {
87  impl_.swap(ptr);
88  }
89 
91  void assign(message_handler other);
92 
94  void assign(behavior other);
95 
97  void handle_timeout() {
98  impl_->handle_timeout();
99  }
100 
103  timespan timeout() const noexcept {
104  return impl_->timeout();
105  }
106 
108  std::optional<message> operator()(message& xs) {
109  return impl_ ? impl_->invoke(xs) : std::nullopt;
110  }
111 
114  return impl_ ? impl_->invoke(f, xs) : false;
115  }
116 
118  operator bool() const {
119  return static_cast<bool>(impl_);
120  }
121 
123 
124  using impl_ptr = intrusive_ptr<detail::behavior_impl>;
125 
126  const impl_ptr& as_behavior_impl() const {
127  return impl_;
128  }
129 
130  behavior(impl_ptr ptr) : impl_(std::move(ptr)) {
131  // nop
132  }
133 
134  behavior& unbox() & {
135  return *this;
136  }
137 
138  behavior&& unbox() && {
139  return std::move(*this);
140  }
141 
143 
144 private:
145  impl_ptr impl_;
146 };
147 
148 } // namespace caf
Describes the behavior of an actor, i.e., provides a message handler and an optional timeout...
Definition: behavior.hpp:24
std::chrono::duration< int64_t, std::nano > timespan
A portable timespan type with nanosecond resolution.
Definition: timespan.hpp:14
Empty struct tag for constructing a typed behavior from an untyped behavior.
Definition: unsafe_behavior_init.hpp:10
Indicates that the thread has been launched by request of a user without using any of the default mec...
Describes a fixed-length, copy-on-write, type-erased tuple with elements of any type.
Definition: message.hpp:32
behavior(timeout_definition< F > tdef)
Creates a behavior from tdef without message handler.
Definition: behavior.hpp:57
void legacy_assign(Ts &&... xs)
Assigns new handlers.
Definition: behavior.hpp:65
void handle_timeout()
Invokes the timeout callback if set.
Definition: behavior.hpp:97
behavior(T arg, Ts &&... args)
The list of arguments can contain match expressions, message handlers, and up to one timeout (if set...
Definition: behavior.hpp:45
Definition: type_id_list.test.cpp:11
timespan timeout() const noexcept
Returns the timespan after which receive operations using this behavior should time out...
Definition: behavior.hpp:103
Definition: fwd.hpp:38
std::optional< message > operator()(message &xs)
Runs this handler and returns its (optional) result.
Definition: behavior.hpp:108
void assign(T &&arg, Ts &&... args)
Assigns new handlers.
Definition: behavior.hpp:72
Inspects the result of message handlers and triggers type-depended actions such as generating result ...
Definition: invoke_result_visitor.hpp:24
Root namespace of libcaf.
Definition: custom_types_4.cpp:139
A partial function implementation used to process a message.
Definition: message_handler.hpp:27
bool operator()(detail::invoke_result_visitor &f, message &xs)
Runs this handler with callback.
Definition: behavior.hpp:113