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; ...@@ -47,13 +47,13 @@ class deserializer;
class execution_unit; class execution_unit;
/** /**
* @brief A unique actor ID. * A unique actor ID.
* @relates abstract_actor * @relates abstract_actor
*/ */
using actor_id = uint32_t; 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; constexpr actor_id invalid_actor_id = 0;
...@@ -64,64 +64,63 @@ class response_promise; ...@@ -64,64 +64,63 @@ class response_promise;
using abstract_actor_ptr = intrusive_ptr<abstract_actor>; 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 { class abstract_actor : public abstract_channel {
// needs access to m_host
friend class response_promise; friend class response_promise;
// java-like access to base class
using super = abstract_channel; using super = abstract_channel;
public: public:
/** /**
* @brief Attaches @p ptr to this actor. * Attaches `ptr` to this actor. The actor will call `ptr->detach(...)` on
* * exit, or immediately if it already finished execution.
* The actor will call <tt>ptr->detach(...)</tt> on exit, or immediately * @returns `true` if `ptr` was successfully attached to the actor,
* if it already finished execution. * otherwise (actor already exited) `false`.
* @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.
*/ */
bool attach(attachable_ptr ptr); bool attach(attachable_ptr ptr);
/** /**
* @brief Convenience function that attaches the functor * Convenience function that attaches the functor `f` to this actor. The
* or function @p f to this actor. * actor executes `f()` on exit or immediatley if it is not running.
* * @returns `true` if `f` was successfully attached to the actor,
* The actor executes <tt>f()</tt> on exit, or immediatley * otherwise (actor already exited) `false`.
* 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.
*/ */
template <class F> 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; 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); void detach(const attachable::token& what);
/** /**
* @brief Links this actor to @p whom. * Links this actor to `whom`.
* @param whom Actor instance that whose execution is coupled to the
* execution of this Actor.
*/ */
virtual void link_to(const actor_addr& whom); virtual void link_to(const actor_addr& whom);
/** /**
* @brief Links this actor to @p whom. * Links this actor to `whom`.
* @param whom Actor instance that whose execution is coupled to the
* execution of this Actor.
*/ */
template <class ActorHandle> template <class ActorHandle>
void link_to(const ActorHandle& whom) { void link_to(const ActorHandle& whom) {
...@@ -129,16 +128,12 @@ class abstract_actor : public abstract_channel { ...@@ -129,16 +128,12 @@ class abstract_actor : public abstract_channel {
} }
/** /**
* @brief Unlinks this actor from @p whom. * Unlinks this actor from `whom`.
* @param whom Linked Actor.
* @note Links are automatically removed if the actor finishes execution.
*/ */
virtual void unlink_from(const actor_addr& whom); virtual void unlink_from(const actor_addr& whom);
/** /**
* @brief Unlinks this actor from @p whom. * Unlinks this actor from `whom`.
* @param whom Linked Actor.
* @note Links are automatically removed if the actor finishes execution.
*/ */
template <class ActorHandle> template <class ActorHandle>
void unlink_from(const ActorHandle& whom) { void unlink_from(const ActorHandle& whom) {
...@@ -146,76 +141,93 @@ class abstract_actor : public abstract_channel { ...@@ -146,76 +141,93 @@ class abstract_actor : public abstract_channel {
} }
/** /**
* @brief Establishes a link relation between this actor and @p other. * Establishes a link relation between this actor and `other`
* @param other Actor instance that wants to link against this Actor. * and returns whether the operation succeeded.
* @returns @c true if this actor is running and added @p other to its
* list of linked actors; otherwise @c false.
*/ */
virtual bool establish_backlink(const actor_addr& other); virtual bool establish_backlink(const actor_addr& other);
/** /**
* @brief Removes a link relation between this actor and @p other. * Removes the link relation between this actor and `other`
* @param other Actor instance that wants to unlink from this Actor. * and returns whether the operation succeeded.
* @returns @c true if this actor is running and removed @p other
* from its list of linked actors; otherwise @c false.
*/ */
virtual bool remove_backlink(const actor_addr& other); virtual bool remove_backlink(const actor_addr& other);
/** /**
* @brief Gets an integer value that uniquely identifies this Actor in * Returns the unique ID of this actor.
* the process it's executed in.
* @returns The unique identifier of this actor.
*/ */
inline actor_id id() const; inline uint32_t id() const {
return m_id;
}
/** /**
* @brief Returns the actor's exit reason of * Returns the actor's exit reason or
* <tt>exit_reason::not_exited</tt> if it's still alive. * `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. * Returns the type interface as set of strings or an empty set
* @note The returned set is empty for all untyped actors. * if this actor is untyped.
*/ */
virtual std::set<std::string> interface() const; virtual std::set<std::string> interface() const;
protected: protected:
/**
* Creates a non-proxy instance.
*/
abstract_actor(); abstract_actor();
/**
* Creates a proxy instance for a proxy running on `nid`.
*/
abstract_actor(actor_id aid, node_id nid); abstract_actor(actor_id aid, node_id nid);
/** /**
* @brief Should be overridden by subtypes and called upon termination. * Called by the runtime system to perform cleanup actions for this actor.
* @note Default implementation sets 'exit_reason' accordingly. * Subtypes should always call this member function when overriding it.
* @note Overridden functions should always call super::cleanup().
*/ */
virtual void cleanup(uint32_t reason); 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); 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); 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 // cannot be changed after construction
const actor_id m_id; const actor_id m_id;
// you're either a proxy or you're not // you're either a proxy or you're not
const bool m_is_proxy; const bool m_is_proxy;
private:
// initially exit_reason::not_exited // initially exit_reason::not_exited
std::atomic<uint32_t> m_exit_reason; std::atomic<uint32_t> m_exit_reason;
...@@ -228,46 +240,10 @@ class abstract_actor : public abstract_channel { ...@@ -228,46 +240,10 @@ class abstract_actor : public abstract_channel {
// attached functors that are executed on cleanup // attached functors that are executed on cleanup
std::vector<attachable_ptr> m_attachables; std::vector<attachable_ptr> m_attachables;
protected:
// identifies the execution unit this actor is currently executed by // identifies the execution unit this actor is currently executed by
execution_unit* m_host; 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 } // namespace caf
#endif // CAF_ABSTRACT_ACTOR_HPP #endif // CAF_ABSTRACT_ACTOR_HPP
...@@ -28,37 +28,29 @@ ...@@ -28,37 +28,29 @@
namespace caf { namespace caf {
/** /**
* @brief Interface for all message receivers. * Interface for all message receivers. * This interface describes an
* * entity that can receive messages and is implemented by {@link actor}
* This interface describes an entity that can receive messages * and {@link group}.
* and is implemented by {@link actor} and {@link group}.
*/ */
class abstract_channel : public ref_counted { class abstract_channel : public ref_counted {
public: public:
virtual ~abstract_channel(); virtual ~abstract_channel();
/** /**
* @brief Enqueues a new message to the channel. * 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.
*/ */
virtual void enqueue(const actor_addr& sender, message_id mid, 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; bool is_remote() const;
...@@ -75,12 +67,12 @@ class abstract_channel : public ref_counted { ...@@ -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>; using abstract_channel_ptr = intrusive_ptr<abstract_channel>;
inline node_id abstract_channel::node() const {
return m_node;
}
} // namespace caf } // namespace caf
#endif // CAF_ABSTRACT_CHANNEL_HPP #endif // CAF_ABSTRACT_CHANNEL_HPP
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <memory> #include <memory>
#include "caf/channel.hpp" #include "caf/channel.hpp"
#include "caf/attachable.hpp"
#include "caf/ref_counted.hpp" #include "caf/ref_counted.hpp"
#include "caf/abstract_channel.hpp" #include "caf/abstract_channel.hpp"
...@@ -44,14 +43,12 @@ class serializer; ...@@ -44,14 +43,12 @@ class serializer;
class deserializer; class deserializer;
/** /**
* @brief A multicast group. * A multicast group.
*/ */
class abstract_group : public abstract_channel { class abstract_group : public abstract_channel {
friend class detail::group_manager;
friend class detail::peer_connection; // needs access to remote_enqueue
public: public:
friend class detail::group_manager;
friend class detail::peer_connection;
~abstract_group(); ~abstract_group();
...@@ -62,60 +59,50 @@ class abstract_group : public abstract_channel { ...@@ -62,60 +59,50 @@ class abstract_group : public abstract_channel {
// unsubscribes its channel from the group on destruction // unsubscribes its channel from the group on destruction
class subscription { class subscription {
public:
friend class abstract_group; friend class abstract_group;
subscription(const subscription&) = delete; subscription(const subscription&) = delete;
subscription& operator=(const subscription&) = delete; subscription& operator=(const subscription&) = delete;
public:
subscription() = default; subscription() = default;
subscription(subscription&&) = default; subscription(subscription&&) = default;
subscription(const channel& s, const intrusive_ptr<abstract_group>& g); subscription(const channel& s, const intrusive_ptr<abstract_group>& g);
~subscription(); ~subscription();
inline bool valid() const { return (m_subscriber) && (m_group); } inline bool valid() const {
return (m_subscriber) && (m_group);
}
private: private:
channel m_subscriber; channel m_subscriber;
intrusive_ptr<abstract_group> m_group; intrusive_ptr<abstract_group> m_group;
}; };
/** /**
* @brief Module interface. * Interface for user-defined multicast implementations.
*/ */
class module { class module {
std::string m_name;
protected:
module(std::string module_name);
public: public:
module(std::string module_name);
virtual ~module(); 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 * @threadsafe
*/ */
const std::string& name(); const std::string& name();
/** /**
* @brief Get a pointer to the group associated with * Returns a pointer to the group associated with the name `group_name`.
* the name @p group_name.
* @threadsafe * @threadsafe
*/ */
virtual group get(const std::string& group_name) = 0; virtual group get(const std::string& group_name) = 0;
virtual group deserialize(deserializer* source) = 0; virtual group deserialize(deserializer* source) = 0;
private:
std::string m_name;
}; };
using module_ptr = module*; using module_ptr = module*;
...@@ -124,40 +111,33 @@ class abstract_group : public abstract_channel { ...@@ -124,40 +111,33 @@ class abstract_group : public abstract_channel {
virtual void serialize(serializer* sink) = 0; virtual void serialize(serializer* sink) = 0;
/** /**
* @brief A string representation of the group identifier. * Returns a string representation of the group identifier, e.g.,
* @returns The group identifier as string (e.g. "224.0.0.1" for IPv4 * "224.0.0.1" for IPv4 multicast or a user-defined string for local groups.
* multicast or a user-defined string for local groups).
*/ */
const std::string& identifier() const; const std::string& identifier() const;
module_ptr get_module() const; module_ptr get_module() const;
/** /**
* @brief The name of the module. * Returns the name of the module.
* @returns The module name of this group (e.g. "local").
*/ */
const std::string& module_name() const; const std::string& module_name() const;
/** /**
* @brief Subscribe @p who to this group. * Subscribes `who` to this group and returns a subscription object.
* @returns A {@link subscription} object that unsubscribes @p who
* if the lifetime of @p who ends.
*/ */
virtual subscription subscribe(const channel& who) = 0; virtual subscription subscribe(const channel& who) = 0;
protected: protected:
abstract_group(module_ptr module, std::string group_id); abstract_group(module_ptr module, std::string group_id);
// called by subscription objects
virtual void unsubscribe(const channel& who) = 0; virtual void unsubscribe(const channel& who) = 0;
module_ptr m_module; module_ptr m_module;
std::string m_identifier; 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 * @relates group
*/ */
using abstract_group_ptr = intrusive_ptr<abstract_group>; using abstract_group_ptr = intrusive_ptr<abstract_group>;
......
...@@ -35,35 +35,34 @@ ...@@ -35,35 +35,34 @@
namespace caf { namespace caf {
class scoped_actor;
struct invalid_actor_t { struct invalid_actor_t {
constexpr invalid_actor_t() {} constexpr invalid_actor_t() {}
}; };
/** /**
* @brief Identifies an invalid {@link actor}. * Identifies an invalid {@link actor}.
* @relates actor * @relates actor
*/ */
constexpr invalid_actor_t invalid_actor = invalid_actor_t{}; constexpr invalid_actor_t invalid_actor = invalid_actor_t{};
template <class T> template <class T>
struct is_convertible_to_actor { struct is_convertible_to_actor {
static constexpr bool value = std::is_base_of<actor_proxy, T>::value || using type = typename std::remove_pointer<T>::type;
std::is_base_of<local_actor, T>::value; 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. * Identifies an untyped actor. Can be used with derived types
* * of `event_based_actor`, `blocking_actor`, `actor_proxy`.
* Can be used with derived types of {@link event_based_actor},
* {@link blocking_actor}, {@link actor_proxy}, or
* {@link io::broker}.
*/ */
class actor : detail::comparable<actor>, class actor : detail::comparable<actor>,
detail::comparable<actor, actor_addr>, detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>, detail::comparable<actor, invalid_actor_t>,
detail::comparable<actor, invalid_actor_addr_t> { detail::comparable<actor, invalid_actor_addr_t> {
friend class local_actor; friend class local_actor;
...@@ -121,8 +120,7 @@ class actor : detail::comparable<actor>, ...@@ -121,8 +120,7 @@ class actor : detail::comparable<actor>,
} }
/** /**
* @brief Returns a handle that grants access to * Returns a handle that grants access to actor operations such as enqueue.
* actor operations such as enqueue.
*/ */
inline abstract_actor* operator->() const { inline abstract_actor* operator->() const {
return m_ptr.get(); return m_ptr.get();
...@@ -145,7 +143,7 @@ class actor : detail::comparable<actor>, ...@@ -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; actor_addr address() const;
......
...@@ -40,13 +40,13 @@ struct invalid_actor_addr_t { ...@@ -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 * @relates actor_addr
*/ */
constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{}; 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>, class actor_addr : detail::comparable<actor_addr>,
detail::comparable<actor_addr, abstract_actor*>, detail::comparable<actor_addr, abstract_actor*>,
...@@ -91,8 +91,7 @@ class actor_addr : detail::comparable<actor_addr>, ...@@ -91,8 +91,7 @@ class actor_addr : detail::comparable<actor_addr>,
node_id node() const; node_id node() const;
/** /**
* @brief Returns whether this is an address of a * Returns whether this is an address of a remote actor.
* remote actor.
*/ */
bool is_remote() const; bool is_remote() const;
......
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
namespace caf { namespace caf {
/**
* Converts actor handle `what` to a different actor handle of type `T`.
*/
template <class T, typename U> template <class T, typename U>
T actor_cast(const U& what) { T actor_cast(const U& what) {
return what.get(); return what.get();
......
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
namespace caf { namespace caf {
/** /**
* @brief An co-existing forwarding all messages through a user-defined * An co-existing forwarding all messages through a user-defined
* callback to another object, thus serving as gateway to * callback to another object, thus serving as gateway to
* allow any object to interact with other actors. * allow any object to interact with other actors.
*/ */
class actor_companion : public extend<local_actor, actor_companion>:: class actor_companion : public extend<local_actor, actor_companion>::
with<mixin::behavior_stack_based<behavior>::impl, with<mixin::behavior_stack_based<behavior>::impl,
...@@ -52,14 +52,14 @@ class actor_companion : public extend<local_actor, actor_companion>:: ...@@ -52,14 +52,14 @@ class actor_companion : public extend<local_actor, actor_companion>::
using enqueue_handler = std::function<void (message_pointer)>; using enqueue_handler = std::function<void (message_pointer)>;
/** /**
* @brief Removes the handler for incoming messages and terminates * Removes the handler for incoming messages and terminates
* the companion for exit reason @ rsn. * the companion for exit reason @ rsn.
*/ */
void disconnect(std::uint32_t rsn = exit_reason::normal); void disconnect(std::uint32_t rsn = exit_reason::normal);
/** /**
* @brief Sets the handler for incoming messages. * Sets the handler for incoming messages.
* @warning @p handler needs to be thread-safe * @warning `handler` needs to be thread-safe
*/ */
void on_enqueue(enqueue_handler handler); void on_enqueue(enqueue_handler handler);
...@@ -77,7 +77,7 @@ class actor_companion : public extend<local_actor, actor_companion>:: ...@@ -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 * @relates actor_companion
*/ */
using actor_companion_ptr = intrusive_ptr<actor_companion>; using actor_companion_ptr = intrusive_ptr<actor_companion>;
......
...@@ -34,89 +34,80 @@ class serializer; ...@@ -34,89 +34,80 @@ class serializer;
class deserializer; class deserializer;
/** /**
* @brief Groups a (distributed) set of actors and allows actors * Groups a (distributed) set of actors and allows actors
* in the same namespace to exchange messages. * in the same namespace to exchange messages.
*/ */
class actor_namespace { class actor_namespace {
public: public:
using key_type = node_id; using key_type = node_id;
/** /**
* @brief The backend of an actor namespace is responsible for * The backend of an actor namespace is responsible for creating proxy actors.
* creating proxy actors.
*/ */
class backend { class backend {
public: public:
virtual ~backend(); 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; virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0;
}; };
actor_namespace(backend& mgm); actor_namespace(backend& mgm);
/** /**
* @brief Writes an actor address to @p sink and adds the actor * Writes an actor address to `sink` and adds the actor
* to the list of known actors for a later deserialization. * to the list of known actors for a later deserialization.
*/ */
void write(serializer* sink, const actor_addr& ptr); void write(serializer* sink, const actor_addr& ptr);
/** /**
* @brief Reads an actor address from @p source, creating * Reads an actor address from `source,` creating
* addresses for remote actors on the fly if needed. * addresses for remote actors on the fly if needed.
*/ */
actor_addr read(deserializer* source); 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>; 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); size_t count_proxies(const key_type& node);
/** /**
* @brief Returns the proxy instance identified by @p node and @p aid * Returns the proxy instance identified by `node` and `aid`
* or @p nullptr if the actor either unknown or expired. * or `nullptr` if the actor either unknown or expired.
*/ */
actor_proxy_ptr get(const key_type& node, actor_id aid); actor_proxy_ptr get(const key_type& node, actor_id aid);
/** /**
* @brief Returns the proxy instance identified by @p node and @p aid * Returns the proxy instance identified by `node` and `aid`
* or creates a new (default) proxy instance. * or creates a new (default) proxy instance.
*/ */
actor_proxy_ptr get_or_put(const key_type& node, actor_id aid); 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); 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); 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; bool empty() const;
private: private:
backend& m_backend; backend& m_backend;
std::map<key_type, proxy_map> m_proxies; std::map<key_type, proxy_map> m_proxies;
}; };
} // namespace caf } // namespace caf
......
...@@ -32,58 +32,48 @@ namespace caf { ...@@ -32,58 +32,48 @@ namespace caf {
class actor_proxy; 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 * @relates actor_proxy
*/ */
using actor_proxy_ptr = intrusive_ptr<actor_proxy>; using actor_proxy_ptr = intrusive_ptr<actor_proxy>;
/** /**
* @brief Represents a remote actor. * Represents a remote actor.
* @extends abstract_actor * @extends abstract_actor
*/ */
class actor_proxy : public abstract_actor { class actor_proxy : public abstract_actor {
using super = abstract_actor;
public: public:
/** /**
* @brief An anchor points to a proxy instance without sharing * An anchor points to a proxy instance without sharing
* ownership to it, i.e., models a weak ptr. * ownership to it, i.e., models a weak ptr.
*/ */
class anchor : public ref_counted { class anchor : public ref_counted {
friend class actor_proxy;
public: public:
friend class actor_proxy;
anchor(actor_proxy* instance = nullptr); anchor(actor_proxy* instance = nullptr);
~anchor(); ~anchor();
/** /**
* @brief Queries whether the proxy was already deleted. * Queries whether the proxy was already deleted.
*/ */
bool expired() const; 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()}. * if the instance is {@link expired()}.
*/ */
actor_proxy_ptr get(); actor_proxy_ptr get();
private: private:
/* /*
* @brief Tries to expire this anchor. Fails if reference * Tries to expire this anchor. Fails if reference
* count of the proxy is nonzero. * count of the proxy is nonzero.
*/ */
bool try_expire(); bool try_expire();
std::atomic<actor_proxy*> m_ptr; std::atomic<actor_proxy*> m_ptr;
detail::shared_spinlock m_lock; detail::shared_spinlock m_lock;
}; };
using anchor_ptr = intrusive_ptr<anchor>; using anchor_ptr = intrusive_ptr<anchor>;
...@@ -91,31 +81,30 @@ class actor_proxy : public abstract_actor { ...@@ -91,31 +81,30 @@ class actor_proxy : public abstract_actor {
~actor_proxy(); ~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. * to the remote instance.
*/ */
virtual void local_link_to(const actor_addr& other) = 0; 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; virtual void local_unlink_from(const actor_addr& other) = 0;
/** /**
* @brief * Invokes cleanup code.
*/ */
virtual void kill_proxy(uint32_t reason) = 0; virtual void kill_proxy(uint32_t reason) = 0;
void request_deletion() override; void request_deletion() override;
inline anchor_ptr get_anchor() { return m_anchor; } inline anchor_ptr get_anchor() {
return m_anchor;
}
protected: protected:
actor_proxy(actor_id aid, node_id nid); actor_proxy(actor_id aid, node_id nid);
anchor_ptr m_anchor; anchor_ptr m_anchor;
}; };
} // namespace caf } // namespace caf
......
...@@ -101,41 +101,41 @@ ...@@ -101,41 +101,41 @@
* It uses a network transparent messaging system to ease development * It uses a network transparent messaging system to ease development
* of both concurrent and distributed software. * 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. * A scheduled actor should not call blocking functions.
* Individual actors can be spawned (created) with a special flag to run in * 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. * 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 * each context <i>is</i> an actor. Even main is implicitly
* converted to an actor if needed. * converted to an actor if needed.
* *
* @section GettingStarted Getting Started * @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>, *3.2</tt>,
* and @p CMake. * and `CMake`.
* *
* The usual build steps on Linux and Mac OS X are: * The usual build steps on Linux and Mac OS X are:
* *
*- <tt>mkdir build</tt> *- `mkdir build
*- <tt>cd build</tt> *- `cd build
*- <tt>cmake ..</tt> *- `cmake ..
*- <tt>make</tt> *- `make
*- <tt>make install</tt> (as root, optionally) *- `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. * works properly.
* *
*- <tt>./bin/unit_tests</tt> *- `./bin/unit_tests
* *
* Please submit a bug report that includes (a) your compiler version, * 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. * (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 * 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 * 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/index.html or as PDF at
* http://neverlord.github.com/libcaf/manual/manual.pdf * http://neverlord.github.com/libcaf/manual/manual.pdf
...@@ -149,83 +149,36 @@ ...@@ -149,83 +149,36 @@
* The {@link math_actor.cpp Math Actor Example} shows the usage * The {@link math_actor.cpp Math Actor Example} shows the usage
* of {@link receive_loop} and {@link caf::arg_match arg_match}. * of {@link receive_loop} and {@link caf::arg_match arg_match}.
* The {@link dining_philosophers.cpp Dining Philosophers Example} * 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. * features.
* *
* @namespace caf * @namespace caf
* @brief Root namespace of libcaf. * Root namespace of libcaf.
* *
* @namespace caf::util * @namespace caf::mixin
* @brief Contains utility classes and metaprogramming * Contains mixin classes implementing several actor traits.
* 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::exit_reason * @namespace caf::exit_reason
* @brief Contains all predefined exit reasons. * 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
* *
* Those two tuples initially point to the same data (the addresses of the * @namespace caf::policy
* first element of @p x is equal to the address of the first element * Contains policies encapsulating characteristics or algorithms.
* of @p y):
* *
* @code * @namespace caf::io
* assert(&(get<0>(x)) == &(get<0>(y))); * Contains all network-related classes and functions.
* @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
* *
* @defgroup MessageHandling Message handling. * @defgroup MessageHandling Message handling.
* *
* @brief This is the beating heart of @p libcaf. Actor programming is * This is the beating heart of `libcaf`. Actor programming is
* all about message handling. * 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, * 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. * @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 * The blocking API of libcaf is intended to be used for migrating
* previously threaded applications. When writing new code, you should use * previously threaded applications. When writing new code, you should use
...@@ -233,7 +186,7 @@ ...@@ -233,7 +186,7 @@
* *
* @section Send Send messages * @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 * The first argument is the receiver of the message followed by any number
* of values: * of values:
* *
...@@ -255,7 +208,7 @@ ...@@ -255,7 +208,7 @@
* *
* @section Receive Receive messages * @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. * is a list of { pattern >> callback } rules.
* *
* @code * @code
...@@ -299,7 +252,7 @@ ...@@ -299,7 +252,7 @@
* *
* @section ReceiveLoops Receive loops * @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 * 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 * 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 * in a variable and pass that variable to receive. This fixes the issue
...@@ -307,13 +260,13 @@ ...@@ -307,13 +260,13 @@
* *
* There are four convenience functions implementing receive loops to * There are four convenience functions implementing receive loops to
* declare behavior where it belongs without unnecessary * 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). * actor finishes execution).
* *
* @p receive_while creates a functor evaluating a lambda expression. * `receive_while` creates a functor evaluating a lambda expression.
* The loop continues until the given lambda returns @p false. A simple example: * The loop continues until the given lambda returns `false`. A simple example:
* *
* @code * @code
* // receive two integers * // receive two integers
...@@ -326,7 +279,7 @@ ...@@ -326,7 +279,7 @@
* // ... * // ...
* @endcode * @endcode
* *
* @p receive_for is a simple ranged-based loop: * `receive_for` is a simple ranged-based loop:
* *
* @code * @code
* std::vector<int> vec {1, 2, 3, 4}; * std::vector<int> vec {1, 2, 3, 4};
...@@ -336,7 +289,7 @@ ...@@ -336,7 +289,7 @@
* ); * );
* @endcode * @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 * takes a lambda expression. The loop continues until the given lambda
* returns true. Example: * returns true. Example:
* *
...@@ -354,7 +307,7 @@ ...@@ -354,7 +307,7 @@
* *
* @section FutureSend Send delayed messages * @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. * This is particularly useful for recurring events, e.g., periodical polling.
* Usage example: * Usage example:
* *
...@@ -374,11 +327,11 @@ ...@@ -374,11 +327,11 @@
* *
* @defgroup ImplicitConversion Implicit type conversions. * @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. * it enforces network transparent messaging.
* Unfortunately, string literals in @p C++ have the type <tt>const char*</tt>, * Unfortunately, string literals in `C++` have the type `const char*,
* resp. <tt>const char[]</tt>. Since @p libcaf is a user-friendly library, * resp. `const char[]. Since `libcaf` is a user-friendly library,
* it silently converts string literals and C-strings to @p std::string objects. * it silently converts string literals and C-strings to `std::string` objects.
* It also converts unicode literals to the corresponding STL container. * It also converts unicode literals to the corresponding STL container.
* *
* A few examples: * A few examples:
...@@ -403,30 +356,22 @@ ...@@ -403,30 +356,22 @@
* @endcode * @endcode
* *
* @defgroup ActorCreation Actor creation. * @defgroup ActorCreation Actor creation.
*
* @defgroup MetaProgramming Metaprogramming utility.
*/ */
// examples // examples
/** /**
* @brief A trivial example program. * A trivial example program.
* @example hello_world.cpp * @example hello_world.cpp
*/ */
/** /**
* @brief Shows the usage of {@link caf::atom atoms} * A simple example for a delayed_send based application.
* and {@link caf::arg_match arg_match}.
* @example math_actor.cpp
*/
/**
* @brief A simple example for a delayed_send based application.
* @example dancing_kirby.cpp * @example dancing_kirby.cpp
*/ */
/** /**
* @brief An event-based "Dining Philosophers" implementation. * An event-based "Dining Philosophers" implementation.
* @example dining_philosophers.cpp * @example dining_philosophers.cpp
*/ */
......
...@@ -41,69 +41,56 @@ namespace caf { ...@@ -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: * The output of this example program is:
* * > foo(1, 2)<br>
* <tt> * > foo_pair(3, 4)
* foo(1, 2)<br>
* foo_pair(3, 4)
* </tt>
* @example announce_1.cpp * @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: * The output of this example program is:
* *
* <tt>foo(1, 2)</tt> * > foo(1, 2)
* @example announce_2.cpp * @example announce_2.cpp
*/ */
/** /**
* @brief An example for @c announce with overloaded * An example for announce with overloaded getter and setter member functions.
* getter and setter member functions.
*
* The output of this example program is: * The output of this example program is:
* *
* <tt>foo(1, 2)</tt> * > foo(1, 2)
* @example announce_3.cpp * @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: * The output of this example program is:
* *
* <tt>bar(foo(1, 2), 3)</tt> * > bar(foo(1, 2), 3)
* @example announce_4.cpp * @example announce_4.cpp
*/ */
/** /**
* @brief An advanced example for @c announce implementing serialization * An advanced example for announce implementing serialization
* for a user-defined tree data type. * for a user-defined tree data type.
* @example announce_5.cpp * @example announce_5.cpp
*/ */
/** /**
* @brief Adds a new type mapping to the type system. * Adds a new mapping to the type system. Returns `false` if a mapping
* @param tinfo C++ RTTI for the new type * for `tinfo` already exists, otherwise `true`.
* @param utype Corresponding {@link uniform_type_info} instance. * @warning `announce` is **not** thead-safe!
* @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.
*/ */
const uniform_type_info* announce(const std::type_info& tinfo, const uniform_type_info* announce(const std::type_info& tinfo,
uniform_type_info_ptr utype); uniform_type_info_ptr utype);
// deals with member pointer // deals with member pointer
/** /**
* @brief Creates meta informations for a non-trivial member @p C. * Creates meta information for a non-trivial member `C`, whereas
* @param c_ptr Pointer to the non-trivial member. * `args` are the "sub-members" of `c_ptr`.
* @param args "Sub-members" of @p c_ptr
* @see {@link announce_4.cpp announce example 4} * @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> template <class C, class Parent, class... Ts>
std::pair<C Parent::*, detail::abstract_uniform_type_info<C>*> std::pair<C Parent::*, detail::abstract_uniform_type_info<C>*>
...@@ -113,12 +100,10 @@ compound_member(C Parent::*c_ptr, const Ts&... args) { ...@@ -113,12 +100,10 @@ compound_member(C Parent::*c_ptr, const Ts&... args) {
// deals with getter returning a mutable reference // deals with getter returning a mutable reference
/** /**
* @brief Creates meta informations for a non-trivial member accessed * Creates meta information for a non-trivial member accessed
* via a getter returning a mutable reference. * via a getter returning a mutable reference, whereas
* @param getter Member function pointer to the getter. * `args` are the "sub-members" of `c_ptr`.
* @param args "Sub-members" of @p c_ptr
* @see {@link announce_4.cpp announce example 4} * @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> template <class C, class Parent, class... Ts>
std::pair<C& (Parent::*)(), detail::abstract_uniform_type_info<C>*> std::pair<C& (Parent::*)(), detail::abstract_uniform_type_info<C>*>
...@@ -128,32 +113,25 @@ compound_member(C& (Parent::*getter)(), const Ts&... args) { ...@@ -128,32 +113,25 @@ compound_member(C& (Parent::*getter)(), const Ts&... args) {
// deals with getter/setter pair // deals with getter/setter pair
/** /**
* @brief Creates meta informations for a non-trivial member accessed * Creates meta information for a non-trivial member accessed
* via a getter/setter pair. * via a pair of getter and setter member function pointers, whereas
* @param gspair A pair of two member function pointers representing * `args` are the "sub-members" of `c_ptr`.
* getter and setter.
* @param args "Sub-members" of @p c_ptr
* @see {@link announce_4.cpp announce example 4} * @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, template <class Parent, class GRes, class SRes, class SArg, class... Ts>
class... Ts>
std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>, std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>,
detail::abstract_uniform_type_info< detail::abstract_uniform_type_info<
typename detail::rm_const_and_ref<GRes>::type>*> typename detail::rm_const_and_ref<GRes>::type>*>
compound_member( compound_member(const std::pair<GRes (Parent::*)() const,
const std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>& gspair, SRes (Parent::*)(SArg)>& gspair,
const Ts&... args) { const Ts&... args) {
using mtype = typename detail::rm_const_and_ref<GRes>::type; using mtype = typename detail::rm_const_and_ref<GRes>::type;
return {gspair, new detail::default_uniform_type_info<mtype>(args...)}; return {gspair, new detail::default_uniform_type_info<mtype>(args...)};
} }
/** /**
* @brief Adds a new type mapping for @p C to the type system. * Adds a new type mapping for `C` to the type system.
* @tparam C A class that is either empty or is default constructible, * @warning `announce` is **not** thead-safe!
* copy constructible, and comparable.
* @param args Members of @p C.
* @warning @p announce is <b>not</b> thead safe!
*/ */
template <class C, class... Ts> template <class C, class... Ts>
inline const uniform_type_info* announce(const Ts&... args) { inline const uniform_type_info* announce(const Ts&... args) {
......
...@@ -25,31 +25,32 @@ ...@@ -25,31 +25,32 @@
namespace caf { 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 * @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 * @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> template <class T>
struct is_anything { struct is_anything : std::is_same<T, anything> {
static constexpr bool value = std::is_same<T, anything>::value; // no content
}; };
} // namespace caf } // namespace caf
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
namespace caf { namespace caf {
/** /**
* @brief The value type of atoms. * The value type of atoms.
*/ */
enum class atom_value : uint64_t { enum class atom_value : uint64_t {
/** @cond PRIVATE */ /** @cond PRIVATE */
...@@ -37,16 +37,12 @@ enum class atom_value : uint64_t { ...@@ -37,16 +37,12 @@ enum class atom_value : uint64_t {
}; };
/** /**
* @brief Returns @p what as a string representation. * Returns `what` as a string representation.
* @param what Compact representation of an atom.
* @returns @p what as string.
*/ */
std::string to_string(const atom_value& what); std::string to_string(const atom_value& what);
/** /**
* @brief Creates an atom from given string literal. * Creates an atom from given string literal.
* @param str String constant representing an atom.
* @returns A compact representation of @p str.
*/ */
template <size_t Size> template <size_t Size>
constexpr atom_value atom(char const (&str)[Size]) { constexpr atom_value atom(char const (&str)[Size]) {
......
...@@ -27,59 +27,46 @@ ...@@ -27,59 +27,46 @@
namespace caf { namespace caf {
/** /**
* @brief Callback utility class. * Callback utility class.
*/ */
class attachable { class attachable {
public:
attachable() = default;
attachable(const attachable&) = delete; attachable(const attachable&) = delete;
attachable& operator=(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 { struct token {
/** /**
* @brief Denotes the type of @c ptr. * Denotes the type of ptr.
*/ */
const std::type_info& subtype; const std::type_info& subtype;
/** /**
* @brief Any value, used to identify @c attachable instances. * Any value, used to identify attachable instances.
*/ */
const void* ptr; const void* ptr;
token(const std::type_info& subtype, const void* ptr); token(const std::type_info& subtype, const void* ptr);
}; };
virtual ~attachable(); 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. * The default implementation does nothing.
* @param reason The exit rason of the observed actor.
*/ */
virtual void actor_exited(uint32_t reason) = 0; virtual void actor_exited(uint32_t reason) = 0;
/** /**
* @brief Selects a group of @c attachable instances by @p what. * Returns `true` if `what` selects this instance, otherwise false.
* @param what A value that selects zero or more @c attachable instances.
* @returns @c true if @p what selects this instance; otherwise @c false.
*/ */
virtual bool matches(const token& what) = 0; virtual bool matches(const token& what) = 0;
}; };
/** /**
* @brief A managed {@link attachable} pointer.
* @relates attachable * @relates attachable
*/ */
using attachable_ptr = std::unique_ptr<attachable>; using attachable_ptr = std::unique_ptr<attachable>;
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
namespace caf { namespace caf {
/** /**
* @brief Blocks execution of this actor until all * Blocks execution of this actor until all other actors finished execution.
* other actors finished execution.
* @warning This function will cause a deadlock if called from multiple actors. * @warning This function will cause a deadlock if called from multiple actors.
* @warning Do not call this function in cooperatively scheduled actors. * @warning Do not call this function in cooperatively scheduled actors.
*/ */
......
...@@ -37,120 +37,125 @@ namespace caf { ...@@ -37,120 +37,125 @@ namespace caf {
class message_handler; 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 { class behavior {
friend class message_handler;
public: 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&)>; 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() = default;
behavior(behavior&&) = default; behavior(behavior&&) = default;
behavior(const behavior&) = default; behavior(const behavior&) = default;
behavior& operator=(behavior&&) = default; behavior& operator=(behavior&&) = default;
behavior& operator=(const behavior&) = default; behavior& operator=(const behavior&) = default;
/**
* Creates a behavior from `fun` without timeout.
*/
behavior(const message_handler& fun); 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> 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 * Returns the duration after which receive operations
* this behavior should time out. * 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 * Returns a value if `arg` was matched by one of the
* handler of this behavior, returns @p nothing otherwise. * handler of this behavior, returns `nothing` otherwise.
*/ */
template <class T> 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 * Adds a continuation to this behavior that is executed
* whenever this behavior was successfully applied to * whenever this behavior was successfully applied to a message.
* a message.
*/ */
behavior add_continuation(continuation_fun fun); 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 * @relates behavior
*/ */
template <class... Cs, typename F> template <class... Cs, typename F>
inline behavior operator, (const match_expr<Cs...>& lhs, behavior operator,(const match_expr<Cs...>& lhs,
const timeout_definition<F>& rhs) { const timeout_definition<F>& rhs) {
return {lhs, 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 } // namespace caf
#endif // CAF_BEHAVIOR_HPP #endif // CAF_BEHAVIOR_HPP
...@@ -38,15 +38,15 @@ using keep_behavior_t = behavior_policy<false>; ...@@ -38,15 +38,15 @@ using keep_behavior_t = behavior_policy<false>;
using discard_behavior_t = behavior_policy<true>; using discard_behavior_t = behavior_policy<true>;
/** /**
* @brief Policy tag that causes {@link event_based_actor::become} to * Policy tag that causes {@link event_based_actor::become} to
* discard the current behavior. * discard the current behavior.
* @relates local_actor * @relates local_actor
*/ */
constexpr discard_behavior_t discard_behavior = discard_behavior_t{}; constexpr discard_behavior_t discard_behavior = discard_behavior_t{};
/** /**
* @brief Policy tag that causes {@link event_based_actor::become} to * Policy tag that causes {@link event_based_actor::become} to
* keep the current behavior available. * keep the current behavior available.
* @relates local_actor * @relates local_actor
*/ */
constexpr keep_behavior_t keep_behavior = keep_behavior_t{}; constexpr keep_behavior_t keep_behavior = keep_behavior_t{};
......
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
namespace caf { namespace caf {
/** /**
* @brief Implements the deserializer interface with * Implements the deserializer interface with a binary serialization protocol.
* a binary serialization protocol.
*/ */
class binary_deserializer : public deserializer { class binary_deserializer : public deserializer {
...@@ -48,12 +47,12 @@ class binary_deserializer : public deserializer { ...@@ -48,12 +47,12 @@ class binary_deserializer : public deserializer {
void read_raw(size_t num_bytes, void* storage) override; 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); 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); void set_rdbuf(const void* begin, const void* m_end);
......
...@@ -35,9 +35,7 @@ ...@@ -35,9 +35,7 @@
namespace caf { namespace caf {
/** /**
* @brief Implements the serializer interface with * Implements the serializer interface with a binary serialization protocol.
* a binary serialization protocol.
* @tparam Buffer A class providing a compatible interface to std::vector<char>.
*/ */
class binary_serializer : public serializer { class binary_serializer : public serializer {
...@@ -48,8 +46,7 @@ class binary_serializer : public serializer { ...@@ -48,8 +46,7 @@ class binary_serializer : public serializer {
using write_fun = std::function<void(const char*, const char*)>; using write_fun = std::function<void(const char*, const char*)>;
/** /**
* @brief Creates a binary serializer writing to @p write_buffer. * Creates a binary serializer writing to given iterator position.
* @warning @p write_buffer must be guaranteed to outlive @p this
*/ */
template <class OutIter> template <class OutIter>
binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) { binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) {
...@@ -59,7 +56,6 @@ class binary_serializer : public serializer { ...@@ -59,7 +56,6 @@ class binary_serializer : public serializer {
m_pos = std::copy(first, last, m_pos); m_pos = std::copy(first, last, m_pos);
} }
OutIter m_pos; OutIter m_pos;
}; };
m_out = fun{iter}; m_out = fun{iter};
} }
...@@ -83,7 +79,7 @@ class binary_serializer : public serializer { ...@@ -83,7 +79,7 @@ class binary_serializer : public serializer {
}; };
template <class T, 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) { binary_serializer& operator<<(binary_serializer& bs, const T& value) {
bs.write_value(value); bs.write_value(value);
return bs; return bs;
......
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
namespace caf { namespace caf {
/** /**
* @brief A thread-mapped or context-switching actor using a blocking * A thread-mapped or context-switching actor using a blocking
* receive rather than a behavior-stack based message processing. * receive rather than a behavior-stack based message processing.
* @extends local_actor * @extends local_actor
*/ */
class blocking_actor class blocking_actor
...@@ -101,8 +101,8 @@ class blocking_actor ...@@ -101,8 +101,8 @@ class blocking_actor
}; };
/** /**
* @brief Dequeues the next message from the mailbox that * Dequeues the next message from the mailbox that is
* is matched by given behavior. * matched by given behavior.
*/ */
template <class... Ts> template <class... Ts>
void receive(Ts&&... args) { void receive(Ts&&... args) {
...@@ -112,8 +112,8 @@ class blocking_actor ...@@ -112,8 +112,8 @@ class blocking_actor
} }
/** /**
* @brief Receives messages in an endless loop. * Semantically equal to: `for (;;) { receive(...); }`, but does
* Semantically equal to: <tt>for (;;) { receive(...); }</tt> * not cause a temporary behavior object per iteration.
*/ */
template <class... Ts> template <class... Ts>
void receive_loop(Ts&&... args) { void receive_loop(Ts&&... args) {
...@@ -122,21 +122,19 @@ class blocking_actor ...@@ -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: * Semantically equal to:
* <tt>for ( ; begin != end; ++begin) { receive(...); }</tt>. * `for ( ; begin != end; ++begin) { receive(...); }`.
* *
* <b>Usage example:</b> * **Usage example:**
* @code * ~~~
* int i = 0; * int i = 0;
* receive_for(i, 10) ( * 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> template <class T>
receive_for_helper<T> receive_for(T& begin, const T& end) { receive_for_helper<T> receive_for(T& begin, const T& end) {
...@@ -144,21 +142,18 @@ class blocking_actor ...@@ -144,21 +142,18 @@ class blocking_actor
} }
/** /**
* @brief Receives messages as long as @p stmt returns true. * Receives messages as long as `stmt` returns true.
* * Semantically equal to: `while (stmt()) { receive(...); }`.
* Semantically equal to: <tt>while (stmt()) { receive(...); }</tt>.
* *
* <b>Usage example:</b> * **Usage example:**
* @code * ~~~
* int i = 0; * int i = 0;
* receive_while([&]() { return (++i <= 10); }) * receive_while([&]() { return (++i <= 10); })
* ( * (
* on<int>() >> int_fun, * on<int>() >> int_fun,
* on<float>() >> float_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> template <class Statement>
receive_while_helper receive_while(Statement stmt) { receive_while_helper receive_while(Statement stmt) {
...@@ -168,13 +163,13 @@ class blocking_actor ...@@ -168,13 +163,13 @@ class blocking_actor
} }
/** /**
* @brief Receives messages until @p stmt returns true. * Receives messages until `stmt` returns true.
* *
* Semantically equal to: * Semantically equal to:
* <tt>do { receive(...); } while (stmt() == false);</tt> * `do { receive(...); } while (stmt() == false);`
* *
* <b>Usage example:</b> * **Usage example:**
* @code * ~~~
* int i = 0; * int i = 0;
* do_receive * do_receive
* ( * (
...@@ -182,9 +177,7 @@ class blocking_actor ...@@ -182,9 +177,7 @@ class blocking_actor
* on<float>() >> float_fun * on<float>() >> float_fun
* ) * )
* .until([&]() { return (++i >= 10); }; * .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> template <class... Ts>
do_receive_helper do_receive(Ts&&... args) { do_receive_helper do_receive(Ts&&... args) {
...@@ -198,17 +191,17 @@ class blocking_actor ...@@ -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(); void await_all_other_actors_done();
/** /**
* @brief Implements the actor's behavior. * Implements the actor's behavior.
*/ */
virtual void act() = 0; 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 * @throws actor_exited
*/ */
virtual void quit(uint32_t reason = exit_reason::normal); virtual void quit(uint32_t reason = exit_reason::normal);
......
...@@ -40,17 +40,15 @@ struct invalid_actor_t; ...@@ -40,17 +40,15 @@ struct invalid_actor_t;
struct invalid_group_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>, class channel : detail::comparable<channel>,
detail::comparable<channel, actor>, detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> { detail::comparable<channel, abstract_channel*> {
public:
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
public:
channel() = default; channel() = default;
channel(const actor&); channel(const actor&);
...@@ -63,19 +61,30 @@ class channel : detail::comparable<channel>, ...@@ -63,19 +61,30 @@ class channel : detail::comparable<channel>,
template <class T> template <class T>
channel(intrusive_ptr<T> ptr, channel(intrusive_ptr<T> ptr,
typename std::enable_if< typename std::enable_if<
std::is_base_of<abstract_channel, T>::value>::type* = 0) std::is_base_of<abstract_channel, T>::value
: m_ptr(ptr) {} >::type* = 0)
: m_ptr(ptr) {
// nop
}
channel(abstract_channel* ptr); 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; intptr_t compare(const channel& other) const;
...@@ -84,14 +93,14 @@ class channel : detail::comparable<channel>, ...@@ -84,14 +93,14 @@ class channel : detail::comparable<channel>,
intptr_t compare(const abstract_channel* other) const; intptr_t compare(const abstract_channel* other) const;
static intptr_t compare(const abstract_channel* lhs, static intptr_t compare(const abstract_channel* lhs,
const abstract_channel* rhs); const abstract_channel* rhs);
private: private:
inline abstract_channel* get() const {
return m_ptr.get();
}
inline abstract_channel* get() const { return m_ptr.get(); } abstract_channel_ptr m_ptr;
intrusive_ptr<abstract_channel> m_ptr;
}; };
} // namespace caf } // namespace caf
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
// - enables optional OpenCL module // - enables optional OpenCL module
/** /**
* @brief Denotes the libcaf version in the format {MAJOR}{MINOR}{PATCH}, * Denotes the libcaf version in the format {MAJOR}{MINOR}{PATCH},
* whereas each number is a two-digit decimal number without * whereas each number is a two-digit decimal number without
* leading zeros (e.g. 900 is version 0.9.0). * leading zeros (e.g. 900 is version 0.9.0).
*/ */
#define CAF_VERSION 1001 #define CAF_VERSION 1001
......
...@@ -32,21 +32,18 @@ namespace caf { ...@@ -32,21 +32,18 @@ namespace caf {
class local_actor; class local_actor;
/** /**
* @brief Helper class to enable users to add continuations * Helper class to enable users to add continuations
* when dealing with synchronous sends. * when dealing with synchronous sends.
*/ */
class continue_helper { class continue_helper {
public: public:
using message_id_wrapper_tag = int; using message_id_wrapper_tag = int;
continue_helper(message_id mid, local_actor* self); continue_helper(message_id mid, local_actor* self);
/** /**
* @brief Adds a continuation to the synchronous message handler * Adds the continuation `fun` to the synchronous message handler
* that is invoked if the response handler successfully returned. * that is invoked if the response handler successfully returned.
* @param fun The continuation as functor object.
*/ */
template <class F> template <class F>
continue_helper& continue_with(F fun) { continue_helper& continue_with(F fun) {
...@@ -55,22 +52,19 @@ class continue_helper { ...@@ -55,22 +52,19 @@ class continue_helper {
} }
/** /**
* @brief Adds a continuation to the synchronous message handler * Adds the continuation `fun` to the synchronous message handler
* that is invoked if the response handler successfully returned. * that is invoked if the response handler successfully returned.
* @param fun The continuation as functor object.
*/ */
continue_helper& continue_with(behavior::continuation_fun fun); 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; } message_id get_message_id() const { return m_mid; }
private: private:
message_id m_mid; message_id m_mid;
local_actor* m_self; local_actor* m_self;
}; };
} // namespace caf } // namespace caf
......
...@@ -28,13 +28,12 @@ ...@@ -28,13 +28,12 @@
namespace caf { namespace caf {
class object;
class actor_namespace; class actor_namespace;
class uniform_type_info; class uniform_type_info;
/** /**
* @ingroup TypeSystem * @ingroup TypeSystem
* @brief Technology-independent deserialization interface. * Technology-independent deserialization interface.
*/ */
class deserializer { class deserializer {
...@@ -48,34 +47,34 @@ class deserializer { ...@@ -48,34 +47,34 @@ class deserializer {
virtual ~deserializer(); virtual ~deserializer();
/** /**
* @brief Begins deserialization of a new object. * Begins deserialization of a new object.
*/ */
virtual const uniform_type_info* begin_object() = 0; virtual const uniform_type_info* begin_object() = 0;
/** /**
* @brief Ends deserialization of an object. * Ends deserialization of an object.
*/ */
virtual void end_object() = 0; virtual void end_object() = 0;
/** /**
* @brief Begins deserialization of a sequence. * Begins deserialization of a sequence.
* @returns The size of the sequence. * @returns The size of the sequence.
*/ */
virtual size_t begin_sequence() = 0; virtual size_t begin_sequence() = 0;
/** /**
* @brief Ends deserialization of a sequence. * Ends deserialization of a sequence.
*/ */
virtual void end_sequence() = 0; 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; virtual void read_value(primitive_variant& storage) = 0;
/** /**
* @brief Reads a value of type @p T from the data source. * Reads a value of type `T` from the data source.
* @note @p T must be a primitive type. * @note `T` must be a primitive type.
*/ */
template <class T> template <class T>
inline T read() { inline T read() {
...@@ -106,11 +105,13 @@ class deserializer { ...@@ -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; 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> template <class Buffer>
void read_raw(size_t num_bytes, Buffer& storage) { void read_raw(size_t num_bytes, Buffer& storage) {
...@@ -119,9 +120,7 @@ class deserializer { ...@@ -119,9 +120,7 @@ class deserializer {
} }
private: private:
actor_namespace* m_namespace; actor_namespace* m_namespace;
}; };
} // namespace caf } // namespace caf
......
...@@ -33,8 +33,8 @@ namespace caf { ...@@ -33,8 +33,8 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @brief Implements all pure virtual functions of {@link uniform_type_info} * Implements all pure virtual functions of `uniform_type_info`
* except serialize() and deserialize(). * except serialize() and deserialize().
*/ */
template <class T> template <class T>
class abstract_uniform_type_info : public uniform_type_info { class abstract_uniform_type_info : public uniform_type_info {
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <cstdint> #include <cstdint>
#include <condition_variable> #include <condition_variable>
#include "caf/attachable.hpp"
#include "caf/abstract_actor.hpp" #include "caf/abstract_actor.hpp"
#include "caf/detail/shared_spinlock.hpp" #include "caf/detail/shared_spinlock.hpp"
...@@ -39,23 +38,18 @@ namespace detail { ...@@ -39,23 +38,18 @@ namespace detail {
class singletons; class singletons;
class actor_registry : public singleton_mixin<actor_registry> { class actor_registry : public singleton_mixin<actor_registry> {
friend class singleton_mixin<actor_registry>;
public: public:
friend class singleton_mixin<actor_registry>;
~actor_registry(); ~actor_registry();
/** /**
* @brief A registry entry consists of a pointer to the actor and an * A registry entry consists of a pointer to the actor and an
* exit reason. An entry with a nullptr means the actor has finished * exit reason. An entry with a nullptr means the actor has finished
* execution for given reason. * execution for given reason.
*/ */
using value_type = std::pair<abstract_actor_ptr, uint32_t>; 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; value_type get_entry(actor_id key) const;
// return nullptr if the actor wasn't put *or* finished execution // return nullptr if the actor wasn't put *or* finished execution
...@@ -78,13 +72,14 @@ class actor_registry : public singleton_mixin<actor_registry> { ...@@ -78,13 +72,14 @@ class actor_registry : public singleton_mixin<actor_registry> {
size_t running() const; 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); void await_running_count_equal(size_t expected);
private: private:
using entries = std::map<actor_id, value_type>; using entries = std::map<actor_id, value_type>;
actor_registry();
std::atomic<size_t> m_running; std::atomic<size_t> m_running;
std::atomic<actor_id> m_ids; std::atomic<actor_id> m_ids;
...@@ -93,9 +88,6 @@ class actor_registry : public singleton_mixin<actor_registry> { ...@@ -93,9 +88,6 @@ class actor_registry : public singleton_mixin<actor_registry> {
mutable detail::shared_spinlock m_instances_mtx; mutable detail::shared_spinlock m_instances_mtx;
entries m_entries; entries m_entries;
actor_registry();
}; };
} // namespace detail } // namespace detail
......
...@@ -58,7 +58,7 @@ class behavior_stack { ...@@ -58,7 +58,7 @@ class behavior_stack {
void clear(); void clear();
// erases the synchronous response handler associated with @p rid // erases the synchronous response handler associated with `rid`
void erase(message_id rid) { void erase(message_id rid) {
erase_if([=](const element_type& e) { return e.second == rid; }); erase_if([=](const element_type& e) { return e.second == rid; });
} }
......
...@@ -24,13 +24,12 @@ namespace caf { ...@@ -24,13 +24,12 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @brief Barton–Nackman trick implementation. * Barton–Nackman trick implementation.
* * `Subclass` must provide a compare member function that compares
* @p Subclass must provide a @c compare member function that compares * to instances of `T` and returns an integer x with:
* to instances of @p T and returns an integer @c x with: * - `x < 0</tt> if <tt>*this < other
* - <tt>x < 0</tt> if <tt>*this < other</tt> * - `x > 0</tt> if <tt>*this > other
* - <tt>x > 0</tt> if <tt>*this > other</tt> * - `x == 0</tt> if <tt>*this == other
* - <tt>x == 0</tt> if <tt>*this == other</tt>
*/ */
template <class Subclass, class T = Subclass> template <class Subclass, class T = Subclass>
class comparable { class comparable {
......
...@@ -49,22 +49,22 @@ class decorated_tuple : public message_data { ...@@ -49,22 +49,22 @@ class decorated_tuple : public message_data {
using rtti = const std::type_info*; 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) { static inline pointer create(pointer d, vector_type v) {
return pointer{new decorated_tuple(std::move(d), std::move(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) { static inline pointer create(pointer d, rtti ti, vector_type v) {
return pointer{new decorated_tuple(std::move(d), ti, std::move(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) { static inline pointer create(pointer d, size_t offset) {
return pointer{new decorated_tuple(std::move(d), 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) { static inline pointer create(pointer d, rtti ti, size_t offset) {
return pointer{new decorated_tuple(std::move(d), ti, offset)}; return pointer{new decorated_tuple(std::move(d), ti, offset)};
} }
......
...@@ -26,12 +26,7 @@ namespace caf { ...@@ -26,12 +26,7 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @addtogroup MetaProgramming * A list of integers (wraps a long... template parameter pack).
* @{
*/
/**
* @brief A list of integers (wraps a long... template parameter pack).
*/ */
template <long... Is> template <long... Is>
struct int_list {}; struct int_list {};
...@@ -63,7 +58,7 @@ struct il_right<int_list<Is...>, N> : il_right_impl<(N > sizeof...(Is) ...@@ -63,7 +58,7 @@ struct il_right<int_list<Is...>, N> : il_right_impl<(N > sizeof...(Is)
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<>> template <class List, long Pos = 0, typename Indices = int_list<>>
struct il_indices; struct il_indices;
...@@ -99,10 +94,6 @@ constexpr auto get_right_indices(const T&) ...@@ -99,10 +94,6 @@ constexpr auto get_right_indices(const T&)
return {}; return {};
} }
/**
* @}
*/
} // namespace detail } // namespace detail
} // namespace caf } // namespace caf
......
...@@ -26,7 +26,7 @@ namespace caf { ...@@ -26,7 +26,7 @@ namespace caf {
namespace detail { 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> template <class Left, typename Right>
struct left_or_right { struct left_or_right {
...@@ -53,7 +53,7 @@ struct left_or_right<const unit_t&, 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> template <class Left, typename Right>
struct if_not_left { struct if_not_left {
......
...@@ -141,10 +141,10 @@ class lifted_fun_invoker<bool, F> { ...@@ -141,10 +141,10 @@ class lifted_fun_invoker<bool, F> {
}; };
/** /**
* @brief A lifted functor consists of a set of projections, a plain-old * A lifted functor consists of a set of projections, a plain-old
* functor and its signature. Note that the signature of the lifted * functor and its signature. Note that the signature of the lifted
* functor might differ from the underlying functor, because * functor might differ from the underlying functor, because
* of the projections. * of the projections.
*/ */
template <class F, class ListOfProjections, class... Args> template <class F, class ListOfProjections, class... Args>
class lifted_fun { class lifted_fun {
...@@ -185,7 +185,7 @@ 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) { optional_result_type operator()(Args... args) {
auto indices = get_indices(m_ps); auto indices = get_indices(m_ps);
......
...@@ -32,41 +32,33 @@ ...@@ -32,41 +32,33 @@
namespace caf { namespace caf {
namespace detail { 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 * @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> template <class T, size_t MaxSize>
class limited_vector { 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: public:
using value_type = T;
using value_type = T; using size_type = size_t;
using size_type = size_t; using difference_type = ptrdiff_t;
using difference_type = ptrdiff_t; using reference = value_type&;
using reference = value_type&; using const_reference = const value_type&;
using const_reference = const value_type&; using pointer = value_type*;
using pointer = value_type*; using const_pointer = const value_type*;
using const_pointer = const value_type*; using iterator = pointer;
using const_iterator = const_pointer;
using iterator = T*; using reverse_iterator = std::reverse_iterator<iterator>;
using const_iterator = const T*; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; limited_vector() : m_size(0) {
// nop
inline limited_vector() : m_size(0) { } }
limited_vector(size_t initial_size) : m_size(initial_size) { 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) { limited_vector(const limited_vector& other) : m_size(other.m_size) {
...@@ -96,149 +88,144 @@ class limited_vector { ...@@ -96,149 +88,144 @@ class limited_vector {
template <class InputIterator> template <class InputIterator>
void assign(InputIterator first, InputIterator last, void assign(InputIterator first, InputIterator last,
// dummy SFINAE argument // dummy SFINAE argument
typename std::iterator_traits<InputIterator>::pointer = 0) { typename std::iterator_traits<InputIterator>::pointer = 0) {
auto dist = std::distance(first, last); auto dist = std::distance(first, last);
CAF_REQUIRE(dist >= 0); CAF_REQUIRE(dist >= 0);
resize(static_cast<size_t>(dist)); resize(static_cast<size_t>(dist));
std::copy(first, last, begin()); std::copy(first, last, begin());
} }
inline size_type size() const { size_type size() const {
return m_size; return m_size;
} }
inline size_type max_size() const { size_type max_size() const {
return MaxSize; return MaxSize;
} }
inline size_type capacity() const { size_type capacity() const {
return max_size() - size(); return max_size() - size();
} }
inline void clear() { void clear() {
m_size = 0; m_size = 0;
} }
inline bool empty() const { bool empty() const {
return m_size == 0; return m_size == 0;
} }
inline bool full() const { bool full() const {
return m_size == MaxSize; return m_size == MaxSize;
} }
inline void push_back(const_reference what) { void push_back(const_reference what) {
CAF_REQUIRE(!full()); CAF_REQUIRE(!full());
m_data[m_size++] = what; m_data[m_size++] = what;
} }
inline void pop_back() { void pop_back() {
CAF_REQUIRE(!empty()); CAF_REQUIRE(!empty());
--m_size; --m_size;
} }
inline reference at(size_type pos) { reference at(size_type pos) {
CAF_REQUIRE(pos < m_size); CAF_REQUIRE(pos < m_size);
return m_data[pos]; return m_data[pos];
} }
inline const_reference at(size_type pos) const { const_reference at(size_type pos) const {
CAF_REQUIRE(pos < m_size); CAF_REQUIRE(pos < m_size);
return m_data[pos]; return m_data[pos];
} }
inline reference operator[](size_type pos) { reference operator[](size_type pos) {
return at(pos); return at(pos);
} }
inline const_reference operator[](size_type pos) const { const_reference operator[](size_type pos) const {
return at(pos); return at(pos);
} }
inline iterator begin() { iterator begin() {
return m_data; return m_data;
} }
inline const_iterator begin() const { const_iterator begin() const {
return m_data; return m_data;
} }
inline const_iterator cbegin() const { const_iterator cbegin() const {
return begin(); return begin();
} }
inline iterator end() { iterator end() {
return begin() + m_size; return begin() + m_size;
} }
inline const_iterator end() const { const_iterator end() const {
return begin() + m_size; return begin() + m_size;
} }
inline const_iterator cend() const { const_iterator cend() const {
return end(); return end();
} }
inline reverse_iterator rbegin() { reverse_iterator rbegin() {
return reverse_iterator(end()); return reverse_iterator(end());
} }
inline const_reverse_iterator rbegin() const { const_reverse_iterator rbegin() const {
return reverse_iterator(end()); return reverse_iterator(end());
} }
inline const_reverse_iterator crbegin() const { const_reverse_iterator crbegin() const {
return rbegin(); return rbegin();
} }
inline reverse_iterator rend() { reverse_iterator rend() {
return reverse_iterator(begin()); return reverse_iterator(begin());
} }
inline const_reverse_iterator rend() const { const_reverse_iterator rend() const {
return reverse_iterator(begin()); return reverse_iterator(begin());
} }
inline const_reverse_iterator crend() const { const_reverse_iterator crend() const {
return rend(); return rend();
} }
inline reference front() { reference front() {
CAF_REQUIRE(!empty()); CAF_REQUIRE(!empty());
return m_data[0]; return m_data[0];
} }
inline const_reference front() const { const_reference front() const {
CAF_REQUIRE(!empty()); CAF_REQUIRE(!empty());
return m_data[0]; return m_data[0];
} }
inline reference back() { reference back() {
CAF_REQUIRE(!empty()); CAF_REQUIRE(!empty());
return m_data[m_size - 1]; return m_data[m_size - 1];
} }
inline const_reference back() const { const_reference back() const {
CAF_REQUIRE(!empty()); CAF_REQUIRE(!empty());
return m_data[m_size - 1]; return m_data[m_size - 1];
} }
inline T* data() { T* data() {
return m_data; return m_data;
} }
inline const T* data() const { const T* data() const {
return m_data; 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> template <class InputIterator>
inline void insert(iterator pos, InputIterator first, InputIterator last) { void insert(iterator pos, InputIterator first, InputIterator last) {
CAF_REQUIRE(first <= last); CAF_REQUIRE(first <= last);
auto num_elements = static_cast<size_t>(std::distance(first, last)); auto num_elements = static_cast<size_t>(std::distance(first, last));
if ((size() + num_elements) > MaxSize) { if ((size() + num_elements) > MaxSize) {
...@@ -258,6 +245,9 @@ class limited_vector { ...@@ -258,6 +245,9 @@ class limited_vector {
} }
} }
private:
size_t m_size;
T m_data[(MaxSize > 0) ? MaxSize : 1];
}; };
} // namespace detail } // namespace detail
......
...@@ -233,7 +233,7 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; } ...@@ -233,7 +233,7 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/** /**
* @def CAF_LOGC * @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) \ #define CAF_LOGC(level, classname, funname, msg) \
CAF_CAT(CAF_PRINT, level)(CAF_CAT(CAF_LVL_NAME, level)(), classname, \ 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; } ...@@ -241,19 +241,19 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/** /**
* @def CAF_LOGF * @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) #define CAF_LOGF(level, msg) CAF_LOGC(level, "NONE", __func__, msg)
/** /**
* @def CAF_LOGMF * @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) #define CAF_LOGMF(level, msg) CAF_LOGC(level, CAF_CLASS_NAME, __func__, msg)
/** /**
* @def CAF_LOGC * @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) \ #define CAF_LOGC_IF(stmt, level, classname, funname, msg) \
CAF_CAT(CAF_PRINT_IF, level)(stmt, CAF_CAT(CAF_LVL_NAME, level)(), \ 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; } ...@@ -261,14 +261,14 @@ inline caf::actor_id caf_set_aid_dummy() { return 0; }
/** /**
* @def CAF_LOGF * @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) \ #define CAF_LOGF_IF(stmt, level, msg) \
CAF_LOGC_IF(stmt, level, "NONE", __func__, msg) CAF_LOGC_IF(stmt, level, "NONE", __func__, msg)
/** /**
* @def CAF_LOGMF * @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) \ #define CAF_LOGMF_IF(stmt, level, msg) \
CAF_LOGC_IF(stmt, level, CAF_CLASS_NAME, __func__, msg) CAF_LOGC_IF(stmt, level, CAF_CLASS_NAME, __func__, msg)
......
...@@ -76,7 +76,7 @@ class memory_cache { ...@@ -76,7 +76,7 @@ class memory_cache {
virtual std::pair<instance_wrapper*, void*> new_instance() = 0; 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; virtual void* downcast(memory_managed* ptr) = 0;
}; };
...@@ -94,10 +94,7 @@ class memory { ...@@ -94,10 +94,7 @@ class memory {
public: public:
/* // Allocates storage, initializes a new object, and returns the new instance.
* @brief Allocates storage, initializes a new object, and returns
* the new instance.
*/
template <class T, class... Ts> template <class T, class... Ts>
static T* create(Ts&&... args) { static T* create(Ts&&... args) {
return new T(std::forward<Ts>(args)...); return new T(std::forward<Ts>(args)...);
...@@ -198,10 +195,7 @@ class memory { ...@@ -198,10 +195,7 @@ class memory {
public: public:
/* // Allocates storage, initializes a new object, and returns the new instance.
* @brief Allocates storage, initializes a new object, and returns
* the new instance.
*/
template <class T, class... Ts> template <class T, class... Ts>
static T* create(Ts&&... args) { static T* create(Ts&&... args) {
auto mc = get_or_set_cache_map_entry<T>(); auto mc = get_or_set_cache_map_entry<T>();
......
...@@ -41,9 +41,9 @@ inline void yield() noexcept { ...@@ -41,9 +41,9 @@ inline void yield() noexcept {
req.tv_nsec = 1; req.tv_nsec = 1;
nanosleep(&req, nullptr); nanosleep(&req, nullptr);
} }
} } // namespace anonymous>
} } // namespace this_thread
} // namespace std::this_thread::<anonymous> } // namespace std
#endif #endif
// another GCC hack // another GCC hack
...@@ -61,17 +61,16 @@ inline void sleep_for(const chrono::duration<Rep, Period>& rt) { ...@@ -61,17 +61,16 @@ inline void sleep_for(const chrono::duration<Rep, Period>& rt) {
req.tv_nsec = nsec.count(); req.tv_nsec = nsec.count();
nanosleep(&req, nullptr); nanosleep(&req, nullptr);
} }
} } // namespace anonymous>
} } // namespace this_thread
} // namespace std::this_thread::<anonymous> } // namespace std
#endif #endif
namespace caf { namespace caf {
namespace detail { namespace detail {
/** /**
* @brief A producer-consumer list. * A producer-consumer list.
*
* For implementation details see http://drdobbs.com/cpp/211601363. * For implementation details see http://drdobbs.com/cpp/211601363.
*/ */
template <class T> template <class T>
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include <type_traits> #include <type_traits>
#include "caf/fwd.hpp"
#include "caf/duration.hpp" #include "caf/duration.hpp"
#include "caf/blocking_actor.hpp"
#include "caf/mailbox_element.hpp" #include "caf/mailbox_element.hpp"
#include "caf/detail/logging.hpp" #include "caf/detail/logging.hpp"
...@@ -35,7 +35,7 @@ namespace detail { ...@@ -35,7 +35,7 @@ namespace detail {
// 'imports' all member functions from policies to the actor, // 'imports' all member functions from policies to the actor,
// the resume mixin also adds the m_hidden member which *must* be // 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> template <class Base, class Derived, class Policies>
class proper_actor_base : public Policies::resume_policy::template class proper_actor_base : public Policies::resume_policy::template
mixin<Base, Derived> { mixin<Base, Derived> {
...@@ -317,8 +317,8 @@ class proper_actor<Base, Policies, true> ...@@ -317,8 +317,8 @@ class proper_actor<Base, Policies, true>
auto msg = make_message(timeout_msg{tid}); auto msg = make_message(timeout_msg{tid});
if (d.is_zero()) { if (d.is_zero()) {
// immediately enqueue timeout message if duration == 0s // immediately enqueue timeout message if duration == 0s
this->enqueue(this->address(), message_id::invalid, std::move(msg), this->enqueue(this->address(), message_id::invalid,
this->m_host); std::move(msg), this->host());
// auto e = this->new_mailbox_element(this, std::move(msg)); // auto e = this->new_mailbox_element(this, std::move(msg));
// this->m_mailbox.enqueue(e); // this->m_mailbox.enqueue(e);
} else { } else {
......
...@@ -43,7 +43,7 @@ struct purge_refs_impl<std::reference_wrapper<const T>> { ...@@ -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> template <class T>
struct purge_refs { struct purge_refs {
......
...@@ -63,7 +63,7 @@ namespace caf { ...@@ -63,7 +63,7 @@ namespace caf {
namespace detail { 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); void ripemd_160(std::array<uint8_t, 20>& storage, const std::string& data);
......
...@@ -34,9 +34,9 @@ namespace caf { ...@@ -34,9 +34,9 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @brief Compares two values by using @p operator== unless two floating * Compares two values by using `operator==` unless two floating
* point numbers are compared. In the latter case, the function * point numbers are compared. In the latter case, the function
* performs an epsilon comparison. * performs an epsilon comparison.
*/ */
template <class T, typename U> template <class T, typename U>
typename std::enable_if< !std::is_floating_point<T>::value typename std::enable_if< !std::is_floating_point<T>::value
......
...@@ -26,7 +26,7 @@ namespace caf { ...@@ -26,7 +26,7 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @brief A lightweight scope guard implementation. * A lightweight scope guard implementation.
*/ */
template <class Fun> template <class Fun>
class scope_guard { class scope_guard {
...@@ -49,8 +49,8 @@ class scope_guard { ...@@ -49,8 +49,8 @@ class scope_guard {
} }
/** /**
* @brief Disables this guard, i.e., the guard does not * Disables this guard, i.e., the guard does not
* run its cleanup code as it goes out of scope. * run its cleanup code as it goes out of scope.
*/ */
inline void disable() { m_enabled = false; } inline void disable() { m_enabled = false; }
...@@ -62,8 +62,7 @@ class scope_guard { ...@@ -62,8 +62,7 @@ class scope_guard {
}; };
/** /**
* @brief Creates a guard that executes @p f as soon as it * Creates a guard that executes `f` as soon as it goes out of scope.
* goes out of scope.
* @relates scope_guard * @relates scope_guard
*/ */
template <class Fun> template <class Fun>
......
...@@ -27,7 +27,7 @@ namespace caf { ...@@ -27,7 +27,7 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @brief A spinlock implementation providing shared and exclusive locking. * A spinlock implementation providing shared and exclusive locking.
*/ */
class shared_spinlock { class shared_spinlock {
......
...@@ -32,32 +32,30 @@ namespace caf { ...@@ -32,32 +32,30 @@ namespace caf {
namespace detail { 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 { enum class enqueue_result {
/** /**
* @brief Indicates that the enqueue operation succeeded and * Indicates that the enqueue operation succeeded and
* the reader is ready to receive the data. * the reader is ready to receive the data.
*/ */
success, success,
/** /**
* @brief Indicates that the enqueue operation succeeded and * Indicates that the enqueue operation succeeded and
* the reader is currently blocked, i.e., needs to be re-scheduled. * the reader is currently blocked, i.e., needs to be re-scheduled.
*/ */
unblocked_reader, unblocked_reader,
/** /**
* @brief Indicates that the enqueue operation failed because the * Indicates that the enqueue operation failed because the
* queue has been closed by the reader. * queue has been closed by the reader.
*/ */
queue_closed queue_closed
}; };
/** /**
* @brief An intrusive, thread-safe queue implementation. * An intrusive, thread-safe queue implementation.
* @note For implementation details see
* http://libcppa.blogspot.com/2011/04/mailbox-part-1.html
*/ */
template <class T, class Delete = std::default_delete<T>> template <class T, class Delete = std::default_delete<T>>
class single_reader_queue { class single_reader_queue {
...@@ -66,7 +64,7 @@ class single_reader_queue { ...@@ -66,7 +64,7 @@ class single_reader_queue {
using pointer = value_type*; 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). * @warning Call only from the reader (owner).
*/ */
pointer try_pop() { pointer try_pop() {
...@@ -74,7 +72,7 @@ class single_reader_queue { ...@@ -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). * @warning Call only from the reader (owner).
*/ */
enqueue_result enqueue(pointer new_element) { enqueue_result enqueue(pointer new_element) {
...@@ -97,8 +95,8 @@ class single_reader_queue { ...@@ -97,8 +95,8 @@ class single_reader_queue {
} }
/** /**
* @brief Queries whether there is new data to read, i.e., whether the next * Queries whether there is new data to read, i.e., whether the next
* call to {@link try_pop} would succeeed. * call to {@link try_pop} would succeeed.
* @pre !closed() * @pre !closed()
*/ */
bool can_fetch_more() { bool can_fetch_more() {
...@@ -111,7 +109,7 @@ class single_reader_queue { ...@@ -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). * @warning Call only from the reader (owner).
*/ */
bool empty() { bool empty() {
...@@ -120,25 +118,22 @@ class single_reader_queue { ...@@ -120,25 +118,22 @@ class single_reader_queue {
} }
/** /**
* @brief Queries whether this has been closed. * Queries whether this has been closed.
*/ */
bool closed() { bool closed() {
return m_stack.load() == nullptr; return m_stack.load() == nullptr;
} }
/** /**
* @brief Queries whether this has been marked as blocked, i.e., the * Queries whether this has been marked as blocked, i.e.,
* owner of the list is waiting for new data. * the owner of the list is waiting for new data.
*/ */
bool blocked() { bool blocked() {
return m_stack.load() == reader_blocked_dummy(); return m_stack.load() == reader_blocked_dummy();
} }
/** /**
* @brief Tries to set this queue from state @p empty to state @p blocked. * Tries to set this queue from state `empty` to state `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.
*/ */
bool try_block() { bool try_block() {
auto e = stack_empty_dummy(); auto e = stack_empty_dummy();
...@@ -149,9 +144,7 @@ class single_reader_queue { ...@@ -149,9 +144,7 @@ class single_reader_queue {
} }
/** /**
* @brief Tries to set this queue from state @p blocked to state @p empty. * Tries to set this queue from state `blocked` to state `empty`.
* @returns @p true if the state change was successful, otherwise @p false.
* @note This function never fails spuriously.
*/ */
bool try_unblock() { bool try_unblock() {
auto e = reader_blocked_dummy(); auto e = reader_blocked_dummy();
...@@ -159,7 +152,7 @@ class single_reader_queue { ...@@ -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). * @warning Call only from the reader (owner).
*/ */
void close() { void close() {
...@@ -170,7 +163,7 @@ class single_reader_queue { ...@@ -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. * elements before deleting them.
* @warning Call only from the reader (owner). * @warning Call only from the reader (owner).
*/ */
......
...@@ -86,17 +86,8 @@ class singletons { ...@@ -86,17 +86,8 @@ class singletons {
static std::atomic<abstract_singleton*>& get_plugin_singleton(size_t id); static std::atomic<abstract_singleton*>& get_plugin_singleton(size_t id);
/* /*
* @brief Type @p T has to provide: <tt>static T* create_singleton()</tt>, * Type `T` has to provide: `static T* create_singleton()`,
* <tt>void initialize()</tt>, <tt>void destroy()</tt>, * `void initialize()`, `void stop()`, and `dispose()`.
* 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.
*/ */
template <class T, typename Factory> template <class T, typename Factory>
static T* lazy_get(std::atomic<T*>& ptr, Factory f) { static T* lazy_get(std::atomic<T*>& ptr, Factory f) {
......
...@@ -23,10 +23,6 @@ ...@@ -23,10 +23,6 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
/**
* @ingroup MetaProgramming
* @brief Predefines the first template parameter of @p Tp1.
*/
template <template <class, typename> class Tpl, typename Arg1> template <template <class, typename> class Tpl, typename Arg1>
struct tbind { struct tbind {
template <class Arg2> template <class Arg2>
......
This diff is collapsed.
...@@ -23,10 +23,6 @@ ...@@ -23,10 +23,6 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
/**
* @ingroup MetaProgramming
* @brief A pair of two types.
*/
template <class First, typename Second> template <class First, typename Second>
struct type_pair { struct type_pair {
using first = First; using first = First;
......
...@@ -34,12 +34,7 @@ namespace caf { ...@@ -34,12 +34,7 @@ namespace caf {
namespace detail { namespace detail {
/** /**
* @addtogroup MetaProgramming * Equal to std::remove_const<std::remove_reference<T>::type>.
* @{
*/
/**
* @brief Equal to std::remove_const<std::remove_reference<T>::type>.
*/ */
template <class T> template <class T>
struct rm_const_and_ref { struct rm_const_and_ref {
...@@ -64,7 +59,7 @@ struct rm_const_and_ref<T&> { ...@@ -64,7 +59,7 @@ struct rm_const_and_ref<T&> {
// template <> struct rm_const_and_ref<void> { }; // template <> struct rm_const_and_ref<void> { };
/** /**
* @brief Joins all bool constants using operator &&. * Joins all bool constants using operator &&.
*/ */
template <bool... BoolConstants> template <bool... BoolConstants>
struct conjunction; struct conjunction;
...@@ -85,7 +80,7 @@ struct conjunction<V0, V1, Vs...> { ...@@ -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> template <bool... BoolConstants>
struct disjunction; struct disjunction;
...@@ -101,13 +96,13 @@ 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> template <class T>
struct is_anything : std::is_same<T, anything> {}; 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> template <class T, typename U>
struct is_array_of { struct is_array_of {
...@@ -118,7 +113,7 @@ 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> template <class T0, typename T1>
struct deduce_ref_type { struct deduce_ref_type {
...@@ -136,7 +131,7 @@ struct deduce_ref_type<const T0&, T1> { ...@@ -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> template <class X, class... Ts>
struct is_one_of; struct is_one_of;
...@@ -151,10 +146,10 @@ template <class X, typename T0, class... Ts> ...@@ -151,10 +146,10 @@ template <class X, typename T0, class... Ts>
struct is_one_of<X, T0, Ts...> : is_one_of<X, 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, * 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> template <class T>
struct is_builtin { struct is_builtin {
...@@ -167,7 +162,7 @@ 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. * type or convertible to one of STL's string types.
*/ */
template <class T> template <class T>
...@@ -180,7 +175,7 @@ struct is_primitive { ...@@ -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> template <class T1, typename T2>
class is_comparable { class is_comparable {
...@@ -207,7 +202,7 @@ 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> template <class T>
class is_forward_iterator { class is_forward_iterator {
...@@ -237,7 +232,7 @@ 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. * functions returning forward iterators.
*/ */
template <class T> template <class T>
...@@ -267,7 +262,7 @@ class is_iterable { ...@@ -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> template <class T>
struct is_legal_tuple_type { struct is_legal_tuple_type {
...@@ -278,7 +273,7 @@ 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> template <class T>
struct is_mutable_ref { struct is_mutable_ref {
...@@ -287,7 +282,7 @@ 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> template <class T>
struct rm_optional { struct rm_optional {
...@@ -300,13 +295,13 @@ struct rm_optional<optional<T>> { ...@@ -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, * (a) a member function pointer, (b) a function,
* (c) a function pointer, (d) an std::function. * (c) a function pointer, (d) an std::function.
* *
* @p result_type is the result type found in the signature. * `result_type` is the result type found in the signature.
* @p arg_types are the argument types as {@link type_list}. * `arg_types` are the argument types as {@link type_list}.
* @p fun_type is an std::function with an equivalent signature. * `fun_type` is an std::function with an equivalent signature.
*/ */
template <class Functor> template <class Functor>
struct callable_trait; struct callable_trait;
...@@ -356,7 +351,7 @@ struct get_callable_trait_helper<false, false, C> { ...@@ -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 * i.e., a function, member function, or a class providing
* the call operator. * the call operator.
*/ */
...@@ -379,7 +374,7 @@ struct get_callable_trait { ...@@ -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> template <class T>
struct is_callable { struct is_callable {
...@@ -406,7 +401,7 @@ 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> template <class... Ts>
struct all_callable { struct all_callable {
...@@ -414,7 +409,7 @@ 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 * A manipulator is a functor that manipulates its arguments via
* mutable references. * mutable references.
...@@ -437,7 +432,7 @@ struct map_to_result_type_impl<false, C> { ...@@ -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. * {@link unit_t} otherwise.
*/ */
template <class T> template <class T>
...@@ -460,7 +455,7 @@ struct replace_type_impl<true, T1, T2> { ...@@ -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> template <class What, typename With, class... IfStmt>
struct replace_type { struct replace_type {
...@@ -469,7 +464,7 @@ 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> template <size_t N, class... Ts>
struct type_at; struct type_at;
...@@ -484,10 +479,6 @@ struct type_at<0, T0, Ts...> { ...@@ -484,10 +479,6 @@ struct type_at<0, T0, Ts...> {
using type = T0; using type = T0;
}; };
/**
* @}
*/
} // namespace detail } // namespace detail
} // namespace caf } // namespace caf
......
...@@ -23,10 +23,6 @@ ...@@ -23,10 +23,6 @@
namespace caf { namespace caf {
namespace detail { namespace detail {
/**
* @ingroup MetaProgramming
* @brief A simple type wrapper.
*/
template <class T> template <class T>
struct wrapped { struct wrapped {
using type = T; using type = T;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
namespace caf { namespace caf {
/** /**
* @brief SI time units to specify timeouts. * SI time units to specify timeouts.
*/ */
enum class time_unit : uint32_t { enum class time_unit : uint32_t {
invalid = 0, invalid = 0,
...@@ -70,8 +70,7 @@ struct ratio_to_time_unit_helper<60, 1> { ...@@ -70,8 +70,7 @@ struct ratio_to_time_unit_helper<60, 1> {
}; };
/** /**
* @brief Converts an STL time period to a * Converts an STL time period to a `time_unit`.
* {@link caf::detail::time_unit time_unit}.
*/ */
template <class Period> template <class Period>
constexpr time_unit get_time_unit_from_period() { constexpr time_unit get_time_unit_from_period() {
...@@ -79,9 +78,7 @@ 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 duration consisting of a `time_unit` and a 64 bit unsigned integer.
* time_unit}
* and a 64 bit unsigned integer.
*/ */
class duration { class duration {
...@@ -92,8 +89,8 @@ class duration { ...@@ -92,8 +89,8 @@ class duration {
constexpr duration(time_unit u, uint32_t v) : unit(u), count(v) {} constexpr duration(time_unit u, uint32_t v) : unit(u), count(v) {}
/** /**
* @brief Creates a new instance from an STL duration. * Creates a new instance from an STL duration.
* @throws std::invalid_argument Thrown if <tt>d.count()</tt> is negative. * @throws std::invalid_argument Thrown if `d.count() is negative.
*/ */
template <class Rep, class Period> template <class Rep, class Period>
duration(std::chrono::duration<Rep, Period> d) duration(std::chrono::duration<Rep, Period> d)
...@@ -104,20 +101,20 @@ class duration { ...@@ -104,20 +101,20 @@ class duration {
} }
/** /**
* @brief Creates a new instance from an STL duration given in minutes. * Creates a new instance from an STL duration given in minutes.
* @throws std::invalid_argument Thrown if <tt>d.count()</tt> is negative. * @throws std::invalid_argument Thrown if `d.count() is negative.
*/ */
template <class Rep> template <class Rep>
duration(std::chrono::duration<Rep, std::ratio<60, 1>> d) duration(std::chrono::duration<Rep, std::ratio<60, 1>> d)
: unit(time_unit::seconds), count(rd(d) * 60) {} : 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; } 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; } inline bool is_zero() const { return count == 0; }
......
...@@ -38,8 +38,7 @@ ...@@ -38,8 +38,7 @@
namespace caf { 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 * This is the recommended base class for user-defined actors and is used
* implicitly when spawning functor-based actors without the * implicitly when spawning functor-based actors without the
* {@link blocking_api} flag. * {@link blocking_api} flag.
...@@ -62,12 +61,12 @@ class event_based_actor ...@@ -62,12 +61,12 @@ class event_based_actor
protected: protected:
/** /**
* @brief Returns the initial actor behavior. * Returns the initial actor behavior.
*/ */
virtual behavior make_behavior() = 0; 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); void forward_to(const actor& whom);
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
namespace caf { namespace caf {
/** /**
* @brief Base class for exceptions. * Base class for exceptions.
*/ */
class caf_exception : public std::exception { class caf_exception : public std::exception {
...@@ -41,22 +41,19 @@ class caf_exception : public std::exception { ...@@ -41,22 +41,19 @@ class caf_exception : public std::exception {
caf_exception& operator=(const caf_exception&) = default; caf_exception& operator=(const caf_exception&) = default;
/** /**
* @brief Returns the error message. * Returns the error message.
* @returns The error message as C-string.
*/ */
const char* what() const noexcept; const char* what() const noexcept;
protected: protected:
/** /**
* @brief Creates an exception with the error string @p what_str. * Creates an exception with the error string `what_str`.
* @param what_str Error message as rvalue string.
*/ */
caf_exception(std::string&& what_str); caf_exception(std::string&& what_str);
/** /**
* @brief Creates an exception with the error string @p what_str. * Creates an exception with the error string `what_str`.
* @param what_str Error message as string.
*/ */
caf_exception(const std::string& what_str); caf_exception(const std::string& what_str);
...@@ -67,7 +64,7 @@ class caf_exception : public std::exception { ...@@ -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 { class actor_exited : public caf_exception {
...@@ -81,9 +78,7 @@ class actor_exited : public caf_exception { ...@@ -81,9 +78,7 @@ class actor_exited : public caf_exception {
actor_exited& operator=(const actor_exited&) = default; actor_exited& operator=(const actor_exited&) = default;
/** /**
* @brief Gets the exit reason. * Returns the exit reason.
* @returns The exit reason of the terminating actor either set via
* {@link quit} or by a special (exit) message.
*/ */
inline uint32_t reason() const noexcept; inline uint32_t reason() const noexcept;
...@@ -94,8 +89,8 @@ class actor_exited : public caf_exception { ...@@ -94,8 +89,8 @@ class actor_exited : public caf_exception {
}; };
/** /**
* @brief Thrown to indicate that either an actor publishing failed or * Thrown to indicate that either an actor publishing failed or
* the middleman was unable to connect to a remote host. * the middleman was unable to connect to a remote host.
*/ */
class network_error : public caf_exception { class network_error : public caf_exception {
...@@ -112,8 +107,8 @@ 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 * Thrown to indicate that an actor publishing failed because
* the requested port could not be used. * the requested port could not be used.
*/ */
class bind_failure : public network_error { class bind_failure : public network_error {
......
...@@ -25,7 +25,7 @@ namespace caf { ...@@ -25,7 +25,7 @@ namespace caf {
class resumable; 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 { class execution_unit {
...@@ -34,9 +34,9 @@ class execution_unit { ...@@ -34,9 +34,9 @@ class execution_unit {
virtual ~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 * @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; virtual void exec_later(resumable* ptr) = 0;
......
...@@ -26,60 +26,60 @@ namespace caf { ...@@ -26,60 +26,60 @@ namespace caf {
namespace exit_reason { 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; 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; static constexpr uint32_t normal = 0x00001;
/** /**
* @brief Indicates that an actor finished execution * Indicates that an actor finished execution
* because of an unhandled exception. * because of an unhandled exception.
*/ */
static constexpr uint32_t unhandled_exception = 0x00002; 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 * tried to use {@link receive()} or a strongly typed actor tried
* to call {@link become()}. * to call {@link become()}.
*/ */
static constexpr uint32_t unallowed_function_call = 0x00003; 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. * synchronous reply message.
*/ */
static constexpr uint32_t unhandled_sync_failure = 0x00004; 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; 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. * the actor has been terminated and no longer exists.
*/ */
static constexpr uint32_t unknown = 0x00006; 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. * a user-generated event.
*/ */
static constexpr uint32_t user_shutdown = 0x00010; 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 * because a connection to a remote link was
* closed unexpectedly. * closed unexpectedly.
*/ */
static constexpr uint32_t remote_link_unreachable = 0x00101; 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 * value greater or equal to prevent collisions
* with default defined exit reasons. * with default defined exit reasons.
*/ */
......
...@@ -30,19 +30,20 @@ struct extend_helper; ...@@ -30,19 +30,20 @@ struct extend_helper;
template <class D, class B> template <class D, class B>
struct extend_helper<D, B> { struct extend_helper<D, B> {
using type = B; using type = B;
}; };
template <class D, class B, template <class, class> class M, template <class D, class B, template <class, class> class M,
template <class, class> class... Ms> 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 } // namespace detail
/** /**
* @brief Allows convenient definition of types using mixins. * Allows convenient definition of types using mixins.
* For example, "extend<ar, T>::with<ob, fo>" is an alias for * For example, `extend<ar, T>::with<ob, fo>` is an alias for
* "fo<ob<ar, T>, T>". * `fo<ob<ar, T>, T>`.
* *
* Mixins always have two template parameters: base type and * Mixins always have two template parameters: base type and
* derived type. This allows mixins to make use of the curiously recurring * 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...> {}; ...@@ -52,11 +53,10 @@ struct extend_helper<D, B, M, Ms...> : extend_helper<D, M<B, D>, Ms...> {};
template <class Base, class Derived = Base> template <class Base, class Derived = Base>
struct extend { struct extend {
/** /**
* @brief Identifies the combined type. * Identifies the combined type.
*/ */
template <template <class, class> class... Mixins> template <template <class, class> class... Mixins>
using with = typename detail::extend_helper<Derived, Base, Mixins...>::type; using with = typename detail::extend_helper<Derived, Base, Mixins...>::type;
}; };
} // namespace caf } // namespace caf
......
...@@ -29,19 +29,13 @@ ...@@ -29,19 +29,13 @@
namespace caf { namespace caf {
/** /**
* @brief Converts a string created by {@link caf::to_string to_string} * Converts a string created by `to_string` to its original value.
* to its original value.
* @param what String representation of a serialized value.
* @returns An {@link caf::object object} instance that contains
* the deserialized value.
*/ */
uniform_value from_string_impl(const std::string& what); uniform_value from_string_impl(const std::string& what);
/** /**
* @brief Convenience function that deserializes a value from @p what and * Convenience function that tries to deserializes a value from
* converts the result to @p T. * `what` and converts the result to `T`.
* @throws std::logic_error if the result is not of type @p T.
* @returns The deserialized value as instance of @p T.
*/ */
template <class T> template <class T>
optional<T> from_string(const std::string& what) { optional<T> from_string(const std::string& what) {
......
...@@ -53,7 +53,6 @@ struct invalid_actor_t; ...@@ -53,7 +53,6 @@ struct invalid_actor_t;
struct invalid_actor_addr_t; struct invalid_actor_addr_t;
// enums // enums
enum primitive_type : unsigned char;
enum class atom_value : uint64_t; enum class atom_value : uint64_t;
// intrusive pointer types // intrusive pointer types
......
...@@ -39,7 +39,7 @@ struct invalid_group_t { ...@@ -39,7 +39,7 @@ struct invalid_group_t {
}; };
/** /**
* @brief Identifies an invalid {@link group}. * Identifies an invalid {@link group}.
* @relates group * @relates group
*/ */
constexpr invalid_group_t invalid_group = invalid_group_t{}; constexpr invalid_group_t invalid_group = invalid_group_t{};
...@@ -73,8 +73,7 @@ class group : detail::comparable<group>, ...@@ -73,8 +73,7 @@ class group : detail::comparable<group>,
inline bool operator!() const { return !static_cast<bool>(m_ptr); } inline bool operator!() const { return !static_cast<bool>(m_ptr); }
/** /**
* @brief Returns a handle that grants access to * Returns a handle that grants access to actor operations such as enqueue.
* actor operations such as enqueue.
*/ */
inline abstract_group* operator->() const { return m_ptr.get(); } inline abstract_group* operator->() const { return m_ptr.get(); }
...@@ -87,16 +86,15 @@ class group : detail::comparable<group>, ...@@ -87,16 +86,15 @@ class group : detail::comparable<group>,
} }
/** /**
* @brief Get a pointer to the group associated with * Get a pointer to the group associated with
* @p group_identifier from the module @p module_name. * `group_identifier` from the module `module_name`.
* @threadsafe * @threadsafe
*/ */
static group get(const std::string& module_name, static group get(const std::string& module_name,
const std::string& group_identifier); const std::string& group_identifier);
/** /**
* @brief Returns an anonymous group. * Returns an anonymous group.
*
* Each calls to this member function returns a new instance * Each calls to this member function returns a new instance
* of an anonymous group. Anonymous groups can be used whenever * of an anonymous group. Anonymous groups can be used whenever
* a set of actors wants to communicate using an exclusive channel. * a set of actors wants to communicate using an exclusive channel.
...@@ -104,13 +102,13 @@ class group : detail::comparable<group>, ...@@ -104,13 +102,13 @@ class group : detail::comparable<group>,
static group anonymous(); static group anonymous();
/** /**
* @brief Add a new group module to the group management. * Add a new group module to the group management.
* @threadsafe * @threadsafe
*/ */
static void add_module(abstract_group::unique_module_ptr); 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 * @threadsafe
*/ */
static abstract_group::module_ptr static abstract_group::module_ptr
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
namespace caf { namespace caf {
/** /**
* @brief An intrusive, reference counting smart pointer impelementation. * An intrusive, reference counting smart pointer impelementation.
* @relates ref_counted * @relates ref_counted
*/ */
template <class T> template <class T>
...@@ -67,8 +67,8 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>, ...@@ -67,8 +67,8 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>,
} }
/** /**
* @brief Returns the raw pointer without modifying reference count * Returns the raw pointer without modifying reference
* and sets this to @p nullptr. * count and sets this to `nullptr`.
*/ */
pointer release() { pointer release() {
auto result = m_ptr; auto result = m_ptr;
...@@ -77,7 +77,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>, ...@@ -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) { void adopt(pointer ptr) {
reset(); reset();
...@@ -161,7 +161,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>, ...@@ -161,7 +161,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>>,
* @relates intrusive_ptr * @relates intrusive_ptr
*/ */
template <class X, typename Y> 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(); return lhs.get() == rhs.get();
} }
...@@ -169,7 +169,7 @@ inline bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) ...@@ -169,7 +169,7 @@ inline bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs)
* @relates intrusive_ptr * @relates intrusive_ptr
*/ */
template <class X, typename Y> 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); return !(lhs == rhs);
} }
......
This diff is collapsed.
...@@ -139,18 +139,18 @@ class match_each_helper { ...@@ -139,18 +139,18 @@ class match_each_helper {
namespace caf { namespace caf {
/** /**
* @brief Starts a match expression. * Starts a match expression.
* @param what Tuple that should be matched against a pattern. * @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) { inline detail::match_helper match(message what) {
return what; return what;
} }
/** /**
* @brief Starts a match expression. * Starts a match expression.
* @param what Value that should be matched against a pattern. * @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> template <class T>
detail::match_helper match(T&& what) { detail::match_helper match(T&& what) {
...@@ -158,17 +158,17 @@ 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 detail::match_helper
match_split(const std::string& str, char delim, bool keep_empties = false); 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). * range [first, last).
* @param first Iterator to the first element. * @param first Iterator to the first element.
* @param last Iterator to the last element (excluded). * @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> template <class InputIterator>
detail::match_each_helper<InputIterator> detail::match_each_helper<InputIterator>
...@@ -177,12 +177,12 @@ match_each(InputIterator first, InputIterator last) { ...@@ -177,12 +177,12 @@ match_each(InputIterator first, InputIterator last) {
} }
/** /**
* @brief Starts a match expression that matches <tt>proj(i)</tt> for * Starts a match expression that matches `proj(i) for
* each element @p i in range [first, last). * each element `i` in range [first, last).
* @param first Iterator to the first element. * @param first Iterator to the first element.
* @param last Iterator to the last element (excluded). * @param last Iterator to the last element (excluded).
* @param proj Projection or extractor functor. * @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> template <class InputIterator, typename Projection>
detail::match_each_helper<InputIterator, Projection> detail::match_each_helper<InputIterator, Projection>
......
...@@ -586,8 +586,8 @@ struct match_result_from_type_list<detail::type_list<Ts...>> { ...@@ -586,8 +586,8 @@ struct match_result_from_type_list<detail::type_list<Ts...>> {
}; };
/** /**
* @brief A match expression encapsulating cases <tt>Cs...</tt>, whereas * A match expression encapsulating cases `Cs..., whereas
* each case is a @p detail::match_expr_case<...>. * each case is a `detail::match_expr_case<`...>.
*/ */
template <class... Cs> template <class... Cs>
class match_expr { class match_expr {
......
...@@ -27,27 +27,23 @@ struct disposer; ...@@ -27,27 +27,23 @@ struct disposer;
} }
/** /**
* @brief This base enables derived classes to enforce a different * This base enables derived classes to enforce a different
* allocation strategy than new/delete by providing a virtual * allocation strategy than new/delete by providing a virtual
* protected @p request_deletion() function and non-public destructor. * protected `request_deletion()` function and non-public destructor.
*/ */
class memory_managed { class memory_managed {
friend struct detail::disposer;
public: public:
friend struct detail::disposer;
/** /**
* @brief Default implementations calls <tt>delete this</tt>, but can * Default implementations calls `delete this, but can
* be overriden in case deletion depends on some condition or * be overriden in case deletion depends on some condition or
* the class doesn't use default new/delete. * the class doesn't use default new/delete.
*/ */
virtual void request_deletion(); virtual void request_deletion();
protected: protected:
virtual ~memory_managed(); virtual ~memory_managed();
}; };
} // namespace caf } // namespace caf
......
This diff is collapsed.
...@@ -31,22 +31,19 @@ ...@@ -31,22 +31,19 @@
namespace caf { namespace caf {
/** /**
* @brief Provides a convenient interface to create a {@link message} * Provides a convenient interface to create a {@link message}
* from a series of values using the member function @p append. * from a series of values using the member function `append`.
*/ */
class message_builder { class message_builder {
public:
message_builder();
message_builder(const message_builder&) = delete; message_builder(const message_builder&) = delete;
message_builder& operator=(const message_builder&) = delete; message_builder& operator=(const message_builder&) = delete;
public: ~message_builder();
message_builder();
/** /**
* @brief Creates a new instance and immediately calls * Creates a new instance and immediately calls `append(first, last)`.
* <tt>append(first, last)</tt>.
*/ */
template <class Iter> template <class Iter>
message_builder(Iter first, Iter last) { message_builder(Iter first, Iter last) {
...@@ -54,15 +51,13 @@ class message_builder { ...@@ -54,15 +51,13 @@ class message_builder {
append(first, last); 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); message_builder& append(uniform_value what);
/** /**
* @brief Appends all values in range [first, last). * Appends all values in range [first, last).
*/ */
template <class Iter> template <class Iter>
message_builder& append(Iter first, Iter last) { message_builder& append(Iter first, Iter last) {
...@@ -78,7 +73,7 @@ class message_builder { ...@@ -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> template <class T>
message_builder& append(T what) { message_builder& append(T what) {
...@@ -86,40 +81,39 @@ class message_builder { ...@@ -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 * It is worth mentioning that a call to `to_message` does neither
* invalidate the @p message_builder instance nor clears the internal * invalidate the `message_builder` instance nor clears the internal
* buffer. However, calling any non-const member function afterwards * 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. * copy it if there is more than one reference to it.
*/ */
message to_message(); 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) { inline optional<message> apply(message_handler handler) {
return to_message().apply(std::move(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(); void clear();
/** /**
* @brief Returns whether the internal buffer is empty. * Returns whether the internal buffer is empty.
*/ */
bool empty() const; 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; size_t size() const;
private: private:
void init(); void init();
template <class T> template <class T>
...@@ -139,7 +133,6 @@ class message_builder { ...@@ -139,7 +133,6 @@ class message_builder {
const dynamic_msg_data* data() const; const dynamic_msg_data* data() const;
intrusive_ptr<ref_counted> m_data; // hide dynamic_msg_data implementation intrusive_ptr<ref_counted> m_data; // hide dynamic_msg_data implementation
}; };
} // namespace caf } // namespace caf
......
...@@ -41,104 +41,98 @@ ...@@ -41,104 +41,98 @@
namespace caf { namespace caf {
class behavior;
/** /**
* @brief A partial function implementation * A partial function implementation used to process a `message`.
* for {@link caf::message messages}.
*/ */
class message_handler { class message_handler {
friend class behavior;
public: 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() = default;
message_handler(message_handler&&) = default; message_handler(message_handler&&) = default;
message_handler(const message_handler&) = default; message_handler(const message_handler&) = default;
message_handler& operator=(message_handler&&) = default; message_handler& operator=(message_handler&&) = default;
message_handler& operator=(const 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> 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 * Runs this handler and returns its (optional) result.
* handler of this behavior, returns @p nothing otherwise.
*/ */
template <class T> 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 * Returns a new handler that concatenates this handler
* this partial function is not defined. * with a new handler from `args...`.
*/ */
template <class... Ts> template <class... Ts>
typename std::conditional< typename std::conditional<
detail::disjunction<may_have_timeout< detail::disjunction<may_have_timeout<
typename detail::rm_const_and_ref<Ts>::type>::value...>::value, typename detail::rm_const_and_ref<Ts>::type>::value...>::value,
behavior, message_handler>::type behavior,
or_else(Ts&&... args) const; 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: private:
impl_ptr m_impl; impl_ptr m_impl;
}; };
/**
* Enables concatenation of message handlers by using a list
* of commata separated handlers.
* @relates message_handler
*/
template <class... Cases> template <class... Cases>
message_handler operator, (const match_expr<Cases...>& mexpr, message_handler operator,(const match_expr<Cases...>& mexpr,
const message_handler& pfun) { const message_handler& pfun) {
return mexpr.as_behavior_impl()->or_else(pfun.as_behavior_impl()); 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> template <class... Cases>
message_handler operator, (const message_handler& pfun, message_handler operator,(const message_handler& pfun,
const match_expr<Cases...>& mexpr) { const match_expr<Cases...>& mexpr) {
return pfun.as_behavior_impl()->or_else(mexpr.as_behavior_impl()); 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 } // namespace caf
#endif // CAF_PARTIAL_FUNCTION_HPP #endif // CAF_PARTIAL_FUNCTION_HPP
...@@ -33,7 +33,7 @@ struct invalid_message_id { ...@@ -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. * @note Asynchronous messages always have an invalid message id.
*/ */
class message_id : detail::comparable<message_id> { class message_id : detail::comparable<message_id> {
......
...@@ -146,7 +146,7 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> { ...@@ -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}. * @note This mixin implicitly includes {@link single_timeout}.
*/ */
template <class BehaviorType> template <class BehaviorType>
......
...@@ -29,8 +29,8 @@ namespace caf { ...@@ -29,8 +29,8 @@ namespace caf {
namespace mixin { namespace mixin {
/** /**
* @brief This mixin adds all member functions and member variables needed * This mixin adds all member functions and member variables needed
* by the memory management subsystem. * by the memory management subsystem.
*/ */
template <class Base, class Subtype> template <class Base, class Subtype>
class memory_cached : public Base { class memory_cached : public Base {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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