Commit 8f2f8a2b authored by Dominik Charousset's avatar Dominik Charousset

Apply new documentation style, e.g., remove @brief

This patch removes *all* "@brief" comments from the code base and replaces
verbose constructs like "@c"/"@p" with Markdown. The patch also enforces the
new coding conventions in more places and removes some dead code.
parent 3cc9f150
......@@ -47,13 +47,13 @@ class deserializer;
class execution_unit;
/**
* @brief A unique actor ID.
* A unique actor ID.
* @relates abstract_actor
*/
using actor_id = uint32_t;
/**
* @brief Denotes an ID that is never used by an actor.
* Denotes an ID that is never used by an actor.
*/
constexpr actor_id invalid_actor_id = 0;
......@@ -64,64 +64,63 @@ class response_promise;
using abstract_actor_ptr = intrusive_ptr<abstract_actor>;
/**
* @brief Base class for all actor implementations.
* Base class for all actor implementations.
*/
class abstract_actor : public abstract_channel {
// needs access to m_host
friend class response_promise;
// java-like access to base class
using super = abstract_channel;
public:
/**
* @brief Attaches @p ptr to this actor.
*
* The actor will call <tt>ptr->detach(...)</tt> on exit, or immediately
* if it already finished execution.
* @param ptr A callback object that's executed if the actor finishes
* execution.
* @returns @c true if @p ptr was successfully attached to the actor;
* otherwise (actor already exited) @p false.
* @warning The actor takes ownership of @p ptr.
* Attaches `ptr` to this actor. The actor will call `ptr->detach(...)` on
* exit, or immediately if it already finished execution.
* @returns `true` if `ptr` was successfully attached to the actor,
* otherwise (actor already exited) `false`.
*/
bool attach(attachable_ptr ptr);
/**
* @brief Convenience function that attaches the functor
* or function @p f to this actor.
*
* The actor executes <tt>f()</tt> on exit, or immediatley
* if it already finished execution.
* @param f A functor, function or lambda expression that's executed
* if the actor finishes execution.
* @returns @c true if @p f was successfully attached to the actor;
* otherwise (actor already exited) @p false.
* Convenience function that attaches the functor `f` to this actor. The
* actor executes `f()` on exit or immediatley if it is not running.
* @returns `true` if `f` was successfully attached to the actor,
* otherwise (actor already exited) `false`.
*/
template <class F>
bool attach_functor(F&& f);
bool attach_functor(F f) {
struct functor_attachable : attachable {
F m_functor;
functor_attachable(F arg) : m_functor(std::move(arg)) {
// nop
}
void actor_exited(uint32_t reason) {
m_functor(reason);
}
bool matches(const attachable::token&) {
return false;
}
};
return attach(attachable_ptr{new functor_attachable(std::move(f))});
}
/**
* @brief Returns the address of this actor.
* Returns the logical actor address.
*/
actor_addr address() const;
/**
* @brief Detaches the first attached object that matches @p what.
* Detaches the first attached object that matches `what`.
*/
void detach(const attachable::token& what);
/**
* @brief Links this actor to @p whom.
* @param whom Actor instance that whose execution is coupled to the
* execution of this Actor.
* Links this actor to `whom`.
*/
virtual void link_to(const actor_addr& whom);
/**
* @brief Links this actor to @p whom.
* @param whom Actor instance that whose execution is coupled to the
* execution of this Actor.
* Links this actor to `whom`.
*/
template <class ActorHandle>
void link_to(const ActorHandle& whom) {
......@@ -129,16 +128,12 @@ class abstract_actor : public abstract_channel {
}
/**
* @brief Unlinks this actor from @p whom.
* @param whom Linked Actor.
* @note Links are automatically removed if the actor finishes execution.
* Unlinks this actor from `whom`.
*/
virtual void unlink_from(const actor_addr& whom);
/**
* @brief Unlinks this actor from @p whom.
* @param whom Linked Actor.
* @note Links are automatically removed if the actor finishes execution.
* Unlinks this actor from `whom`.
*/
template <class ActorHandle>
void unlink_from(const ActorHandle& whom) {
......@@ -146,76 +141,93 @@ class abstract_actor : public abstract_channel {
}
/**
* @brief Establishes a link relation between this actor and @p other.
* @param other Actor instance that wants to link against this Actor.
* @returns @c true if this actor is running and added @p other to its
* list of linked actors; otherwise @c false.
* Establishes a link relation between this actor and `other`
* and returns whether the operation succeeded.
*/
virtual bool establish_backlink(const actor_addr& other);
/**
* @brief Removes a link relation between this actor and @p other.
* @param other Actor instance that wants to unlink from this Actor.
* @returns @c true if this actor is running and removed @p other
* from its list of linked actors; otherwise @c false.
* Removes the link relation between this actor and `other`
* and returns whether the operation succeeded.
*/
virtual bool remove_backlink(const actor_addr& other);
/**
* @brief Gets an integer value that uniquely identifies this Actor in
* the process it's executed in.
* @returns The unique identifier of this actor.
* Returns the unique ID of this actor.
*/
inline actor_id id() const;
inline uint32_t id() const {
return m_id;
}
/**
* @brief Returns the actor's exit reason of
* <tt>exit_reason::not_exited</tt> if it's still alive.
* Returns the actor's exit reason or
* `exit_reason::not_exited` if it's still alive.
*/
inline uint32_t exit_reason() const;
inline uint32_t exit_reason() const {
return m_exit_reason;
}
/**
* @brief Returns the type interface as set of strings.
* @note The returned set is empty for all untyped actors.
* Returns the type interface as set of strings or an empty set
* if this actor is untyped.
*/
virtual std::set<std::string> interface() const;
protected:
/**
* Creates a non-proxy instance.
*/
abstract_actor();
/**
* Creates a proxy instance for a proxy running on `nid`.
*/
abstract_actor(actor_id aid, node_id nid);
/**
* @brief Should be overridden by subtypes and called upon termination.
* @note Default implementation sets 'exit_reason' accordingly.
* @note Overridden functions should always call super::cleanup().
* Called by the runtime system to perform cleanup actions for this actor.
* Subtypes should always call this member function when overriding it.
*/
virtual void cleanup(uint32_t reason);
/**
* @brief The default implementation for {@link link_to()}.
* The default implementation for `link_to()`.
*/
bool link_to_impl(const actor_addr& other);
/**
* @brief The default implementation for {@link unlink_from()}.
* The default implementation for {@link unlink_from()}.
*/
bool unlink_from_impl(const actor_addr& other);
/**
* @brief Returns <tt>exit_reason() != exit_reason::not_exited</tt>.
* Returns `exit_reason() != exit_reason::not_exited`.
*/
inline bool exited() const {
return exit_reason() != exit_reason::not_exited;
}
/**
* Returns the execution unit currently used by this actor.
*/
inline bool exited() const;
inline execution_unit* host() const {
return m_host;
}
/**
* Sets the execution unit for this actor.
*/
inline void host(execution_unit* new_host) {
m_host = new_host;
}
private:
// cannot be changed after construction
const actor_id m_id;
// you're either a proxy or you're not
const bool m_is_proxy;
private:
// initially exit_reason::not_exited
std::atomic<uint32_t> m_exit_reason;
......@@ -228,46 +240,10 @@ class abstract_actor : public abstract_channel {
// attached functors that are executed on cleanup
std::vector<attachable_ptr> m_attachables;
protected:
// identifies the execution unit this actor is currently executed by
execution_unit* m_host;
};
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
inline uint32_t abstract_actor::id() const { return m_id; }
inline uint32_t abstract_actor::exit_reason() const { return m_exit_reason; }
inline bool abstract_actor::exited() const {
return exit_reason() != exit_reason::not_exited;
}
template <class F>
struct functor_attachable : attachable {
F m_functor;
template <class T>
inline functor_attachable(T&& arg) : m_functor(std::forward<T>(arg)) { }
void actor_exited(uint32_t reason) { m_functor(reason); }
bool matches(const attachable::token&) { return false; }
};
template <class F>
bool abstract_actor::attach_functor(F&& f) {
using f_type = typename detail::rm_const_and_ref<F>::type;
using impl = functor_attachable<f_type>;
return attach(attachable_ptr{new impl(std::forward<F>(f))});
}
} // namespace caf
#endif // CAF_ABSTRACT_ACTOR_HPP
......@@ -28,37 +28,29 @@
namespace caf {
/**
* @brief Interface for all message receivers.
*
* This interface describes an entity that can receive messages
* and is implemented by {@link actor} and {@link group}.
* Interface for all message receivers. * This interface describes an
* entity that can receive messages and is implemented by {@link actor}
* and {@link group}.
*/
class abstract_channel : public ref_counted {
public:
virtual ~abstract_channel();
/**
* @brief Enqueues a new message to the channel.
* @param header Contains meta information about this message
* such as the address of the sender and the
* ID of the message if it is a synchronous message.
* @param content The content encapsulated in a copy-on-write tuple.
* @param host Pointer to the {@link execution_unit execution unit} the
* caller is executed by or @p nullptr if the caller
* is not a scheduled actor.
* Enqueues a new message to the channel.
*/
virtual void enqueue(const actor_addr& sender, message_id mid,
message content, execution_unit* host) = 0;
message content, execution_unit* host) = 0;
/**
* @brief Returns the ID of the node this actor is running on.
* Returns the ID of the node this actor is running on.
*/
inline node_id node() const;
inline node_id node() const {
return m_node;
}
/**
* @brief Returns true if {@link node_ptr} returns
* Returns true if {@link node_ptr} returns
*/
bool is_remote() const;
......@@ -75,12 +67,12 @@ class abstract_channel : public ref_counted {
};
/**
* A smart pointer to an abstract channel.
* @relates abstract_channel_ptr
*/
using abstract_channel_ptr = intrusive_ptr<abstract_channel>;
inline node_id abstract_channel::node() const {
return m_node;
}
} // namespace caf
#endif // CAF_ABSTRACT_CHANNEL_HPP
......@@ -24,7 +24,6 @@
#include <memory>
#include "caf/channel.hpp"
#include "caf/attachable.hpp"
#include "caf/ref_counted.hpp"
#include "caf/abstract_channel.hpp"
......@@ -44,14 +43,12 @@ class serializer;
class deserializer;
/**
* @brief A multicast group.
* A multicast group.
*/
class abstract_group : public abstract_channel {
friend class detail::group_manager;
friend class detail::peer_connection; // needs access to remote_enqueue
public:
friend class detail::group_manager;
friend class detail::peer_connection;
~abstract_group();
......@@ -62,60 +59,50 @@ class abstract_group : public abstract_channel {
// unsubscribes its channel from the group on destruction
class subscription {
public:
friend class abstract_group;
subscription(const subscription&) = delete;
subscription& operator=(const subscription&) = delete;
public:
subscription() = default;
subscription(subscription&&) = default;
subscription(const channel& s, const intrusive_ptr<abstract_group>& g);
~subscription();
inline bool valid() const { return (m_subscriber) && (m_group); }
inline bool valid() const {
return (m_subscriber) && (m_group);
}
private:
channel m_subscriber;
intrusive_ptr<abstract_group> m_group;
};
/**
* @brief Module interface.
* Interface for user-defined multicast implementations.
*/
class module {
std::string m_name;
protected:
module(std::string module_name);
public:
module(std::string module_name);
virtual ~module();
/**
* @brief Get the name of this module implementation.
* @returns The name of this module implementation.
* Returns the name of this module implementation.
* @threadsafe
*/
const std::string& name();
/**
* @brief Get a pointer to the group associated with
* the name @p group_name.
* Returns a pointer to the group associated with the name `group_name`.
* @threadsafe
*/
virtual group get(const std::string& group_name) = 0;
virtual group deserialize(deserializer* source) = 0;
private:
std::string m_name;
};
using module_ptr = module*;
......@@ -124,40 +111,33 @@ class abstract_group : public abstract_channel {
virtual void serialize(serializer* sink) = 0;
/**
* @brief A string representation of the group identifier.
* @returns The group identifier as string (e.g. "224.0.0.1" for IPv4
* multicast or a user-defined string for local groups).
* Returns a string representation of the group identifier, e.g.,
* "224.0.0.1" for IPv4 multicast or a user-defined string for local groups.
*/
const std::string& identifier() const;
module_ptr get_module() const;
/**
* @brief The name of the module.
* @returns The module name of this group (e.g. "local").
* Returns the name of the module.
*/
const std::string& module_name() const;
/**
* @brief Subscribe @p who to this group.
* @returns A {@link subscription} object that unsubscribes @p who
* if the lifetime of @p who ends.
* Subscribes `who` to this group and returns a subscription object.
*/
virtual subscription subscribe(const channel& who) = 0;
protected:
abstract_group(module_ptr module, std::string group_id);
// called by subscription objects
virtual void unsubscribe(const channel& who) = 0;
module_ptr m_module;
std::string m_identifier;
};
/**
* @brief A smart pointer type that manages instances of {@link group}.
* A smart pointer type that manages instances of {@link group}.
* @relates group
*/
using abstract_group_ptr = intrusive_ptr<abstract_group>;
......
......@@ -35,35 +35,34 @@
namespace caf {
class scoped_actor;
struct invalid_actor_t {
constexpr invalid_actor_t() {}
};
/**
* @brief Identifies an invalid {@link actor}.
* Identifies an invalid {@link actor}.
* @relates actor
*/
constexpr invalid_actor_t invalid_actor = invalid_actor_t{};
template <class T>
struct is_convertible_to_actor {
static constexpr bool value = std::is_base_of<actor_proxy, T>::value ||
std::is_base_of<local_actor, T>::value;
using type = typename std::remove_pointer<T>::type;
static constexpr bool value = std::is_base_of<actor_proxy, type>::value
|| std::is_base_of<local_actor, type>::value
|| std::is_same<scoped_actor, type>::value;
};
/**
* @brief Identifies an untyped actor.
*
* Can be used with derived types of {@link event_based_actor},
* {@link blocking_actor}, {@link actor_proxy}, or
* {@link io::broker}.
* Identifies an untyped actor. Can be used with derived types
* of `event_based_actor`, `blocking_actor`, `actor_proxy`.
*/
class actor : detail::comparable<actor>,
detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>,
detail::comparable<actor, invalid_actor_addr_t> {
detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>,
detail::comparable<actor, invalid_actor_addr_t> {
friend class local_actor;
......@@ -121,8 +120,7 @@ class actor : detail::comparable<actor>,
}
/**
* @brief Returns a handle that grants access to
* actor operations such as enqueue.
* Returns a handle that grants access to actor operations such as enqueue.
*/
inline abstract_actor* operator->() const {
return m_ptr.get();
......@@ -145,7 +143,7 @@ class actor : detail::comparable<actor>,
}
/**
* @brief Queries the address of the stored actor.
* Returns the address of the stored actor.
*/
actor_addr address() const;
......
......@@ -40,13 +40,13 @@ struct invalid_actor_addr_t {
};
/**
* @brief Identifies an invalid {@link actor_addr}.
* Identifies an invalid {@link actor_addr}.
* @relates actor_addr
*/
constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{};
/**
* @brief Stores the address of typed as well as untyped actors.
* Stores the address of typed as well as untyped actors.
*/
class actor_addr : detail::comparable<actor_addr>,
detail::comparable<actor_addr, abstract_actor*>,
......@@ -91,8 +91,7 @@ class actor_addr : detail::comparable<actor_addr>,
node_id node() const;
/**
* @brief Returns whether this is an address of a
* remote actor.
* Returns whether this is an address of a remote actor.
*/
bool is_remote() const;
......
......@@ -22,6 +22,9 @@
namespace caf {
/**
* Converts actor handle `what` to a different actor handle of type `T`.
*/
template <class T, typename U>
T actor_cast(const U& what) {
return what.get();
......
......@@ -35,9 +35,9 @@
namespace caf {
/**
* @brief An co-existing forwarding all messages through a user-defined
* callback to another object, thus serving as gateway to
* allow any object to interact with other actors.
* An co-existing forwarding all messages through a user-defined
* callback to another object, thus serving as gateway to
* allow any object to interact with other actors.
*/
class actor_companion : public extend<local_actor, actor_companion>::
with<mixin::behavior_stack_based<behavior>::impl,
......@@ -52,14 +52,14 @@ class actor_companion : public extend<local_actor, actor_companion>::
using enqueue_handler = std::function<void (message_pointer)>;
/**
* @brief Removes the handler for incoming messages and terminates
* the companion for exit reason @ rsn.
* Removes the handler for incoming messages and terminates
* the companion for exit reason @ rsn.
*/
void disconnect(std::uint32_t rsn = exit_reason::normal);
/**
* @brief Sets the handler for incoming messages.
* @warning @p handler needs to be thread-safe
* Sets the handler for incoming messages.
* @warning `handler` needs to be thread-safe
*/
void on_enqueue(enqueue_handler handler);
......@@ -77,7 +77,7 @@ class actor_companion : public extend<local_actor, actor_companion>::
};
/**
* @brief A pointer to a co-existing (actor) object.
* A pointer to a co-existing (actor) object.
* @relates actor_companion
*/
using actor_companion_ptr = intrusive_ptr<actor_companion>;
......
......@@ -34,89 +34,80 @@ class serializer;
class deserializer;
/**
* @brief Groups a (distributed) set of actors and allows actors
* in the same namespace to exchange messages.
* Groups a (distributed) set of actors and allows actors
* in the same namespace to exchange messages.
*/
class actor_namespace {
public:
using key_type = node_id;
/**
* @brief The backend of an actor namespace is responsible for
* creating proxy actors.
* The backend of an actor namespace is responsible for creating proxy actors.
*/
class backend {
public:
virtual ~backend();
/**
* @brief Creates a new proxy instance.
* Creates a new proxy instance.
*/
virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0;
};
actor_namespace(backend& mgm);
/**
* @brief Writes an actor address to @p sink and adds the actor
* to the list of known actors for a later deserialization.
* Writes an actor address to `sink` and adds the actor
* to the list of known actors for a later deserialization.
*/
void write(serializer* sink, const actor_addr& ptr);
/**
* @brief Reads an actor address from @p source, creating
* addresses for remote actors on the fly if needed.
* Reads an actor address from `source,` creating
* addresses for remote actors on the fly if needed.
*/
actor_addr read(deserializer* source);
/**
* @brief A map that stores all proxies for known remote actors.
* A map that stores all proxies for known remote actors.
*/
using proxy_map = std::map<actor_id, actor_proxy::anchor_ptr>;
/**
* @brief Returns the number of proxies for @p node.
* Returns the number of proxies for `node`.
*/
size_t count_proxies(const key_type& node);
/**
* @brief Returns the proxy instance identified by @p node and @p aid
* or @p nullptr if the actor either unknown or expired.
* Returns the proxy instance identified by `node` and `aid`
* or `nullptr` if the actor either unknown or expired.
*/
actor_proxy_ptr get(const key_type& node, actor_id aid);
/**
* @brief Returns the proxy instance identified by @p node and @p aid
* or creates a new (default) proxy instance.
* Returns the proxy instance identified by `node` and `aid`
* or creates a new (default) proxy instance.
*/
actor_proxy_ptr get_or_put(const key_type& node, actor_id aid);
/**
* @brief Deletes all proxies for @p node.
* Deletes all proxies for `node`.
*/
void erase(const key_type& node);
/**
* @brief Deletes the proxy with id @p aid for @p node.
* Deletes the proxy with id `aid` for `node`.
*/
void erase(const key_type& node, actor_id aid);
/**
* @brief Queries whether there are any proxies left.
* Queries whether there are any proxies left.
*/
bool empty() const;
private:
backend& m_backend;
std::map<key_type, proxy_map> m_proxies;
};
} // namespace caf
......
......@@ -32,58 +32,48 @@ namespace caf {
class actor_proxy;
/**
* @brief A smart pointer to an {@link actor_proxy} instance.
* A smart pointer to an {@link actor_proxy} instance.
* @relates actor_proxy
*/
using actor_proxy_ptr = intrusive_ptr<actor_proxy>;
/**
* @brief Represents a remote actor.
* Represents a remote actor.
* @extends abstract_actor
*/
class actor_proxy : public abstract_actor {
using super = abstract_actor;
public:
/**
* @brief An anchor points to a proxy instance without sharing
* ownership to it, i.e., models a weak ptr.
* An anchor points to a proxy instance without sharing
* ownership to it, i.e., models a weak ptr.
*/
class anchor : public ref_counted {
friend class actor_proxy;
public:
friend class actor_proxy;
anchor(actor_proxy* instance = nullptr);
~anchor();
/**
* @brief Queries whether the proxy was already deleted.
* Queries whether the proxy was already deleted.
*/
bool expired() const;
/**
* @brief Gets a pointer to the proxy or @p nullptr
* Gets a pointer to the proxy or `nullptr`
* if the instance is {@link expired()}.
*/
actor_proxy_ptr get();
private:
/*
* @brief Tries to expire this anchor. Fails if reference
* Tries to expire this anchor. Fails if reference
* count of the proxy is nonzero.
*/
bool try_expire();
std::atomic<actor_proxy*> m_ptr;
detail::shared_spinlock m_lock;
};
using anchor_ptr = intrusive_ptr<anchor>;
......@@ -91,31 +81,30 @@ class actor_proxy : public abstract_actor {
~actor_proxy();
/**
* @brief Establishes a local link state that's not synchronized back
* Establishes a local link state that's not synchronized back
* to the remote instance.
*/
virtual void local_link_to(const actor_addr& other) = 0;
/**
* @brief Removes a local link state.
* Removes a local link state.
*/
virtual void local_unlink_from(const actor_addr& other) = 0;
/**
* @brief
* Invokes cleanup code.
*/
virtual void kill_proxy(uint32_t reason) = 0;
void request_deletion() override;
inline anchor_ptr get_anchor() { return m_anchor; }
inline anchor_ptr get_anchor() {
return m_anchor;
}
protected:
actor_proxy(actor_id aid, node_id nid);
anchor_ptr m_anchor;
};
} // namespace caf
......
......@@ -101,41 +101,41 @@
* It uses a network transparent messaging system to ease development
* of both concurrent and distributed software.
*
* @p libcaf uses a thread pool to schedule actors by default.
* `libcaf` uses a thread pool to schedule actors by default.
* A scheduled actor should not call blocking functions.
* Individual actors can be spawned (created) with a special flag to run in
* an own thread if one needs to make use of blocking APIs.
*
* Writing applications in @p libcaf requires a minimum of gluecode and
* Writing applications in `libcaf` requires a minimum of gluecode and
* each context <i>is</i> an actor. Even main is implicitly
* converted to an actor if needed.
*
* @section GettingStarted Getting Started
*
* To build @p libcaf, you need <tt>GCC >= 4.7</tt> or <tt>Clang >=
* To build `libcaf,` you need `GCC >= 4.7 or <tt>Clang >=
*3.2</tt>,
* and @p CMake.
* and `CMake`.
*
* The usual build steps on Linux and Mac OS X are:
*
*- <tt>mkdir build</tt>
*- <tt>cd build</tt>
*- <tt>cmake ..</tt>
*- <tt>make</tt>
*- <tt>make install</tt> (as root, optionally)
*- `mkdir build
*- `cd build
*- `cmake ..
*- `make
*- `make install (as root, optionally)
*
* Please run the unit tests as well to verify that @p libcaf
* Please run the unit tests as well to verify that `libcaf`
* works properly.
*
*- <tt>./bin/unit_tests</tt>
*- `./bin/unit_tests
*
* Please submit a bug report that includes (a) your compiler version,
* (b) your OS, and (c) the output of the unit tests if an error occurs.
*
* Windows is not supported yet, because MVSC++ doesn't implement the
* C++11 features needed to compile @p libcaf.
* C++11 features needed to compile `libcaf`.
*
* Please read the <b>Manual</b> for an introduction to @p libcaf.
* Please read the <b>Manual</b> for an introduction to `libcaf`.
* It is available online as HTML at
* http://neverlord.github.com/libcaf/manual/index.html or as PDF at
* http://neverlord.github.com/libcaf/manual/manual.pdf
......@@ -149,83 +149,36 @@
* The {@link math_actor.cpp Math Actor Example} shows the usage
* of {@link receive_loop} and {@link caf::arg_match arg_match}.
* The {@link dining_philosophers.cpp Dining Philosophers Example}
* introduces event-based actors and includes a lot of <tt>libcaf</tt>
* introduces event-based actors and includes a lot of `libcaf
* features.
*
* @namespace caf
* @brief Root namespace of libcaf.
* Root namespace of libcaf.
*
* @namespace caf::util
* @brief Contains utility classes and metaprogramming
* utilities used by the libcaf implementation.
*
* @namespace caf::intrusive
* @brief Contains intrusive container implementations.
*
* @namespace caf::opencl
* @brief Contains all classes of libcaf's OpenCL binding (optional).
*
* @namespace caf::network
* @brief Contains all network related classes.
*
* @namespace caf::factory
* @brief Contains factory functions to create actors from lambdas or
* other functors.
* @namespace caf::mixin
* Contains mixin classes implementing several actor traits.
*
* @namespace caf::exit_reason
* @brief Contains all predefined exit reasons.
*
* @namespace caf::placeholders
* @brief Contains the guard placeholders @p _x1 to @p _x9.
*
* @defgroup CopyOnWrite Copy-on-write optimization.
* @p libcaf uses a copy-on-write optimization for its message
* passing implementation.
*
* {@link caf::cow_tuple Tuples} should @b always be used with by-value
* semantic, since tuples use a copy-on-write smart pointer internally.
* Let's assume two
* tuple @p x and @p y, whereas @p y is a copy of @p x:
*
* @code
* auto x = make_message(1, 2, 3);
* auto y = x;
* @endcode
* Contains all predefined exit reasons.
*
* Those two tuples initially point to the same data (the addresses of the
* first element of @p x is equal to the address of the first element
* of @p y):
* @namespace caf::policy
* Contains policies encapsulating characteristics or algorithms.
*
* @code
* assert(&(get<0>(x)) == &(get<0>(y)));
* @endcode
*
* <tt>get<0>(x)</tt> returns a const-reference to the first element of @p x.
* The function @p get does not have a const-overload to avoid
* unintended copies. The function @p get_ref could be used to
* modify tuple elements. A call to this function detaches
* the tuple by copying the data before modifying it if there are two or more
* references to the data:
*
* @code
* // detaches x from y
* get_ref<0>(x) = 42;
* // x and y no longer point to the same data
* assert(&(get<0>(x)) != &(get<0>(y)));
* @endcode
* @namespace caf::io
* Contains all network-related classes and functions.
*
* @defgroup MessageHandling Message handling.
*
* @brief This is the beating heart of @p libcaf. Actor programming is
* all about message handling.
* This is the beating heart of `libcaf`. Actor programming is
* all about message handling.
*
* A message in @p libcaf is a n-tuple of values (with size >= 1)
* A message in `libcaf` is a n-tuple of values (with size >= 1)
* You can use almost every type in a messages - as long as it is announced,
* i.e., known by the type system of @p libcaf.
* i.e., known by the type system of `libcaf`.
*
* @defgroup BlockingAPI Blocking API.
*
* @brief Blocking functions to receive messages.
* Blocking functions to receive messages.
*
* The blocking API of libcaf is intended to be used for migrating
* previously threaded applications. When writing new code, you should use
......@@ -233,7 +186,7 @@
*
* @section Send Send messages
*
* The function @p send can be used to send a message to an actor.
* The function `send` can be used to send a message to an actor.
* The first argument is the receiver of the message followed by any number
* of values:
*
......@@ -255,7 +208,7 @@
*
* @section Receive Receive messages
*
* The function @p receive takes a @p behavior as argument. The behavior
* The function `receive` takes a `behavior` as argument. The behavior
* is a list of { pattern >> callback } rules.
*
* @code
......@@ -299,7 +252,7 @@
*
* @section ReceiveLoops Receive loops
*
* Previous examples using @p receive create behaviors on-the-fly.
* Previous examples using `receive` create behaviors on-the-fly.
* This is inefficient in a loop since the argument passed to receive
* is created in each iteration again. It's possible to store the behavior
* in a variable and pass that variable to receive. This fixes the issue
......@@ -307,13 +260,13 @@
*
* There are four convenience functions implementing receive loops to
* declare behavior where it belongs without unnecessary
* copies: @p receive_loop, @p receive_while, @p receive_for and @p do_receive.
* copies: `receive_loop,` `receive_while,` `receive_for` and `do_receive`.
*
* @p receive_loop is analogous to @p receive and loops "forever" (until the
* `receive_loop` is analogous to `receive` and loops "forever" (until the
* actor finishes execution).
*
* @p receive_while creates a functor evaluating a lambda expression.
* The loop continues until the given lambda returns @p false. A simple example:
* `receive_while` creates a functor evaluating a lambda expression.
* The loop continues until the given lambda returns `false`. A simple example:
*
* @code
* // receive two integers
......@@ -326,7 +279,7 @@
* // ...
* @endcode
*
* @p receive_for is a simple ranged-based loop:
* `receive_for` is a simple ranged-based loop:
*
* @code
* std::vector<int> vec {1, 2, 3, 4};
......@@ -336,7 +289,7 @@
* );
* @endcode
*
* @p do_receive returns a functor providing the function @p until that
* `do_receive` returns a functor providing the function `until` that
* takes a lambda expression. The loop continues until the given lambda
* returns true. Example:
*
......@@ -354,7 +307,7 @@
*
* @section FutureSend Send delayed messages
*
* The function @p delayed_send provides a simple way to delay a message.
* The function `delayed_send` provides a simple way to delay a message.
* This is particularly useful for recurring events, e.g., periodical polling.
* Usage example:
*
......@@ -374,11 +327,11 @@
*
* @defgroup ImplicitConversion Implicit type conversions.
*
* The message passing of @p libcaf prohibits pointers in messages because
* The message passing of `libcaf` prohibits pointers in messages because
* it enforces network transparent messaging.
* Unfortunately, string literals in @p C++ have the type <tt>const char*</tt>,
* resp. <tt>const char[]</tt>. Since @p libcaf is a user-friendly library,
* it silently converts string literals and C-strings to @p std::string objects.
* Unfortunately, string literals in `C++` have the type `const char*,
* resp. `const char[]. Since `libcaf` is a user-friendly library,
* it silently converts string literals and C-strings to `std::string` objects.
* It also converts unicode literals to the corresponding STL container.
*
* A few examples:
......@@ -403,30 +356,22 @@
* @endcode
*
* @defgroup ActorCreation Actor creation.
*
* @defgroup MetaProgramming Metaprogramming utility.
*/
// examples
/**
* @brief A trivial example program.
* A trivial example program.
* @example hello_world.cpp
*/
/**
* @brief Shows the usage of {@link caf::atom atoms}
* and {@link caf::arg_match arg_match}.
* @example math_actor.cpp
*/
/**
* @brief A simple example for a delayed_send based application.
* A simple example for a delayed_send based application.
* @example dancing_kirby.cpp
*/
/**
* @brief An event-based "Dining Philosophers" implementation.
* An event-based "Dining Philosophers" implementation.
* @example dining_philosophers.cpp
*/
......
......@@ -41,69 +41,56 @@ namespace caf {
*/
/**
* @brief A simple example for @c announce with public accessible members.
*
* A simple example for announce with public accessible members.
* The output of this example program is:
*
* <tt>
* foo(1, 2)<br>
* foo_pair(3, 4)
* </tt>
* > foo(1, 2)<br>
* > foo_pair(3, 4)
* @example announce_1.cpp
*/
/**
* @brief An example for @c announce with getter and setter member functions.
*
* An example for announce with getter and setter member functions.
* The output of this example program is:
*
* <tt>foo(1, 2)</tt>
* > foo(1, 2)
* @example announce_2.cpp
*/
/**
* @brief An example for @c announce with overloaded
* getter and setter member functions.
*
* An example for announce with overloaded getter and setter member functions.
* The output of this example program is:
*
* <tt>foo(1, 2)</tt>
* > foo(1, 2)
* @example announce_3.cpp
*/
/**
* @brief An example for @c announce with non-primitive members.
*
* An example for announce with non-primitive members.
* The output of this example program is:
*
* <tt>bar(foo(1, 2), 3)</tt>
* > bar(foo(1, 2), 3)
* @example announce_4.cpp
*/
/**
* @brief An advanced example for @c announce implementing serialization
* for a user-defined tree data type.
* An advanced example for announce implementing serialization
* for a user-defined tree data type.
* @example announce_5.cpp
*/
/**
* @brief Adds a new type mapping to the type system.
* @param tinfo C++ RTTI for the new type
* @param utype Corresponding {@link uniform_type_info} instance.
* @returns @c true if @p uniform_type was added as known
* instance (mapped to @p plain_type); otherwise @c false
* is returned and @p uniform_type was deleted.
* Adds a new mapping to the type system. Returns `false` if a mapping
* for `tinfo` already exists, otherwise `true`.
* @warning `announce` is **not** thead-safe!
*/
const uniform_type_info* announce(const std::type_info& tinfo,
uniform_type_info_ptr utype);
uniform_type_info_ptr utype);
// deals with member pointer
/**
* @brief Creates meta informations for a non-trivial member @p C.
* @param c_ptr Pointer to the non-trivial member.
* @param args "Sub-members" of @p c_ptr
* Creates meta information for a non-trivial member `C`, whereas
* `args` are the "sub-members" of `c_ptr`.
* @see {@link announce_4.cpp announce example 4}
* @returns A pair of @p c_ptr and the created meta informations.
*/
template <class C, class Parent, class... Ts>
std::pair<C Parent::*, detail::abstract_uniform_type_info<C>*>
......@@ -113,12 +100,10 @@ compound_member(C Parent::*c_ptr, const Ts&... args) {
// deals with getter returning a mutable reference
/**
* @brief Creates meta informations for a non-trivial member accessed
* via a getter returning a mutable reference.
* @param getter Member function pointer to the getter.
* @param args "Sub-members" of @p c_ptr
* Creates meta information for a non-trivial member accessed
* via a getter returning a mutable reference, whereas
* `args` are the "sub-members" of `c_ptr`.
* @see {@link announce_4.cpp announce example 4}
* @returns A pair of @p c_ptr and the created meta informations.
*/
template <class C, class Parent, class... Ts>
std::pair<C& (Parent::*)(), detail::abstract_uniform_type_info<C>*>
......@@ -128,32 +113,25 @@ compound_member(C& (Parent::*getter)(), const Ts&... args) {
// deals with getter/setter pair
/**
* @brief Creates meta informations for a non-trivial member accessed
* via a getter/setter pair.
* @param gspair A pair of two member function pointers representing
* getter and setter.
* @param args "Sub-members" of @p c_ptr
* Creates meta information for a non-trivial member accessed
* via a pair of getter and setter member function pointers, whereas
* `args` are the "sub-members" of `c_ptr`.
* @see {@link announce_4.cpp announce example 4}
* @returns A pair of @p c_ptr and the created meta informations.
*/
template <class Parent, typename GRes, typename SRes, typename SArg,
class... Ts>
template <class Parent, class GRes, class SRes, class SArg, class... Ts>
std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>,
detail::abstract_uniform_type_info<
typename detail::rm_const_and_ref<GRes>::type>*>
compound_member(
const std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>& gspair,
const Ts&... args) {
detail::abstract_uniform_type_info<
typename detail::rm_const_and_ref<GRes>::type>*>
compound_member(const std::pair<GRes (Parent::*)() const,
SRes (Parent::*)(SArg)>& gspair,
const Ts&... args) {
using mtype = typename detail::rm_const_and_ref<GRes>::type;
return {gspair, new detail::default_uniform_type_info<mtype>(args...)};
}
/**
* @brief Adds a new type mapping for @p C to the type system.
* @tparam C A class that is either empty or is default constructible,
* copy constructible, and comparable.
* @param args Members of @p C.
* @warning @p announce is <b>not</b> thead safe!
* Adds a new type mapping for `C` to the type system.
* @warning `announce` is **not** thead-safe!
*/
template <class C, class... Ts>
inline const uniform_type_info* announce(const Ts&... args) {
......
......@@ -25,31 +25,32 @@
namespace caf {
/**
* @brief Acts as wildcard expression in patterns.
* Acts as wildcard expression in patterns.
*/
struct anything {};
struct anything {
// no content
};
/**
* @brief Compares two instances of {@link anything}.
* @returns @p false
* @relates anything
*/
inline bool operator==(const anything&, const anything&) { return true; }
inline bool operator==(const anything&, const anything&) {
return true;
}
/**
* @brief Compares two instances of {@link anything}.
* @returns @p false
* @relates anything
*/
inline bool operator!=(const anything&, const anything&) { return false; }
inline bool operator!=(const anything&, const anything&) {
return false;
}
/**
* @brief Checks wheter @p T is {@link anything}.
* @relates anything
*/
template <class T>
struct is_anything {
static constexpr bool value = std::is_same<T, anything>::value;
struct is_anything : std::is_same<T, anything> {
// no content
};
} // namespace caf
......
......@@ -27,7 +27,7 @@
namespace caf {
/**
* @brief The value type of atoms.
* The value type of atoms.
*/
enum class atom_value : uint64_t {
/** @cond PRIVATE */
......@@ -37,16 +37,12 @@ enum class atom_value : uint64_t {
};
/**
* @brief Returns @p what as a string representation.
* @param what Compact representation of an atom.
* @returns @p what as string.
* Returns `what` as a string representation.
*/
std::string to_string(const atom_value& what);
/**
* @brief Creates an atom from given string literal.
* @param str String constant representing an atom.
* @returns A compact representation of @p str.
* Creates an atom from given string literal.
*/
template <size_t Size>
constexpr atom_value atom(char const (&str)[Size]) {
......
......@@ -27,59 +27,46 @@
namespace caf {
/**
* @brief Callback utility class.
* Callback utility class.
*/
class attachable {
public:
attachable() = default;
attachable(const attachable&) = delete;
attachable& operator=(const attachable&) = delete;
protected:
attachable() = default;
public:
/**
* @brief Represents a pointer to a value with its RTTI.
* Represents a pointer to a value with its RTTI.
*/
struct token {
/**
* @brief Denotes the type of @c ptr.
* Denotes the type of ptr.
*/
const std::type_info& subtype;
/**
* @brief Any value, used to identify @c attachable instances.
* Any value, used to identify attachable instances.
*/
const void* ptr;
token(const std::type_info& subtype, const void* ptr);
};
virtual ~attachable();
/**
* @brief Executed if the actor finished execution with given @p reason.
*
* Executed if the actor finished execution with given `reason`.
* The default implementation does nothing.
* @param reason The exit rason of the observed actor.
*/
virtual void actor_exited(uint32_t reason) = 0;
/**
* @brief Selects a group of @c attachable instances by @p what.
* @param what A value that selects zero or more @c attachable instances.
* @returns @c true if @p what selects this instance; otherwise @c false.
* Returns `true` if `what` selects this instance, otherwise false.
*/
virtual bool matches(const token& what) = 0;
};
/**
* @brief A managed {@link attachable} pointer.
* @relates attachable
*/
using attachable_ptr = std::unique_ptr<attachable>;
......
......@@ -26,8 +26,7 @@
namespace caf {
/**
* @brief Blocks execution of this actor until all
* other actors finished execution.
* Blocks execution of this actor until all other actors finished execution.
* @warning This function will cause a deadlock if called from multiple actors.
* @warning Do not call this function in cooperatively scheduled actors.
*/
......
......@@ -37,120 +37,125 @@ namespace caf {
class message_handler;
/**
* @brief Describes the behavior of an actor.
* Describes the behavior of an actor, i.e., provides a message
* handler and an optional timeout.
*/
class behavior {
friend class message_handler;
public:
friend class message_handler;
/**
* The type of continuations that can be used to extend an existing behavior.
*/
using continuation_fun = std::function<optional<message>(message&)>;
/** @cond PRIVATE */
using impl_ptr = intrusive_ptr<detail::behavior_impl>;
inline auto as_behavior_impl() const -> const impl_ptr&;
inline behavior(impl_ptr ptr);
/** @endcond */
behavior() = default;
behavior(behavior&&) = default;
behavior(const behavior&) = default;
behavior& operator=(behavior&&) = default;
behavior& operator=(const behavior&) = default;
/**
* Creates a behavior from `fun` without timeout.
*/
behavior(const message_handler& fun);
template <class F>
behavior(const timeout_definition<F>& arg);
/**
* The list of arguments can contain match expressions, message handlers,
* and up to one timeout (if set, the timeout has to be the last argument).
*/
template <class T, class... Ts>
behavior(const T& arg, Ts&&... args)
: m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) {
// nop
}
/**
* Creates a behavior from `tdef` without message handler.
*/
template <class F>
behavior(const duration& d, F f);
behavior(const timeout_definition<F>& tdef)
: m_impl(detail::new_default_behavior(tdef.timeout, tdef.handler)) {
// nop
}
template <class T, class... Ts>
behavior(const T& arg, Ts&&... args);
/**
* Creates a behavior using `d` and `f` as timeout definition
* without message handler.
*/
template <class F>
behavior(const duration& d, F f)
: m_impl(detail::new_default_behavior(d, f)) {
// nop
}
/**
* @brief Invokes the timeout callback.
* Invokes the timeout callback if set.
*/
inline void handle_timeout();
inline void handle_timeout() {
m_impl->handle_timeout();
}
/**
* @brief Returns the duration after which receives using
* this behavior should time out.
* Returns the duration after which receive operations
* using this behavior should time out.
*/
inline const duration& timeout() const;
inline const duration& timeout() const {
return m_impl->timeout();
}
/**
* @brief Returns a value if @p arg was matched by one of the
* handler of this behavior, returns @p nothing otherwise.
* Returns a value if `arg` was matched by one of the
* handler of this behavior, returns `nothing` otherwise.
*/
template <class T>
inline optional<message> operator()(T&& arg);
optional<message> operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
}
/**
* @brief Adds a continuation to this behavior that is executed
* whenever this behavior was successfully applied to
* a message.
* Adds a continuation to this behavior that is executed
* whenever this behavior was successfully applied to a message.
*/
behavior add_continuation(continuation_fun fun);
inline operator bool() const { return static_cast<bool>(m_impl); }
/**
* Checks whether this behavior is not empty.
*/
inline operator bool() const {
return static_cast<bool>(m_impl);
}
private:
/** @cond PRIVATE */
impl_ptr m_impl;
using impl_ptr = intrusive_ptr<detail::behavior_impl>;
inline const impl_ptr& as_behavior_impl() const {
return m_impl;
}
inline behavior(impl_ptr ptr) : m_impl(std::move(ptr)) {
// nop
}
/** @endcond */
private:
impl_ptr m_impl;
};
/**
* @brief Creates a behavior from a match expression and a timeout definition.
* Creates a behavior from a match expression and a timeout definition.
* @relates behavior
*/
template <class... Cs, typename F>
inline behavior operator, (const match_expr<Cs...>& lhs,
const timeout_definition<F>& rhs) {
behavior operator,(const match_expr<Cs...>& lhs,
const timeout_definition<F>& rhs) {
return {lhs, rhs};
}
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
template <class T, class... Ts>
behavior::behavior(const T& arg, Ts&&... args)
: m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) {}
template <class F>
behavior::behavior(const timeout_definition<F>& arg)
: m_impl(detail::new_default_behavior(arg.timeout, arg.handler)) {}
template <class F>
behavior::behavior(const duration& d, F f)
: m_impl(detail::new_default_behavior(d, f)) {}
inline behavior::behavior(impl_ptr ptr) : m_impl(std::move(ptr)) {}
inline void behavior::handle_timeout() { m_impl->handle_timeout(); }
inline const duration& behavior::timeout() const { return m_impl->timeout(); }
template <class T>
inline optional<message> behavior::operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
}
inline auto behavior::as_behavior_impl() const -> const impl_ptr& {
return m_impl;
}
} // namespace caf
#endif // CAF_BEHAVIOR_HPP
......@@ -38,15 +38,15 @@ using keep_behavior_t = behavior_policy<false>;
using discard_behavior_t = behavior_policy<true>;
/**
* @brief Policy tag that causes {@link event_based_actor::become} to
* discard the current behavior.
* Policy tag that causes {@link event_based_actor::become} to
* discard the current behavior.
* @relates local_actor
*/
constexpr discard_behavior_t discard_behavior = discard_behavior_t{};
/**
* @brief Policy tag that causes {@link event_based_actor::become} to
* keep the current behavior available.
* Policy tag that causes {@link event_based_actor::become} to
* keep the current behavior available.
* @relates local_actor
*/
constexpr keep_behavior_t keep_behavior = keep_behavior_t{};
......
......@@ -25,8 +25,7 @@
namespace caf {
/**
* @brief Implements the deserializer interface with
* a binary serialization protocol.
* Implements the deserializer interface with a binary serialization protocol.
*/
class binary_deserializer : public deserializer {
......@@ -48,12 +47,12 @@ class binary_deserializer : public deserializer {
void read_raw(size_t num_bytes, void* storage) override;
/**
* @brief Replaces the current read buffer.
* Replaces the current read buffer.
*/
void set_rdbuf(const void* buf, size_t buf_size);
/**
* @brief Replaces the current read buffer.
* Replaces the current read buffer.
*/
void set_rdbuf(const void* begin, const void* m_end);
......
......@@ -35,9 +35,7 @@
namespace caf {
/**
* @brief Implements the serializer interface with
* a binary serialization protocol.
* @tparam Buffer A class providing a compatible interface to std::vector<char>.
* Implements the serializer interface with a binary serialization protocol.
*/
class binary_serializer : public serializer {
......@@ -48,8 +46,7 @@ class binary_serializer : public serializer {
using write_fun = std::function<void(const char*, const char*)>;
/**
* @brief Creates a binary serializer writing to @p write_buffer.
* @warning @p write_buffer must be guaranteed to outlive @p this
* Creates a binary serializer writing to given iterator position.
*/
template <class OutIter>
binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) {
......@@ -59,7 +56,6 @@ class binary_serializer : public serializer {
m_pos = std::copy(first, last, m_pos);
}
OutIter m_pos;
};
m_out = fun{iter};
}
......@@ -83,7 +79,7 @@ class binary_serializer : public serializer {
};
template <class T,
class = typename std::enable_if<detail::is_primitive<T>::value>::type>
class = typename std::enable_if<detail::is_primitive<T>::value>::type>
binary_serializer& operator<<(binary_serializer& bs, const T& value) {
bs.write_value(value);
return bs;
......
......@@ -36,8 +36,8 @@
namespace caf {
/**
* @brief A thread-mapped or context-switching actor using a blocking
* receive rather than a behavior-stack based message processing.
* A thread-mapped or context-switching actor using a blocking
* receive rather than a behavior-stack based message processing.
* @extends local_actor
*/
class blocking_actor
......@@ -101,8 +101,8 @@ class blocking_actor
};
/**
* @brief Dequeues the next message from the mailbox that
* is matched by given behavior.
* Dequeues the next message from the mailbox that is
* matched by given behavior.
*/
template <class... Ts>
void receive(Ts&&... args) {
......@@ -112,8 +112,8 @@ class blocking_actor
}
/**
* @brief Receives messages in an endless loop.
* Semantically equal to: <tt>for (;;) { receive(...); }</tt>
* Semantically equal to: `for (;;) { receive(...); }`, but does
* not cause a temporary behavior object per iteration.
*/
template <class... Ts>
void receive_loop(Ts&&... args) {
......@@ -122,21 +122,19 @@ class blocking_actor
}
/**
* @brief Receives messages as in a range-based loop.
*
* Receives messages for range `[begin, first)`.
* Semantically equal to:
* <tt>for ( ; begin != end; ++begin) { receive(...); }</tt>.
* `for ( ; begin != end; ++begin) { receive(...); }`.
*
* <b>Usage example:</b>
* @code
* **Usage example:**
* ~~~
* int i = 0;
* receive_for(i, 10) (
* on(atom("get")) >> [&]() -> message { return {"result", i}; }
* on(atom("get")) >> [&]() -> message {
* return {"result", i};
* }
* );
* @endcode
* @param begin First value in range.
* @param end Last value in range (excluded).
* @returns A functor implementing the loop.
* ~~~
*/
template <class T>
receive_for_helper<T> receive_for(T& begin, const T& end) {
......@@ -144,21 +142,18 @@ class blocking_actor
}
/**
* @brief Receives messages as long as @p stmt returns true.
*
* Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>.
* Receives messages as long as `stmt` returns true.
* Semantically equal to: `while (stmt()) { receive(...); }`.
*
* <b>Usage example:</b>
* @code
* **Usage example:**
* ~~~
* int i = 0;
* receive_while([&]() { return (++i <= 10); })
* (
* on<int>() >> int_fun,
* on<float>() >> float_fun
* );
* @endcode
* @param stmt Lambda expression, functor or function returning a @c bool.
* @returns A functor implementing the loop.
* ~~~
*/
template <class Statement>
receive_while_helper receive_while(Statement stmt) {
......@@ -168,13 +163,13 @@ class blocking_actor
}
/**
* @brief Receives messages until @p stmt returns true.
* Receives messages until `stmt` returns true.
*
* Semantically equal to:
* <tt>do { receive(...); } while (stmt() == false);</tt>
* `do { receive(...); } while (stmt() == false);`
*
* <b>Usage example:</b>
* @code
* **Usage example:**
* ~~~
* int i = 0;
* do_receive
* (
......@@ -182,9 +177,7 @@ class blocking_actor
* on<float>() >> float_fun
* )
* .until([&]() { return (++i >= 10); };
* @endcode
* @param args Denotes the actor's response the next incoming message.
* @returns A functor providing the @c until member function.
* ~~~
*/
template <class... Ts>
do_receive_helper do_receive(Ts&&... args) {
......@@ -198,17 +191,17 @@ class blocking_actor
}
/**
* @brief Blocks this actor until all other actors are done.
* Blocks this actor until all other actors are done.
*/
void await_all_other_actors_done();
/**
* @brief Implements the actor's behavior.
* Implements the actor's behavior.
*/
virtual void act() = 0;
/**
* @brief Unwinds the stack by throwing an actor_exited exception.
* Unwinds the stack by throwing an actor_exited exception.
* @throws actor_exited
*/
virtual void quit(uint32_t reason = exit_reason::normal);
......
......@@ -40,17 +40,15 @@ struct invalid_actor_t;
struct invalid_group_t;
/**
* @brief A handle to instances of {@link abstract_channel}.
* A handle to instances of `abstract_channel`.
*/
class channel : detail::comparable<channel>,
detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> {
detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> {
public:
template <class T, typename U>
friend T actor_cast(const U&);
public:
channel() = default;
channel(const actor&);
......@@ -63,19 +61,30 @@ class channel : detail::comparable<channel>,
template <class T>
channel(intrusive_ptr<T> ptr,
typename std::enable_if<
std::is_base_of<abstract_channel, T>::value>::type* = 0)
: m_ptr(ptr) {}
typename std::enable_if<
std::is_base_of<abstract_channel, T>::value
>::type* = 0)
: m_ptr(ptr) {
// nop
}
channel(abstract_channel* ptr);
inline explicit operator bool() const { return static_cast<bool>(m_ptr); }
inline explicit operator bool() const {
return static_cast<bool>(m_ptr);
}
inline bool operator!() const { return !m_ptr; }
inline bool operator!() const {
return !m_ptr;
}
inline abstract_channel* operator->() const { return m_ptr.get(); }
inline abstract_channel* operator->() const {
return m_ptr.get();
}
inline abstract_channel& operator*() const { return *m_ptr; }
inline abstract_channel& operator*() const {
return *m_ptr;
}
intptr_t compare(const channel& other) const;
......@@ -84,14 +93,14 @@ class channel : detail::comparable<channel>,
intptr_t compare(const abstract_channel* other) const;
static intptr_t compare(const abstract_channel* lhs,
const abstract_channel* rhs);
const abstract_channel* rhs);
private:
inline abstract_channel* get() const {
return m_ptr.get();
}
inline abstract_channel* get() const { return m_ptr.get(); }
intrusive_ptr<abstract_channel> m_ptr;
abstract_channel_ptr m_ptr;
};
} // namespace caf
......
......@@ -33,9 +33,9 @@
// - enables optional OpenCL module
/**
* @brief Denotes the libcaf version in the format {MAJOR}{MINOR}{PATCH},
* whereas each number is a two-digit decimal number without
* leading zeros (e.g. 900 is version 0.9.0).
* Denotes the libcaf version in the format {MAJOR}{MINOR}{PATCH},
* whereas each number is a two-digit decimal number without
* leading zeros (e.g. 900 is version 0.9.0).
*/
#define CAF_VERSION 1001
......
......@@ -32,21 +32,18 @@ namespace caf {
class local_actor;
/**
* @brief Helper class to enable users to add continuations
* when dealing with synchronous sends.
* Helper class to enable users to add continuations
* when dealing with synchronous sends.
*/
class continue_helper {
public:
using message_id_wrapper_tag = int;
continue_helper(message_id mid, local_actor* self);
/**
* @brief Adds a continuation to the synchronous message handler
* that is invoked if the response handler successfully returned.
* @param fun The continuation as functor object.
* Adds the continuation `fun` to the synchronous message handler
* that is invoked if the response handler successfully returned.
*/
template <class F>
continue_helper& continue_with(F fun) {
......@@ -55,22 +52,19 @@ class continue_helper {
}
/**
* @brief Adds a continuation to the synchronous message handler
* that is invoked if the response handler successfully returned.
* @param fun The continuation as functor object.
* Adds the continuation `fun` to the synchronous message handler
* that is invoked if the response handler successfully returned.
*/
continue_helper& continue_with(behavior::continuation_fun fun);
/**
* @brief Returns the ID of the expected response message.
* Returns the ID of the expected response message.
*/
message_id get_message_id() const { return m_mid; }
private:
message_id m_mid;
local_actor* m_self;
};
} // namespace caf
......
......@@ -28,13 +28,12 @@
namespace caf {
class object;
class actor_namespace;
class uniform_type_info;
/**
* @ingroup TypeSystem
* @brief Technology-independent deserialization interface.
* Technology-independent deserialization interface.
*/
class deserializer {
......@@ -48,34 +47,34 @@ class deserializer {
virtual ~deserializer();
/**
* @brief Begins deserialization of a new object.
* Begins deserialization of a new object.
*/
virtual const uniform_type_info* begin_object() = 0;
/**
* @brief Ends deserialization of an object.
* Ends deserialization of an object.
*/
virtual void end_object() = 0;
/**
* @brief Begins deserialization of a sequence.
* Begins deserialization of a sequence.
* @returns The size of the sequence.
*/
virtual size_t begin_sequence() = 0;
/**
* @brief Ends deserialization of a sequence.
* Ends deserialization of a sequence.
*/
virtual void end_sequence() = 0;
/**
* @brief Reads a primitive value from the data source.
* Reads a primitive value from the data source.
*/
virtual void read_value(primitive_variant& storage) = 0;
/**
* @brief Reads a value of type @p T from the data source.
* @note @p T must be a primitive type.
* Reads a value of type `T` from the data source.
* @note `T` must be a primitive type.
*/
template <class T>
inline T read() {
......@@ -106,11 +105,13 @@ class deserializer {
}
/**
* @brief Reads a raw memory block.
* Reads a raw memory block.
*/
virtual void read_raw(size_t num_bytes, void* storage) = 0;
inline actor_namespace* get_namespace() { return m_namespace; }
inline actor_namespace* get_namespace() {
return m_namespace;
}
template <class Buffer>
void read_raw(size_t num_bytes, Buffer& storage) {
......@@ -119,9 +120,7 @@ class deserializer {
}
private:
actor_namespace* m_namespace;
};
} // namespace caf
......
......@@ -33,8 +33,8 @@ namespace caf {
namespace detail {
/**
* @brief Implements all pure virtual functions of {@link uniform_type_info}
* except serialize() and deserialize().
* Implements all pure virtual functions of `uniform_type_info`
* except serialize() and deserialize().
*/
template <class T>
class abstract_uniform_type_info : public uniform_type_info {
......
......@@ -27,7 +27,6 @@
#include <cstdint>
#include <condition_variable>
#include "caf/attachable.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/detail/shared_spinlock.hpp"
......@@ -39,23 +38,18 @@ namespace detail {
class singletons;
class actor_registry : public singleton_mixin<actor_registry> {
friend class singleton_mixin<actor_registry>;
public:
friend class singleton_mixin<actor_registry>;
~actor_registry();
/**
* @brief A registry entry consists of a pointer to the actor and an
* exit reason. An entry with a nullptr means the actor has finished
* execution for given reason.
* A registry entry consists of a pointer to the actor and an
* exit reason. An entry with a nullptr means the actor has finished
* execution for given reason.
*/
using value_type = std::pair<abstract_actor_ptr, uint32_t>;
/**
* @brief Returns the {nullptr, invalid_exit_reason}.
*/
value_type get_entry(actor_id key) const;
// return nullptr if the actor wasn't put *or* finished execution
......@@ -78,13 +72,14 @@ class actor_registry : public singleton_mixin<actor_registry> {
size_t running() const;
// blocks the caller until running-actors-count becomes @p expected
// blocks the caller until running-actors-count becomes `expected`
void await_running_count_equal(size_t expected);
private:
using entries = std::map<actor_id, value_type>;
actor_registry();
std::atomic<size_t> m_running;
std::atomic<actor_id> m_ids;
......@@ -93,9 +88,6 @@ class actor_registry : public singleton_mixin<actor_registry> {
mutable detail::shared_spinlock m_instances_mtx;
entries m_entries;
actor_registry();
};
} // namespace detail
......
......@@ -58,7 +58,7 @@ class behavior_stack {
void clear();
// erases the synchronous response handler associated with @p rid
// erases the synchronous response handler associated with `rid`
void erase(message_id rid) {
erase_if([=](const element_type& e) { return e.second == rid; });
}
......
......@@ -24,13 +24,12 @@ namespace caf {
namespace detail {
/**
* @brief Barton–Nackman trick implementation.
*
* @p Subclass must provide a @c compare member function that compares
* to instances of @p T and returns an integer @c x with:
* - <tt>x < 0</tt> if <tt>*this < other</tt>
* - <tt>x > 0</tt> if <tt>*this > other</tt>
* - <tt>x == 0</tt> if <tt>*this == other</tt>
* Barton–Nackman trick implementation.
* `Subclass` must provide a compare member function that compares
* to instances of `T` and returns an integer x with:
* - `x < 0</tt> if <tt>*this < other
* - `x > 0</tt> if <tt>*this > other
* - `x == 0</tt> if <tt>*this == other
*/
template <class Subclass, class T = Subclass>
class comparable {
......
......@@ -49,22 +49,22 @@ class decorated_tuple : public message_data {
using rtti = const std::type_info*;
// creates a dynamically typed subtuple from @p d with an offset
// creates a dynamically typed subtuple from `d` with an offset
static inline pointer create(pointer d, vector_type v) {
return pointer{new decorated_tuple(std::move(d), std::move(v))};
}
// creates a statically typed subtuple from @p d with an offset
// creates a statically typed subtuple from `d` with an offset
static inline pointer create(pointer d, rtti ti, vector_type v) {
return pointer{new decorated_tuple(std::move(d), ti, std::move(v))};
}
// creates a dynamically typed subtuple from @p d with an offset
// creates a dynamically typed subtuple from `d` with an offset
static inline pointer create(pointer d, size_t offset) {
return pointer{new decorated_tuple(std::move(d), offset)};
}
// creates a statically typed subtuple from @p d with an offset
// creates a statically typed subtuple from `d` with an offset
static inline pointer create(pointer d, rtti ti, size_t offset) {
return pointer{new decorated_tuple(std::move(d), ti, offset)};
}
......
......@@ -26,12 +26,7 @@ namespace caf {
namespace detail {
/**
* @addtogroup MetaProgramming
* @{
*/
/**
* @brief A list of integers (wraps a long... template parameter pack).
* A list of integers (wraps a long... template parameter pack).
*/
template <long... Is>
struct int_list {};
......@@ -63,7 +58,7 @@ struct il_right<int_list<Is...>, N> : il_right_impl<(N > sizeof...(Is)
Is...> { };
/**
* @brief Creates indices for @p List beginning at @p Pos.
* Creates indices for `List` beginning at `Pos`.
*/
template <class List, long Pos = 0, typename Indices = int_list<>>
struct il_indices;
......@@ -99,10 +94,6 @@ constexpr auto get_right_indices(const T&)
return {};
}
/**
* @}
*/
} // namespace detail
} // namespace caf
......
......@@ -26,7 +26,7 @@ namespace caf {
namespace detail {
/**
* @brief Evaluates to @p Right if @p Left == unit_t, @p Left otherwise.
* Evaluates to `Right` if `Left` == unit_t, `Left` otherwise.
*/
template <class Left, typename Right>
struct left_or_right {
......@@ -53,7 +53,7 @@ struct left_or_right<const unit_t&, Right> {
};
/**
* @brief Evaluates to @p Right if @p Left != unit_t, @p unit_t otherwise.
* Evaluates to `Right` if `Left` != unit_t, `unit_t` otherwise.
*/
template <class Left, typename Right>
struct if_not_left {
......
......@@ -141,10 +141,10 @@ class lifted_fun_invoker<bool, F> {
};
/**
* @brief A lifted functor consists of a set of projections, a plain-old
* functor and its signature. Note that the signature of the lifted
* functor might differ from the underlying functor, because
* of the projections.
* A lifted functor consists of a set of projections, a plain-old
* functor and its signature. Note that the signature of the lifted
* functor might differ from the underlying functor, because
* of the projections.
*/
template <class F, class ListOfProjections, class... Args>
class lifted_fun {
......@@ -185,7 +185,7 @@ class lifted_fun {
}
/**
* @brief Invokes @p fun with a lifted_fun of <tt>args...</tt>.
* Invokes `fun` with a lifted_fun of `args....
*/
optional_result_type operator()(Args... args) {
auto indices = get_indices(m_ps);
......
......@@ -32,41 +32,33 @@
namespace caf {
namespace detail {
/**
* @brief A vector with a fixed maximum size (uses an array internally).
/*
* A vector with a fixed maximum size (uses an array internally).
* @warning This implementation is highly optimized for arithmetic types and
* does <b>not</b> call constructors or destructors properly.
* does <b>not</b> call constructors or destructors.
*/
template <class T, size_t MaxSize>
class limited_vector {
//static_assert(std::is_arithmetic<T>::value || std::is_pointer<T>::value,
// "T must be an arithmetic or pointer type");
size_t m_size;
// support for MaxSize == 0
T m_data[(MaxSize > 0) ? MaxSize : 1];
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using iterator = T*;
using const_iterator = const T*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
inline limited_vector() : m_size(0) { }
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using iterator = pointer;
using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
limited_vector() : m_size(0) {
// nop
}
limited_vector(size_t initial_size) : m_size(initial_size) {
std::fill_n(begin(), initial_size, 0);
T tmp;
std::fill_n(begin(), initial_size, tmp);
}
limited_vector(const limited_vector& other) : m_size(other.m_size) {
......@@ -96,149 +88,144 @@ class limited_vector {
template <class InputIterator>
void assign(InputIterator first, InputIterator last,
// dummy SFINAE argument
typename std::iterator_traits<InputIterator>::pointer = 0) {
// dummy SFINAE argument
typename std::iterator_traits<InputIterator>::pointer = 0) {
auto dist = std::distance(first, last);
CAF_REQUIRE(dist >= 0);
resize(static_cast<size_t>(dist));
std::copy(first, last, begin());
}
inline size_type size() const {
size_type size() const {
return m_size;
}
inline size_type max_size() const {
size_type max_size() const {
return MaxSize;
}
inline size_type capacity() const {
size_type capacity() const {
return max_size() - size();
}
inline void clear() {
void clear() {
m_size = 0;
}
inline bool empty() const {
bool empty() const {
return m_size == 0;
}
inline bool full() const {
bool full() const {
return m_size == MaxSize;
}
inline void push_back(const_reference what) {
void push_back(const_reference what) {
CAF_REQUIRE(!full());
m_data[m_size++] = what;
}
inline void pop_back() {
void pop_back() {
CAF_REQUIRE(!empty());
--m_size;
}
inline reference at(size_type pos) {
reference at(size_type pos) {
CAF_REQUIRE(pos < m_size);
return m_data[pos];
}
inline const_reference at(size_type pos) const {
const_reference at(size_type pos) const {
CAF_REQUIRE(pos < m_size);
return m_data[pos];
}
inline reference operator[](size_type pos) {
reference operator[](size_type pos) {
return at(pos);
}
inline const_reference operator[](size_type pos) const {
const_reference operator[](size_type pos) const {
return at(pos);
}
inline iterator begin() {
iterator begin() {
return m_data;
}
inline const_iterator begin() const {
const_iterator begin() const {
return m_data;
}
inline const_iterator cbegin() const {
const_iterator cbegin() const {
return begin();
}
inline iterator end() {
iterator end() {
return begin() + m_size;
}
inline const_iterator end() const {
const_iterator end() const {
return begin() + m_size;
}
inline const_iterator cend() const {
const_iterator cend() const {
return end();
}
inline reverse_iterator rbegin() {
reverse_iterator rbegin() {
return reverse_iterator(end());
}
inline const_reverse_iterator rbegin() const {
const_reverse_iterator rbegin() const {
return reverse_iterator(end());
}
inline const_reverse_iterator crbegin() const {
const_reverse_iterator crbegin() const {
return rbegin();
}
inline reverse_iterator rend() {
reverse_iterator rend() {
return reverse_iterator(begin());
}
inline const_reverse_iterator rend() const {
const_reverse_iterator rend() const {
return reverse_iterator(begin());
}
inline const_reverse_iterator crend() const {
const_reverse_iterator crend() const {
return rend();
}
inline reference front() {
reference front() {
CAF_REQUIRE(!empty());
return m_data[0];
}
inline const_reference front() const {
const_reference front() const {
CAF_REQUIRE(!empty());
return m_data[0];
}
inline reference back() {
reference back() {
CAF_REQUIRE(!empty());
return m_data[m_size - 1];
}
inline const_reference back() const {
const_reference back() const {
CAF_REQUIRE(!empty());
return m_data[m_size - 1];
}
inline T* data() {
T* data() {
return m_data;
}
inline const T* data() const {
const T* data() const {
return m_data;
}
/**
* @brief Inserts elements before the element pointed to by @p pos.
* @throw std::length_error if
* <tt>size() + distance(first, last) > MaxSize</tt>
*/
template <class InputIterator>
inline void insert(iterator pos, InputIterator first, InputIterator last) {
void insert(iterator pos, InputIterator first, InputIterator last) {
CAF_REQUIRE(first <= last);
auto num_elements = static_cast<size_t>(std::distance(first, last));
if ((size() + num_elements) > MaxSize) {
......@@ -258,6 +245,9 @@ class limited_vector {
}
}
private:
size_t m_size;
T m_data[(MaxSize > 0) ? MaxSize : 1];
};
} // namespace detail
......
......@@ -233,7 +233,7 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/**
* @def CAF_LOGC
* @brief Logs a message with custom class and function names.
* Logs a message with custom class and function names.
*/
#define CAF_LOGC(level, classname, funname, msg) \
CAF_CAT(CAF_PRINT, level)(CAF_CAT(CAF_LVL_NAME, level)(), classname, \
......@@ -241,19 +241,19 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/**
* @def CAF_LOGF
* @brief Logs a message inside a free function.
* Logs a message inside a free function.
*/
#define CAF_LOGF(level, msg) CAF_LOGC(level, "NONE", __func__, msg)
/**
* @def CAF_LOGMF
* @brief Logs a message inside a member function.
* Logs a message inside a member function.
*/
#define CAF_LOGMF(level, msg) CAF_LOGC(level, CAF_CLASS_NAME, __func__, msg)
/**
* @def CAF_LOGC
* @brief Logs a message with custom class and function names.
* Logs a message with custom class and function names.
*/
#define CAF_LOGC_IF(stmt, level, classname, funname, msg) \
CAF_CAT(CAF_PRINT_IF, level)(stmt, CAF_CAT(CAF_LVL_NAME, level)(), \
......@@ -261,14 +261,14 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/**
* @def CAF_LOGF
* @brief Logs a message inside a free function.
* Logs a message inside a free function.
*/
#define CAF_LOGF_IF(stmt, level, msg) \
CAF_LOGC_IF(stmt, level, "NONE", __func__, msg)
/**
* @def CAF_LOGMF
* @brief Logs a message inside a member function.
* Logs a message inside a member function.
*/
#define CAF_LOGMF_IF(stmt, level, msg) \
CAF_LOGC_IF(stmt, level, CAF_CLASS_NAME, __func__, msg)
......
......@@ -76,7 +76,7 @@ class memory_cache {
virtual std::pair<instance_wrapper*, void*> new_instance() = 0;
// casts @p ptr to the derived type and returns it
// casts `ptr` to the derived type and returns it
virtual void* downcast(memory_managed* ptr) = 0;
};
......@@ -94,10 +94,7 @@ class memory {
public:
/*
* @brief Allocates storage, initializes a new object, and returns
* the new instance.
*/
// Allocates storage, initializes a new object, and returns the new instance.
template <class T, class... Ts>
static T* create(Ts&&... args) {
return new T(std::forward<Ts>(args)...);
......@@ -198,10 +195,7 @@ class memory {
public:
/*
* @brief Allocates storage, initializes a new object, and returns
* the new instance.
*/
// Allocates storage, initializes a new object, and returns the new instance.
template <class T, class... Ts>
static T* create(Ts&&... args) {
auto mc = get_or_set_cache_map_entry<T>();
......
......@@ -41,9 +41,9 @@ inline void yield() noexcept {
req.tv_nsec = 1;
nanosleep(&req, nullptr);
}
}
}
} // namespace std::this_thread::<anonymous>
} // namespace anonymous>
} // namespace this_thread
} // namespace std
#endif
// another GCC hack
......@@ -61,17 +61,16 @@ inline void sleep_for(const chrono::duration<Rep, Period>& rt) {
req.tv_nsec = nsec.count();
nanosleep(&req, nullptr);
}
}
}
} // namespace std::this_thread::<anonymous>
} // namespace anonymous>
} // namespace this_thread
} // namespace std
#endif
namespace caf {
namespace detail {
/**
* @brief A producer-consumer list.
*
* A producer-consumer list.
* For implementation details see http://drdobbs.com/cpp/211601363.
*/
template <class T>
......
......@@ -22,8 +22,8 @@
#include <type_traits>
#include "caf/fwd.hpp"
#include "caf/duration.hpp"
#include "caf/blocking_actor.hpp"
#include "caf/mailbox_element.hpp"
#include "caf/detail/logging.hpp"
......@@ -35,7 +35,7 @@ namespace detail {
// 'imports' all member functions from policies to the actor,
// the resume mixin also adds the m_hidden member which *must* be
// initialized to @p true
// initialized to `true`
template <class Base, class Derived, class Policies>
class proper_actor_base : public Policies::resume_policy::template
mixin<Base, Derived> {
......@@ -317,8 +317,8 @@ class proper_actor<Base, Policies, true>
auto msg = make_message(timeout_msg{tid});
if (d.is_zero()) {
// immediately enqueue timeout message if duration == 0s
this->enqueue(this->address(), message_id::invalid, std::move(msg),
this->m_host);
this->enqueue(this->address(), message_id::invalid,
std::move(msg), this->host());
// auto e = this->new_mailbox_element(this, std::move(msg));
// this->m_mailbox.enqueue(e);
} else {
......
......@@ -43,7 +43,7 @@ struct purge_refs_impl<std::reference_wrapper<const T>> {
};
/**
* @brief Removes references and reference wrappers.
* Removes references and reference wrappers.
*/
template <class T>
struct purge_refs {
......
......@@ -63,7 +63,7 @@ namespace caf {
namespace detail {
/**
* @brief Creates a hash from @p data using the RIPEMD-160 algorithm.
* Creates a hash from `data` using the RIPEMD-160 algorithm.
*/
void ripemd_160(std::array<uint8_t, 20>& storage, const std::string& data);
......
......@@ -34,9 +34,9 @@ namespace caf {
namespace detail {
/**
* @brief Compares two values by using @p operator== unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
* Compares two values by using `operator==` unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
*/
template <class T, typename U>
typename std::enable_if< !std::is_floating_point<T>::value
......
......@@ -26,7 +26,7 @@ namespace caf {
namespace detail {
/**
* @brief A lightweight scope guard implementation.
* A lightweight scope guard implementation.
*/
template <class Fun>
class scope_guard {
......@@ -49,8 +49,8 @@ class scope_guard {
}
/**
* @brief Disables this guard, i.e., the guard does not
* run its cleanup code as it goes out of scope.
* Disables this guard, i.e., the guard does not
* run its cleanup code as it goes out of scope.
*/
inline void disable() { m_enabled = false; }
......@@ -62,8 +62,7 @@ class scope_guard {
};
/**
* @brief Creates a guard that executes @p f as soon as it
* goes out of scope.
* Creates a guard that executes `f` as soon as it goes out of scope.
* @relates scope_guard
*/
template <class Fun>
......
......@@ -27,7 +27,7 @@ namespace caf {
namespace detail {
/**
* @brief A spinlock implementation providing shared and exclusive locking.
* A spinlock implementation providing shared and exclusive locking.
*/
class shared_spinlock {
......
......@@ -32,32 +32,30 @@ namespace caf {
namespace detail {
/**
* @brief Denotes in which state queue and reader are after an enqueue.
* Denotes in which state queue and reader are after an enqueue.
*/
enum class enqueue_result {
/**
* @brief Indicates that the enqueue operation succeeded and
* the reader is ready to receive the data.
* Indicates that the enqueue operation succeeded and
* the reader is ready to receive the data.
*/
success,
/**
* @brief Indicates that the enqueue operation succeeded and
* the reader is currently blocked, i.e., needs to be re-scheduled.
* Indicates that the enqueue operation succeeded and
* the reader is currently blocked, i.e., needs to be re-scheduled.
*/
unblocked_reader,
/**
* @brief Indicates that the enqueue operation failed because the
* queue has been closed by the reader.
* Indicates that the enqueue operation failed because the
* queue has been closed by the reader.
*/
queue_closed
};
/**
* @brief An intrusive, thread-safe queue implementation.
* @note For implementation details see
* http://libcppa.blogspot.com/2011/04/mailbox-part-1.html
* An intrusive, thread-safe queue implementation.
*/
template <class T, class Delete = std::default_delete<T>>
class single_reader_queue {
......@@ -66,7 +64,7 @@ class single_reader_queue {
using pointer = value_type*;
/**
* @brief Tries to dequeue a new element from the mailbox.
* Tries to dequeue a new element from the mailbox.
* @warning Call only from the reader (owner).
*/
pointer try_pop() {
......@@ -74,7 +72,7 @@ class single_reader_queue {
}
/**
* @brief Tries to enqueue a new element to the mailbox.
* Tries to enqueue a new element to the mailbox.
* @warning Call only from the reader (owner).
*/
enqueue_result enqueue(pointer new_element) {
......@@ -97,8 +95,8 @@ class single_reader_queue {
}
/**
* @brief Queries whether there is new data to read, i.e., whether the next
* call to {@link try_pop} would succeeed.
* Queries whether there is new data to read, i.e., whether the next
* call to {@link try_pop} would succeeed.
* @pre !closed()
*/
bool can_fetch_more() {
......@@ -111,7 +109,7 @@ class single_reader_queue {
}
/**
* @brief Queries whether this queue is empty.
* Queries whether this queue is empty.
* @warning Call only from the reader (owner).
*/
bool empty() {
......@@ -120,25 +118,22 @@ class single_reader_queue {
}
/**
* @brief Queries whether this has been closed.
* Queries whether this has been closed.
*/
bool closed() {
return m_stack.load() == nullptr;
}
/**
* @brief Queries whether this has been marked as blocked, i.e., the
* owner of the list is waiting for new data.
* Queries whether this has been marked as blocked, i.e.,
* the owner of the list is waiting for new data.
*/
bool blocked() {
return m_stack.load() == reader_blocked_dummy();
}
/**
* @brief Tries to set this queue from state @p empty to state @p blocked.
* @returns @p true if the state change was successful or if the mailbox
* was already blocked, otherwise @p false.
* @note This function never fails spuriously.
* Tries to set this queue from state `empty` to state `blocked`.
*/
bool try_block() {
auto e = stack_empty_dummy();
......@@ -149,9 +144,7 @@ class single_reader_queue {
}
/**
* @brief Tries to set this queue from state @p blocked to state @p empty.
* @returns @p true if the state change was successful, otherwise @p false.
* @note This function never fails spuriously.
* Tries to set this queue from state `blocked` to state `empty`.
*/
bool try_unblock() {
auto e = reader_blocked_dummy();
......@@ -159,7 +152,7 @@ class single_reader_queue {
}
/**
* @brief Closes this queue and deletes all remaining elements.
* Closes this queue and deletes all remaining elements.
* @warning Call only from the reader (owner).
*/
void close() {
......@@ -170,7 +163,7 @@ class single_reader_queue {
}
/**
* @brief Closes this queue and applies f to all remaining
* Closes this queue and applies f to all remaining
* elements before deleting them.
* @warning Call only from the reader (owner).
*/
......
......@@ -86,17 +86,8 @@ class singletons {
static std::atomic<abstract_singleton*>& get_plugin_singleton(size_t id);
/*
* @brief Type @p T has to provide: <tt>static T* create_singleton()</tt>,
* <tt>void initialize()</tt>, <tt>void destroy()</tt>,
* and <tt>dispose()</tt>.
* The constructor of T shall be lightweigt, since more than one object
* might get constructed initially.
* <tt>dispose()</tt> is called on objects with failed CAS operation.
* <tt>initialize()</tt> is called on objects with succeeded CAS operation.
* <tt>destroy()</tt> is called during shutdown on initialized objects.
*
* Both <tt>dispose</tt> and <tt>destroy</tt> must delete the object
* eventually.
* Type `T` has to provide: `static T* create_singleton()`,
* `void initialize()`, `void stop()`, and `dispose()`.
*/
template <class T, typename Factory>
static T* lazy_get(std::atomic<T*>& ptr, Factory f) {
......
......@@ -23,10 +23,6 @@
namespace caf {
namespace detail {
/**
* @ingroup MetaProgramming
* @brief Predefines the first template parameter of @p Tp1.
*/
template <template <class, typename> class Tpl, typename Arg1>
struct tbind {
template <class Arg2>
......
......@@ -32,18 +32,13 @@ namespace caf {
namespace detail {
/**
* @addtogroup MetaProgramming
* @{
*/
/**
* @brief A list of types.
* A list of types.
*/
template <class... Ts>
struct type_list { };
/**
* @brief Denotes the empty list.
* Denotes the empty list.
*/
using empty_type_list = type_list<>;
......@@ -60,7 +55,7 @@ struct is_type_list<type_list<Ts...>> {
// T head(type_list)
/**
* @brief Gets the first element of @p List.
* Gets the first element of `List`.
*/
template <class List>
struct tl_head;
......@@ -78,7 +73,7 @@ struct tl_head<List<T0, Ts...>> {
// type_list tail(type_list)
/**
* @brief Gets the tail of @p List.
* Gets the tail of `List`.
*/
template <class List>
struct tl_tail;
......@@ -96,7 +91,7 @@ struct tl_tail<List<T0, Ts...>> {
// size_t size(type_list)
/**
* @brief Gets the number of template parameters of @p List.
* Gets the number of template parameters of `List`.
*/
template <class List>
struct tl_size;
......@@ -109,7 +104,7 @@ struct tl_size<List<Ts...>> {
// T back(type_list)
/**
* @brief Gets the last element in @p List.
* Gets the last element in `List`.
*/
template <class List>
struct tl_back;
......@@ -134,7 +129,7 @@ struct tl_back<List<T0, T1, Ts...>> {
// bool empty(type_list)
/**
* @brief Tests whether a list is empty.
* Tests whether a list is empty.
*/
template <class List>
struct tl_empty {
......@@ -213,7 +208,7 @@ struct tl_slice_<List, ListSize, 0, ListSize, PadType> {
};
/**
* @brief Creates a new list from range (First, Last].
* Creates a new list from range (First, Last].
*/
template <class List, size_t First, size_t Last>
struct tl_slice {
......@@ -227,9 +222,9 @@ struct tl_slice {
};
/**
* @brief Zips two lists of equal size.
* Zips two lists of equal size.
*
* Creates a list formed from the two lists @p ListA and @p ListB,
* Creates a list formed from the two lists `ListA` and `ListB,`
* e.g., tl_zip<type_list<int, double>, type_list<float, string>>::type
* is type_list<type_pair<int, float>, type_pair<double, string>>.
*/
......@@ -312,7 +307,7 @@ struct tl_reverse_impl<empty_type_list, E...> {
};
/**
* @brief Creates a new list wih elements in reversed order.
* Creates a new list wih elements in reversed order.
*/
template <class List>
struct tl_reverse {
......@@ -322,7 +317,7 @@ struct tl_reverse {
// bool find(list, type)
/**
* @brief Finds the first element of type @p What beginning at index @p Pos.
* Finds the first element of type `What` beginning at index `Pos`.
*/
template <class List, template <class> class Pred, int Pos = 0>
struct tl_find_impl;
......@@ -342,8 +337,8 @@ struct tl_find_impl<List<T0, Ts...>, Pred, Pos> {
};
/**
* @brief Finds the first element satisfying @p Pred beginning at
* index @p Pos.
* Finds the first element satisfying `Pred` beginning at
* index `Pos`.
*/
template <class List, template <class> class Pred, int Pos = 0>
struct tl_find_if {
......@@ -351,8 +346,8 @@ struct tl_find_if {
};
/**
* @brief Finds the first element of type @p What beginning at
* index @p Pos.
* Finds the first element of type `What` beginning at
* index `Pos`.
*/
template <class List, class What, int Pos = 0>
struct tl_find {
......@@ -366,7 +361,7 @@ struct tl_find {
// bool forall(predicate)
/**
* @brief Tests whether a predicate holds for all elements of a list.
* Tests whether a predicate holds for all elements of a list.
*/
template <class List, template <class> class Pred>
struct tl_forall {
......@@ -395,8 +390,8 @@ struct tl_forall2_impl<empty_type_list, empty_type_list, Pred> {
};
/**
* @brief Tests whether a binary predicate holds for all
* corresponding elements of @p ListA and @p ListB.
* Tests whether a binary predicate holds for all
* corresponding elements of `ListA` and `ListB`.
*/
template <class ListA, class ListB, template <class, class> class Pred>
struct tl_binary_forall {
......@@ -406,7 +401,7 @@ struct tl_binary_forall {
};
/**
* @brief Tests whether a predicate holds for some of the elements of a list.
* Tests whether a predicate holds for some of the elements of a list.
*/
template <class List, template <class> class Pred>
struct tl_exists {
......@@ -424,7 +419,7 @@ struct tl_exists<empty_type_list, Pred> {
// size_t count(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
* Counts the number of elements in the list which satisfy a predicate.
*/
template <class List, template <class> class Pred>
struct tl_count {
......@@ -441,7 +436,7 @@ struct tl_count<empty_type_list, Pred> {
// size_t count_not(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
* Counts the number of elements in the list which satisfy a predicate.
*/
template <class List, template <class> class Pred>
struct tl_count_not {
......@@ -461,7 +456,7 @@ template <class ListA, class ListB>
struct tl_concat_impl;
/**
* @brief Concatenates two lists.
* Concatenates two lists.
*/
template <class... LhsTs, class... RhsTs>
struct tl_concat_impl<type_list<LhsTs...>, type_list<RhsTs...>> {
......@@ -471,7 +466,7 @@ struct tl_concat_impl<type_list<LhsTs...>, type_list<RhsTs...>> {
// static list concat(list, list)
/**
* @brief Concatenates lists.
* Concatenates lists.
*/
template <class... Lists>
struct tl_concat;
......@@ -496,7 +491,7 @@ template <class List, class What>
struct tl_push_back;
/**
* @brief Appends @p What to given list.
* Appends `What` to given list.
*/
template <class... ListTs, class What>
struct tl_push_back<type_list<ListTs...>, What> {
......@@ -508,7 +503,7 @@ template <class List, class What>
struct tl_push_front;
/**
* @brief Appends @p What to given list.
* Appends `What` to given list.
*/
template <class... ListTs, class What>
struct tl_push_front<type_list<ListTs...>, What> {
......@@ -532,7 +527,7 @@ struct tl_apply_all<T, Fun0, Funs...> {
};
/**
* @brief Creates a new list by applying a "template function" to each element.
* Creates a new list by applying a "template function" to each element.
*/
template <class List, template <class> class... Funs>
struct tl_map;
......@@ -543,8 +538,8 @@ struct tl_map<type_list<Ts...>, Funs...> {
};
/**
* @brief Creates a new list by applying a @p Fun to each element which
* returns @p TraitResult for @p Trait.
* Creates a new list by applying a `Fun` to each element which
* returns `TraitResult` for `Trait`.
*/
template <class List, template <class> class Trait, bool TRes,
template <class> class... Funs>
......@@ -574,7 +569,7 @@ struct tl_map_conditional<empty_type_list, Trait, TraitResult, Funs...> {
// list pop_back()
/**
* @brief Creates a new list wih all but the last element of @p List.
* Creates a new list wih all but the last element of `List`.
*/
template <class List>
struct tl_pop_back {
......@@ -610,7 +605,7 @@ template <class List, size_t N>
struct tl_at;
/**
* @brief Gets element at index @p N of @p List.
* Gets element at index `N` of `List`.
*/
template <size_t N, class... E>
struct tl_at<type_list<E...>, N> {
......@@ -623,7 +618,7 @@ template <class List, class What>
struct tl_prepend;
/**
* @brief Creates a new list with @p What prepended to @p List.
* Creates a new list with `What` prepended to `List`.
*/
template <class What, class... T>
struct tl_prepend<type_list<T...>, What> {
......@@ -662,7 +657,7 @@ template <class List, template <class> class Pred>
struct tl_filter;
/**
* @brief Create a new list containing all elements which satisfy @p Pred.
* Create a new list containing all elements which satisfy `Pred`.
*/
template <template <class> class Pred, class... T>
struct tl_filter<type_list<T...>, Pred> {
......@@ -674,8 +669,8 @@ struct tl_filter<type_list<T...>, Pred> {
};
/**
* @brief Creates a new list containing all elements which
* do not satisfy @p Pred.
* Creates a new list containing all elements which
* do not satisfy `Pred`.
*/
template <class List, template <class> class Pred>
struct tl_filter_not;
......@@ -695,8 +690,8 @@ struct tl_filter_not<type_list<T...>, Pred> {
};
/**
* @brief Creates a new list containing all elements which
* are equal to @p Type.
* Creates a new list containing all elements which
* are equal to `Type`.
*/
template <class List, class Type>
struct tl_filter_type;
......@@ -711,8 +706,8 @@ struct tl_filter_type<type_list<T...>, Type> {
};
/**
* @brief Creates a new list containing all elements which
* are not equal to @p Type.
* Creates a new list containing all elements which
* are not equal to `Type`.
*/
template <class List, class Type>
struct tl_filter_not_type;
......@@ -729,7 +724,7 @@ struct tl_filter_not_type<type_list<T...>, Type> {
// list distinct(list)
/**
* @brief Creates a new list from @p List without any duplicate elements.
* Creates a new list from `List` without any duplicate elements.
*/
template <class List>
struct tl_distinct;
......@@ -756,7 +751,7 @@ struct tl_distinct<type_list<T0, Ts...>> {
// bool is_distinct
/**
* @brief Tests whether a list is distinct.
* Tests whether a list is distinct.
*/
template <class L>
struct tl_is_distinct {
......@@ -765,7 +760,7 @@ struct tl_is_distinct {
};
/**
* @brief Creates a new list containing the last @p N elements.
* Creates a new list containing the last `N` elements.
*/
template <class List, size_t N>
struct tl_right {
......@@ -808,8 +803,8 @@ struct tl_pad_right_impl<List, true, OldSize, NewSize, FillType> {
};
/**
* @brief Resizes the list to contain @p NewSize elements and uses
* @p FillType to initialize the new elements with.
* Resizes the list to contain `NewSize` elements and uses
* `FillType` to initialize the new elements with.
*/
template <class List, size_t NewSize, class FillType = unit_t>
struct tl_pad_right {
......@@ -845,8 +840,8 @@ struct tl_pad_left_impl<List, Size, Size, FillType> {
};
/**
* @brief Resizes the list to contain @p NewSize elements and uses
* @p FillType to initialize prepended elements with.
* Resizes the list to contain `NewSize` elements and uses
* `FillType` to initialize prepended elements with.
*/
template <class List, size_t NewSize, class FillType = unit_t>
struct tl_pad_left {
......@@ -868,7 +863,7 @@ struct tl_is_zipped {
};
/**
* @brief Removes trailing @p What elements from the end.
* Removes trailing `What` elements from the end.
*/
template <class List, class What = unit_t>
struct tl_trim {
......@@ -948,7 +943,7 @@ struct tl_group_by {
};
/**
* @brief Applies the types of the list to @p VarArgTemplate.
* Applies the types of the list to `VarArgTemplate`.
*/
template <class List, template <class...> class VarArgTemplate>
struct tl_apply;
......@@ -969,7 +964,7 @@ struct tl_is_strict_subset_step {
};
/**
* @brief Tests whether ListA ist a strict subset of ListB (or equal).
* Tests whether ListA ist a strict subset of ListB (or equal).
*/
template <class ListA, class ListB>
struct tl_is_strict_subset {
......@@ -987,7 +982,7 @@ struct tl_is_strict_subset {
};
/**
* @brief Tests whether ListA contains the same elements as ListB
* Tests whether ListA contains the same elements as ListB
* and vice versa. This comparison ignores element positions.
*/
template <class ListA, class ListB>
......@@ -997,10 +992,6 @@ struct tl_equal {
&& tl_is_strict_subset<ListB, ListA>::value;
};
/**
* @}
*/
} // namespace detail
} // namespace caf
......
......@@ -23,10 +23,6 @@
namespace caf {
namespace detail {
/**
* @ingroup MetaProgramming
* @brief A pair of two types.
*/
template <class First, typename Second>
struct type_pair {
using first = First;
......
......@@ -34,12 +34,7 @@ namespace caf {
namespace detail {
/**
* @addtogroup MetaProgramming
* @{
*/
/**
* @brief Equal to std::remove_const<std::remove_reference<T>::type>.
* Equal to std::remove_const<std::remove_reference<T>::type>.
*/
template <class T>
struct rm_const_and_ref {
......@@ -64,7 +59,7 @@ struct rm_const_and_ref<T&> {
// template <> struct rm_const_and_ref<void> { };
/**
* @brief Joins all bool constants using operator &&.
* Joins all bool constants using operator &&.
*/
template <bool... BoolConstants>
struct conjunction;
......@@ -85,7 +80,7 @@ struct conjunction<V0, V1, Vs...> {
};
/**
* @brief Joins all bool constants using operator ||.
* Joins all bool constants using operator ||.
*/
template <bool... BoolConstants>
struct disjunction;
......@@ -101,13 +96,13 @@ struct disjunction<> {
};
/**
* @brief Equal to std::is_same<T, anything>.
* Equal to std::is_same<T, anything>.
*/
template <class T>
struct is_anything : std::is_same<T, anything> {};
/**
* @brief Checks whether @p T is an array of type @p U.
* Checks whether `T` is an array of type `U`.
*/
template <class T, typename U>
struct is_array_of {
......@@ -118,7 +113,7 @@ struct is_array_of {
};
/**
* @brief Deduces the reference type of T0 and applies it to T1.
* Deduces the reference type of T0 and applies it to T1.
*/
template <class T0, typename T1>
struct deduce_ref_type {
......@@ -136,7 +131,7 @@ struct deduce_ref_type<const T0&, T1> {
};
/**
* @brief Checks wheter @p X is in the template parameter pack Ts.
* Checks wheter `X` is in the template parameter pack Ts.
*/
template <class X, class... Ts>
struct is_one_of;
......@@ -151,10 +146,10 @@ template <class X, typename T0, class... Ts>
struct is_one_of<X, T0, Ts...> : is_one_of<X, Ts...> {};
/**
* @brief Checks wheter @p T is considered a builtin type.
* Checks wheter `T` is considered a builtin type.
*
* Builtin types are: (1) all arithmetic types, (2) string types from the STL,
* and (3) built-in types such as @p actor_ptr.
* and (3) built-in types such as `actor_ptr`.
*/
template <class T>
struct is_builtin {
......@@ -167,7 +162,7 @@ struct is_builtin {
};
/**
* @brief Chekcs wheter @p T is primitive, i.e., either an arithmetic
* Chekcs wheter `T` is primitive, i.e., either an arithmetic
* type or convertible to one of STL's string types.
*/
template <class T>
......@@ -180,7 +175,7 @@ struct is_primitive {
};
/**
* @brief Chekcs wheter @p T1 is comparable with @p T2.
* Chekcs wheter `T1` is comparable with `T2`.
*/
template <class T1, typename T2>
class is_comparable {
......@@ -207,7 +202,7 @@ class is_comparable {
};
/**
* @brief Checks wheter @p T behaves like a forward iterator.
* Checks wheter `T` behaves like a forward iterator.
*/
template <class T>
class is_forward_iterator {
......@@ -237,7 +232,7 @@ class is_forward_iterator {
};
/**
* @brief Checks wheter @p T has <tt>begin()</tt> and <tt>end()</tt> member
* Checks wheter `T` has `begin()</tt> and <tt>end() member
* functions returning forward iterators.
*/
template <class T>
......@@ -267,7 +262,7 @@ class is_iterable {
};
/**
* @brief Checks wheter @p T is neither a reference nor a pointer nor an array.
* Checks wheter `T` is neither a reference nor a pointer nor an array.
*/
template <class T>
struct is_legal_tuple_type {
......@@ -278,7 +273,7 @@ struct is_legal_tuple_type {
};
/**
* @brief Checks wheter @p T is a non-const reference.
* Checks wheter `T` is a non-const reference.
*/
template <class T>
struct is_mutable_ref {
......@@ -287,7 +282,7 @@ struct is_mutable_ref {
};
/**
* @brief Returns either @p T or @p T::type if @p T is an option.
* Returns either `T` or `T::type` if `T` is an option.
*/
template <class T>
struct rm_optional {
......@@ -300,13 +295,13 @@ struct rm_optional<optional<T>> {
};
/**
* @brief Defines @p result_type, @p arg_types, and @p fun_type. Functor is
* Defines `result_type,` `arg_types,` and `fun_type`. Functor is
* (a) a member function pointer, (b) a function,
* (c) a function pointer, (d) an std::function.
*
* @p result_type is the result type found in the signature.
* @p arg_types are the argument types as {@link type_list}.
* @p fun_type is an std::function with an equivalent signature.
* `result_type` is the result type found in the signature.
* `arg_types` are the argument types as {@link type_list}.
* `fun_type` is an std::function with an equivalent signature.
*/
template <class Functor>
struct callable_trait;
......@@ -356,7 +351,7 @@ struct get_callable_trait_helper<false, false, C> {
};
/**
* @brief Gets a callable trait for @p T, where @p T is a functor type,
* Gets a callable trait for `T,` where `T` is a functor type,
* i.e., a function, member function, or a class providing
* the call operator.
*/
......@@ -379,7 +374,7 @@ struct get_callable_trait {
};
/**
* @brief Checks wheter @p T is a function or member function.
* Checks wheter `T` is a function or member function.
*/
template <class T>
struct is_callable {
......@@ -406,7 +401,7 @@ struct is_callable {
};
/**
* @brief Checks wheter each @p T in @p Ts is a function or member function.
* Checks wheter each `T` in `Ts` is a function or member function.
*/
template <class... Ts>
struct all_callable {
......@@ -414,7 +409,7 @@ struct all_callable {
};
/**
* @brief Checks wheter @p F takes mutable references.
* Checks wheter `F` takes mutable references.
*
* A manipulator is a functor that manipulates its arguments via
* mutable references.
......@@ -437,7 +432,7 @@ struct map_to_result_type_impl<false, C> {
};
/**
* @brief Maps @p T to its result type if it's callable,
* Maps `T` to its result type if it's callable,
* {@link unit_t} otherwise.
*/
template <class T>
......@@ -460,7 +455,7 @@ struct replace_type_impl<true, T1, T2> {
};
/**
* @brief Replaces @p What with @p With if any IfStmt::value evaluates to true.
* Replaces `What` with `With` if any IfStmt::value evaluates to true.
*/
template <class What, typename With, class... IfStmt>
struct replace_type {
......@@ -469,7 +464,7 @@ struct replace_type {
};
/**
* @brief Gets the Nth element of the template parameter pack @p Ts.
* Gets the Nth element of the template parameter pack `Ts`.
*/
template <size_t N, class... Ts>
struct type_at;
......@@ -484,10 +479,6 @@ struct type_at<0, T0, Ts...> {
using type = T0;
};
/**
* @}
*/
} // namespace detail
} // namespace caf
......
......@@ -23,10 +23,6 @@
namespace caf {
namespace detail {
/**
* @ingroup MetaProgramming
* @brief A simple type wrapper.
*/
template <class T>
struct wrapped {
using type = T;
......
......@@ -28,7 +28,7 @@
namespace caf {
/**
* @brief SI time units to specify timeouts.
* SI time units to specify timeouts.
*/
enum class time_unit : uint32_t {
invalid = 0,
......@@ -70,8 +70,7 @@ struct ratio_to_time_unit_helper<60, 1> {
};
/**
* @brief Converts an STL time period to a
* {@link caf::detail::time_unit time_unit}.
* Converts an STL time period to a `time_unit`.
*/
template <class Period>
constexpr time_unit get_time_unit_from_period() {
......@@ -79,9 +78,7 @@ constexpr time_unit get_time_unit_from_period() {
}
/**
* @brief Time duration consisting of a {@link caf::detail::time_unit
* time_unit}
* and a 64 bit unsigned integer.
* Time duration consisting of a `time_unit` and a 64 bit unsigned integer.
*/
class duration {
......@@ -92,8 +89,8 @@ class duration {
constexpr duration(time_unit u, uint32_t v) : unit(u), count(v) {}
/**
* @brief Creates a new instance from an STL duration.
* @throws std::invalid_argument Thrown if <tt>d.count()</tt> is negative.
* Creates a new instance from an STL duration.
* @throws std::invalid_argument Thrown if `d.count() is negative.
*/
template <class Rep, class Period>
duration(std::chrono::duration<Rep, Period> d)
......@@ -104,20 +101,20 @@ class duration {
}
/**
* @brief Creates a new instance from an STL duration given in minutes.
* @throws std::invalid_argument Thrown if <tt>d.count()</tt> is negative.
* Creates a new instance from an STL duration given in minutes.
* @throws std::invalid_argument Thrown if `d.count() is negative.
*/
template <class Rep>
duration(std::chrono::duration<Rep, std::ratio<60, 1>> d)
: unit(time_unit::seconds), count(rd(d) * 60) {}
/**
* @brief Returns true if <tt>unit != time_unit::none</tt>.
* Returns `unit != time_unit::invalid`.
*/
inline bool valid() const { return unit != time_unit::invalid; }
/**
* @brief Returns true if <tt>count == 0</tt>.
* Returns `count == 0`.
*/
inline bool is_zero() const { return count == 0; }
......
......@@ -38,8 +38,7 @@
namespace caf {
/**
* @brief A cooperatively scheduled, event-based actor implementation.
*
* A cooperatively scheduled, event-based actor implementation.
* This is the recommended base class for user-defined actors and is used
* implicitly when spawning functor-based actors without the
* {@link blocking_api} flag.
......@@ -62,12 +61,12 @@ class event_based_actor
protected:
/**
* @brief Returns the initial actor behavior.
* Returns the initial actor behavior.
*/
virtual behavior make_behavior() = 0;
/**
* @brief Forwards the last received message to @p whom.
* Forwards the last received message to `whom`.
*/
void forward_to(const actor& whom);
......
......@@ -28,7 +28,7 @@
namespace caf {
/**
* @brief Base class for exceptions.
* Base class for exceptions.
*/
class caf_exception : public std::exception {
......@@ -41,22 +41,19 @@ class caf_exception : public std::exception {
caf_exception& operator=(const caf_exception&) = default;
/**
* @brief Returns the error message.
* @returns The error message as C-string.
* Returns the error message.
*/
const char* what() const noexcept;
protected:
/**
* @brief Creates an exception with the error string @p what_str.
* @param what_str Error message as rvalue string.
* Creates an exception with the error string `what_str`.
*/
caf_exception(std::string&& what_str);
/**
* @brief Creates an exception with the error string @p what_str.
* @param what_str Error message as string.
* Creates an exception with the error string `what_str`.
*/
caf_exception(const std::string& what_str);
......@@ -67,7 +64,7 @@ class caf_exception : public std::exception {
};
/**
* @brief Thrown if an actor finished execution.
* Thrown if an actor finished execution.
*/
class actor_exited : public caf_exception {
......@@ -81,9 +78,7 @@ class actor_exited : public caf_exception {
actor_exited& operator=(const actor_exited&) = default;
/**
* @brief Gets the exit reason.
* @returns The exit reason of the terminating actor either set via
* {@link quit} or by a special (exit) message.
* Returns the exit reason.
*/
inline uint32_t reason() const noexcept;
......@@ -94,8 +89,8 @@ class actor_exited : public caf_exception {
};
/**
* @brief Thrown to indicate that either an actor publishing failed or
* the middleman was unable to connect to a remote host.
* Thrown to indicate that either an actor publishing failed or
* the middleman was unable to connect to a remote host.
*/
class network_error : public caf_exception {
......@@ -112,8 +107,8 @@ class network_error : public caf_exception {
};
/**
* @brief Thrown to indicate that an actor publishing failed because
* the requested port could not be used.
* Thrown to indicate that an actor publishing failed because
* the requested port could not be used.
*/
class bind_failure : public network_error {
......
......@@ -25,7 +25,7 @@ namespace caf {
class resumable;
/**
* @brief Identifies an execution unit, e.g., a worker thread of the scheduler.
* Identifies an execution unit, e.g., a worker thread of the scheduler.
*/
class execution_unit {
......@@ -34,9 +34,9 @@ class execution_unit {
virtual ~execution_unit();
/**
* @brief Enqueues @p ptr to the job list of the execution unit.
* Enqueues `ptr` to the job list of the execution unit.
* @warning Must only be called from a {@link resumable} currently
* executed by this execution unit.
* executed by this execution unit.
*/
virtual void exec_later(resumable* ptr) = 0;
......
......@@ -26,60 +26,60 @@ namespace caf {
namespace exit_reason {
/**
* @brief Indicates that the actor is still alive.
* Indicates that the actor is still alive.
*/
static constexpr uint32_t not_exited = 0x00000;
/**
* @brief Indicates that an actor finished execution.
* Indicates that an actor finished execution.
*/
static constexpr uint32_t normal = 0x00001;
/**
* @brief Indicates that an actor finished execution
* Indicates that an actor finished execution
* because of an unhandled exception.
*/
static constexpr uint32_t unhandled_exception = 0x00002;
/**
* @brief Indicates that an event-based actor
* Indicates that an event-based actor
* tried to use {@link receive()} or a strongly typed actor tried
* to call {@link become()}.
*/
static constexpr uint32_t unallowed_function_call = 0x00003;
/**
* @brief Indicates that the actor received an unexpected
* Indicates that the actor received an unexpected
* synchronous reply message.
*/
static constexpr uint32_t unhandled_sync_failure = 0x00004;
/**
* @brief Indicates that a synchronous message timed out.
* Indicates that a synchronous message timed out.
*/
static constexpr uint32_t unhandled_sync_timeout = 0x00005;
/**
* @brief Indicates that the exit reason for this actor is unknown, i.e.,
* Indicates that the exit reason for this actor is unknown, i.e.,
* the actor has been terminated and no longer exists.
*/
static constexpr uint32_t unknown = 0x00006;
/**
* @brief Indicates that the actor was forced to shutdown by
* Indicates that the actor was forced to shutdown by
* a user-generated event.
*/
static constexpr uint32_t user_shutdown = 0x00010;
/**
* @brief Indicates that an actor finishied execution
* Indicates that an actor finishied execution
* because a connection to a remote link was
* closed unexpectedly.
*/
static constexpr uint32_t remote_link_unreachable = 0x00101;
/**
* @brief Any user defined exit reason should have a
* Any user defined exit reason should have a
* value greater or equal to prevent collisions
* with default defined exit reasons.
*/
......
......@@ -30,19 +30,20 @@ struct extend_helper;
template <class D, class B>
struct extend_helper<D, B> {
using type = B;
};
template <class D, class B, template <class, class> class M,
template <class, class> class... Ms>
struct extend_helper<D, B, M, Ms...> : extend_helper<D, M<B, D>, Ms...> {};
struct extend_helper<D, B, M, Ms...> : extend_helper<D, M<B, D>, Ms...> {
// no content
};
} // namespace detail
/**
* @brief Allows convenient definition of types using mixins.
* For example, "extend<ar, T>::with<ob, fo>" is an alias for
* "fo<ob<ar, T>, T>".
* Allows convenient definition of types using mixins.
* For example, `extend<ar, T>::with<ob, fo>` is an alias for
* `fo<ob<ar, T>, T>`.
*
* Mixins always have two template parameters: base type and
* derived type. This allows mixins to make use of the curiously recurring
......@@ -52,11 +53,10 @@ struct extend_helper<D, B, M, Ms...> : extend_helper<D, M<B, D>, Ms...> {};
template <class Base, class Derived = Base>
struct extend {
/**
* @brief Identifies the combined type.
* Identifies the combined type.
*/
template <template <class, class> class... Mixins>
using with = typename detail::extend_helper<Derived, Base, Mixins...>::type;
};
} // namespace caf
......
......@@ -29,19 +29,13 @@
namespace caf {
/**
* @brief Converts a string created by {@link caf::to_string to_string}
* to its original value.
* @param what String representation of a serialized value.
* @returns An {@link caf::object object} instance that contains
* the deserialized value.
* Converts a string created by `to_string` to its original value.
*/
uniform_value from_string_impl(const std::string& what);
/**
* @brief Convenience function that deserializes a value from @p what and
* converts the result to @p T.
* @throws std::logic_error if the result is not of type @p T.
* @returns The deserialized value as instance of @p T.
* Convenience function that tries to deserializes a value from
* `what` and converts the result to `T`.
*/
template <class T>
optional<T> from_string(const std::string& what) {
......
......@@ -53,7 +53,6 @@ struct invalid_actor_t;
struct invalid_actor_addr_t;
// enums
enum primitive_type : unsigned char;
enum class atom_value : uint64_t;
// intrusive pointer types
......
......@@ -39,7 +39,7 @@ struct invalid_group_t {
};
/**
* @brief Identifies an invalid {@link group}.
* Identifies an invalid {@link group}.
* @relates group
*/
constexpr invalid_group_t invalid_group = invalid_group_t{};
......@@ -73,8 +73,7 @@ class group : detail::comparable<group>,
inline bool operator!() const { return !static_cast<bool>(m_ptr); }
/**
* @brief Returns a handle that grants access to
* actor operations such as enqueue.
* Returns a handle that grants access to actor operations such as enqueue.
*/
inline abstract_group* operator->() const { return m_ptr.get(); }
......@@ -87,16 +86,15 @@ class group : detail::comparable<group>,
}
/**
* @brief Get a pointer to the group associated with
* @p group_identifier from the module @p module_name.
* Get a pointer to the group associated with
* `group_identifier` from the module `module_name`.
* @threadsafe
*/
static group get(const std::string& module_name,
const std::string& group_identifier);
/**
* @brief Returns an anonymous group.
*
* Returns an anonymous group.
* Each calls to this member function returns a new instance
* of an anonymous group. Anonymous groups can be used whenever
* a set of actors wants to communicate using an exclusive channel.
......@@ -104,13 +102,13 @@ class group : detail::comparable<group>,
static group anonymous();
/**
* @brief Add a new group module to the group management.
* Add a new group module to the group management.
* @threadsafe
*/
static void add_module(abstract_group::unique_module_ptr);
/**
* @brief Returns the module associated with @p module_name.
* Returns the module associated with `module_name`.
* @threadsafe
*/
static abstract_group::module_ptr
......
......@@ -30,7 +30,7 @@
namespace caf {
/**
* @brief An intrusive, reference counting smart pointer impelementation.
* An intrusive, reference counting smart pointer impelementation.
* @relates ref_counted
*/
template <class T>
......@@ -67,8 +67,8 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>,
}
/**
* @brief Returns the raw pointer without modifying reference count
* and sets this to @p nullptr.
* Returns the raw pointer without modifying reference
* count and sets this to `nullptr`.
*/
pointer release() {
auto result = m_ptr;
......@@ -77,7 +77,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>,
}
/**
* @brief Sets this pointer to @p ptr without modifying reference count.
* Sets this pointer to `ptr` without modifying reference count.
*/
void adopt(pointer ptr) {
reset();
......@@ -161,7 +161,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>,
* @relates intrusive_ptr
*/
template <class X, typename Y>
inline bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
return lhs.get() == rhs.get();
}
......@@ -169,7 +169,7 @@ inline bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs)
* @relates intrusive_ptr
*/
template <class X, typename Y>
inline bool operator!=(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
bool operator!=(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
return !(lhs == rhs);
}
......
......@@ -55,7 +55,7 @@ namespace caf {
class sync_handle_helper;
/**
* @brief Base class for local running Actors.
* Base class for local running Actors.
* @extends abstract_actor
*/
class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
......@@ -77,7 +77,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
template <class C, spawn_options Os = no_spawn_options, class... Ts>
actor spawn(Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = spawn_class<C, os>(m_host, empty_before_launch_callback{},
auto res = spawn_class<C, os>(host(), empty_before_launch_callback{},
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
......@@ -85,7 +85,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn(Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = spawn_functor<os>(m_host, empty_before_launch_callback{},
auto res = spawn_functor<os>(host(), empty_before_launch_callback{},
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
......@@ -93,7 +93,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
template <class C, spawn_options Os, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = spawn_class<C, os>(m_host, group_subscriber{grp},
auto res = spawn_class<C, os>(host(), group_subscriber{grp},
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
......@@ -101,7 +101,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = spawn_functor<os>(m_host, group_subscriber{grp},
auto res = spawn_functor<os>(host(), group_subscriber{grp},
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
......@@ -111,25 +111,29 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
**************************************************************************/
template <class C, spawn_options Os = no_spawn_options, class... Ts>
typename detail::actor_handle_from_signature_list<
typename C::signatures>::type
typename actor_handle_from_signature_list<
typename C::signatures
>::type
spawn_typed(Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = spawn_class<C, os>(m_host, empty_before_launch_callback{},
auto res = spawn_class<C, os>(host(), empty_before_launch_callback{},
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
template <spawn_options Os = no_spawn_options, typename F, class... Ts>
typename detail::infer_typed_actor_handle<
typename infer_typed_actor_handle<
typename detail::get_callable_trait<F>::result_type,
typename detail::tl_head<
typename detail::get_callable_trait<F>::arg_types>::type>::type
typename detail::get_callable_trait<F>::arg_types
>::type
>::type
spawn_typed(F fun, Ts&&... args) {
constexpr auto os = make_unbound(Os);
auto res = caf::spawn_typed_functor<os>(
m_host, empty_before_launch_callback{}, std::move(fun),
std::forward<Ts>(args)...);
auto res = caf::spawn_typed_functor<os>(host(),
empty_before_launch_callback{},
std::move(fun),
std::forward<Ts>(args)...);
return eval_opts(Os, std::move(res));
}
......@@ -138,23 +142,19 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
**************************************************************************/
/**
* @brief Sends @p what to the receiver specified in @p dest.
* Sends `what` to the receiver specified in `dest`.
*/
void send_tuple(message_priority prio, const channel& whom, message what);
/**
* @brief Sends @p what to the receiver specified in @p dest.
* Sends `what` to the receiver specified in `dest`.
*/
inline void send_tuple(const channel& whom, message what) {
send_tuple(message_priority::normal, whom, std::move(what));
}
/**
* @brief Sends <tt>{what...}</tt> to @p whom.
* @param prio Priority of the message.
* @param whom Receiver of the message.
* @param what Message elements.
* @pre <tt>sizeof...(Ts) > 0</tt>.
* Sends `{what...} to `whom` using the priority `prio`.
*/
template <class... Ts>
inline void send(message_priority prio, const channel& whom, Ts&&... what) {
......@@ -163,10 +163,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
}
/**
* @brief Sends <tt>{what...}</tt> to @p whom.
* @param whom Receiver of the message.
* @param what Message elements.
* @pre <tt>sizeof...(Ts) > 0</tt>.
* Sends `{what...} to `whom`.
*/
template <class... Ts>
inline void send(const channel& whom, Ts&&... what) {
......@@ -176,34 +173,32 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
}
/**
* @brief Sends <tt>{what...}</tt> to @p whom.
* @param whom Receiver of the message.
* @param what Message elements.
* @pre <tt>sizeof...(Ts) > 0</tt>.
* Sends `{what...} to `whom`.
*/
template <class... Rs, class... Ts>
void send(const typed_actor<Rs...>& whom, Ts... what) {
check_typed_input(
whom, detail::type_list<typename detail::implicit_conversions<
typename detail::rm_const_and_ref<Ts>::type>::type...>{});
check_typed_input(whom,
detail::type_list<typename detail::implicit_conversions<
typename detail::rm_const_and_ref<Ts>::type
>::type...>{});
send_tuple(message_priority::normal, actor{whom.m_ptr.get()},
make_message(std::forward<Ts>(what)...));
make_message(std::forward<Ts>(what)...));
}
/**
* @brief Sends an exit message to @p whom.
* Sends an exit message to `whom`.
*/
void send_exit(const actor_addr& whom, uint32_t reason);
/**
* @brief Sends an exit message to @p whom.
* Sends an exit message to `whom`.
*/
inline void send_exit(const actor& whom, uint32_t reason) {
send_exit(whom.address(), reason);
}
/**
* @brief Sends an exit message to @p whom.
* Sends an exit message to `whom`.
*/
template <class... Rs>
void send_exit(const typed_actor<Rs...>& whom, uint32_t reason) {
......@@ -211,50 +206,33 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
}
/**
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param prio Priority of the message.
* @param whom Receiver of the message.
* @param rtime Relative time to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param data Message content as a tuple.
* Sends a message to `whom` with priority `prio`
* that is delayed by `rel_time`.
*/
void delayed_send_tuple(message_priority prio, const channel& whom,
const duration& rtime, message data);
const duration& rtime, message data);
/**
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param whom Receiver of the message.
* @param rtime Relative time to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param data Message content as a tuple.
* Sends a message to `whom` that is delayed by `rel_time`.
*/
inline void delayed_send_tuple(const channel& whom, const duration& rtime,
message data) {
delayed_send_tuple(message_priority::normal, whom, rtime,
std::move(data));
message data) {
delayed_send_tuple(message_priority::normal, whom, rtime, std::move(data));
}
/**
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param prio Priority of the message.
* @param whom Receiver of the message.
* @param rtime Relative time to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param args Message content as a tuple.
* Sends a message to `whom` using priority `prio`
* that is delayed by `rel_time`.
*/
template <class... Ts>
void delayed_send(message_priority prio, const channel& whom,
const duration& rtime, Ts&&... args) {
const duration& rtime, Ts&&... args) {
delayed_send_tuple(prio, whom, rtime,
make_message(std::forward<Ts>(args)...));
make_message(std::forward<Ts>(args)...));
}
/**
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param whom Receiver of the message.
* @param rtime Relative time to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param args Message content as a tuple.
* Sends a message to `whom` that is delayed by `rel_time`.
*/
template <class... Ts>
void delayed_send(const channel& whom, const duration& rtime,
......@@ -268,74 +246,60 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
**************************************************************************/
/**
* @brief Causes this actor to subscribe to the group @p what.
*
* Causes this actor to subscribe to the group `what`.
* The group will be unsubscribed if the actor finishes execution.
* @param what Group instance that should be joined.
*/
void join(const group& what);
/**
* @brief Causes this actor to leave the group @p what.
* @param what Joined group that should be leaved.
* @note Groups are leaved automatically if the Actor finishes
* execution.
* Causes this actor to leave the group `what`.
*/
void leave(const group& what);
/**
* @brief Finishes execution of this actor after any currently running
* message handler is done.
*
* This member function clear the behavior stack of the running actor
* and invokes {@link on_exit()}. The actors does not finish execution
* if the implementation of {@link on_exit()} sets a new behavior.
* When setting a new behavior in {@link on_exit()}, one has to make sure
* Finishes execution of this actor after any currently running
* message handler is done.
* This member function clears the behavior stack of the running actor
* and invokes `on_exit()`. The actors does not finish execution
* if the implementation of `on_exit()` sets a new behavior.
* When setting a new behavior in `on_exit()`, one has to make sure
* to not produce an infinite recursion.
*
* If {@link on_exit()} did not set a new behavior, the actor sends an
* exit message to all of its linked actors, sets its state to @c exited
* If `on_exit()` did not set a new behavior, the actor sends an
* exit message to all of its linked actors, sets its state to exited
* and finishes execution.
*
* @param reason Exit reason that will be send to
* linked actors and monitors. Can be queried using
* {@link planned_exit_reason()}, e.g., from inside
* {@link on_exit()}.
* @note Throws {@link actor_exited} to unwind the stack
* when called in context-switching or thread-based actors.
* (only) when called in detached actors.
* @warning This member function throws immediately in thread-based actors
* that do not use the behavior stack, i.e., actors that use
* blocking API calls such as {@link receive()}.
* that do not use the behavior stack, i.e., actors that use
* blocking API calls such as {@link receive()}.
*/
virtual void quit(uint32_t reason = exit_reason::normal);
/**
* @brief Checks whether this actor traps exit messages.
* Checks whether this actor traps exit messages.
*/
inline bool trap_exit() const;
/**
* @brief Enables or disables trapping of exit messages.
* Enables or disables trapping of exit messages.
*/
inline void trap_exit(bool new_value);
/**
* @brief Returns the last message that was dequeued
* from the actor's mailbox.
* Returns the last message that was dequeued from the actor's mailbox.
* @warning Only set during callback invocation.
*/
inline message& last_dequeued();
/**
* @brief Returns the address of the last sender of the
* last dequeued message.
* Returns the address of the last sender of the last dequeued message.
*/
inline actor_addr& last_sender();
/**
* @brief Adds a unidirectional @p monitor to @p whom.
* @param whom The actor that should be monitored by this actor.
* @note Each call to @p monitor creates a new, independent monitor.
* Adds a unidirectional `monitor` to `whom`.
* @note Each call to `monitor` creates a new, independent monitor.
*/
void monitor(const actor_addr& whom);
......@@ -353,57 +317,54 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
}
/**
* @brief Removes a monitor from @p whom.
* @param whom A monitored actor.
* Removes a monitor from `whom`.
*/
void demonitor(const actor_addr& whom);
/**
* @brief Removes a monitor from @p whom.
* @param whom A monitored actor.
* Removes a monitor from `whom`.
*/
inline void demonitor(const actor& whom) { demonitor(whom.address()); }
/**
* @brief Can be overridden to perform cleanup code after an actor
* finished execution.
* Can be overridden to perform cleanup code after an actor
* finished execution.
*/
virtual void on_exit();
/**
* @brief Returns all joined groups of this actor.
* Returns all joined groups.
*/
std::vector<group> joined_groups() const;
/**
* @brief Creates a {@link response_promise} to allow actors to response
* to a request later on.
* Creates a `response_promise` to response to a request later on.
*/
response_promise make_response_promise();
/**
* @brief Sets the handler for unexpected synchronous response messages.
* Sets the handler for unexpected synchronous response messages.
*/
inline void on_sync_timeout(std::function<void()> fun) {
m_sync_timeout_handler = std::move(fun);
}
/**
* @brief Sets the handler for @p timed_sync_send timeout messages.
* Sets the handler for `timed_sync_send` timeout messages.
*/
inline void on_sync_failure(std::function<void()> fun) {
m_sync_failure_handler = std::move(fun);
}
/**
* @brief Checks wheter this actor has a user-defined sync failure handler.
* Checks wheter this actor has a user-defined sync failure handler.
*/
inline bool has_sync_failure_handler() {
return static_cast<bool>(m_sync_failure_handler);
}
/**
* @brief Calls <tt>on_sync_timeout(fun); on_sync_failure(fun);</tt>.
* Calls `on_sync_timeout(fun); on_sync_failure(fun);.
*/
inline void on_sync_timeout_or_failure(std::function<void()> fun) {
on_sync_timeout(fun);
......@@ -544,7 +505,7 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
};
/**
* @brief A smart pointer to a {@link local_actor} instance.
* A smart pointer to a {@link local_actor} instance.
* @relates local_actor
*/
using local_actor_ptr = intrusive_ptr<local_actor>;
......
......@@ -139,18 +139,18 @@ class match_each_helper {
namespace caf {
/**
* @brief Starts a match expression.
* Starts a match expression.
* @param what Tuple that should be matched against a pattern.
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing `operator(...).
*/
inline detail::match_helper match(message what) {
return what;
}
/**
* @brief Starts a match expression.
* Starts a match expression.
* @param what Value that should be matched against a pattern.
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing `operator(...).
*/
template <class T>
detail::match_helper match(T&& what) {
......@@ -158,17 +158,17 @@ detail::match_helper match(T&& what) {
}
/**
* @brief Splits @p str using @p delim and match the resulting strings.
* Splits `str` using `delim` and match the resulting strings.
*/
detail::match_helper
match_split(const std::string& str, char delim, bool keep_empties = false);
/**
* @brief Starts a match expression that matches each element in
* Starts a match expression that matches each element in
* range [first, last).
* @param first Iterator to the first element.
* @param last Iterator to the last element (excluded).
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing `operator(...).
*/
template <class InputIterator>
detail::match_each_helper<InputIterator>
......@@ -177,12 +177,12 @@ match_each(InputIterator first, InputIterator last) {
}
/**
* @brief Starts a match expression that matches <tt>proj(i)</tt> for
* each element @p i in range [first, last).
* Starts a match expression that matches `proj(i) for
* each element `i` in range [first, last).
* @param first Iterator to the first element.
* @param last Iterator to the last element (excluded).
* @param proj Projection or extractor functor.
* @returns A helper object providing <tt>operator(...)</tt>.
* @returns A helper object providing `operator(...).
*/
template <class InputIterator, typename Projection>
detail::match_each_helper<InputIterator, Projection>
......
......@@ -586,8 +586,8 @@ struct match_result_from_type_list<detail::type_list<Ts...>> {
};
/**
* @brief A match expression encapsulating cases <tt>Cs...</tt>, whereas
* each case is a @p detail::match_expr_case<...>.
* A match expression encapsulating cases `Cs..., whereas
* each case is a `detail::match_expr_case<`...>.
*/
template <class... Cs>
class match_expr {
......
......@@ -27,27 +27,23 @@ struct disposer;
}
/**
* @brief This base enables derived classes to enforce a different
* allocation strategy than new/delete by providing a virtual
* protected @p request_deletion() function and non-public destructor.
* This base enables derived classes to enforce a different
* allocation strategy than new/delete by providing a virtual
* protected `request_deletion()` function and non-public destructor.
*/
class memory_managed {
friend struct detail::disposer;
public:
friend struct detail::disposer;
/**
* @brief Default implementations calls <tt>delete this</tt>, but can
* be overriden in case deletion depends on some condition or
* the class doesn't use default new/delete.
* Default implementations calls `delete this, but can
* be overriden in case deletion depends on some condition or
* the class doesn't use default new/delete.
*/
virtual void request_deletion();
protected:
virtual ~memory_managed();
};
} // namespace caf
......
......@@ -17,8 +17,8 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_ANY_TUPLE_HPP
#define CAF_ANY_TUPLE_HPP
#ifndef CAF_MESSAGE_HPP
#define CAF_MESSAGE_HPP
#include <type_traits>
......@@ -38,182 +38,234 @@ namespace caf {
class message_handler;
/**
* @brief Describes a fixed-length copy-on-write tuple
* with elements of any type.
* Describes a fixed-length copy-on-write tuple with elements of any type.
*/
class message {
public:
/**
* @brief A raw pointer to the data.
* A raw pointer to the data.
*/
using raw_ptr = detail::message_data*;
/**
* @brief A (COW) smart pointer to the data.
* A (COW) smart pointer to the data.
*/
using data_ptr = detail::message_data::ptr;
/**
* @brief An iterator to access each element as <tt>const void*</tt>.
* An iterator to access each element as `const void*.
*/
using const_iterator = detail::message_data::const_iterator;
/**
* @brief Creates an empty tuple.
* Creates an empty tuple.
*/
message() = default;
/**
* @brief Move constructor.
* Move constructor.
*/
message(message&&);
/**
* @brief Copy constructor.
* Copy constructor.
*/
message(const message&) = default;
/**
* @brief Move assignment.
* Move assignment.
*/
message& operator=(message&&);
/**
* @brief Copy assignment.
* Copy assignment.
*/
message& operator=(const message&) = default;
/**
* @brief Gets the size of this tuple.
* Gets the size of this tuple.
*/
inline size_t size() const;
inline size_t size() const {
return m_vals ? m_vals->size() : 0;
}
/**
* @brief Creates a new tuple with all but the first n values.
* Creates a new tuple with all but the first n values.
*/
message drop(size_t n) const;
/**
* @brief Creates a new tuple with all but the last n values.
* Creates a new tuple with all but the last n values.
*/
message drop_right(size_t n) const;
/**
* @brief Creates a new tuple from the first n values.
* Creates a new tuple from the first n values.
*/
inline message take(size_t n) const;
inline message take(size_t n) const {
return n >= size() ? *this : drop_right(size() - n);
}
/**
* @brief Creates a new tuple from the last n values.
* Creates a new tuple from the last n values.
*/
inline message take_right(size_t n) const;
inline message take_right(size_t n) const {
return n >= size() ? *this : drop(size() - n);
}
/**
* @brief Gets a mutable pointer to the element at position @p p.
* Gets a mutable pointer to the element at position @p p.
*/
void* mutable_at(size_t p);
/**
* @brief Gets a const pointer to the element at position @p p.
* Gets a const pointer to the element at position @p p.
*/
const void* at(size_t p) const;
/**
* @brief Gets {@link uniform_type_info uniform type information}
* of the element at position @p p.
* Gets {@link uniform_type_info uniform type information}
* of the element at position @p p.
*/
const uniform_type_info* type_at(size_t p) const;
/**
* @brief Returns true if this message has the types @p Ts.
* Returns true if this message has the types @p Ts.
*/
template <class... Ts>
bool has_types() const;
bool has_types() const {
if (size() != sizeof...(Ts)) {
return false;
}
const std::type_info* ts[] = {&typeid(Ts)...};
for (size_t i = 0; i < sizeof...(Ts); ++i) {
if (!type_at(i)->equal_to(*ts[i])) {
return false;
}
}
return true;
}
/**
* @brief Returns @c true if <tt>*this == other</tt>, otherwise false.
* Returns @c true if `*this == other, otherwise false.
*/
bool equals(const message& other) const;
/**
* @brief Returns true if <tt>size() == 0</tt>, otherwise false.
* Returns true if `size() == 0, otherwise false.
*/
inline bool empty() const;
inline bool empty() const {
return size() == 0;
}
/**
* @brief Returns the value at @p as instance of @p T.
* Returns the value at @p as instance of @p T.
*/
template <class T>
inline const T& get_as(size_t p) const;
inline const T& get_as(size_t p) const {
CAF_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<const T*>(at(p));
}
/**
* @brief Returns the value at @p as mutable data_ptr& of type @p T&.
* Returns the value at @p as mutable data_ptr& of type @p T&.
*/
template <class T>
inline T& get_as_mutable(size_t p);
inline T& get_as_mutable(size_t p) {
CAF_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<T*>(mutable_at(p));
}
/**
* @brief Returns an iterator to the beginning.
* Returns an iterator to the beginning.
*/
inline const_iterator begin() const;
inline const_iterator begin() const {
return m_vals->begin();
}
/**
* @brief Returns an iterator to the end.
* Returns an iterator to the end.
*/
inline const_iterator end() const;
inline const_iterator end() const {
return m_vals->end();
}
/**
* @brief Returns a copy-on-write pointer to the internal data.
* Returns a copy-on-write pointer to the internal data.
*/
inline data_ptr& vals();
inline data_ptr& vals() {
return m_vals;
}
/**
* @brief Returns a const copy-on-write pointer to the internal data.
* Returns a const copy-on-write pointer to the internal data.
*/
inline const data_ptr& vals() const;
inline const data_ptr& vals() const {
return m_vals;
}
/**
* @brief Returns a const copy-on-write pointer to the internal data.
* Returns a const copy-on-write pointer to the internal data.
*/
inline const data_ptr& cvals() const;
inline const data_ptr& cvals() const {
return m_vals;
}
/**
* @brief Returns either <tt>&typeid(detail::type_list<Ts...>)</tt>, where
* <tt>Ts...</tt> are the element types, or <tt>&typeid(void)</tt>.
* Returns either `&typeid(detail::type_list<Ts...>)`, where
* `Ts...` are the element types, or `&typeid(void)`.
*
* The type token @p &typeid(void) indicates that this tuple is dynamically
* The type token `&typeid(void)` indicates that this tuple is dynamically
* typed, i.e., the types where not available at compile time.
*/
inline const std::type_info* type_token() const;
inline const std::type_info* type_token() const {
return m_vals->type_token();
}
/**
* @brief Checks whether this tuple is dynamically typed, i.e.,
* its types were not known at compile time.
* Checks whether this tuple is dynamically typed, i.e.,
* its types were not known at compile time.
*/
inline bool dynamically_typed() const;
inline bool dynamically_typed() const {
return m_vals->dynamically_typed();
}
/**
* @brief Applies @p handler to this message and returns the result
* of <tt>handler(*this)</tt>.
* Applies @p handler to this message and returns the result
* of `handler(*this)`.
*/
optional<message> apply(message_handler handler);
/** @cond PRIVATE */
inline void force_detach();
inline void force_detach() {
m_vals.detach();
}
void reset();
explicit message(raw_ptr);
inline const std::string* tuple_type_names() const;
inline const std::string* tuple_type_names() const {
return m_vals->tuple_type_names();
}
explicit message(const data_ptr& vals);
struct move_from_tuple_helper {
template <class... Ts>
inline message operator()(Ts&... vs) {
return make_message(std::move(vs)...);
}
};
template <class... Ts>
static inline message move_from_tuple(std::tuple<Ts...>&&);
inline message move_from_tuple(std::tuple<Ts...>&& tup) {
move_from_tuple_helper f;
return detail::apply_args(f, detail::get_indices(tup), tup);
}
/** @endcond */
......@@ -238,14 +290,15 @@ inline bool operator!=(const message& lhs, const message& rhs) {
}
/**
* @brief Creates an {@link message} containing the elements @p args.
* @param args Values to initialize the tuple elements.
* Creates a new `message` containing the elements `args...`.
* @relates message
*/
template <class T, class... Ts>
typename std::enable_if<
!std::is_same<message, typename detail::rm_const_and_ref<T>::type>::value ||
(sizeof...(Ts) > 0),
message>::type
!std::is_same<message, typename detail::rm_const_and_ref<T>::type>::value
|| (sizeof...(Ts) > 0),
message
>::type
make_message(T&& arg, Ts&&... args) {
using namespace detail;
using data = tuple_vals<typename strip_and_convert<T>::type,
......@@ -254,86 +307,14 @@ make_message(T&& arg, Ts&&... args) {
return message{detail::message_data::ptr{ptr}};
}
inline message make_message(message other) { return std::move(other); }
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
inline bool message::empty() const { return size() == 0; }
template <class T>
inline const T& message::get_as(size_t p) const {
CAF_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<const T*>(at(p));
}
template <class T>
inline T& message::get_as_mutable(size_t p) {
CAF_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<T*>(mutable_at(p));
}
inline message::const_iterator message::begin() const {
return m_vals->begin();
}
inline message::const_iterator message::end() const { return m_vals->end(); }
inline message::data_ptr& message::vals() { return m_vals; }
inline const message::data_ptr& message::vals() const { return m_vals; }
inline const message::data_ptr& message::cvals() const { return m_vals; }
inline const std::type_info* message::type_token() const {
return m_vals->type_token();
}
inline bool message::dynamically_typed() const {
return m_vals->dynamically_typed();
}
inline void message::force_detach() { m_vals.detach(); }
inline const std::string* message::tuple_type_names() const {
return m_vals->tuple_type_names();
}
inline size_t message::size() const { return m_vals ? m_vals->size() : 0; }
inline message message::take(size_t n) const {
return n >= size() ? *this : drop_right(size() - n);
}
inline message message::take_right(size_t n) const {
return n >= size() ? *this : drop(size() - n);
}
struct move_from_tuple_helper {
template <class... Ts>
inline message operator()(Ts&... vs) {
return make_message(std::move(vs)...);
}
};
template <class... Ts>
inline message message::move_from_tuple(std::tuple<Ts...>&& tup) {
move_from_tuple_helper f;
return detail::apply_args(f, detail::get_indices(tup), tup);
}
template <class... Ts>
bool message::has_types() const {
if (size() != sizeof...(Ts)) return false;
const std::type_info* ts[] = {&typeid(Ts)...};
for (size_t i = 0; i < sizeof...(Ts); ++i) {
if (!type_at(i)->equal_to(*ts[i])) return false;
}
return true;
/**
* Returns a copy of @p other.
* @relates message
*/
inline message make_message(message other) {
return std::move(other);
}
} // namespace caf
#endif // CAF_ANY_TUPLE_HPP
#endif // CAF_MESSAGE_HPP
......@@ -31,22 +31,19 @@
namespace caf {
/**
* @brief Provides a convenient interface to create a {@link message}
* from a series of values using the member function @p append.
* Provides a convenient interface to create a {@link message}
* from a series of values using the member function `append`.
*/
class message_builder {
public:
message_builder();
message_builder(const message_builder&) = delete;
message_builder& operator=(const message_builder&) = delete;
public:
message_builder();
~message_builder();
/**
* @brief Creates a new instance and immediately calls
* <tt>append(first, last)</tt>.
* Creates a new instance and immediately calls `append(first, last)`.
*/
template <class Iter>
message_builder(Iter first, Iter last) {
......@@ -54,15 +51,13 @@ class message_builder {
append(first, last);
}
~message_builder();
/**
* @brief Adds @p what to the elements of the internal buffer.
* Adds `what` to the elements of the internal buffer.
*/
message_builder& append(uniform_value what);
/**
* @brief Appends all values in range [first, last).
* Appends all values in range [first, last).
*/
template <class Iter>
message_builder& append(Iter first, Iter last) {
......@@ -78,7 +73,7 @@ class message_builder {
}
/**
* @brief Adds @p what to the elements of the internal buffer.
* Adds `what` to the elements of the internal buffer.
*/
template <class T>
message_builder& append(T what) {
......@@ -86,40 +81,39 @@ class message_builder {
}
/**
* @brief Converts the internal buffer to an actual message object.
* Converts the internal buffer to an actual message object.
*
* It is worth mentioning that a call to @p to_message does neither
* invalidate the @p message_builder instance nor clears the internal
* It is worth mentioning that a call to `to_message` does neither
* invalidate the `message_builder` instance nor clears the internal
* buffer. However, calling any non-const member function afterwards
* can cause the @p message_builder to detach its data, i.e.,
* can cause the `message_builder` to detach its data, i.e.,
* copy it if there is more than one reference to it.
*/
message to_message();
/**
* @brief Convenience function for <tt>to_message().apply(handler)</tt>.
* Convenience function for `to_message().apply(handler).
*/
inline optional<message> apply(message_handler handler) {
return to_message().apply(std::move(handler));
}
/**
* @brief Removes all elements from the internal buffer.
* Removes all elements from the internal buffer.
*/
void clear();
/**
* @brief Returns whether the internal buffer is empty.
* Returns whether the internal buffer is empty.
*/
bool empty() const;
/**
* @brief Returns the number of elements in the internal buffer.
* Returns the number of elements in the internal buffer.
*/
size_t size() const;
private:
void init();
template <class T>
......@@ -139,7 +133,6 @@ class message_builder {
const dynamic_msg_data* data() const;
intrusive_ptr<ref_counted> m_data; // hide dynamic_msg_data implementation
};
} // namespace caf
......
......@@ -41,104 +41,98 @@
namespace caf {
class behavior;
/**
* @brief A partial function implementation
* for {@link caf::message messages}.
* A partial function implementation used to process a `message`.
*/
class message_handler {
friend class behavior;
public:
/** @cond PRIVATE */
using impl_ptr = intrusive_ptr<detail::behavior_impl>;
inline auto as_behavior_impl() const -> impl_ptr;
message_handler(impl_ptr ptr);
/** @endcond */
message_handler() = default;
message_handler(message_handler&&) = default;
message_handler(const message_handler&) = default;
message_handler& operator=(message_handler&&) = default;
message_handler& operator=(const message_handler&) = default;
/**
* A pointer to the underlying implementation.
*/
using impl_ptr = intrusive_ptr<detail::behavior_impl>;
/**
* Returns a pointer to the implementation.
*/
inline const impl_ptr& as_behavior_impl() const {
return m_impl;
}
/**
* Creates a message handler from @p ptr.
*/
message_handler(impl_ptr ptr);
/**
* Create a message handler a list of match expressions,
* functors, or other message handlers.
*/
template <class T, class... Ts>
message_handler(const T& arg, Ts&&... args);
message_handler(const T& arg, Ts&&... args)
: m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) {
// nop
}
/**
* @brief Returns a value if @p arg was matched by one of the
* handler of this behavior, returns @p nothing otherwise.
* Runs this handler and returns its (optional) result.
*/
template <class T>
inline optional<message> operator()(T&& arg);
optional<message> operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
}
/**
* @brief Adds a fallback which is used where
* this partial function is not defined.
* Returns a new handler that concatenates this handler
* with a new handler from `args...`.
*/
template <class... Ts>
typename std::conditional<
detail::disjunction<may_have_timeout<
typename detail::rm_const_and_ref<Ts>::type>::value...>::value,
behavior, message_handler>::type
or_else(Ts&&... args) const;
behavior,
message_handler
>::type
or_else(Ts&&... args) const {
// using a behavior is safe here, because we "cast"
// it back to a message_handler when appropriate
behavior tmp{std::forward<Ts>(args)...};
return m_impl->or_else(tmp.as_behavior_impl());
}
private:
impl_ptr m_impl;
};
/**
* Enables concatenation of message handlers by using a list
* of commata separated handlers.
* @relates message_handler
*/
template <class... Cases>
message_handler operator, (const match_expr<Cases...>& mexpr,
const message_handler& pfun) {
message_handler operator,(const match_expr<Cases...>& mexpr,
const message_handler& pfun) {
return mexpr.as_behavior_impl()->or_else(pfun.as_behavior_impl());
}
/**
* Enables concatenation of message handlers by using a list
* of commata separated handlers.
* @relates message_handler
*/
template <class... Cases>
message_handler operator, (const message_handler& pfun,
const match_expr<Cases...>& mexpr) {
message_handler operator,(const message_handler& pfun,
const match_expr<Cases...>& mexpr) {
return pfun.as_behavior_impl()->or_else(mexpr.as_behavior_impl());
}
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
template <class T, class... Ts>
message_handler::message_handler(const T& arg, Ts&&... args)
: m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) {}
template <class T>
inline optional<message> message_handler::operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
}
template <class... Ts>
typename std::conditional<
detail::disjunction<may_have_timeout<
typename detail::rm_const_and_ref<Ts>::type>::value...>::value,
behavior, message_handler>::type
message_handler::or_else(Ts&&... args) const {
// using a behavior is safe here, because we "cast"
// it back to a message_handler when appropriate
behavior tmp{std::forward<Ts>(args)...};
return m_impl->or_else(tmp.as_behavior_impl());
}
inline auto message_handler::as_behavior_impl() const -> impl_ptr {
return m_impl;
}
} // namespace caf
#endif // CAF_PARTIAL_FUNCTION_HPP
......@@ -33,7 +33,7 @@ struct invalid_message_id {
};
/**
* @brief Denotes whether a message is asynchronous or synchronous
* Denotes whether a message is asynchronous or synchronous
* @note Asynchronous messages always have an invalid message id.
*/
class message_id : detail::comparable<message_id> {
......
......@@ -146,7 +146,7 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> {
};
/**
* @brief Mixin for actors using a stack-based message processing.
* Mixin for actors using a stack-based message processing.
* @note This mixin implicitly includes {@link single_timeout}.
*/
template <class BehaviorType>
......
......@@ -29,8 +29,8 @@ namespace caf {
namespace mixin {
/**
* @brief This mixin adds all member functions and member variables needed
* by the memory management subsystem.
* This mixin adds all member functions and member variables needed
* by the memory management subsystem.
*/
template <class Base, class Subtype>
class memory_cached : public Base {
......
......@@ -28,7 +28,7 @@ namespace caf {
namespace mixin {
/**
* @brief Mixin for actors using a non-nestable message processing.
* Mixin for actors using a non-nestable message processing.
*/
template <class Base, class Subtype>
class single_timeout : public Base {
......@@ -53,7 +53,7 @@ class single_timeout : public Base {
if (d.is_zero()) {
// immediately enqueue timeout message if duration == 0s
this->enqueue(this->address(), message_id::invalid,
std::move(msg), this->m_host);
std::move(msg), this->host());
} else
this->delayed_send_tuple(this, d, std::move(msg));
} else
......
......@@ -44,13 +44,13 @@ class sync_sender_impl : public Base {
**************************************************************************/
/**
* @brief Sends @p what as a synchronous message to @p whom.
* Sends `what` as a synchronous message to `whom`.
* @param dest Receiver of the message.
* @param what Message content as tuple.
* @returns A handle identifying a future to the response of @p whom.
* @returns A handle identifying a future to the response of `whom`.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* @throws std::invalid_argument if `whom == nullptr
*/
response_handle_type sync_send_tuple(message_priority prio,
const actor& dest, message what) {
......@@ -63,14 +63,13 @@ class sync_sender_impl : public Base {
}
/**
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom.
* Sends `{what...}` as a synchronous message to `whom`.
* @param dest Receiver of the message.
* @param what Message elements.
* @returns A handle identifying a future to the response of @p whom.
* @returns A handle identifying a future to the response of `whom`.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @pre <tt>sizeof...(Ts) > 0</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* sent message cannot be received by another actor.
* @throws std::invalid_argument if `whom == nullptr`
*/
template <class... Ts>
response_handle_type sync_send(message_priority prio, const actor& dest,
......
......@@ -41,16 +41,15 @@ struct invalid_node_id_t {
};
/**
* @brief Identifies an invalid {@link node_id}.
* Identifies an invalid {@link node_id}.
* @relates node_id
*/
constexpr invalid_node_id_t invalid_node_id = invalid_node_id_t{};
/**
* @brief A node ID consists of a host ID and process ID. The host ID
* identifies the physical machine in the network, whereas the
* process ID identifies the running system-level process on that
* machine.
* A node ID consists of a host ID and process ID. The host ID identifies
* the physical machine in the network, whereas the process ID identifies
* the running system-level process on that machine.
*/
class node_id : detail::comparable<node_id>,
detail::comparable<node_id, invalid_node_id_t> {
......@@ -68,17 +67,17 @@ class node_id : detail::comparable<node_id>,
node_id& operator=(const invalid_node_id_t&);
/**
* @brief A 160 bit hash (20 bytes).
* A 160 bit hash (20 bytes).
*/
static constexpr size_t host_id_size = 20;
/**
* @brief Represents a 160 bit hash.
* Represents a 160 bit hash.
*/
using host_id_type = std::array<uint8_t, host_id_size>;
/**
* @brief A reference counted container for host ID and process ID.
* A reference counted container for host ID and process ID.
*/
class data : public ref_counted {
......@@ -116,27 +115,27 @@ class node_id : detail::comparable<node_id>,
node_id(const node_id&);
/**
* @brief Creates @c this from @p process_id and @p hash.
* Creates this from `process_id` and `hash`.
* @param process_id System-wide unique process identifier.
* @param hash Unique node id as hexadecimal string representation.
*/
node_id(uint32_t process_id, const std::string& hash);
/**
* @brief Creates @c this from @p process_id and @p hash.
* Creates this from `process_id` and `hash`.
* @param process_id System-wide unique process identifier.
* @param node_id Unique node id.
*/
node_id(uint32_t process_id, const host_id_type& node_id);
/**
* @brief Identifies the running process.
* Identifies the running process.
* @returns A system-wide unique process identifier.
*/
uint32_t process_id() const;
/**
* @brief Identifies the host system.
* Identifies the host system.
* @returns A hash build from the MAC address of the first network device
* and the UUID of the root partition (mounted in "/" or "C:").
*/
......
......@@ -226,35 +226,35 @@ struct pattern_type
namespace caf {
/**
* @brief A wildcard that matches any number of any values.
* A wildcard that matches any number of any values.
*/
constexpr anything any_vals = anything{};
#ifdef CAF_DOCUMENTATION
/**
* @brief A wildcard that matches the argument types
* of a given callback. Must be the last argument to {@link on()}.
* A wildcard that matches the argument types
* of a given callback. Must be the last argument to {@link on()}.
* @see {@link math_actor_example.cpp Math Actor Example}
*/
constexpr __unspecified__ arg_match;
/**
* @brief Left-hand side of a partial function expression.
* Left-hand side of a partial function expression.
*
* Equal to <tt>on(arg_match)</tt>.
* Equal to `on(arg_match).
*/
constexpr __unspecified__ on_arg_match;
/**
* @brief A wildcard that matches any value of type @p T.
* A wildcard that matches any value of type `T`.
* @see {@link math_actor_example.cpp Math Actor Example}
*/
template <class T>
__unspecified__ val();
/**
* @brief Left-hand side of a partial function expression that matches values.
* Left-hand side of a partial function expression that matches values.
*
* This overload can be used with the wildcards {@link caf::val val},
* {@link caf::any_vals any_vals} and {@link caf::arg_match arg_match}.
......@@ -263,7 +263,7 @@ template <class T, class... Ts>
__unspecified__ on(const T& arg, const Ts&... args);
/**
* @brief Left-hand side of a partial function expression that matches types.
* Left-hand side of a partial function expression that matches types.
*
* This overload matches types only. The type {@link caf::anything anything}
* can be used as wildcard to match any number of elements of any types.
......@@ -272,7 +272,7 @@ template <class... Ts>
__unspecified__ on();
/**
* @brief Left-hand side of a partial function expression that matches types.
* Left-hand side of a partial function expression that matches types.
*
* This overload matches up to four leading atoms.
* The type {@link caf::anything anything}
......@@ -282,9 +282,9 @@ template <atom_value... Atoms, class... Ts>
__unspecified__ on();
/**
* @brief Converts @p arg to a match expression by returning
* <tt>on_arg_match >> arg</tt> if @p arg is a callable type,
* otherwise returns @p arg.
* Converts `arg` to a match expression by returning
* `on_arg_match >> arg if `arg` is a callable type,
* otherwise returns `arg`.
*/
template <class T>
__unspecified__ lift_to_match_expr(T arg);
......
......@@ -30,44 +30,45 @@
namespace caf {
/**
* @brief Represents an optional value of @p T.
* Represents an optional value of `T`.
*/
template <class T>
class optional {
public:
/**
* @brief Typdef for @p T.
* Typdef for `T`.
*/
using type = T;
/* *
* @brief Default constructor.
* @post <tt>valid() == false</tt>
*/
//optional() : m_valid(false) { }
/**
* @post <tt>valid() == false</tt>
* Creates an empty instance with `valid() == false`.
*/
optional(const none_t& = none) : m_valid(false) { }
optional(const none_t& = none) : m_valid(false) {
// nop
}
/**
* @brief Creates an @p option from @p value.
* @post <tt>valid() == true</tt>
* Creates an valid instance from `value`.
*/
optional(T value) : m_valid(false) { cr(std::move(value)); }
optional(T value) : m_valid(false) {
cr(std::move(value));
}
optional(const optional& other) : m_valid(false) {
if (other.m_valid) cr(other.m_value);
if (other.m_valid) {
cr(other.m_value);
}
}
optional(optional&& other) : m_valid(false) {
if (other.m_valid) cr(std::move(other.m_value));
if (other.m_valid) {
cr(std::move(other.m_value));
}
}
~optional() { destroy(); }
~optional() {
destroy();
}
optional& operator=(const optional& other) {
if (m_valid) {
......@@ -92,239 +93,242 @@ class optional {
}
/**
* @brief Returns @p true if this @p option has a valid value;
* otherwise @p false.
* Queries whether this instance holds a value.
*/
inline bool valid() const { return m_valid; }
bool valid() const {
return m_valid;
}
/**
* @brief Returns <tt>!valid()</tt>.
* Returns `!valid()`.
*/
inline bool empty() const { return !m_valid; }
bool empty() const {
return !m_valid;
}
/**
* @brief Returns @p true if this @p option has a valid value;
* otherwise @p false.
* Returns `valid()`.
*/
inline explicit operator bool() const { return valid(); }
explicit operator bool() const {
return valid();
}
/**
* @brief Returns <tt>!valid()</tt>.
* Returns `!valid()`.
*/
inline bool operator!() const { return empty(); }
inline bool operator==(const none_t&) { return empty(); }
bool operator!() const {
return !valid();
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline T& operator*() {
T& operator*() {
CAF_REQUIRE(valid());
return m_value;
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline const T& operator*() const {
const T& operator*() const {
CAF_REQUIRE(valid());
return m_value;
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline const T* operator->() const {
const T* operator->() const {
CAF_REQUIRE(valid());
return &m_value;
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline T* operator->() {
T* operator->() {
CAF_REQUIRE(valid());
return &m_value;
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline T& get() {
T& get() {
CAF_REQUIRE(valid());
return m_value;
}
/**
* @brief Returns the value.
* Returns the value.
*/
inline const T& get() const {
const T& get() const {
CAF_REQUIRE(valid());
return m_value;
}
/**
* @brief Returns the value. The value is set to @p default_value
* if <tt>valid() == false</tt>.
* @post <tt>valid() == true</tt>
* Returns the value if `valid()`, otherwise returns `default_value`.
*/
inline const T& get_or_else(const T& default_value) const {
if (valid()) return get();
return default_value;
const T& get_or_else(const T& default_value) const {
return valid() ? get() : default_value;
}
private:
bool m_valid;
union { T m_value; };
void destroy() {
if (m_valid) {
m_value.~T();
m_valid = false;
}
}
template <class V>
void cr(V&& value) {
CAF_REQUIRE(!valid());
m_valid = true;
new (&m_value) T (std::forward<V>(value));
new (&m_value) T(std::forward<V>(value));
}
bool m_valid;
union { T m_value; };
};
/**
* Template specialization to allow `optional`
* to hold a reference rather than an actual value.
*/
template <class T>
class optional<T&> {
public:
using type = T;
optional(const none_t& = none) : m_value(nullptr) { }
optional(const none_t& = none) : m_value(nullptr) {
// nop
}
optional(T& value) : m_value(&value) { }
optional(T& value) : m_value(&value) {
// nop
}
optional(const optional& other) = default;
optional& operator=(const optional& other) = default;
inline bool valid() const { return m_value != nullptr; }
inline bool empty() const { return !valid(); }
bool valid() const {
return m_value != nullptr;
}
inline explicit operator bool() const { return valid(); }
bool empty() const {
return !valid();
}
inline bool operator!() const { return empty(); }
explicit operator bool() const {
return valid();
}
inline bool operator==(const none_t&) { return empty(); }
bool operator!() const {
return !valid();
}
inline T& operator*() {
T& operator*() {
CAF_REQUIRE(valid());
return *m_value;
}
inline const T& operator*() const {
const T& operator*() const {
CAF_REQUIRE(valid());
return *m_value;
}
inline T* operator->() {
T* operator->() {
CAF_REQUIRE(valid());
return m_value;
}
inline const T* operator->() const {
const T* operator->() const {
CAF_REQUIRE(valid());
return m_value;
}
inline T& get() {
T& get() {
CAF_REQUIRE(valid());
return *m_value;
}
inline const T& get() const {
const T& get() const {
CAF_REQUIRE(valid());
return *m_value;
}
inline const T& get_or_else(const T& default_value) const {
const T& get_or_else(const T& default_value) const {
if (valid()) return get();
return default_value;
}
private:
T* m_value;
};
template <>
class optional<void> {
public:
optional(const unit_t&) : m_valid(true) { }
optional(const none_t& = none) : m_valid(false) { }
inline bool valid() const { return m_valid; }
inline bool empty() const { return !m_valid; }
inline explicit operator bool() const { return valid(); }
inline bool operator!() const { return empty(); }
inline bool operator==(const none_t&) { return empty(); }
inline const unit_t& operator*() const { return unit; }
private:
bool m_valid;
};
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
if ((lhs) && (rhs)) return *lhs == *rhs;
return false;
}
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator==(const optional<T>& lhs, const U& rhs) {
if (lhs) return *lhs == rhs;
return false;
}
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator==(const T& lhs, const optional<U>& rhs) {
return rhs == lhs;
}
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
return !(lhs == rhs);
}
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator!=(const optional<T>& lhs, const U& rhs) {
return !(lhs == rhs);
}
/** @relates option */
/** @relates optional */
template <class T, typename U>
bool operator!=(const T& lhs, const optional<U>& rhs) {
return !(lhs == rhs);
}
/** @relates optional */
template <class T>
bool operator==(const optional<T>& val, const none_t&) {
return val.valid();
}
/** @relates optional */
template <class T>
bool operator==(const none_t&, const optional<T>& val) {
return val.valid();
}
/** @relates optional */
template <class T>
bool operator!=(const optional<T>& val, const none_t&) {
return !val.valid();
}
/** @relates optional */
template <class T>
bool operator!=(const none_t&, const optional<T>& val) {
return !val.valid();
}
} // namespace caf
#endif // CAF_OPTIONAL_HPP
......@@ -24,7 +24,7 @@ namespace caf {
namespace policy {
/**
* @brief A container for actor-related policies.
* A container for actor-related policies.
*/
template <class SchedulingPolicy,
class PriorityPolicy,
......
......@@ -54,11 +54,11 @@ class event_based_resume {
void detach_from_scheduler() override { this->deref(); }
resumable::resume_result resume(execution_unit* host) override {
resumable::resume_result resume(execution_unit* new_host) override {
auto d = static_cast<Derived*>(this);
d->m_host = host;
d->host(new_host);
CAF_LOG_TRACE("id = " << d->id());
auto done_cb = [&]()->bool {
auto done_cb = [&]() -> bool {
CAF_LOG_TRACE("");
d->bhvr_stack().clear();
d->bhvr_stack().cleanup();
......
......@@ -33,8 +33,8 @@ namespace caf {
namespace policy {
/**
* @brief An implementation of the {@link job_queue_policy} concept for
* fork-join like processing of actors.
* An implementation of the `job_queue_policy` concept for fork-join
* like processing of actors.
*
* This work-stealing fork-join implementation uses two queues: a
* synchronized queue accessible by other threads and an internal queue.
......@@ -74,12 +74,12 @@ class fork_join {
}
/**
* @brief A thead-safe queue implementation.
* A thead-safe queue implementation.
*/
using sync_queue = detail::producer_consumer_list<resumable>;
/**
* @brief A queue implementation supporting fast push and pop
* A queue implementation supporting fast push and pop
* operations on both ends of the queue.
*/
using priv_queue = std::deque<resumable*>;
......
......@@ -36,7 +36,6 @@
#include "caf/response_promise.hpp"
#include "caf/detail/memory.hpp"
#include "caf/detail/matches.hpp"
#include "caf/detail/logging.hpp"
#include "caf/detail/scope_guard.hpp"
......@@ -63,200 +62,138 @@ struct rp_flag {
};
/**
* @brief The invoke_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any resume policy.
* Base class for invoke policies.
*/
template <class Derived>
class invoke_policy {
public:
enum class msg_type {
normal_exit, // an exit message with normal exit reason
non_normal_exit, // an exit message with abnormal exit reason
expired_timeout, // an 'old & obsolete' timeout
inactive_timeout, // a currently inactive timeout
expired_sync_response, // a sync response that already timed out
timeout, // triggers currently active timeout
timeout_response, // triggers timeout of a sync message
ordinary, // an asynchronous message or sync. request
sync_response // a synchronous response
};
/**
* @note @p node_ptr.release() is called whenever a message was
* @note `node_ptr`.release() is called whenever a message was
* handled or dropped.
*/
template <class Actor, class Fun>
bool invoke_message(Actor* self, unique_mailbox_element_pointer& node_ptr,
Fun& fun, message_id awaited_response) {
if (!node_ptr) return false;
bool result = false;
bool reset_pointer = true;
Fun& fun, message_id awaited_response) {
if (!node_ptr) {
return false;
}
switch (handle_message(self, node_ptr.get(), fun, awaited_response)) {
case hm_msg_handled: {
result = true;
break;
}
case hm_drop_msg: { break; }
case hm_cache_msg: {
reset_pointer = false;
break;
}
case hm_skip_msg: {
// "received" a marked node
reset_pointer = false;
break;
}
case hm_msg_handled:
node_ptr.reset();
return true;
case hm_cache_msg:
case hm_skip_msg:
// do not reset ptr (not handled => cache or skip)
return false;
default: // drop message
node_ptr.reset();
return false;
}
if (reset_pointer) node_ptr.reset();
return result;
}
using nestable = typename rp_flag<rp_nestable>::type;
using sequential = typename rp_flag<rp_sequential>::type;
private:
inline void handle_timeout(message_handler&) {
CAF_CRITICAL("handle_timeout(message_handler&)");
}
enum class msg_type {
normal_exit, // an exit message with normal exit reason
non_normal_exit, // an exit message with abnormal exit reason
expired_timeout, // an 'old & obsolete' timeout
inactive_timeout, // a currently inactive timeout
expired_sync_response, // a sync response that already timed out
timeout, // triggers currently active timeout
timeout_response, // triggers timeout of a sync message
ordinary, // an asynchronous message or sync. request
sync_response // a synchronous response
};
// identifies 'special' messages that should not be processed normally:
// - system messages such as EXIT (if self doesn't trap exits) and TIMEOUT
// - expired synchronous response messages
template <class Actor>
msg_type filter_msg(Actor* self, mailbox_element* node) {
const message& msg = node->msg;
auto mid = node->mid;
if (msg.size() == 1) {
if (msg.type_at(0)->equal_to(typeid(exit_msg))) {
auto& em = msg.get_as<exit_msg>(0);
CAF_REQUIRE(!mid.valid());
if (self->trap_exit() == false) {
if (em.reason != exit_reason::normal) {
self->quit(em.reason);
return msg_type::non_normal_exit;
}
return msg_type::normal_exit;
}
} else if (msg.type_at(0)->equal_to(typeid(timeout_msg))) {
auto& tm = msg.get_as<timeout_msg>(0);
auto tid = tm.timeout_id;
CAF_REQUIRE(!mid.valid());
if (self->is_active_timeout(tid)) return msg_type::timeout;
return self->waits_for_timeout(tid) ?
msg_type::inactive_timeout :
msg_type::expired_timeout;
} else if (msg.type_at(0)->equal_to(typeid(sync_timeout_msg)) &&
mid.is_response()) {
return msg_type::timeout_response;
}
}
if (mid.is_response()) {
return (self->awaits(mid)) ? msg_type::sync_response :
msg_type::expired_sync_response;
}
return msg_type::ordinary;
}
public:
template <class Actor>
inline response_promise fetch_response_promise(Actor* cl, int) {
response_promise fetch_response_promise(Actor* cl, int) {
return cl->make_response_promise();
}
template <class Actor>
inline response_promise fetch_response_promise(Actor*,
response_promise& hdl) {
response_promise fetch_response_promise(Actor*, response_promise& hdl) {
return std::move(hdl);
}
// - extracts response message from handler
// - returns true if fun was successfully invoked
template <class Actor, class Fun, class MaybeResponseHandle = int>
template <class Actor, class Fun, class MaybeResponseHdl = int>
optional<message> invoke_fun(Actor* self, message& msg, message_id& mid,
Fun& fun, MaybeResponseHandle hdl =
MaybeResponseHandle{}) {
# ifdef CAF_LOG_LEVEL
auto msg_str = to_string(msg);
# endif
Fun& fun,
MaybeResponseHdl hdl = MaybeResponseHdl{}) {
# ifdef CAF_LOG_LEVEL
auto msg_str = to_string(msg);
# endif
CAF_LOG_TRACE(CAF_MARG(mid, integer_value) << ", msg = " << msg_str);
auto res = fun(msg); // might change mid
CAF_LOG_DEBUG_IF(res, "actor did consume message: " << msg_str);
CAF_LOG_DEBUG_IF(!res, "actor did ignore message: " << msg_str);
if (res) {
if (res->empty()) {
// make sure synchronous requests
// always receive a response
if (mid.is_request() && !mid.is_answered()) {
CAF_LOG_WARNING("actor with ID "
<< self->id()
<< " did not reply to a "
"synchronous request message");
auto fhdl = fetch_response_promise(self, hdl);
if (fhdl) fhdl.deliver(make_message(unit));
if (!res) {
return none;
}
if (res->empty()) {
// make sure synchronous requests
// always receive a response
if (mid.is_request() && !mid.is_answered()) {
CAF_LOG_WARNING("actor with ID " << self->id()
<< " did not reply to a synchronous request message");
auto fhdl = fetch_response_promise(self, hdl);
if (fhdl) {
fhdl.deliver(make_message(unit));
}
} else {
CAF_LOGF_DEBUG("res = " << to_string(*res));
if (res->template has_types<atom_value, uint64_t>() &&
res->template get_as<atom_value>(0) == atom("MESSAGE_ID")) {
CAF_LOG_DEBUG(
"message handler returned a "
"message id wrapper");
auto id = res->template get_as<uint64_t>(1);
auto msg_id = message_id::from_integer_value(id);
auto ref_opt = self->sync_handler(msg_id);
// calls self->response_promise() if hdl is a dummy
// argument, forwards hdl otherwise to reply to the
// original request message
auto fhdl = fetch_response_promise(self, hdl);
if (ref_opt) {
behavior cpy = *ref_opt;
*ref_opt =
cpy.add_continuation([=](message & intermediate)
->optional<message> {
if (!intermediate.empty()) {
// do no use lamba expresion type to
// avoid recursive template instantiaton
behavior::continuation_fun f2 = [=](
message & m)->optional<message> {
return std::move(m);
}
} else {
CAF_LOGF_DEBUG("res = " << to_string(*res));
if (res->template has_types<atom_value, uint64_t>()
&& res->template get_as<atom_value>(0) == atom("MESSAGE_ID")) {
CAF_LOG_DEBUG("message handler returned a message id wrapper");
auto id = res->template get_as<uint64_t>(1);
auto msg_id = message_id::from_integer_value(id);
auto ref_opt = self->sync_handler(msg_id);
// calls self->response_promise() if hdl is a dummy
// argument, forwards hdl otherwise to reply to the
// original request message
auto fhdl = fetch_response_promise(self, hdl);
if (ref_opt) {
behavior cpy = *ref_opt;
*ref_opt =
cpy.add_continuation([=](message & intermediate)
->optional<message> {
if (!intermediate.empty()) {
// do no use lamba expresion type to
// avoid recursive template instantiaton
behavior::continuation_fun f2 = [=](
message & m)->optional<message> {
return std::move(m);
};
auto mutable_mid = mid;
// recursively call invoke_fun on the
// result to correctly handle stuff like
// sync_send(...).then(...).then(...)...
return invoke_fun(self, intermediate,
mutable_mid, f2, fhdl);
}
return none;
});
}
// reset res to prevent "outer" invoke_fun
// from handling the result again
res->reset();
} else {
// respond by using the result of 'fun'
CAF_LOG_DEBUG("respond via response_promise");
auto fhdl = fetch_response_promise(self, hdl);
if (fhdl) {
fhdl.deliver(std::move(*res));
// inform caller about success
return message{};
}
};
auto mutable_mid = mid;
// recursively call invoke_fun on the
// result to correctly handle stuff like
// sync_send(...).then(...).then(...)...
return invoke_fun(self, intermediate,
mutable_mid, f2, fhdl);
}
return none;
});
}
// reset res to prevent "outer" invoke_fun
// from handling the result again
res->reset();
} else {
// respond by using the result of 'fun'
CAF_LOG_DEBUG("respond via response_promise");
auto fhdl = fetch_response_promise(self, hdl);
if (fhdl) {
fhdl.deliver(std::move(*res));
// inform caller about success
return message{};
}
}
return res;
}
// fun did not return a value => no match
return none;
return res;
}
// the workflow of handle_message (hm) is as follows:
......@@ -269,35 +206,29 @@ class invoke_policy {
template <class Actor, class Fun>
handle_message_result handle_message(Actor* self, mailbox_element* node,
Fun& fun,
message_id awaited_response) {
Fun& fun, message_id awaited_response) {
bool handle_sync_failure_on_mismatch = true;
if (dptr()->hm_should_skip(node)) {
return hm_skip_msg;
}
switch (this->filter_msg(self, node)) {
case msg_type::normal_exit: {
case msg_type::normal_exit:
CAF_LOG_DEBUG("dropped normal exit signal");
return hm_drop_msg;
}
case msg_type::expired_sync_response: {
case msg_type::expired_sync_response:
CAF_LOG_DEBUG("dropped expired sync response");
return hm_drop_msg;
}
case msg_type::expired_timeout: {
case msg_type::expired_timeout:
CAF_LOG_DEBUG("dropped expired timeout message");
return hm_drop_msg;
}
case msg_type::inactive_timeout: {
case msg_type::inactive_timeout:
CAF_LOG_DEBUG("skipped inactive timeout message");
return hm_skip_msg;
}
case msg_type::non_normal_exit: {
case msg_type::non_normal_exit:
CAF_LOG_DEBUG("handled non-normal exit signal");
// this message was handled
// by calling self->quit(...)
return hm_msg_handled;
}
case msg_type::timeout: {
CAF_LOG_DEBUG("handle timeout message");
auto& tm = node->msg.get_as<timeout_msg>(0);
......@@ -308,11 +239,10 @@ class invoke_policy {
}
return hm_msg_handled;
}
case msg_type::timeout_response: {
case msg_type::timeout_response:
handle_sync_failure_on_mismatch = false;
CAF_ANNOTATE_FALLTHROUGH;
}
case msg_type::sync_response: {
case msg_type::sync_response:
CAF_LOG_DEBUG("handle as synchronous response: "
<< CAF_TARG(node->msg, to_string) << ", "
<< CAF_MARG(node->mid, integer_value) << ", "
......@@ -331,8 +261,7 @@ class invoke_policy {
return hm_msg_handled;
}
return hm_cache_msg;
}
case msg_type::ordinary: {
case msg_type::ordinary:
if (!awaited_response.valid()) {
auto previous_node = dptr()->hm_begin(self, node);
auto res = invoke_fun(self, node->msg, node->mid, fun);
......@@ -347,14 +276,60 @@ class invoke_policy {
"ignored message; await response: "
<< awaited_response.integer_value());
return hm_cache_msg;
}
}
// should be unreachable
CAF_CRITICAL("invalid message type");
}
Derived* dptr() { return static_cast<Derived*>(this); }
protected:
Derived* dptr() {
return static_cast<Derived*>(this);
}
private:
void handle_timeout(message_handler&) {
CAF_CRITICAL("handle_timeout(message_handler&)");
}
// identifies 'special' messages that should not be processed normally:
// - system messages such as EXIT (if self doesn't trap exits) and TIMEOUT
// - expired synchronous response messages
template <class Actor>
msg_type filter_msg(Actor* self, mailbox_element* node) {
const message& msg = node->msg;
auto mid = node->mid;
if (msg.size() == 1) {
if (msg.type_at(0)->equal_to(typeid(exit_msg))) {
auto& em = msg.get_as<exit_msg>(0);
CAF_REQUIRE(!mid.valid());
if (self->trap_exit() == false) {
if (em.reason != exit_reason::normal) {
self->quit(em.reason);
return msg_type::non_normal_exit;
}
return msg_type::normal_exit;
}
} else if (msg.type_at(0)->equal_to(typeid(timeout_msg))) {
auto& tm = msg.get_as<timeout_msg>(0);
auto tid = tm.timeout_id;
CAF_REQUIRE(!mid.valid());
if (self->is_active_timeout(tid)) {
return msg_type::timeout;
}
return self->waits_for_timeout(tid) ? msg_type::inactive_timeout
: msg_type::expired_timeout;
} else if (msg.type_at(0)->equal_to(typeid(sync_timeout_msg))
&& mid.is_response()) {
return msg_type::timeout_response;
}
}
if (mid.is_response()) {
return self->awaits(mid) ? msg_type::sync_response
: msg_type::expired_sync_response;
}
return msg_type::ordinary;
}
};
} // namespace policy
......
......@@ -28,8 +28,8 @@ namespace caf {
namespace policy {
/**
* @brief An implementation of the {@link steal_policy} concept
* that iterates over all other workers when stealing.
* An implementation of the {@link steal_policy} concept
* that simply iterates over other workers when stealing.
*
* @relates steal_policy
*/
......
......@@ -26,57 +26,57 @@ namespace caf {
namespace policy {
/**
* @brief This concept class describes the interface of a policy class
* for managing the queue(s) of a scheduler worker.
* This concept class describes the interface of a policy class
* for managing the queue(s) of a scheduler worker.
*/
class job_queue_policy {
public:
/**
* @brief Enqueues a new job to the worker's queue from an
* external source, i.e., from any other thread.
* Enqueues a new job to the worker's queue from an
* external source, i.e., from any other thread.
*/
template <class Worker>
void external_enqueue(Worker* self, resumable* job);
/**
* @brief Enqueues a new job to the worker's queue from an
* internal source, i.e., from the same thread.
* Enqueues a new job to the worker's queue from an
* internal source, i.e., from the same thread.
*/
template <class Worker>
void internal_enqueue(Worker* self, resumable* job);
/**
* @brief Called by external sources to try to dequeue an element.
* Returns @p nullptr if no element could be dequeued immediately.
* Returns `nullptr` if no element could be dequeued immediately.
* Called by external sources to try to dequeue an element.
*/
template <class Worker>
resumable* try_external_dequeue(Worker* self);
/**
* @brief Called by the worker itself to acquire a new job.
* Blocks until a job could be dequeued.
* Blocks until a job could be dequeued.
* Called by the worker itself to acquire a new job.
*/
template <class Worker>
resumable* internal_dequeue(Worker* self);
/**
* @brief Moves all elements form the internal queue to the external queue.
* Moves all elements form the internal queue to the external queue.
*/
template <class Worker>
void clear_internal_queue(Worker* self);
/**
* @brief Tries to move at least one element from the internal queue ot
* the external queue if possible to allow others to steal from us.
* Tries to move at least one element from the internal queue to
* the external queue if possible to allow others to steal from us.
*/
template <class Worker>
void assert_stealable(Worker* self);
/**
* @brief Applies given functor to all elements in all queues and
* clears all queues afterwards.
* Applies given functor to all elements in all queues and
* clears all queues afterwards.
*/
template <class Worker, typename UnaryFunction>
void consume_all(Worker* self, UnaryFunction f);
......
......@@ -28,23 +28,23 @@ namespace caf {
namespace policy {
/**
* @brief The priority_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any priority policy.
* The priority_policy *concept* class. Please note that this
* class is **not** implemented. It merely explains all
* required member functions.
*/
class priority_policy {
public:
/**
* @brief Returns the next message from the mailbox or @p nullptr
* if it's empty.
* Returns the next message from the mailbox or `nullptr`
* if it's empty.
*/
template <class Actor>
unique_mailbox_element_pointer next_message(Actor* self);
/**
* @brief Queries whether the mailbox is not empty.
* Queries whether the mailbox is not empty.
*/
template <class Actor>
bool has_next_message(Actor* self);
......
......@@ -33,33 +33,29 @@ class duration;
namespace policy {
/**
* @brief The resume_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any resume policy.
* The resume_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any resume policy.
*/
class resume_policy {
public:
/**
* @brief Resumes the actor by reading a new message <tt>msg</tt> and then
* calling <tt>self->invoke(msg)</tt>. This process is repeated
* until either no message is left in the actor's mailbox or the
* actor finishes execution.
* Resumes the actor by reading a new message and then
* calling `self->invoke(msg)`. This process is repeated
* until either no message is left in the actor's mailbox or the
* actor finishes execution.
*/
template <class Actor>
resumable::resume_result resume(Actor* self, execution_unit*);
/**
* @brief Waits unconditionally until the actor is ready to resume.
* Waits unconditionally until the actor is ready to be resumed.
* This member function calls `self->await_data()`.
* @note This member function must raise a compiler error if the resume
* strategy cannot be used to implement blocking actors.
*
* This member function calls {@link scheduling_policy::await_data}
* strategy cannot be used to implement blocking actors.
*/
template <class Actor>
bool await_ready(Actor* self);
};
} // namespace policy
......
......@@ -34,29 +34,29 @@ enum class timed_fetch_result {
};
/**
* @brief The scheduling_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any scheduling policy.
* The scheduling_policy <b>concept</b> class. Please note that this
* class is <b>not</b> implemented. It only explains the all
* required member function and their behavior for any scheduling policy.
*/
class scheduling_policy {
public:
/**
* @brief This type can be set freely by any implementation and is
* used by callers to pass the result of @p init_timeout back to
* @p fetch_messages.
* This type can be set freely by any implementation and is
* used by callers to pass the result of `init_timeout` back to
* `fetch_messages`.
*/
using timeout_type = int;
/**
* @brief Fetches new messages from the actor's mailbox and feeds them
* to the given callback. The member function returns @p false if
* no message was read, @p true otherwise.
* Fetches new messages from the actor's mailbox and feeds them
* to the given callback. The member function returns `false` if
* no message was read, `true` otherwise.
*
* In case this function returned @p false, the policy also sets the state
* In case this function returned `false,` the policy also sets the state
* of the actor to blocked. Any caller must evaluate the return value and
* act properly in case of a returned @p false, i.e., it must <b>not</b>
* act properly in case of a returned `false,` i.e., it must <b>not</b>
* atttempt to call any further function on the actor, since it might be
* already in the pipe for re-scheduling.
*/
......@@ -64,9 +64,9 @@ class scheduling_policy {
bool fetch_messages(Actor* self, F cb);
/**
* @brief Tries to fetch new messages from the actor's mailbox and to feeds
* them to the given callback. The member function returns @p false
* if no message was read, @p true otherwise.
* Tries to fetch new messages from the actor's mailbox and to feeds
* them to the given callback. The member function returns `false`
* if no message was read, `true` otherwise.
*
* This member function does not have any side-effect other than removing
* messages from the actor's mailbox.
......@@ -75,27 +75,27 @@ class scheduling_policy {
bool try_fetch_messages(Actor* self, F cb);
/**
* @brief Tries to fetch new messages before a timeout occurs. The message
* can either return @p success, or @p no_message,
* or @p indeterminate. The latter occurs for cooperative scheduled
* operations and means that timeouts are signaled using
* special-purpose messages. In this case, clients have to simply
* wait for the arriving message.
* Tries to fetch new messages before a timeout occurs. The message
* can either return `success,` or `no_message,`
* or `indeterminate`. The latter occurs for cooperative scheduled
* operations and means that timeouts are signaled using
* special-purpose messages. In this case, clients have to simply
* wait for the arriving message.
*/
template <class Actor, typename F>
timed_fetch_result fetch_messages(Actor* self, F cb, timeout_type abs_time);
/**
* @brief Enqueues given message to the actor's mailbox and take any
* steps to resume the actor if it's currently blocked.
* Enqueues given message to the actor's mailbox and take any
* steps to resume the actor if it's currently blocked.
*/
template <class Actor>
void enqueue(Actor* self, const actor_addr& sender, message_id mid,
message& msg, execution_unit* host);
/**
* @brief Starts the given actor either by launching a thread or enqueuing
* it to the cooperative scheduler's job queue.
* Starts the given actor either by launching a thread or enqueuing
* it to the cooperative scheduler's job queue.
*/
template <class Actor>
void launch(Actor* self);
......
......@@ -30,7 +30,7 @@ namespace caf {
namespace policy {
/**
* @brief An actor that is scheduled or otherwise managed.
* An actor that is scheduled or otherwise managed.
*/
class sequential_invoke : public invoke_policy<sequential_invoke> {
......
......@@ -28,16 +28,16 @@ namespace caf {
namespace policy {
/**
* @brief This concept class describes the interface of a policy class
* for stealing jobs from other workers.
* This concept class describes the interface of a policy class
* for stealing jobs from other workers.
*/
class steal_policy {
public:
/**
* @brief Go on a raid in quest for a shiny new job. Returns @p nullptr
* if no other worker provided any work to steal.
* Go on a raid in quest for a shiny new job. Returns `nullptr`
* if no other worker provided any work to steal.
*/
template <class Worker>
resumable* raid(Worker* self);
......
......@@ -28,16 +28,12 @@
namespace caf {
/**
* @brief A (thread safe) base class for reference counted objects
* with an atomic reference count.
*
* Base class for reference counted objects with an atomic reference count.
* Serves the requirements of {@link intrusive_ptr}.
* @relates intrusive_ptr
*/
class ref_counted : public memory_managed {
public:
ref_counted();
ref_counted(const ref_counted&);
......@@ -47,34 +43,42 @@ class ref_counted : public memory_managed {
~ref_counted();
/**
* @brief Increases reference count by one.
* Increases reference count by one.
*/
inline void ref() { ++m_rc; }
/**
* @brief Decreases reference count by one and calls
* @p request_deletion when it drops to zero.
* Decreases reference count by one and calls `request_deletion`
* when it drops to zero.
*/
inline void deref() {
if (--m_rc == 0) request_deletion();
}
/**
* @brief Queries whether there is exactly one reference.
* Queries whether there is exactly one reference.
*/
inline bool unique() const { return m_rc == 1; }
inline size_t get_reference_count() const { return m_rc; }
private:
std::atomic<size_t> m_rc;
};
inline void intrusive_ptr_add_ref(ref_counted* p) { p->ref(); }
/**
* @relates ref_counted
*/
inline void intrusive_ptr_add_ref(ref_counted* p) {
p->ref();
}
inline void intrusive_ptr_release(ref_counted* p) { p->deref(); }
/**
* @relates ref_counted
*/
inline void intrusive_ptr_release(ref_counted* p) {
p->deref();
}
} // namespace caf
......
......@@ -35,27 +35,22 @@
namespace caf {
/**
* @brief This tag identifies response handles featuring a
* nonblocking API by providing a @p then member function.
* This tag identifies response handles featuring a
* nonblocking API by providing a `then` member function.
* @relates response_handle
*/
struct nonblocking_response_handle_tag {};
/**
* @brief This tag identifies response handles featuring a
* blocking API by providing an @p await member function.
* This tag identifies response handles featuring a
* blocking API by providing an `await` member function.
* @relates response_handle
*/
struct blocking_response_handle_tag {};
/**
* @brief This helper class identifies an expected response message
* and enables <tt>sync_send(...).then(...)</tt>.
*
* @tparam Self The type of the actor this handle belongs to.
* @tparam Result Either message or type_list<R1, R2, ... Rn>.
* @tparam Tag Either {@link nonblocking_response_handle_tag} or
* {@link blocking_response_handle_tag}.
* This helper class identifies an expected response message
* and enables `sync_send(...).then(...)`.
*/
template <class Self, class Result, class Tag>
class response_handle;
......
......@@ -28,14 +28,12 @@
namespace caf {
/**
* @brief A response promise can be used to deliver a uniquely identifiable
* response message from the server (i.e. receiver of the request)
* to the client (i.e. the sender of the request).
* A response promise can be used to deliver a uniquely identifiable
* response message from the server (i.e. receiver of the request)
* to the client (i.e. the sender of the request).
*/
class response_promise {
public:
response_promise() = default;
response_promise(response_promise&&) = default;
response_promise(const response_promise&) = default;
......@@ -43,11 +41,11 @@ class response_promise {
response_promise& operator=(const response_promise&) = default;
response_promise(const actor_addr& from, const actor_addr& to,
const message_id& response_id);
const message_id& response_id);
/**
* @brief Queries whether this promise is still valid, i.e., no response
* was yet delivered to the client.
* Queries whether this promise is still valid, i.e., no response
* was yet delivered to the client.
*/
inline explicit operator bool() const {
// handle is valid if it has a receiver
......@@ -55,16 +53,14 @@ class response_promise {
}
/**
* @brief Sends @p response_message and invalidates this handle afterwards.
* Sends `response_message` and invalidates this handle afterwards.
*/
void deliver(message response_message);
private:
actor_addr m_from;
actor_addr m_to;
message_id m_id;
};
} // namespace caf
......
......@@ -25,13 +25,11 @@ namespace caf {
class execution_unit;
/**
* @brief A cooperatively executed task managed by one or more instances of
* {@link execution_unit}.
* A cooperatively executed task managed by one or more
* instances of `execution_unit`.
*/
class resumable {
public:
enum resume_result {
resume_later,
done,
......@@ -44,27 +42,23 @@ class resumable {
virtual ~resumable();
/**
* @brief Initializes this object, e.g., by increasing the
* the reference count.
* Initializes this object, e.g., by increasing the the reference count.
*/
virtual void attach_to_scheduler() = 0;
/**
* @brief Uninitializes this object, e.g., by decrementing the
* the reference count.
* Uninitializes this object, e.g., by decrementing the the reference count.
*/
virtual void detach_from_scheduler() = 0;
/**
* @brief Resume any pending computation until it is either finished
* or needs to be re-scheduled later.
* Resume any pending computation until it is either finished
* or needs to be re-scheduled later.
*/
virtual resume_result resume(execution_unit*) = 0;
protected:
bool m_hidden;
};
} // namespace caf
......
......@@ -28,37 +28,30 @@
namespace caf {
/**
* @brief A base class for state-based actors using the
* Curiously Recurring Template Pattern
* to initialize the derived actor with its @p init_state member.
* @tparam Derived Direct subclass of @p sb_actor.
* A base class for state-based actors using the
* Curiously Recurring Template Pattern
* to initialize the derived actor with its `init_state` member.
*/
template <class Derived, class Base = event_based_actor>
class sb_actor : public Base {
public:
static_assert(std::is_base_of<event_based_actor, Base>::value,
"Base must be event_based_actor or a derived type");
protected:
using combined_type = sb_actor;
public:
/**
* @brief Overrides {@link event_based_actor::make_behavior()} and sets
* the initial actor behavior to <tt>Derived::init_state</tt>.
* Overrides {@link event_based_actor::make_behavior()} and sets
* the initial actor behavior to `Derived::init_state.
*/
behavior make_behavior() override {
return static_cast<Derived*>(this)->init_state;
}
protected:
using combined_type = sb_actor;
template <class... Ts>
sb_actor(Ts&&... args)
: Base(std::forward<Ts>(args)...) {}
};
} // namespace caf
......
......@@ -48,7 +48,7 @@ namespace scheduler {
class abstract_coordinator;
/**
* @brief Base class for work-stealing workers.
* Base class for work-stealing workers.
*/
class abstract_worker : public execution_unit {
......@@ -57,46 +57,44 @@ class abstract_worker : public execution_unit {
public:
/**
* @brief Attempt to steal an element from this worker.
* Attempt to steal an element from this worker.
*/
virtual resumable* try_steal() = 0;
/**
* @brief Enqueues a new job to the worker's queue from an external
* source, i.e., from any other thread.
* Enqueues a new job to the worker's queue from an external
* source, i.e., from any other thread.
*/
virtual void external_enqueue(resumable*) = 0;
/**
* @brief Starts the thread of this worker.
* Starts the thread of this worker.
*/
virtual void start(size_t id, abstract_coordinator* parent) = 0;
};
/**
* @brief A coordinator creates the workers, manages delayed sends and
* the central printer instance for {@link aout}. It also forwards
* sends from detached workers or non-actor threads to randomly
* chosen workers.
* A coordinator creates the workers, manages delayed sends and
* the central printer instance for {@link aout}. It also forwards
* sends from detached workers or non-actor threads to randomly
* chosen workers.
*/
class abstract_coordinator {
friend class detail::singletons;
public:
friend class detail::singletons;
explicit abstract_coordinator(size_t num_worker_threads);
virtual ~abstract_coordinator();
/**
* @brief Returns a handle to the central printing actor.
* Returns a handle to the central printing actor.
*/
actor printer() const;
/**
* @brief Puts @p what into the queue of a randomly chosen worker.
* Puts `what` into the queue of a randomly chosen worker.
*/
void enqueue(resumable* what);
......@@ -125,7 +123,6 @@ class abstract_coordinator {
virtual void stop();
private:
// Creates a default instance.
static abstract_coordinator* create_singleton();
......@@ -143,16 +140,16 @@ class abstract_coordinator {
std::thread m_timer_thread;
std::thread m_printer_thread;
};
/**
* @brief Policy-based implementation of the abstract worker base class.
* Policy-based implementation of the abstract worker base class.
*/
template <class StealPolicy, class JobQueuePolicy>
class worker : public abstract_worker {
public:
worker(const worker&) = delete;
worker& operator=(const worker&) = delete;
worker() = default;
......@@ -164,7 +161,6 @@ class worker : public abstract_worker {
// cannot be moved once m_this_thread is up and running
auto running = [](std::thread& t) {
return t.get_id() != std::thread::id{};
};
if (running(m_this_thread) || running(other.m_this_thread)) {
throw std::runtime_error("running workers cannot be moved");
......@@ -174,16 +170,12 @@ class worker : public abstract_worker {
return *this;
}
worker(const worker&) = delete;
worker& operator=(const worker&) = delete;
using job_ptr = resumable*;
using job_queue = detail::producer_consumer_list<resumable>;
/**
* @brief Attempt to steal an element from the exposed job queue.
* Attempt to steal an element from the exposed job queue.
*/
job_ptr try_steal() override {
auto result = m_queue_policy.try_external_dequeue(this);
......@@ -192,8 +184,8 @@ class worker : public abstract_worker {
}
/**
* @brief Enqueues a new job to the worker's queue from an external
* source, i.e., from any other thread.
* Enqueues a new job to the worker's queue from an external
* source, i.e., from any other thread.
*/
void external_enqueue(job_ptr job) override {
CAF_REQUIRE(job != nullptr);
......@@ -202,9 +194,8 @@ class worker : public abstract_worker {
}
/**
* @brief Enqueues a new job to the worker's queue from an internal
* source, i.e., a job that is currently executed by
* this worker.
* Enqueues a new job to the worker's queue from an internal
* source, i.e., a job that is currently executed by this worker.
* @warning Must not be called from other threads.
*/
void exec_later(job_ptr job) override {
......@@ -253,12 +244,11 @@ class worker : public abstract_worker {
actor_id id_of(resumable* ptr) {
abstract_actor* aptr = ptr ? dynamic_cast<abstract_actor*>(ptr)
: nullptr;
: nullptr;
return aptr ? aptr->id() : 0;
}
private:
void run() {
CAF_LOG_TRACE("worker with ID " << m_id);
// scheduling loop
......@@ -286,27 +276,23 @@ class worker : public abstract_worker {
// the worker's thread
std::thread m_this_thread;
// the worker's ID received from scheduler
size_t m_id;
// pointer to central coordinator
abstract_coordinator* m_parent;
// policy managing queues
JobQueuePolicy m_queue_policy;
// policy managing steal operations
StealPolicy m_steal_policy;
};
/**
* @brief Policy-based implementation of the abstract coordinator base class.
* Policy-based implementation of the abstract coordinator base class.
*/
template <class StealPolicy, class JobQueuePolicy>
class coordinator : public abstract_coordinator {
using super = abstract_coordinator;
public:
using super = abstract_coordinator;
coordinator(size_t nw = std::thread::hardware_concurrency()) : super(nw) {
// nop
......@@ -319,7 +305,6 @@ class coordinator : public abstract_coordinator {
}
protected:
void initialize() override {
super::initialize();
// create & start workers
......@@ -338,16 +323,14 @@ class coordinator : public abstract_coordinator {
}
private:
// vector of size std::thread::hardware_concurrency()
// usually of size std::thread::hardware_concurrency()
std::vector<worker_type> m_workers;
};
} // namespace scheduler
/**
* @brief Sets a user-defined scheduler.
* Sets a user-defined scheduler.
* @note This function must be used before actor is spawned. Dynamically
* changing the scheduler at runtime is not supported.
* @throws std::logic_error if a scheduler is already defined
......@@ -355,8 +338,8 @@ class coordinator : public abstract_coordinator {
void set_scheduler(scheduler::abstract_coordinator* ptr);
/**
* @brief Sets a user-defined scheduler using given policies. The scheduler
* is instantiated with @p nw number of workers.
* Sets a user-defined scheduler using given policies. The scheduler
* is instantiated with `nw` number of workers.
* @note This function must be used before actor is spawned. Dynamically
* changing the scheduler at runtime is not supported.
* @throws std::logic_error if a scheduler is already defined
......
......@@ -26,7 +26,7 @@
namespace caf {
/**
* @brief A scoped handle to a blocking actor.
* A scoped handle to a blocking actor.
*/
class scoped_actor {
......
......@@ -28,7 +28,7 @@
namespace caf {
/**
* @brief Sends @p to a message under the identity of @p from.
* Sends `to` a message under the identity of `from`.
*/
inline void send_tuple_as(const actor& from, const channel& to, message msg) {
if (to)
......@@ -37,7 +37,7 @@ inline void send_tuple_as(const actor& from, const channel& to, message msg) {
}
/**
* @brief Sends @p to a message under the identity of @p from.
* Sends `to` a message under the identity of `from`.
*/
template <class... Ts>
void send_as(const actor& from, const channel& to, Ts&&... args) {
......@@ -45,14 +45,14 @@ void send_as(const actor& from, const channel& to, Ts&&... args) {
}
/**
* @brief Anonymously sends @p to a message.
* Anonymously sends `to` a message.
*/
inline void anon_send_tuple(const channel& to, message msg) {
send_tuple_as(invalid_actor, to, std::move(msg));
}
/**
* @brief Anonymously sends @p to a message.
* Anonymously sends `to` a message.
*/
template <class... Ts>
inline void anon_send(const channel& to, Ts&&... args) {
......@@ -61,12 +61,12 @@ inline void anon_send(const channel& to, Ts&&... args) {
// implemented in local_actor.cpp
/**
* @brief Anonymously sends @p whom an exit message.
* Anonymously sends `whom` an exit message.
*/
void anon_send_exit(const actor_addr& whom, uint32_t reason);
/**
* @brief Anonymously sends @p whom an exit message.
* Anonymously sends `whom` an exit message.
*/
template <class ActorHandle>
inline void anon_send_exit(const ActorHandle& whom, uint32_t reason) {
......
......@@ -35,51 +35,49 @@ class uniform_type_info;
/**
* @ingroup TypeSystem
* @brief Technology-independent serialization interface.
* Technology-independent serialization interface.
*/
class serializer {
public:
serializer(const serializer&) = delete;
serializer& operator=(const serializer&) = delete;
public:
/**
* @note @p addressing must be guaranteed to outlive the serializer
* @note `addressing` must be guaranteed to outlive the serializer
*/
serializer(actor_namespace* addressing = nullptr);
virtual ~serializer();
/**
* @brief Begins serialization of an object of type @p uti.
* Begins serialization of an object of type `uti`.
*/
virtual void begin_object(const uniform_type_info* uti) = 0;
/**
* @brief Ends serialization of an object.
* Ends serialization of an object.
*/
virtual void end_object() = 0;
/**
* @brief Begins serialization of a sequence of size @p num.
* Begins serialization of a sequence of size `num`.
*/
virtual void begin_sequence(size_t num) = 0;
/**
* @brief Ends serialization of a sequence.
* Ends serialization of a sequence.
*/
virtual void end_sequence() = 0;
/**
* @brief Writes a single value to the data sink.
* Writes a single value to the data sink.
* @param value A primitive data value.
*/
virtual void write_value(const primitive_variant& value) = 0;
/**
* @brief Writes a raw block of data.
* @param num_bytes The size of @p data in bytes.
* Writes a raw block of data.
* @param num_bytes The size of `data` in bytes.
* @param data Raw data.
*/
virtual void write_raw(size_t num_bytes, const void* data) = 0;
......@@ -99,24 +97,22 @@ class serializer {
}
private:
actor_namespace* m_namespace;
};
/**
* @brief Serializes a value to @p s.
* Serializes a value to `s`.
* @param s A valid serializer.
* @param what A value of an announced or primitive type.
* @returns @p s
* @returns `s`
* @relates serializer
*/
template <class T>
serializer& operator<<(serializer& s, const T& what) {
auto mtype = uniform_typeid<T>();
if (mtype == nullptr) {
throw std::logic_error("no uniform type info found for " +
detail::to_uniform_name(typeid(T)));
throw std::logic_error("no uniform type info found for "
+ detail::to_uniform_name(typeid(T)));
}
mtype->serialize(&what, &s);
return s;
......
......@@ -25,9 +25,9 @@ namespace caf {
// note: implemented in singletons.cpp
/**
* @brief Destroys all singletons and stops the scheduler.
* It is recommended to use this function as very last
* function call before leaving main().
* Destroys all singletons and stops the scheduler.
* It is recommended to use this function as very last
* function call before leaving main().
*/
void shutdown();
......
......@@ -28,7 +28,7 @@
namespace caf {
/**
* @brief Mixin for actors using a non-nestable message processing.
* Mixin for actors using a non-nestable message processing.
*/
template <class Base, class Subtype>
class single_timeout : public Base {
......
......@@ -23,9 +23,9 @@
namespace caf {
/**
* @brief Optional return type for functors used in pattern matching
* expressions. This type is evaluated by the runtime system
* and can be used to intentionally skip messages.
* Optional return type for functors used in pattern matching
* expressions. This type is evaluated by the runtime system
* and can be used to intentionally skip messages.
*/
struct skip_message_t {
constexpr skip_message_t() {}
......@@ -33,9 +33,9 @@ struct skip_message_t {
};
/**
* @brief Tells the runtime system to skip a message when used as message
* handler, i.e., causes the runtime to leave the message in
* the mailbox of an actor.
* Tells the runtime system to skip a message when used as message
* handler, i.e., causes the runtime to leave the message in
* the mailbox of an actor.
*/
constexpr skip_message_t skip_message() {
return {};
......
......@@ -49,19 +49,27 @@ namespace caf {
class execution_unit;
// marker interface to prevent spawn_impl to wrap
// the implementation in a proper_actor
/**
* Marker interface that prevents `spawn` from wrapping the a class
* in a `proper_actor` when spawning new instances.
*/
class spawn_as_is {};
template <class C, spawn_options Os, typename BeforeLaunch, class... Ts>
intrusive_ptr<C> spawn_impl(execution_unit* eu, BeforeLaunch before_launch_fun,
Ts&&... args) {
static_assert( !std::is_base_of<blocking_actor, C>::value
|| has_blocking_api_flag(Os),
"C is derived type of blocking_actor but "
"blocking_api_flag is missing");
/**
* Returns a newly spawned instance of type `C` using `args...` as constructor
* arguments. The instance will be added to the job list of `host`. However,
* before the instance is launched, `before_launch_fun` will be called, e.g.,
* to join a group before the actor is running.
*/
template <class C, spawn_options Os, class BeforeLaunch, class... Ts>
intrusive_ptr<C> spawn_impl(execution_unit* host,
BeforeLaunch before_launch_fun, Ts&&... args) {
static_assert(!std::is_base_of<blocking_actor, C>::value
|| has_blocking_api_flag(Os),
"C is derived from blocking_actor but "
"spawned without blocking_api_flag");
static_assert(is_unbound(Os),
"top-level spawns cannot have monitor or link flag");
"top-level spawns cannot have monitor or link flag");
CAF_LOGF_TRACE("spawn " << detail::demangle<C>());
using scheduling_policy =
typename std::conditional<
......@@ -104,44 +112,57 @@ intrusive_ptr<C> spawn_impl(execution_unit* eu, BeforeLaunch before_launch_fun,
CAF_LOGF_DEBUG("spawned actor with ID " << ptr->id());
CAF_PUSH_AID(ptr->id());
before_launch_fun(ptr.get());
ptr->launch(has_hide_flag(Os), eu);
ptr->launch(has_hide_flag(Os), host);
return ptr;
}
/**
* Converts `scoped_actor` and pointers to actors to handles of type `actor`
* but simply forwards any other argument in the same way `std::forward` does.
*/
template <class T>
struct spawn_fwd {
static inline T& fwd(T& arg) { return arg; }
static inline const T& fwd(const T& arg) { return arg; }
static inline T&& fwd(T&& arg) { return std::move(arg); }
};
template <class T, class... Ts>
struct spawn_fwd<T(Ts...)> {
using fun_pointer = T (*)(Ts...);
static inline fun_pointer fwd(fun_pointer arg) { return arg; }
};
typename std::conditional<
is_convertible_to_actor<typename detail::rm_const_and_ref<T>::type>::value,
actor,
T&&
>::type
spawn_fwd(typename std::remove_reference<T>::type& arg) noexcept {
return static_cast<T&&>(arg);
}
template <>
struct spawn_fwd<scoped_actor> {
template <class T>
static inline actor fwd(T& arg) {
return arg;
}
};
/**
* Converts `scoped_actor` and pointers to actors to handles of type `actor`
* but simply forwards any other argument in the same way `std::forward` does.
*/
template <class T>
typename std::conditional<
is_convertible_to_actor<typename detail::rm_const_and_ref<T>::type>::value,
actor,
T&&
>::type
spawn_fwd(typename std::remove_reference<T>::type&& arg) noexcept {
static_assert(!std::is_lvalue_reference<T>::value,
"silently converting an lvalue to an rvalue");
return static_cast<T&&>(arg);
}
// forwards the arguments to spawn_impl, replacing pointers
// to actors with instances of 'actor'
/**
* Called by `spawn` when used to create a class-based actor (usually
* should not be called by users of the library). This function
* simply forwards its arguments to `spawn_impl` using `spawn_fwd`.
*/
template <class C, spawn_options Os, typename BeforeLaunch, class... Ts>
intrusive_ptr<C> spawn_class(execution_unit* eu, BeforeLaunch before_launch_fun,
Ts&&... args) {
return spawn_impl<C, Os>(
eu, before_launch_fun,
spawn_fwd<typename detail::rm_const_and_ref<Ts>::type>::fwd(
std::forward<Ts>(args))...);
intrusive_ptr<C> spawn_class(execution_unit* host,
BeforeLaunch before_launch_fun, Ts&&... args) {
return spawn_impl<C, Os>(host, before_launch_fun,
spawn_fwd<Ts>(args)...);
}
/**
* Called by `spawn` when used to create a functor-based actor (usually
* should not be called by users of the library). This function
* selects a proper implementation class and then delegates to `spawn_class`.
*/
template <spawn_options Os, typename BeforeLaunch, typename F, class... Ts>
actor spawn_functor(execution_unit* eu, BeforeLaunch cb, F fun, Ts&&... args) {
using trait = typename detail::get_callable_trait<F>::type;
......@@ -160,11 +181,11 @@ actor spawn_functor(execution_unit* eu, BeforeLaunch cb, F fun, Ts&&... args) {
constexpr bool has_blocking_base =
std::is_base_of<blocking_actor, base_class>::value;
static_assert(has_blocking_base || !has_blocking_api_flag(Os),
"blocking functor-based actors "
"need to be spawned using the blocking_api flag");
"blocking functor-based actors "
"need to be spawned using the blocking_api flag");
static_assert(!has_blocking_base || has_blocking_api_flag(Os),
"non-blocking functor-based actors "
"cannot be spawned using the blocking_api flag");
"non-blocking functor-based actors "
"cannot be spawned using the blocking_api flag");
using impl_class = typename base_class::functor_based;
return spawn_class<impl_class, Os>(eu, cb, fun, std::forward<Ts>(args)...);
}
......@@ -175,52 +196,43 @@ actor spawn_functor(execution_unit* eu, BeforeLaunch cb, F fun, Ts&&... args) {
*/
/**
* @brief Spawns an actor of type @p C.
* @param args Constructor arguments.
* @tparam Impl Subtype of {@link event_based_actor} or {@link sb_actor}.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* Returns a new actor of type `C` using `args...` as constructor
* arguments. The behavior of `spawn` can be modified by setting `Os`, e.g.,
* to opt-out of the cooperative scheduling.
*/
template <class Impl, spawn_options Os = no_spawn_options, class... Ts>
template <class C, spawn_options Os = no_spawn_options, class... Ts>
actor spawn(Ts&&... args) {
return spawn_class<Impl, Os>(nullptr, empty_before_launch_callback{},
std::forward<Ts>(args)...);
return spawn_class<C, Os>(nullptr, empty_before_launch_callback{},
std::forward<Ts>(args)...);
}
/**
* @brief Spawns a new {@link actor} that evaluates given arguments.
* @param args A functor followed by its arguments.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* Returns a new functor-based actor. The first argument must be the functor,
* the remainder of `args...` is used to invoke the functor.
* The behavior of `spawn` can be modified by setting `Os`, e.g.,
* to opt-out of the cooperative scheduling.
*/
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn(Ts&&... args) {
static_assert(sizeof...(Ts) > 0, "too few arguments provided");
return spawn_functor<Os>(nullptr, empty_before_launch_callback{},
std::forward<Ts>(args)...);
std::forward<Ts>(args)...);
}
/**
* @brief Spawns an actor of type @p C that immediately joins @p grp.
* @param args Constructor arguments.
* @tparam Impl Subtype of {@link event_based_actor} or {@link sb_actor}.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @note The spawned has joined the group before this function returns.
* Returns a new actor that immediately, i.e., before this function
* returns, joins `grp` of type `C` using `args` as constructor arguments
*/
template <class Impl, spawn_options Os = no_spawn_options, class... Ts>
template <class C, spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... args) {
return spawn_class<Impl, Os>(nullptr, group_subscriber{grp},
return spawn_class<C, Os>(nullptr, group_subscriber{grp},
std::forward<Ts>(args)...);
}
/**
* @brief Spawns a new actor that evaluates given arguments and
* immediately joins @p grp.
* @param args A functor followed by its arguments.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @note The spawned has joined the group before this function returns.
* Returns a new actor that immediately, i.e., before this function
* returns, joins `grp`. The first element of `args` must
* be the functor, the remaining arguments its arguments.
*/
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... args) {
......@@ -229,22 +241,46 @@ actor spawn_in_group(const group& grp, Ts&&... args) {
std::forward<Ts>(args)...);
}
namespace detail {
/**
* Base class for strongly typed actors using a functor-based implementation.
*/
template <class... Rs>
class functor_based_typed_actor : public typed_event_based_actor<Rs...> {
using super = typed_event_based_actor<Rs...>;
public:
using pointer = typed_event_based_actor<Rs...>*;
using behavior_type = typename super::behavior_type;
/**
* Base class for actors using given interface.
*/
using base = typed_event_based_actor<Rs...>;
/**
* Pointer to the base class.
*/
using pointer = base*;
/**
* Behavior with proper type information.
*/
using behavior_type = typename base::behavior_type;
/**
* First valid functor signature.
*/
using no_arg_fun = std::function<behavior_type()>;
/**
* Second valid functor signature.
*/
using one_arg_fun1 = std::function<behavior_type(pointer)>;
/**
* Third (and last) valid functor signature.
*/
using one_arg_fun2 = std::function<void(pointer)>;
/**
* Creates a new instance from given functor, binding `args...`
* to the functor.
*/
template <class F, class... Ts>
functor_based_typed_actor(F fun, Ts&&... args) {
using trait = typename detail::get_callable_trait<F>::type;
......@@ -260,11 +296,11 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> {
}
protected:
behavior_type make_behavior() override { return m_fun(this); }
behavior_type make_behavior() override {
return m_fun(this);
}
private:
template <class F>
void set(std::true_type, std::true_type, F&& fun) {
// behavior_type (pointer)
......@@ -302,49 +338,51 @@ class functor_based_typed_actor : public typed_event_based_actor<Rs...> {
std::bind(fun, std::forward<T0>(arg0), std::forward<Ts>(args)...));
}
// we convert any of the three accepted signatures to this one
one_arg_fun1 m_fun;
};
template <class TypedBehavior, class FirstArg>
/**
* Infers the appropriate base class for a functor-based typed actor
* from the result and the first argument of the functor.
*/
template <class Result, class FirstArg>
struct infer_typed_actor_base;
template <class... Rs, class FirstArg>
struct infer_typed_actor_base<typed_behavior<Rs...>, FirstArg> {
using type = functor_based_typed_actor<Rs...>;
};
template <class... Rs>
struct infer_typed_actor_base<void, typed_event_based_actor<Rs...>*> {
using type = functor_based_typed_actor<Rs...>;
};
} // namespace detail
/**
* @brief Spawns a typed actor of type @p C.
* @param args Constructor arguments.
* @tparam C Subtype of {@link typed_event_based_actor}.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns A {@link typed_actor} handle to the spawned actor.
* Returns a new typed actor of type `C` using `args...` as
* constructor arguments.
*/
template <class C, spawn_options Os = no_spawn_options, class... Ts>
typename detail::actor_handle_from_signature_list<typename C::signatures>::type
typename actor_handle_from_signature_list<typename C::signatures>::type
spawn_typed(Ts&&... args) {
return spawn_class<C, Os>(nullptr, empty_before_launch_callback{},
std::forward<Ts>(args)...);
std::forward<Ts>(args)...);
}
/**
* Spawns a typed actor from a functor .
*/
template <spawn_options Os, typename BeforeLaunch, typename F, class... Ts>
typename detail::infer_typed_actor_handle<
typename infer_typed_actor_handle<
typename detail::get_callable_trait<F>::result_type,
typename detail::tl_head<
typename detail::get_callable_trait<F>::arg_types>::type>::type
typename detail::get_callable_trait<F>::arg_types
>::type
>::type
spawn_typed_functor(execution_unit* eu, BeforeLaunch bl, F fun, Ts&&... args) {
using impl =
typename detail::infer_typed_actor_base<
typename infer_typed_actor_base<
typename detail::get_callable_trait<F>::result_type,
typename detail::tl_head<
typename detail::get_callable_trait<F>::arg_types
......@@ -354,19 +392,21 @@ spawn_typed_functor(execution_unit* eu, BeforeLaunch bl, F fun, Ts&&... args) {
}
/**
* @brief Spawns a typed actor from a functor.
* @param args A functor followed by its arguments.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* Returns a new typed actor from a functor. The first element
* of `args` must be the functor, the remaining arguments are used to
* invoke the functor. This function delegates its arguments to
* `spawn_typed_functor`.
*/
template <spawn_options Os = no_spawn_options, typename F, class... Ts>
typename detail::infer_typed_actor_handle<
typename infer_typed_actor_handle<
typename detail::get_callable_trait<F>::result_type,
typename detail::tl_head<
typename detail::get_callable_trait<F>::arg_types>::type>::type
typename detail::get_callable_trait<F>::arg_types
>::type
>::type
spawn_typed(F fun, Ts&&... args) {
return spawn_typed_functor<Os>(nullptr, empty_before_launch_callback{},
std::move(fun), std::forward<Ts>(args)...);
std::move(fun), std::forward<Ts>(args)...);
}
/** @} */
......
......@@ -36,13 +36,13 @@ template <class C,
typename BeforeLaunch = std::function<void (C*)>,
class... Ts>
intrusive_ptr<C> spawn_class(execution_unit* host,
BeforeLaunch before_launch_fun, Ts&&... args);
BeforeLaunch before_launch_fun, Ts&&... args);
template <spawn_options Os = no_spawn_options,
typename BeforeLaunch = void (*)(abstract_actor*),
typename F = behavior (*)(), class... Ts>
actor spawn_functor(execution_unit* host, BeforeLaunch before_launch_fun, F fun,
Ts&&... args);
Ts&&... args);
class group_subscriber {
......@@ -61,21 +61,17 @@ class group_subscriber {
};
class empty_before_launch_callback {
public:
struct empty_before_launch_callback {
template <class T>
inline void operator()(T*) const {}
inline void operator()(T*) const {
// nop
}
};
/******************************************************************************
* typed actors *
******************************************************************************/
namespace detail { // some utility
template <class TypedBehavior, class FirstArg>
struct infer_typed_actor_handle;
......@@ -83,14 +79,12 @@ struct infer_typed_actor_handle;
template <class... Rs, class FirstArg>
struct infer_typed_actor_handle<typed_behavior<Rs...>, FirstArg> {
using type = typed_actor<Rs...>;
};
// infer actor type from first argument if result type is void
template <class... Rs>
struct infer_typed_actor_handle<void, typed_event_based_actor<Rs...>*> {
using type = typed_actor<Rs...>;
};
template <class SignatureList>
......@@ -99,16 +93,15 @@ struct actor_handle_from_signature_list;
template <class... Rs>
struct actor_handle_from_signature_list<detail::type_list<Rs...>> {
using type = typed_actor<Rs...>;
};
} // namespace detail
template <spawn_options Os, typename BeforeLaunch, typename F, class... Ts>
typename detail::infer_typed_actor_handle<
typename infer_typed_actor_handle<
typename detail::get_callable_trait<F>::result_type,
typename detail::tl_head<
typename detail::get_callable_trait<F>::arg_types>::type>::type
typename detail::get_callable_trait<F>::arg_types
>::type
>::type
spawn_typed_functor(execution_unit*, BeforeLaunch bl, F fun, Ts&&... args);
} // namespace caf
......
......@@ -28,7 +28,7 @@ namespace caf {
*/
/**
* @brief Stores options passed to the @p spawn function family.
* Stores options passed to the `spawn` function family.
*/
#ifdef CAF_DOCUMENTATION
class spawn_options {};
......@@ -46,7 +46,7 @@ enum class spawn_options : int {
#endif
/**
* @brief Concatenates two {@link spawn_options}.
* Concatenates two {@link spawn_options}.
* @relates spawn_options
*/
constexpr spawn_options operator+(const spawn_options& lhs,
......@@ -56,48 +56,47 @@ constexpr spawn_options operator+(const spawn_options& lhs,
}
/**
* @brief Denotes default settings.
* Denotes default settings.
*/
constexpr spawn_options no_spawn_options = spawn_options::no_flags;
/**
* @brief Causes @p spawn to call <tt>self->monitor(...)</tt> immediately
* after the new actor was spawned.
* Causes `spawn` to call `self->monitor(...) immediately
* after the new actor was spawned.
*/
constexpr spawn_options monitored = spawn_options::monitor_flag;
/**
* @brief Causes @p spawn to call <tt>self->link_to(...)</tt> immediately
* after the new actor was spawned.
* Causes `spawn` to call `self->link_to(...) immediately
* after the new actor was spawned.
*/
constexpr spawn_options linked = spawn_options::link_flag;
/**
* @brief Causes the new actor to opt out of the cooperative scheduling.
* Causes the new actor to opt out of the cooperative scheduling.
*/
constexpr spawn_options detached = spawn_options::detach_flag;
/**
* @brief Causes the runtime to ignore the new actor in
* {@link await_all_actors_done()}.
* Causes the runtime to ignore the new actor in `await_all_actors_done()`.
*/
constexpr spawn_options hidden = spawn_options::hide_flag;
/**
* @brief Causes the new actor to opt in to the blocking API,
* i.e., the actor uses a context-switching or thread-based backend
* instead of the default event-based implementation.
* Causes the new actor to opt in to the blocking API,
* i.e., the actor uses a context-switching or thread-based backend
* instead of the default event-based implementation.
*/
constexpr spawn_options blocking_api = spawn_options::blocking_api_flag;
/**
* @brief Causes the new actor to evaluate message priorities.
* Causes the new actor to evaluate message priorities.
* @note This implicitly causes the actor to run in its own thread.
*/
constexpr spawn_options priority_aware = spawn_options::priority_aware_flag;
/**
* @brief Checks wheter @p haystack contains @p needle.
* Checks wheter `haystack` contains `needle`.
* @relates spawn_options
*/
constexpr bool has_spawn_option(spawn_options haystack, spawn_options needle) {
......@@ -105,7 +104,7 @@ constexpr bool has_spawn_option(spawn_options haystack, spawn_options needle) {
}
/**
* @brief Checks wheter the {@link detached} flag is set in @p opts.
* Checks wheter the {@link detached} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_detach_flag(spawn_options opts) {
......@@ -113,7 +112,7 @@ constexpr bool has_detach_flag(spawn_options opts) {
}
/**
* @brief Checks wheter the {@link priority_aware} flag is set in @p opts.
* Checks wheter the {@link priority_aware} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_priority_aware_flag(spawn_options opts) {
......@@ -121,7 +120,7 @@ constexpr bool has_priority_aware_flag(spawn_options opts) {
}
/**
* @brief Checks wheter the {@link hidden} flag is set in @p opts.
* Checks wheter the {@link hidden} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_hide_flag(spawn_options opts) {
......@@ -129,7 +128,7 @@ constexpr bool has_hide_flag(spawn_options opts) {
}
/**
* @brief Checks wheter the {@link linked} flag is set in @p opts.
* Checks wheter the {@link linked} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_link_flag(spawn_options opts) {
......@@ -137,7 +136,7 @@ constexpr bool has_link_flag(spawn_options opts) {
}
/**
* @brief Checks wheter the {@link monitored} flag is set in @p opts.
* Checks wheter the {@link monitored} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_monitor_flag(spawn_options opts) {
......@@ -145,7 +144,7 @@ constexpr bool has_monitor_flag(spawn_options opts) {
}
/**
* @brief Checks wheter the {@link blocking_api} flag is set in @p opts.
* Checks wheter the {@link blocking_api} flag is set in `opts`.
* @relates spawn_options
*/
constexpr bool has_blocking_api_flag(spawn_options opts) {
......
......@@ -91,9 +91,9 @@ void replace_all(std::string& str,
}
/**
* @brief Compares two values by using @p operator== unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
* Compares two values by using `operator==` unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
*/
template <class T, typename U>
typename std::enable_if<
......
......@@ -33,46 +33,46 @@
namespace caf {
/**
* @brief Sent to all links when an actor is terminated.
* Sent to all links when an actor is terminated.
* @note This message can be handled manually by calling
* {@link local_actor::trap_exit(true) local_actor::trap_exit(bool)}
* and is otherwise handled implicitly by the runtime system.
* `local_actor::trap_exit(true)` and is otherwise handled
* implicitly by the runtime system.
*/
struct exit_msg {
/**
* @brief The source of this message, i.e., the terminated actor.
* The source of this message, i.e., the terminated actor.
*/
actor_addr source;
/**
* @brief The exit reason of the terminated actor.
* The exit reason of the terminated actor.
*/
uint32_t reason;
};
/**
* @brief Sent to all actors monitoring an actor when it is terminated.
* Sent to all actors monitoring an actor when it is terminated.
*/
struct down_msg {
/**
* @brief The source of this message, i.e., the terminated actor.
* The source of this message, i.e., the terminated actor.
*/
actor_addr source;
/**
* @brief The exit reason of the terminated actor.
* The exit reason of the terminated actor.
*/
uint32_t reason;
};
/**
* @brief Sent whenever a terminated actor receives a synchronous request.
* Sent whenever a terminated actor receives a synchronous request.
*/
struct sync_exited_msg {
/**
* @brief The source of this message, i.e., the terminated actor.
* The source of this message, i.e., the terminated actor.
*/
actor_addr source;
/**
* @brief The exit reason of the terminated actor.
* The exit reason of the terminated actor.
*/
uint32_t reason;
};
......@@ -96,11 +96,11 @@ operator!=(const T& lhs, const T& rhs) {
}
/**
* @brief Sent to all members of a group when it goes offline.
* Sent to all members of a group when it goes offline.
*/
struct group_down_msg {
/**
* @brief The source of this message, i.e., the now unreachable group.
* The source of this message, i.e., the now unreachable group.
*/
group source;
};
......@@ -114,8 +114,7 @@ inline bool operator!=(const group_down_msg& lhs, const group_down_msg& rhs) {
}
/**
* @brief Sent whenever a timeout occurs during a synchronous send.
*
* Sent whenever a timeout occurs during a synchronous send.
* This system message does not have any fields, because the message ID
* sent alongside this message identifies the matching request that timed out.
*/
......@@ -136,12 +135,12 @@ inline bool operator!=(const sync_timeout_msg&, const sync_timeout_msg&) {
}
/**
* @brief Signalizes a timeout event.
* Signalizes a timeout event.
* @note This message is handled implicitly by the runtime system.
*/
struct timeout_msg {
/**
* @brief Actor-specific timeout ID.
* Actor-specific timeout ID.
*/
uint32_t timeout_id;
};
......
......@@ -85,8 +85,7 @@ inline std::string to_string(const any& what) {
*/
/**
* @brief Converts @p e to a string including the demangled type of e
* and @p e.what().
* Converts `e` to a string including the demangled type of `e` and `e.what()`.
*/
std::string to_verbose_string(const std::exception& e);
......
......@@ -39,8 +39,8 @@ template <class... Rs>
class typed_event_based_actor;
/**
* @brief Identifies a strongly typed actor.
* @tparam Rs Interface as @p replies_to<...>::with<...> parameter pack.
* Identifies a strongly typed actor.
* @tparam Rs Interface as `replies_to<`...>::with<...> parameter pack.
*/
template <class... Rs>
class typed_actor
......@@ -61,23 +61,23 @@ class typed_actor
public:
/**
* @brief Identifies the behavior type actors of this kind use
* for their behavior stack.
* Identifies the behavior type actors of this kind use
* for their behavior stack.
*/
using behavior_type = typed_behavior<Rs...>;
/**
* @brief Identifies pointers to instances of this kind of actor.
* Identifies pointers to instances of this kind of actor.
*/
using pointer = typed_event_based_actor<Rs...>*;
/**
* @brief Identifies the base class for this kind of actor.
* Identifies the base class for this kind of actor.
*/
using base = typed_event_based_actor<Rs...>;
/**
* @brief Stores the interface of the actor as type list.
* Stores the interface of the actor as type list.
*/
using interface = detail::type_list<Rs...>;
......@@ -112,7 +112,7 @@ class typed_actor
}
/**
* @brief Queries the address of the stored actor.
* Queries the address of the stored actor.
*/
actor_addr address() const {
return m_ptr ? m_ptr->address() : actor_addr{};
......
......@@ -28,11 +28,11 @@
namespace caf {
namespace detail {
template <class... Rs>
class functor_based_typed_actor;
namespace detail {
// converts a list of replies_to<...>::with<...> elements to a list of
// lists containing the replies_to<...> half only
template <class List>
......@@ -145,7 +145,7 @@ class typed_behavior {
template <class, class, class>
friend class mixin::behavior_stack_based_impl;
template <class...>
friend class detail::functor_based_typed_actor;
friend class functor_based_typed_actor;
public:
typed_behavior(typed_behavior&&) = default;
typed_behavior(const typed_behavior&) = default;
......@@ -172,13 +172,13 @@ class typed_behavior {
}
/**
* @brief Invokes the timeout callback.
* Invokes the timeout callback.
*/
inline void handle_timeout() { m_bhvr.handle_timeout(); }
/**
* @brief Returns the duration after which receives using
* this behavior should time out.
* Returns the duration after which receives using
* this behavior should time out.
*/
inline const duration& timeout() const { return m_bhvr.timeout(); }
......
......@@ -31,13 +31,10 @@
namespace caf {
/**
* @brief A cooperatively scheduled, event-based actor implementation
* with strong type checking.
*
* This is the recommended base class for user-defined actors and is used
* implicitly when spawning typed, functor-based actors without the
* {@link blocking_api} flag.
*
* A cooperatively scheduled, event-based actor implementation with strong type
* checking. This is the recommended base class for user-defined actors and is
* used implicitly when spawning typed, functor-based actors without the
* `blocking_api` flag.
* @extends local_actor
*/
template <class... Rs>
......@@ -46,10 +43,10 @@ class typed_event_based_actor
mixin::mailbox_based,
mixin::behavior_stack_based<typed_behavior<Rs...>>::template impl,
mixin::sync_sender<nonblocking_response_handle_tag>::template impl> {
public:
typed_event_based_actor() : m_initialized(false) {}
typed_event_based_actor() : m_initialized(false) {
// nop
}
using signatures = detail::type_list<Rs...>;
......@@ -60,11 +57,8 @@ class typed_event_based_actor
}
protected:
virtual behavior_type make_behavior() = 0;
bool m_initialized;
};
} // namespace caf
......
......@@ -74,15 +74,15 @@ uniform_value make_uniform_value(const uniform_type_info* ti, Ts&&... args) {
/**
* @defgroup TypeSystem Platform-independent type system.
*
* @p libcaf provides a fully network transparent communication between
* `libcaf` provides a fully network transparent communication between
* actors. Thus, it needs to serialize and deserialize message objects.
* Unfortunately, this is not possible using the C++ RTTI system.
*
* Since it is not possible to extend <tt>std::type_info</tt>, @p libcaf
* Since it is not possible to extend `std::type_info, `libcaf`
* uses its own type abstraction:
* {@link caf::uniform_type_info uniform_type_info}.
*
* Unlike <tt>std::type_info::name()</tt>,
* Unlike `std::type_info::name(),
* {@link caf::uniform_type_info::name() uniform_type_info::name()}
* is guaranteed to return the same name on all supported platforms.
* Furthermore, it allows to create an instance of a type by name:
......@@ -121,10 +121,10 @@ uniform_value make_uniform_value(const uniform_type_info* ti, Ts&&... args) {
* what(): uniform_type_info::by_type_info(): foo is an unknown typeid name
* </tt>
*
* The user-defined struct @p foo is not known by the type system.
* Thus, @p foo cannot be serialized and is rejected.
* The user-defined struct `foo` is not known by the type system.
* Thus, `foo` cannot be serialized and is rejected.
*
* Fortunately, there is an easy way to add @p foo the type system,
* Fortunately, there is an easy way to add `foo` the type system,
* without needing to implement serialize/deserialize by yourself:
*
* @code
......@@ -147,20 +147,19 @@ uniform_value make_uniform_value(const uniform_type_info* ti, Ts&&... args) {
/**
* @ingroup TypeSystem
* @brief Provides a platform independent type name and a (very primitive)
* kind of reflection in combination with {@link caf::object object}.
*
* Provides a platform independent type name and a (very primitive)
* kind of reflection in combination with {@link caf::object object}.
* The platform independent name is equal to the "in-sourcecode-name"
* with a few exceptions:
* - @c std::string is named @c \@str
* - @c std::u16string is named @c \@u16str
* - @c std::u32string is named @c \@u32str
* - @c integers are named <tt>\@(i|u)$size</tt>\n
* e.g.: @c \@i32 is a 32 bit signed integer; @c \@u16
* - std::string is named \@str
* - std::u16string is named \@u16str
* - std::u32string is named \@u32str
* - integers are named `\@(i|u)$size\n
* e.g.: \@i32 is a 32 bit signed integer; \@u16
* is a 16 bit unsigned integer
* - the <em>anonymous namespace</em> is named @c \@_ \n
* e.g.: <tt>namespace { class foo { }; }</tt> is mapped to
* @c \@_::foo
* - the <em>anonymous namespace</em> is named \@_ \n
* e.g.: `namespace { class foo { }; } is mapped to
* \@_::foo
*/
class uniform_type_info {
......@@ -180,65 +179,65 @@ class uniform_type_info {
virtual ~uniform_type_info();
/**
* @brief Get instance by uniform name.
* Get instance by uniform name.
* @param uniform_name The internal name for a type.
* @returns The instance associated to @p uniform_name.
* @throws std::runtime_error if no type named @p uniform_name was found.
* @returns The instance associated to `uniform_name`.
* @throws std::runtime_error if no type named `uniform_name` was found.
*/
static const uniform_type_info* from(const std::string& uniform_name);
/**
* @brief Get instance by std::type_info.
* Get instance by std::type_info.
* @param tinfo A STL RTTI object.
* @returns An instance describing the same type as @p tinfo.
* @throws std::runtime_error if @p tinfo is not an announced type.
* @returns An instance describing the same type as `tinfo`.
* @throws std::runtime_error if `tinfo` is not an announced type.
*/
static const uniform_type_info* from(const std::type_info& tinfo);
/**
* @brief Get all instances.
* Get all instances.
* @returns A vector with all known (announced) instances.
*/
static std::vector<const uniform_type_info*> instances();
/**
* @brief Creates a copy of @p other.
* Creates a copy of `other`.
*/
virtual uniform_value
create(const uniform_value& other = uniform_value{}) const = 0;
/**
* @brief Deserializes an object of this type from @p source.
* Deserializes an object of this type from `source`.
*/
uniform_value deserialize(deserializer* source) const;
/**
* @brief Get the internal name for this type.
* Get the internal name for this type.
* @returns A string describing the internal type name.
*/
virtual const char* name() const = 0;
/**
* @brief Determines if this uniform_type_info describes the same
* type than @p tinfo.
* @returns @p true if @p tinfo describes the same type as @p this.
* Determines if this uniform_type_info describes the same
* type than `tinfo`.
* @returns `true` if `tinfo` describes the same type as `this`.
*/
virtual bool equal_to(const std::type_info& tinfo) const = 0;
/**
* @brief Compares two instances of this type.
* Compares two instances of this type.
* @param instance1 Left hand operand.
* @param instance2 Right hand operand.
* @returns @p true if <tt>*instance1 == *instance2</tt>.
* @pre @p instance1 and @p instance2 have the type of @p this.
* @returns `true` if `*instance1 == *instance2.
* @pre `instance1` and `instance2` have the type of `this`.
*/
virtual bool equals(const void* instance1, const void* instance2) const = 0;
/**
* @brief Serializes @p instance to @p sink.
* Serializes `instance` to `sink`.
* @param instance Instance of this type.
* @param sink Target data sink.
* @pre @p instance has the type of @p this.
* @pre `instance` has the type of `this`.
* @throws std::ios_base::failure Thrown when the underlying serialization
* layer is unable to serialize the data,
* e.g., when exceeding maximum buffer
......@@ -247,15 +246,15 @@ class uniform_type_info {
virtual void serialize(const void* instance, serializer* sink) const = 0;
/**
* @brief Deserializes @p instance from @p source.
* Deserializes `instance` from `source`.
* @param instance Instance of this type.
* @param source Data source.
* @pre @p instance has the type of @p this.
* @pre `instance` has the type of `this`.
*/
virtual void deserialize(void* instance, deserializer* source) const = 0;
/**
* @brief Returns @p instance encapsulated as an @p message.
* Returns `instance` encapsulated as an `message`.
*/
virtual message as_message(void* instance) const = 0;
......
......@@ -64,10 +64,10 @@ template <class T, typename U>
struct is_equal_int_type<T, U, false> : std::false_type { };
/**
* @brief Compares @p T to @p U und evaluates to @p true_type if either
* <tt>T == U</tt> or if T and U are both integral types of the
* same size and signedness. This works around the issue that
* <tt>uint8_t != unsigned char</tt> on some compilers.
* Compares `T` to `U` und evaluates to `true_type` if either
* `T == U or if T and U are both integral types of the
* same size and signedness. This works around the issue that
* `uint8_t != unsigned char on some compilers.
*/
template <class T, typename U>
struct is_same_ish : std::conditional<
......@@ -77,8 +77,7 @@ struct is_same_ish : std::conditional<
>::type { };
/**
* @brief A variant represents always a valid value of one of
* the types @p Ts.
* A variant represents always a valid value of one of the types `Ts...`.
*/
template <class... Ts>
class variant {
......
......@@ -28,8 +28,7 @@
namespace caf {
/**
* @brief Denotes the position of {@link caf::anything anything} in a
* template parameter pack.
* Denotes the position of `anything` in a template parameter pack.
*/
enum class wildcard_position {
nil,
......@@ -37,28 +36,26 @@ enum class wildcard_position {
leading,
in_between,
multiple
};
/**
* @brief Gets the position of {@link caf::anything anything} from the
* type list @p Types.
* @tparam A template parameter pack as {@link caf::detail::type_list
* type_list}.
* Gets the position of `anything` from the type list `Types`.
*/
template <class Types>
constexpr wildcard_position get_wildcard_position() {
return detail::tl_count<Types, is_anything>::value > 1 ?
wildcard_position::multiple :
(detail::tl_count<Types, is_anything>::value == 1 ?
(std::is_same<typename detail::tl_head<Types>::type,
anything>::value ?
wildcard_position::leading :
(std::is_same<typename detail::tl_back<Types>::type,
anything>::value ?
wildcard_position::trailing :
wildcard_position::in_between)) :
wildcard_position::nil);
return detail::tl_count<Types, is_anything>::value > 1
? wildcard_position::multiple
: (detail::tl_count<Types, is_anything>::value == 1
? (std::is_same<
typename detail::tl_head<Types>::type, anything
>::value
? wildcard_position::leading
: (std::is_same<
typename detail::tl_back<Types>::type, anything
>::value
? wildcard_position::trailing
: wildcard_position::in_between))
: wildcard_position::nil);
}
} // namespace caf
......
......@@ -38,10 +38,6 @@ namespace caf {
template <class... Ts>
class cow_tuple;
/**
* @ingroup CopyOnWrite
* @brief A fixed-length copy-on-write tuple.
*/
template <class Head, class... Tail>
class cow_tuple<Head, Tail...> {
......@@ -67,10 +63,6 @@ class cow_tuple<Head, Tail...> {
// nop
}
/**
* @brief Initializes the cow_tuple with @p args.
* @param args Initialization values.
*/
template <class... Ts>
cow_tuple(Head arg, Ts&&... args)
: m_vals(new data_type(std::move(arg), std::forward<Ts>(args)...)) {
......@@ -82,31 +74,18 @@ class cow_tuple<Head, Tail...> {
cow_tuple& operator=(cow_tuple&&) = default;
cow_tuple& operator=(const cow_tuple&) = default;
/**
* @brief Gets the size of this cow_tuple.
*/
inline size_t size() const {
return sizeof...(Tail) + 1;
}
/**
* @brief Gets a const pointer to the element at position @p p.
*/
inline const void* at(size_t p) const {
return m_vals->at(p);
}
/**
* @brief Gets a mutable pointer to the element at position @p p.
*/
inline void* mutable_at(size_t p) {
return m_vals->mutable_at(p);
}
/**
* @brief Gets {@link uniform_type_info uniform type information}
* of the element at position @p p.
*/
inline const uniform_type_info* type_at(size_t p) const {
return m_vals->type_at(p);
}
......@@ -139,14 +118,6 @@ class cow_tuple<Head, Tail...> {
};
/**
* @ingroup CopyOnWrite
* @brief Gets a const-reference to the <tt>N</tt>th element of @p tup.
* @param tup The cow_tuple object.
* @returns A const-reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @relates cow_tuple
*/
template <size_t N, class... Ts>
const typename detail::type_at<N, Ts...>::type&
get(const cow_tuple<Ts...>& tup) {
......@@ -154,15 +125,6 @@ get(const cow_tuple<Ts...>& tup) {
return *reinterpret_cast<const result_type*>(tup.at(N));
}
/**
* @ingroup CopyOnWrite
* @brief Gets a reference to the <tt>N</tt>th element of @p tup.
* @param tup The cow_tuple object.
* @returns A reference of type T, whereas T is the type of the
* <tt>N</tt>th element of @p tup.
* @note Detaches @p tup if there are two or more references to the cow_tuple.
* @relates cow_tuple
*/
template <size_t N, class... Ts>
typename detail::type_at<N, Ts...>::type&
get_ref(cow_tuple<Ts...>& tup) {
......@@ -170,13 +132,6 @@ get_ref(cow_tuple<Ts...>& tup) {
return *reinterpret_cast<result_type*>(tup.mutable_at(N));
}
/**
* @ingroup ImplicitConversion
* @brief Creates a new cow_tuple from @p args.
* @param args Values for the cow_tuple elements.
* @returns A cow_tuple object containing the values @p args.
* @relates cow_tuple
*/
template <class... Ts>
cow_tuple<typename detail::strip_and_convert<Ts>::type...>
make_cow_tuple(Ts&&... args) {
......
......@@ -50,8 +50,8 @@ string_proj extract_longopt_arg(const std::string& prefix) {
}
/**
* @brief Right-hand side of a match expression for a program option
* reading an argument of type @p T.
* Right-hand side of a match expression for a program option
* reading an argument of type `T`.
*/
template <class T>
detail::rd_arg_functor<T> rd_arg(T& storage) {
......@@ -59,8 +59,8 @@ detail::rd_arg_functor<T> rd_arg(T& storage) {
}
/**
* @brief Right-hand side of a match expression for a program option
* adding an argument of type @p T to @p storage.
* Right-hand side of a match expression for a program option
* adding an argument of type `T` to `storage`.
*/
template <class T>
detail::add_arg_functor<T> add_arg(std::vector<T>& storage) {
......@@ -72,7 +72,7 @@ inline std::function<void()> set_flag(bool& storage) {
}
/**
* @brief Stores a help text along with the number of expected arguments.
* Stores a help text along with the number of expected arguments.
*/
struct option_info {
std::string help_text;
......@@ -80,7 +80,7 @@ struct option_info {
};
/**
* @brief Stores a help text for program options with option groups.
* Stores a help text for program options with option groups.
*/
using options_description =
std::map<
......@@ -98,7 +98,7 @@ using opt_rvalue_builder =
using opt0_rvalue_builder = decltype(on(std::string{}) || on(std::string{}));
/**
* @brief Left-hand side of a match expression for a program option with
* Left-hand side of a match expression for a program option with
* one argument.
*/
inline opt_rvalue_builder on_opt1(char short_opt,
......@@ -135,8 +135,7 @@ inline opt_rvalue_builder on_opt1(char short_opt,
}
/**
* @brief Left-hand side of a match expression for a program option with
* no argument.
* Left-hand side of a match expression for a program option with no argument.
*/
inline opt0_rvalue_builder on_opt0(char short_opt,
std::string long_opt,
......@@ -155,7 +154,7 @@ inline opt0_rvalue_builder on_opt0(char short_opt,
}
/**
* @brief Returns a function that prints the help text of @p desc to @p out.
* Returns a function that prints the help text of `desc` to `out`.
*/
std::function<void()> print_desc(options_description* desc,
std::ostream& out = std::cout) {
......@@ -194,8 +193,8 @@ std::function<void()> print_desc(options_description* desc,
}
/**
* @brief Returns a function that prints the help text of @p desc to @p out
* and then calls <tt>exit(exit_reason)</tt>.
* Returns a function that prints the help text of `desc` to `out`
* and then calls `exit(exit_reason).
*/
inline std::function<void()> print_desc_and_exit(options_description* desc,
std::ostream& out = std::cout,
......
......@@ -63,7 +63,9 @@ bool actor_proxy::anchor::try_expire() {
actor_proxy::~actor_proxy() {}
actor_proxy::actor_proxy(actor_id aid, node_id nid)
: super(aid, nid), m_anchor(new anchor{this}) {}
: abstract_actor(aid, nid), m_anchor(new anchor{this}) {
// nop
}
void actor_proxy::request_deletion() {
if (m_anchor->try_expire()) delete this;
......
......@@ -65,7 +65,9 @@ class continuation_decorator : public detail::behavior_impl {
};
} // namespace <anonymous>
behavior::behavior(const message_handler& fun) : m_impl(fun.m_impl) {}
behavior::behavior(const message_handler& mh) : m_impl(mh.as_behavior_impl()) {
// nop
}
behavior behavior::add_continuation(continuation_fun fun) {
return behavior::impl_ptr{
......
......@@ -141,7 +141,7 @@ class local_broker : public event_based_actor {
CAF_LOGC_TRACE("caf::local_broker", "init$FORWARD",
CAF_TARG(what, to_string));
// local forwarding
m_group->send_all_subscribers(last_sender(), what, m_host);
m_group->send_all_subscribers(last_sender(), what, host());
// forward to all acquaintances
send_to_acquaintances(what);
},
......@@ -175,7 +175,7 @@ class local_broker : public event_based_actor {
<< m_acquaintances.size() << " acquaintances; "
<< CAF_TSARG(sender) << ", " << CAF_TSARG(what));
for (auto& acquaintance : m_acquaintances) {
acquaintance->enqueue(sender, message_id::invalid, what, m_host);
acquaintance->enqueue(sender, message_id::invalid, what, host());
}
}
......@@ -253,7 +253,7 @@ class proxy_broker : public event_based_actor {
behavior make_behavior() {
return (others() >> [=] {
m_group->send_all_subscribers(last_sender(), last_dequeued(),
m_host);
host());
});
}
......
......@@ -114,7 +114,7 @@ void local_actor::reply_message(message&& what) {
send_tuple(actor_cast<channel>(whom), std::move(what));
} else if (!id.is_answered()) {
auto ptr = actor_cast<actor>(whom);
ptr->enqueue(address(), id.response_id(), std::move(what), m_host);
ptr->enqueue(address(), id.response_id(), std::move(what), host());
id.mark_as_answered();
}
}
......@@ -124,7 +124,7 @@ void local_actor::forward_message(const actor& dest, message_priority prio) {
auto id = (prio == message_priority::high) ?
m_current_node->mid.with_high_priority() :
m_current_node->mid.with_normal_priority();
dest->enqueue(m_current_node->sender, id, m_current_node->msg, m_host);
dest->enqueue(m_current_node->sender, id, m_current_node->msg, host());
// treat this message as asynchronous message from now on
m_current_node->mid = message_id::invalid;
}
......@@ -134,7 +134,7 @@ void local_actor::send_tuple(message_priority prio, const channel& dest,
if (!dest) return;
message_id id;
if (prio == message_priority::high) id = id.with_high_priority();
dest->enqueue(address(), id, std::move(what), m_host);
dest->enqueue(address(), id, std::move(what), host());
}
void local_actor::send_exit(const actor_addr& whom, uint32_t reason) {
......@@ -191,7 +191,7 @@ message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
}
auto nri = new_request_id();
if (mp == message_priority::high) nri = nri.with_high_priority();
dest->enqueue(address(), nri, std::move(what), m_host);
dest->enqueue(address(), nri, std::move(what), host());
auto rri = nri.response_id();
detail::singletons::get_scheduling_coordinator()->delayed_send(
rtime, address(), this, rri, make_message(sync_timeout_msg{}));
......@@ -208,7 +208,7 @@ message_id local_actor::sync_send_tuple_impl(message_priority mp,
}
auto nri = new_request_id();
if (mp == message_priority::high) nri = nri.with_high_priority();
dest->enqueue(address(), nri, std::move(what), m_host);
dest->enqueue(address(), nri, std::move(what), host());
return nri.response_id();
}
......
......@@ -26,7 +26,7 @@ namespace caf {
namespace io {
/**
* @brief Generic handle type for managing incoming connections.
* Generic handle type for managing incoming connections.
*/
class accept_handle : public handle<accept_handle> {
......
......@@ -32,8 +32,7 @@ namespace io {
namespace basp {
/**
* @brief The header of a Binary Actor System Protocol (BASP) message.
*
* The header of a Binary Actor System Protocol (BASP) message.
* A BASP header consists of a routing part, i.e., source and
* destination, as well as an operation and operation data. Several
* message types consist of only a header.
......@@ -49,13 +48,13 @@ struct header {
};
/**
* @brief The current BASP version. Different BASP versions will not
* be able to exchange messages.
* The current BASP version. Different BASP versions will not
* be able to exchange messages.
*/
constexpr uint64_t version = 1;
/**
* @brief Size of a BASP header in serialized form
* Size of a BASP header in serialized form
*/
constexpr size_t header_size =
node_id::host_id_size * 2 + sizeof(uint32_t) * 2 +
......@@ -80,14 +79,13 @@ inline bool nonzero(T aid) {
}
/**
* @brief Send from server, i.e., the node with a published actor, to client,
* i.e., node that initiates a new connection using remote_actor().
*
* @param source_node ID of server
* @param dest_node invalid
* @param source_actor Optional: ID of published actor
* @param dest_actor 0
* @param payload_len Optional: size of actor id + interface definition
* Send from server, i.e., the node with a published actor, to client,
* i.e., node that initiates a new connection using remote_actor().
* @param source_node ID of server
* @param dest_node invalid
* @param source_actor Optional: ID of published actor
* @param dest_actor 0
* @param payload_len Optional: size of actor id + interface definition
* @param operation_data BASP version of the server
*/
constexpr uint32_t server_handshake = 0x00;
......@@ -102,14 +100,13 @@ inline bool server_handshake_valid(const header& hdr) {
}
/**
* @brief Send from client to server after it has successfully received the
* server_handshake to establish the connection.
*
* @param source_node ID of client
* @param dest_node ID of server
* @param source_actor 0
* @param dest_actor 0
* @param payload_len 0
* Send from client to server after it has successfully received the
* server_handshake to establish the connection.
* @param source_node ID of client
* @param dest_node ID of server
* @param source_actor 0
* @param dest_actor 0
* @param payload_len 0
* @param operation_data 0
*/
constexpr uint32_t client_handshake = 0x01;
......@@ -125,14 +122,13 @@ inline bool client_handshake_valid(const header& hdr) {
}
/**
* @brief Transmits a message from source_node:source_actor to
* dest_node:dest_actor.
*
* @param source_node ID of sending node (invalid in case of anon_send)
* @param dest_node ID of receiving node
* @param source_actor ID of sending actor (invalid in case of anon_send)
* @param dest_actor ID of receiving actor, must not be invalid
* @param payload_len size of serialized message object, must not be 0
* Transmits a message from source_node:source_actor to
* dest_node:dest_actor.
* @param source_node ID of sending node (invalid in case of anon_send)
* @param dest_node ID of receiving node
* @param source_actor ID of sending actor (invalid in case of anon_send)
* @param dest_actor ID of receiving actor, must not be invalid
* @param payload_len size of serialized message object, must not be 0
* @param operation_data message ID (0 for asynchronous messages)
*/
constexpr uint32_t dispatch_message = 0x02;
......@@ -144,16 +140,15 @@ inline bool dispatch_message_valid(const header& hdr) {
}
/**
* @brief Informs the receiving node that the sending node has created a proxy
* instance for one of its actors. Causes the receiving node to attach
* a functor to the actor that triggers a kill_proxy_instance
* message on termination.
*
* @param source_node ID of sending node
* @param dest_node ID of receiving node
* @param source_actor 0
* @param dest_actor ID of monitored actor
* @param payload_len 0
* Informs the receiving node that the sending node has created a proxy
* instance for one of its actors. Causes the receiving node to attach
* a functor to the actor that triggers a kill_proxy_instance
* message on termination.
* @param source_node ID of sending node
* @param dest_node ID of receiving node
* @param source_actor 0
* @param dest_actor ID of monitored actor
* @param payload_len 0
* @param operation_data 0
*/
constexpr uint32_t announce_proxy_instance = 0x03;
......@@ -169,14 +164,13 @@ inline bool announce_proxy_instance_valid(const header& hdr) {
}
/**
* @brief Informs the receiving node that it has a proxy for an actor
* that has been terminated.
*
* @param source_node ID of sending node
* @param dest_node ID of receiving node
* @param source_actor ID of monitored actor
* @param dest_actor 0
* @param payload_len 0
* Informs the receiving node that it has a proxy for an actor
* that has been terminated.
* @param source_node ID of sending node
* @param dest_node ID of receiving node
* @param source_actor ID of monitored actor
* @param dest_actor 0
* @param payload_len 0
* @param operation_data exit reason (uint32)
*/
constexpr uint32_t kill_proxy_instance = 0x04;
......@@ -192,7 +186,7 @@ inline bool kill_proxy_instance_valid(const header& hdr) {
}
/**
* @brief Checks whether given header is valid.
* Checks whether given header is valid.
*/
inline bool valid(header& hdr) {
switch (hdr.operation) {
......
......@@ -38,7 +38,7 @@ namespace caf {
namespace io {
/**
* @brief A broker implementation for the Binary Actor System Protocol (BASP).
* A broker implementation for the Binary Actor System Protocol (BASP).
*/
class basp_broker : public broker, public actor_namespace::backend {
......
......@@ -47,13 +47,12 @@ class middleman;
using broker_ptr = intrusive_ptr<broker>;
/**
* @brief A broker mediates between an actor system
* and other components in the network.
* A broker mediates between actor systems and other components in the network.
* @extends local_actor
*/
class broker : public extend<local_actor>::
with<mixin::behavior_stack_based<behavior>::impl>,
public spawn_as_is {
with<mixin::behavior_stack_based<behavior>::impl>,
public spawn_as_is {
friend class policy::sequential_invoke;
......@@ -100,17 +99,17 @@ class broker : public extend<local_actor>::
scribe(broker* parent, connection_handle hdl);
/**
* @brief Implicitly starts the read loop on first call.
* Implicitly starts the read loop on first call.
*/
virtual void configure_read(receive_policy::config config) = 0;
/**
* @brief Grants access to the output buffer.
* Grants access to the output buffer.
*/
virtual buffer_type& wr_buf() = 0;
/**
* @brief Flushes the output buffer, i.e., sends the content of
* Flushes the output buffer, i.e., sends the content of
* the buffer via the network.
*/
virtual void flush() = 0;
......@@ -190,29 +189,29 @@ class broker : public extend<local_actor>::
~broker();
/**
* @brief Modifies the receive policy for given connection.
* Modifies the receive policy for given connection.
* @param hdl Identifies the affected connection.
* @param config Contains the new receive policy.
*/
void configure_read(connection_handle hdl, receive_policy::config config);
/**
* @brief Returns the write buffer for given connection.
* Returns the write buffer for given connection.
*/
buffer_type& wr_buf(connection_handle hdl);
/**
* @brief Writes @p data into the buffer for given connection.
* Writes `data` into the buffer for given connection.
*/
void write(connection_handle hdl, size_t data_size, const void* data);
/**
* @brief Sends the content of the buffer for given connection.
* Sends the content of the buffer for given connection.
*/
void flush(connection_handle hdl);
/**
* @brief Returns the number of open connections.
* Returns the number of open connections.
*/
inline size_t num_connections() const { return m_scribes.size(); }
......@@ -363,18 +362,18 @@ class broker : public extend<local_actor>::
}
/**
* @brief Closes all connections and acceptors.
* Closes all connections and acceptors.
*/
void close_all();
/**
* @brief Closes the connection identified by @p handle.
* Unwritten data will still be send.
* Closes the connection identified by `handle`.
* Unwritten data will still be send.
*/
void close(connection_handle handle);
/**
* @brief Closes the acceptor identified by @p handle.
* Closes the acceptor identified by `handle`.
*/
void close(accept_handle handle);
......@@ -461,15 +460,12 @@ class broker : public extend<local_actor>::
bool m_running;
middleman& m_mm;
};
class broker::functor_based : public extend<broker>::
with<mixin::functor_based> {
using super = combined_type;
with<mixin::functor_based> {
public:
using super = combined_type;
template <class... Ts>
functor_based(Ts&&... vs)
......@@ -478,7 +474,6 @@ class broker::functor_based : public extend<broker>::
~functor_based();
behavior make_behavior() override;
};
} // namespace io
......
......@@ -26,7 +26,7 @@ namespace caf {
namespace io {
/**
* @brief Generic handle type for identifying connections.
* Generic handle type for identifying connections.
*/
class connection_handle : public handle<connection_handle> {
......
......@@ -27,15 +27,14 @@
namespace caf {
/**
* @brief Base class for IO handles such as {@link accept_handle} or
* {@link connection_handle}.
* Base class for IO handles such as `accept_handle` or `connection_handle`.
*/
template <class Subtype, int64_t InvalidId = -1>
class handle : detail::comparable<Subtype> {
public:
constexpr handle() : m_id{InvalidId} {}
constexpr handle() : m_id{InvalidId} {
// nop
}
handle(const Subtype& other) { m_id = other.id(); }
......@@ -47,12 +46,12 @@ class handle : detail::comparable<Subtype> {
}
/**
* @brief Returns the unique identifier of this handle.
* Returns the unique identifier of this handle.
*/
inline int64_t id() const { return m_id; }
/**
* @brief Sets the unique identifier of this handle.
* Sets the unique identifier of this handle.
*/
inline void set_id(int64_t value) { m_id = value; }
......@@ -67,13 +66,10 @@ class handle : detail::comparable<Subtype> {
}
protected:
inline handle(int64_t handle_id) : m_id{handle_id} {}
private:
int64_t m_id;
};
} // namespace caf
......
......@@ -26,13 +26,13 @@ namespace caf {
namespace io {
/**
* @brief Sets the maximum size of a message over network.
* Sets the maximum size of a message over network.
* @param size The maximum number of bytes a message may occupy.
*/
void max_msg_size(size_t size);
/**
* @brief Queries the maximum size of messages over network.
* Queries the maximum size of messages over network.
* @returns The number maximum number of bytes a message may occupy.
*/
size_t max_msg_size();
......
......@@ -37,34 +37,32 @@ namespace caf {
namespace io {
/**
* @brief Manages brokers.
* Manages brokers.
*/
class middleman : public detail::abstract_singleton {
friend class detail::singletons;
public:
friend class detail::singletons;
/**
* @brief Get middleman instance.
* Get middleman instance.
*/
static middleman* instance();
~middleman();
/**
* @brief Returns the broker associated with @p name.
* Returns the broker associated with `name`.
*/
template <class Impl>
intrusive_ptr<Impl> get_named_broker(atom_value name);
/**
* @brief Adds @p bptr to the list of known brokers.
* Adds `bptr` to the list of known brokers.
*/
void add_broker(broker_ptr bptr);
/**
* @brief Runs @p fun in the event loop of the middleman.
* Runs `fun` in the event loop of the middleman.
* @note This member function is thread-safe.
*/
template <class F>
......@@ -73,7 +71,7 @@ class middleman : public detail::abstract_singleton {
}
/**
* @brief Returns the IO backend used by this middleman.
* Returns the IO backend used by this middleman.
*/
inline network::multiplexer& backend() { return m_backend; }
......@@ -91,7 +89,6 @@ class middleman : public detail::abstract_singleton {
/** @endcond */
private:
middleman();
network::multiplexer m_backend; // networking backend
......@@ -102,7 +99,6 @@ class middleman : public detail::abstract_singleton {
std::map<atom_value, broker_ptr> m_named_brokers;
std::set<broker_ptr> m_brokers;
};
template <class Impl>
......
......@@ -125,12 +125,12 @@ namespace network {
#endif
/**
* @brief Platform-specific native socket type.
* Platform-specific native socket type.
*/
using native_socket = native_socket_t;
/**
* @brief Platform-specific native acceptor socket type.
* Platform-specific native acceptor socket type.
*/
using native_socket_acceptor = native_socket;
......@@ -142,70 +142,70 @@ inline int64_t int64_from_native_socket(native_socket sock) {
}
/**
* @brief Returns the last socket error as human-readable string.
* Returns the last socket error as human-readable string.
*/
std::string last_socket_error_as_string();
/**
* @brief Sets fd to nonblocking if <tt>set_nonblocking == true</tt>
* or to blocking if <tt>set_nonblocking == false</tt>
* throws @p network_error on error
* Sets fd to nonblocking if `set_nonblocking == true`
* or to blocking if `set_nonblocking == false`
* throws `network_error` on error
*/
void nonblocking(native_socket fd, bool new_value);
/**
* @brief Creates two connected sockets. The former is the read handle
* and the latter is the write handle.
* Creates two connected sockets. The former is the read handle
* and the latter is the write handle.
*/
std::pair<native_socket, native_socket> create_pipe();
/**
* @brief Throws network_error with given error message and
* the platform-specific error code if @p add_errno is @p true.
* Throws network_error with given error message and
* the platform-specific error code if `add_errno` is `true`.
*/
void throw_io_failure(const char* what, bool add_errno = true);
/**
* @brief Returns true if @p fd is configured as nodelay socket.
* Returns true if `fd` is configured as nodelay socket.
* @throws network_error
*/
void tcp_nodelay(native_socket fd, bool new_value);
/**
* @brief Throws @p network_error if @p result is invalid.
* Throws `network_error` if `result` is invalid.
*/
void handle_write_result(ssize_t result);
/**
* @brief Throws @p network_error if @p result is invalid.
* Throws `network_error` if `result` is invalid.
*/
void handle_read_result(ssize_t result);
/**
* @brief Reads up to @p len bytes from @p fd, writing the received data
* to @p buf. Returns @p true as long as @p fd is readable and @p false
* if the socket has been closed or an IO error occured. The number
* of read bytes is stored in @p result (can be 0).
* Reads up to `len` bytes from `fd,` writing the received data
* to `buf`. Returns `true` as long as `fd` is readable and `false`
* if the socket has been closed or an IO error occured. The number
* of read bytes is stored in `result` (can be 0).
*/
bool read_some(size_t& result, native_socket fd, void* buf, size_t len);
/**
* @brief Writes up to @p len bytes from @p buf to @p fd.
* Returns @p true as long as @p fd is readable and @p false
* if the socket has been closed or an IO error occured. The number
* of written bytes is stored in @p result (can be 0).
* Writes up to `len` bytes from `buf` to `fd`.
* Returns `true` as long as `fd` is readable and `false`
* if the socket has been closed or an IO error occured. The number
* of written bytes is stored in `result` (can be 0).
*/
bool write_some(size_t& result, native_socket fd, const void* buf, size_t len);
/**
* @brief Tries to accept a new connection from @p fd. On success,
* the new connection is stored in @p result. Returns true
* as long as
* Tries to accept a new connection from `fd`. On success,
* the new connection is stored in `result`. Returns true
* as long as
*/
bool try_accept(native_socket& result, native_socket fd);
/**
* @brief Identifies network IO operations, i.e., read or write.
* Identifies network IO operations, i.e., read or write.
*/
enum class operation {
read,
......@@ -216,7 +216,7 @@ enum class operation {
class multiplexer;
/**
* @brief A socket IO event handler.
* A socket IO event handler.
*/
class event_handler {
......@@ -229,27 +229,27 @@ class event_handler {
virtual ~event_handler();
/**
* @brief Returns true once the requested operation is done, i.e.,
* to signalize the multiplexer to remove this handler.
* The handler remains in the event loop as long as it returns false.
* Returns true once the requested operation is done, i.e.,
* to signalize the multiplexer to remove this handler.
* The handler remains in the event loop as long as it returns false.
*/
virtual void handle_event(operation op) = 0;
/**
* @brief Callback to signalize that this handler has been removed
* from the event loop for operations of type @p op.
* Callback to signalize that this handler has been removed
* from the event loop for operations of type `op`.
*/
virtual void removed_from_loop(operation op) = 0;
/**
* @brief Returns the bit field storing the subscribed events.
* Returns the bit field storing the subscribed events.
*/
inline int eventbf() const {
return m_eventbf;
}
/**
* @brief Sets the bit field storing the subscribed events.
* Sets the bit field storing the subscribed events.
*/
inline void eventbf(int eventbf) {
m_eventbf = eventbf;
......@@ -266,7 +266,7 @@ class event_handler {
class supervisor;
/**
* @brief Low-level backend for IO multiplexing.
* Low-level backend for IO multiplexing.
*/
class multiplexer {
......@@ -381,12 +381,10 @@ class multiplexer {
multiplexer& get_multiplexer_singleton();
/**
* @brief Makes sure a {@link multiplexer} does not stop its event loop
* before the application requests a shutdown.
*
* The supervisor informs the multiplexer in its constructor that it
* must not exit the event loop until the destructor of the supervisor
* has been called.
* Makes sure a {@link multiplexer} does not stop its event loop before the
* application requests a shutdown. The supervisor informs the multiplexer in
* its constructor that it must not exit the event loop until the destructor
* of the supervisor has been called.
*/
class supervisor {
......@@ -403,7 +401,7 @@ class supervisor {
};
/**
* @brief Low-level socket type used as default.
* Low-level socket type used as default.
*/
class default_socket {
......@@ -441,7 +439,7 @@ class default_socket {
};
/**
* @brief Low-level socket type used as default.
* Low-level socket type used as default.
*/
using default_socket_acceptor = default_socket;
......@@ -459,8 +457,8 @@ inline accept_handle accept_hdl_from_socket(const T& sock) {
/**
* @brief A manager configures an IO device and provides callbacks
* for various IO operations.
* A manager configures an IO device and provides callbacks
* for various IO operations.
*/
class manager : public ref_counted {
......@@ -469,14 +467,13 @@ class manager : public ref_counted {
virtual ~manager();
/**
* @brief Causes the manager to stop read operations on its IO device.
* Unwritten bytes are still send before the socket will
* be closed.
* Causes the manager to stop read operations on its IO device.
* Unwritten bytes are still send before the socket will be closed.
*/
virtual void stop_reading() = 0;
/**
* @brief Called by the underlying IO device to report failures.
* Called by the underlying IO device to report failures.
*/
virtual void io_failure(operation op) = 0;
};
......@@ -487,8 +484,8 @@ class manager : public ref_counted {
using manager_ptr = intrusive_ptr<manager>;
/**
* @brief A stream manager configures an IO stream and provides callbacks
* for incoming data as well as for error handling.
* A stream manager configures an IO stream and provides callbacks
* for incoming data as well as for error handling.
*/
class stream_manager : public manager {
......@@ -497,15 +494,15 @@ class stream_manager : public manager {
virtual ~stream_manager();
/**
* @brief Called by the underlying IO device whenever it received data.
* Called by the underlying IO device whenever it received data.
*/
virtual void consume(const void* data, size_t num_bytes) = 0;
};
/**
* @brief A stream capable of both reading and writing. The stream's input
* data is forwarded to its {@link stream_manager manager}.
* A stream capable of both reading and writing. The stream's input
* data is forwarded to its {@link stream_manager manager}.
*/
template <class Socket>
class stream : public event_handler {
......@@ -513,13 +510,13 @@ class stream : public event_handler {
public:
/**
* @brief A smart pointer to a stream manager.
* A smart pointer to a stream manager.
*/
using manager_ptr = intrusive_ptr<stream_manager>;
/**
* @brief A buffer class providing a compatible
* interface to @p std::vector.
* A buffer class providing a compatible
* interface to `std::vector`.
*/
using buffer_type = std::vector<char>;
......@@ -528,29 +525,28 @@ class stream : public event_handler {
}
/**
* @brief Returns the @p multiplexer this stream belongs to.
* Returns the `multiplexer` this stream belongs to.
*/
inline multiplexer& backend() {
return m_sock.backend();
}
/**
* @brief Returns the IO socket.
* Returns the IO socket.
*/
inline Socket& socket_handle() {
return m_sock;
}
/**
* @brief Initializes this stream, setting the socket handle to @p fd.
* Initializes this stream, setting the socket handle to `fd`.
*/
void init(Socket fd) {
m_sock = std::move(fd);
}
/**
* @brief Starts reading data from the socket, forwarding incoming
* data to @p mgr.
* Starts reading data from the socket, forwarding incoming data to `mgr`.
*/
void start(const manager_ptr& mgr) {
CAF_REQUIRE(mgr != nullptr);
......@@ -568,10 +564,10 @@ class stream : public event_handler {
}
/**
* @brief Configures how much data will be provided
* for the next @p consume callback.
* Configures how much data will be provided
* for the next `consume` callback.
* @warning Must not be called outside the IO multiplexers event loop
* once the stream has been started.
* once the stream has been started.
*/
void configure_read(receive_policy::config config) {
m_rd_flag = config.first;
......@@ -579,7 +575,7 @@ class stream : public event_handler {
}
/**
* @brief Copies data to the write buffer.
* Copies data to the write buffer.
* @note Not thread safe.
*/
void write(const void* buf, size_t num_bytes) {
......@@ -590,9 +586,9 @@ class stream : public event_handler {
}
/**
* @brief Returns the write buffer of this stream.
* Returns the write buffer of this stream.
* @warning Must not be modified outside the IO multiplexers event loop
* once the stream has been started.
* once the stream has been started.
*/
buffer_type& wr_buf() {
return m_wr_offline_buf;
......@@ -603,11 +599,10 @@ class stream : public event_handler {
}
/**
* @brief Sends the content of the write buffer, calling
* the @p io_failure member function of @p mgr in
* case of an error.
* Sends the content of the write buffer, calling the `io_failure`
* member function of `mgr` in case of an error.
* @warning Must not be called outside the IO multiplexers event loop
* once the stream has been started.
* once the stream has been started.
*/
void flush(const manager_ptr& mgr) {
CAF_REQUIRE(mgr != nullptr);
......@@ -747,8 +742,8 @@ class stream : public event_handler {
};
/**
* @brief An acceptor manager configures an acceptor and provides
* callbacks for incoming connections as well as for error handling.
* An acceptor manager configures an acceptor and provides
* callbacks for incoming connections as well as for error handling.
*/
class acceptor_manager : public manager {
......@@ -757,15 +752,15 @@ class acceptor_manager : public manager {
~acceptor_manager();
/**
* @brief Called by the underlying IO device to indicate that
* a new connection is awaiting acceptance.
* Called by the underlying IO device to indicate that
* a new connection is awaiting acceptance.
*/
virtual void new_connection() = 0;
};
/**
* @brief An acceptor is responsible for accepting incoming connections.
* An acceptor is responsible for accepting incoming connections.
*/
template <class SocketAcceptor>
class acceptor : public event_handler {
......@@ -775,12 +770,12 @@ class acceptor : public event_handler {
using socket_type = typename SocketAcceptor::socket_type;
/**
* @brief A manager providing the @p accept member function.
* A manager providing the `accept` member function.
*/
using manager_type = acceptor_manager;
/**
* @brief A smart pointer to an acceptor manager.
* A smart pointer to an acceptor manager.
*/
using manager_ptr = intrusive_ptr<manager_type>;
......@@ -790,29 +785,29 @@ class acceptor : public event_handler {
}
/**
* @brief Returns the @p multiplexer this acceptor belongs to.
* Returns the `multiplexer` this acceptor belongs to.
*/
inline multiplexer& backend() {
return m_backend;
}
/**
* @brief Returns the IO socket.
* Returns the IO socket.
*/
inline SocketAcceptor& socket_handle() {
return m_accept_sock;
}
/**
* @brief Returns the accepted socket. This member function should
* be called only from the @p new_connection callback.
* Returns the accepted socket. This member function should
* be called only from the `new_connection` callback.
*/
inline socket_type& accepted_socket() {
return m_sock;
}
/**
* @brief Initializes this acceptor, setting the socket handle to @p fd.
* Initializes this acceptor, setting the socket handle to `fd`.
*/
void init(SocketAcceptor sock) {
CAF_LOG_TRACE("sock.fd = " << sock.fd());
......@@ -820,9 +815,9 @@ class acceptor : public event_handler {
}
/**
* @brief Starts this acceptor, forwarding all incoming connections to
* @p manager. The intrusive pointer will be released after the
* acceptor has been closed or an IO error occured.
* Starts this acceptor, forwarding all incoming connections to
* `manager`. The intrusive pointer will be released after the
* acceptor has been closed or an IO error occured.
*/
void start(const manager_ptr& mgr) {
CAF_LOG_TRACE("m_accept_sock.fd = " << m_accept_sock.fd());
......@@ -832,7 +827,7 @@ class acceptor : public event_handler {
}
/**
* @brief Closes the network connection, thus stopping this acceptor.
* Closes the network connection, thus stopping this acceptor.
*/
void stop_reading() {
CAF_LOG_TRACE("m_accept_sock.fd = " << m_accept_sock.fd()
......
......@@ -31,13 +31,10 @@ namespace caf {
namespace io {
/**
* @brief Publishes @p whom at @p port.
*
* The connection is automatically closed if the lifetime of @p whom ends.
* @param whom Actor that should be published at @p port.
* Publishes `whom` at `port`. The connection is managed by the middleman.
* @param whom Actor that should be published at `port`.
* @param port Unused TCP port.
* @param addr The IP address to listen to, or @p INADDR_ANY if @p addr is
* @p nullptr.
* @param addr The IP address to listen to or `INADDR_ANY` if `addr == nullptr`.
* @throws bind_failure
*/
inline void publish(caf::actor whom, uint16_t port,
......
......@@ -26,8 +26,7 @@ namespace caf {
namespace io {
/**
* @brief Makes *all* local groups accessible via
* network on address @p addr and @p port.
* Makes *all* local groups accessible via network on address `addr` and `port`.
* @throws bind_failure
* @throws network_error
*/
......
......@@ -35,7 +35,7 @@ namespace caf {
namespace io {
/**
* @brief Establish a new connection to a remote actor via @p connection.
* Establish a new connection to a remote actor via `connection`.
* @param connection A connection to another process described by a pair
* of input and output stream.
* @returns An {@link actor_ptr} to the proxy instance
......@@ -48,7 +48,7 @@ inline actor remote_actor(Socket fd) {
return actor_cast<actor>(res);
}
/**
* @brief Establish a new connection to the actor at @p host on given @p port.
* Establish a new connection to the actor at `host` on given `port`.
* @param host Valid hostname or IP address.
* @param port TCP port.
* @returns An {@link actor_ptr} to the proxy instance
......
......@@ -30,7 +30,7 @@ namespace caf {
namespace io {
/**
* @brief Spawns a new functor-based broker.
* Spawns a new functor-based broker.
*/
template <spawn_options Os = no_spawn_options,
typename F = std::function<void(broker*)>, class... Ts>
......@@ -40,7 +40,7 @@ actor spawn_io(F fun, Ts&&... args) {
}
/**
* @brief Spawns a new functor-based broker connecting to <tt>host:port</tt>.
* Spawns a new functor-based broker connecting to `host:port.
*/
template <spawn_options Os = no_spawn_options,
typename F = std::function<void(broker*)>, class... Ts>
......@@ -77,7 +77,7 @@ struct is_socket : decltype(is_socket_test::test<T>(0)) {
};
/**
* @brief Spawns a new broker as server running on given @p port.
* Spawns a new broker as server running on given `port`.
*/
template <spawn_options Os = no_spawn_options,
typename F = std::function<void(broker*)>,
......@@ -93,7 +93,7 @@ spawn_io_server(F fun, Socket sock, Ts&&... args) {
}
/**
* @brief Spawns a new broker as server running on given @p port.
* Spawns a new broker as server running on given `port`.
*/
template <spawn_options Os = no_spawn_options,
typename F = std::function<void(broker*)>, class... Ts>
......
......@@ -28,39 +28,39 @@ namespace caf {
namespace io {
/**
* @brief Signalizes a newly accepted connection from a {@link broker}.
* Signalizes a newly accepted connection from a {@link broker}.
*/
struct new_connection_msg {
/**
* @brief The handle that accepted the new connection.
* The handle that accepted the new connection.
*/
accept_handle source;
/**
* @brief The handle for the new connection.
* The handle for the new connection.
*/
connection_handle handle;
};
inline bool operator==(const new_connection_msg& lhs,
const new_connection_msg& rhs) {
const new_connection_msg& rhs) {
return lhs.source == rhs.source && lhs.handle == rhs.handle;
}
inline bool operator!=(const new_connection_msg& lhs,
const new_connection_msg& rhs) {
const new_connection_msg& rhs) {
return !(lhs == rhs);
}
/**
* @brief Signalizes newly arrived data for a {@link broker}.
* Signalizes newly arrived data for a {@link broker}.
*/
struct new_data_msg {
/**
* @brief Handle to the related connection.
* Handle to the related connection.
*/
connection_handle handle;
/**
* @brief Buffer containing the received data.
* Buffer containing the received data.
*/
std::vector<char> buf;
};
......@@ -74,42 +74,42 @@ inline bool operator!=(const new_data_msg& lhs, const new_data_msg& rhs) {
}
/**
* @brief Signalizes that a {@link broker} connection has been closed.
* Signalizes that a {@link broker} connection has been closed.
*/
struct connection_closed_msg {
/**
* @brief Handle to the closed connection.
* Handle to the closed connection.
*/
connection_handle handle;
};
inline bool operator==(const connection_closed_msg& lhs,
const connection_closed_msg& rhs) {
const connection_closed_msg& rhs) {
return lhs.handle == rhs.handle;
}
inline bool operator!=(const connection_closed_msg& lhs,
const connection_closed_msg& rhs) {
const connection_closed_msg& rhs) {
return !(lhs == rhs);
}
/**
* @brief Signalizes that a {@link broker} acceptor has been closed.
* Signalizes that a {@link broker} acceptor has been closed.
*/
struct acceptor_closed_msg {
/**
* @brief Handle to the closed connection.
* Handle to the closed connection.
*/
accept_handle handle;
};
inline bool operator==(const acceptor_closed_msg& lhs,
const acceptor_closed_msg& rhs) {
const acceptor_closed_msg& rhs) {
return lhs.handle == rhs.handle;
}
inline bool operator!=(const acceptor_closed_msg& lhs,
const acceptor_closed_msg& rhs) {
const acceptor_closed_msg& rhs) {
return !(lhs == rhs);
}
......
......@@ -477,7 +477,7 @@ actor_proxy_ptr basp_broker::make_proxy(const id_type& nid, actor_id aid) {
// use a direct route if possible, i.e., when talking to a third node
auto hdl = get_route(nid);
if (hdl.invalid()) {
// this happens if and only if we don't have a path to @p nid
// this happens if and only if we don't have a path to `nid`
// and m_current_context->hdl has been blacklisted
CAF_LOG_INFO("cannot create a proxy instance for an actor "
"running on a node we don't have a route to");
......
......@@ -52,25 +52,20 @@ remote_actor_proxy::remote_actor_proxy(actor_id aid,
}
remote_actor_proxy::~remote_actor_proxy() {
anon_send(m_parent, make_message(atom("_DelProxy"),
node(),
m_id));
anon_send(m_parent, make_message(atom("_DelProxy"), node(), id()));
}
void remote_actor_proxy::forward_msg(const actor_addr& sender,
message_id mid,
message msg) {
CAF_LOG_TRACE(CAF_ARG(m_id)
<< ", " << CAF_TSARG(sender)
<< ", " << CAF_MARG(mid, integer_value)
<< ", " << CAF_TSARG(msg));
<< ", " << CAF_TSARG(sender)
<< ", " << CAF_MARG(mid, integer_value)
<< ", " << CAF_TSARG(msg));
m_parent->enqueue(invalid_actor_addr,
message_id::invalid,
make_message(atom("_Dispatch"),
sender,
address(),
mid,
std::move(msg)),
make_message(atom("_Dispatch"), sender, address(),
mid, std::move(msg)),
nullptr);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment