Commit 870ed47e authored by Dominik Charousset's avatar Dominik Charousset

Tweak network layer, namespaces & singletons

This patch ports most changes from Boost.Actor back to libcppa. This includes:
1) a new network abstraction that is easier to maintain and not entangled with
the middleman, 2) a new default network protocol named BAP: "Binary Actor
Protocol" that replaces the previous mostly undocumented mess, 3) an all-new
and clean broker-based communication infrastructure that replaces the
peer/peer_acceptor design, 4) a reorganization of the namespaces: removed
"util" and "intrusive" and moved most of these classes to "detail", 5) a new
singleton class replacing singleton_manager, and 6) a new `actor_cast` function
replacing the clumsy `detail::raw_access` API.
parent a96f232d
......@@ -127,18 +127,8 @@ file(GLOB LIBCPPA_HDRS "cppa/*.hpp"
"cppa/io/*.hpp"
"cppa/opencl/*.hpp"
"cppa/qtsupport/*.hpp"
"cppa/util/*.hpp")
# platform-dependent files
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LIBCPPA_PLATFORM_SRCS src/middleman_event_handler_epoll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBCPPA_PLATFORM_SRCS src/middleman_event_handler_poll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Window")
set(LIBCPPA_PLATFORM_SRCS src/middleman_event_handler_poll.cpp src/execinfo_windows.cpp)
else ()
message(FATAL_ERROR "This platform is not supported by libcppa")
endif()
"cppa/policy/*.hpp"
"cppa/mixin/*.hpp")
# list cpp files excluding platform-dependent files
set (LIBCPPA_SRCS
......@@ -146,7 +136,6 @@ set (LIBCPPA_SRCS
src/abstract_actor.cpp
src/abstract_channel.cpp
src/abstract_group.cpp
src/acceptor.cpp
src/actor.cpp
src/actor_addr.cpp
src/actor_companion.cpp
......@@ -154,23 +143,18 @@ set (LIBCPPA_SRCS
src/actor_ostream.cpp
src/actor_proxy.cpp
src/actor_registry.cpp
src/algorithm.cpp
src/atom.cpp
src/attachable.cpp
src/basp_broker.cpp
src/behavior.cpp
src/behavior_stack.cpp
src/binary_deserializer.cpp
src/binary_serializer.cpp
src/blocking_actor.cpp
src/broker.cpp
src/buffer.cpp
src/channel.cpp
src/context_switching_resume.cpp
src/continuable.cpp
src/continue_helper.cpp
src/cs_thread.cpp
src/decorated_tuple.cpp
src/default_message_queue.cpp
src/demangle.cpp
src/deserializer.cpp
src/duration.cpp
......@@ -178,14 +162,10 @@ set (LIBCPPA_SRCS
src/exception.cpp
src/execution_unit.cpp
src/exit_reason.cpp
src/fd_util.cpp
src/functor_based_actor.cpp
src/functor_based_blocking_actor.cpp
src/get_mac_addresses.cpp
src/get_root_uuid.cpp
src/group.cpp
src/group_manager.cpp
src/input_stream.cpp
src/local_actor.cpp
src/logging.cpp
src/mailbox_element.cpp
......@@ -194,41 +174,30 @@ set (LIBCPPA_SRCS
src/memory_managed.cpp
src/message.cpp
src/message_builder.cpp
src/message_data.cpp
src/message_handler.cpp
src/message_header.cpp
src/middleman.cpp
src/middleman_event_handler.cpp
src/network.cpp
src/node_id.cpp
src/opencl/global.cpp
src/opencl/opencl_metainfo.cpp
src/opencl/program.cpp
src/opt.cpp
src/output_stream.cpp
src/peer.cpp
src/peer_acceptor.cpp
src/primitive_variant.cpp
src/options_description.cpp
src/ref_counted.cpp
src/remote_actor_proxy.cpp
src/response_promise.cpp
src/resumable.cpp
src/ripemd_160.cpp
src/scheduler.cpp
src/shutdown.cpp
src/scoped_actor.cpp
src/serializer.cpp
src/shared_spinlock.cpp
src/singleton_manager.cpp
src/stream.cpp
src/singletons.cpp
src/string_algorithms.cpp
src/string_serialization.cpp
src/sync_request_bouncer.cpp
src/tcp_acceptor.cpp
src/tcp_io_stream.cpp
src/publish_local_groups.cpp
src/to_uniform_name.cpp
src/type_lookup_table.cpp
src/unicast_network.cpp
src/uniform_type_info.cpp
src/uniform_type_info_map.cpp
src/weak_ptr_anchor.cpp
src/yield_interface.cpp)
src/uniform_type_info_map.cpp)
if (BOOST_ROOT)
# Prevent falling back to system paths when using a custom Boost prefix.
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ABSTRACT_ACTOR_HPP
#define CPPA_ABSTRACT_ACTOR_HPP
......@@ -30,14 +29,14 @@
#include <type_traits>
#include "cppa/node_id.hpp"
#include "cppa/cppa_fwd.hpp"
#include "cppa/fwd.hpp"
#include "cppa/attachable.hpp"
#include "cppa/message_id.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/abstract_channel.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/type_traits.hpp"
namespace cppa {
......@@ -50,7 +49,12 @@ class execution_unit;
* @brief A unique actor ID.
* @relates abstract_actor
*/
typedef std::uint32_t actor_id;
typedef uint32_t actor_id;
/**
* @brief Denotes an ID that is never used by an actor.
*/
constexpr actor_id invalid_actor_id = 0;
class actor;
class abstract_actor;
......@@ -65,6 +69,8 @@ class abstract_actor : public abstract_channel {
friend class response_promise;
using super = abstract_channel;
public:
/**
......@@ -161,23 +167,11 @@ class abstract_actor : public abstract_channel {
*/
inline actor_id id() const;
/**
* @brief Checks if this actor is running on a remote node.
* @returns @c true if this actor represents a remote actor;
* otherwise @c false.
*/
inline bool is_proxy() const;
/**
* @brief Returns the ID of the node this actor is running on.
*/
inline const node_id& node() const;
/**
* @brief Returns the actor's exit reason of
* <tt>exit_reason::not_exited</tt> if it's still alive.
*/
inline std::uint32_t exit_reason() const;
inline uint32_t exit_reason() const;
/**
* @brief Returns the type interface as set of strings.
......@@ -189,14 +183,14 @@ class abstract_actor : public abstract_channel {
abstract_actor();
abstract_actor(actor_id aid);
abstract_actor(actor_id aid, node_id nid);
/**
* @brief Should be overridden by subtypes and called upon termination.
* @note Default implementation sets 'exit_reason' accordingly.
* @note Overridden functions should always call super::cleanup().
*/
virtual void cleanup(std::uint32_t reason);
virtual void cleanup(uint32_t reason);
/**
* @brief The default implementation for {@link link_to()}.
......@@ -222,7 +216,7 @@ class abstract_actor : public abstract_channel {
private:
// initially exit_reason::not_exited
std::atomic<std::uint32_t> m_exit_reason;
std::atomic<uint32_t> m_exit_reason;
// guards access to m_exit_reason, m_attachables, and m_links
std::mutex m_mtx;
......@@ -235,9 +229,6 @@ class abstract_actor : public abstract_channel {
protected:
// identifies the node this actor is running on
node_id_ptr m_node;
// identifies the execution unit this actor is currently executed by
execution_unit* m_host;
......@@ -247,26 +238,14 @@ class abstract_actor : public abstract_channel {
* inline and template member function implementations *
******************************************************************************/
inline std::uint32_t abstract_actor::id() const {
return m_id;
}
inline uint32_t abstract_actor::id() const { return m_id; }
inline bool abstract_actor::is_proxy() const {
return m_is_proxy;
}
inline std::uint32_t abstract_actor::exit_reason() const {
return m_exit_reason;
}
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;
}
inline const node_id& abstract_actor::node() const {
return *m_node;
}
template<class F>
struct functor_attachable : attachable {
......@@ -275,7 +254,7 @@ struct functor_attachable : attachable {
template<typename T>
inline functor_attachable(T&& arg) : m_functor(std::forward<T>(arg)) { }
void actor_exited(std::uint32_t reason) { m_functor(reason); }
void actor_exited(uint32_t reason) { m_functor(reason); }
bool matches(const attachable::token&) { return false; }
......@@ -283,7 +262,7 @@ struct functor_attachable : attachable {
template<typename F>
bool abstract_actor::attach_functor(F&& f) {
typedef typename util::rm_const_and_ref<F>::type f_type;
typedef typename detail::rm_const_and_ref<F>::type f_type;
typedef functor_attachable<f_type> impl;
return attach(attachable_ptr{new impl(std::forward<F>(f))});
}
......
......@@ -16,11 +16,12 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ABSTRACT_CHANNEL_HPP
#define CPPA_ABSTRACT_CHANNEL_HPP
#include "cppa/cppa_fwd.hpp"
#include "cppa/fwd.hpp"
#include "cppa/node_id.hpp"
#include "cppa/message_id.hpp"
#include "cppa/ref_counted.hpp"
namespace cppa {
......@@ -35,6 +36,8 @@ class abstract_channel : public ref_counted {
public:
virtual ~abstract_channel();
/**
* @brief Enqueues a new message to the channel.
* @param header Contains meta information about this message
......@@ -45,16 +48,38 @@ class abstract_channel : public ref_counted {
* caller is executed by or @p nullptr if the caller
* is not a scheduled actor.
*/
virtual void enqueue(msg_hdr_cref header,
message content,
execution_unit* host) = 0;
virtual void enqueue(const actor_addr& sender, message_id mid,
message content, execution_unit* host) = 0;
/**
* @brief Returns the ID of the node this actor is running on.
*/
inline node_id node() const;
/**
* @brief Returns true if {@link node_ptr} returns
*/
bool is_remote() const;
protected:
virtual ~abstract_channel();
abstract_channel();
abstract_channel(node_id nid);
private:
// identifies the node of this channel
node_id m_node;
};
using abstract_channel_ptr = intrusive_ptr<abstract_channel>;
inline node_id abstract_channel::node() const {
return m_node;
}
} // namespace cppa
#endif // CPPA_ABSTRACT_CHANNEL_HPP
......@@ -37,7 +37,6 @@ class peer_connection;
} // namespace detail
} // namespace cppa
namespace cppa {
class group;
......@@ -163,14 +162,6 @@ class abstract_group : public abstract_channel {
*/
typedef intrusive_ptr<abstract_group> abstract_group_ptr;
/**
* @brief Makes *all* local groups accessible via network on address @p addr
* and @p port.
* @throws bind_failure
* @throws network_error
*/
void publish_local_groups(std::uint16_t port, const char* addr = nullptr);
} // namespace cppa
#endif // CPPA_ABSTRACT_GROUP_HPP
......@@ -16,22 +16,21 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACCEPT_HANDLE_HPP
#define CPPA_ACCEPT_HANDLE_HPP
#ifndef CPPA_IO_ACCEPT_HANDLE_HPP
#define CPPA_IO_ACCEPT_HANDLE_HPP
#include "cppa/detail/handle.hpp"
#include "cppa/io_handle.hpp"
namespace cppa {
namespace io {
class broker;
class accept_handle : public detail::handle<accept_handle> {
/**
* @brief Generic handle type for managing incoming connections.
*/
class accept_handle : public io_handle<accept_handle> {
friend class detail::handle<accept_handle>;
friend class io_handle<accept_handle>;
typedef detail::handle<accept_handle> super;
typedef io_handle<accept_handle> super;
public:
......@@ -39,11 +38,10 @@ class accept_handle : public detail::handle<accept_handle> {
private:
inline accept_handle(int handle_id) : super{handle_id} { }
inline accept_handle(int64_t handle_id) : super{handle_id} {}
};
} // namespace io
} // namespace cppa
#endif // CPPA_IO_ACCEPT_HANDLE_HPP
#endif // CPPA_ACCEPT_HANDLE_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACTOR_HPP
#define CPPA_ACTOR_HPP
......@@ -26,36 +25,19 @@
#include <type_traits>
#include "cppa/intrusive_ptr.hpp"
#include "cppa/fwd.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/util/comparable.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/comparable.hpp"
#include "cppa/detail/type_traits.hpp"
namespace cppa {
class actor_addr;
class actor_proxy;
class local_actor;
class blocking_actor;
class actor_companion;
class event_based_actor;
struct invalid_actor_addr_t;
namespace io {
class broker;
} // namespace io
namespace opencl {
template<typename Signature>
class actor_facade;
} // namespace opencl
struct invalid_actor_t {
constexpr invalid_actor_t() {}
namespace detail {
class raw_access;
} // namespace detail
struct invalid_actor_t { constexpr invalid_actor_t() { } };
};
/**
* @brief Identifies an invalid {@link actor}.
......@@ -65,16 +47,9 @@ constexpr invalid_actor_t invalid_actor = invalid_actor_t{};
template<typename T>
struct is_convertible_to_actor {
static constexpr bool value = std::is_base_of<io::broker, T>::value
|| std::is_base_of<actor_proxy, T>::value
|| std::is_base_of<blocking_actor, T>::value
|| std::is_base_of<actor_companion, T>::value
|| std::is_base_of<event_based_actor, T>::value;
};
static constexpr bool value = std::is_base_of<actor_proxy, T>::value ||
std::is_base_of<local_actor, T>::value;
template<typename T>
struct is_convertible_to_actor<opencl::actor_facade<T>> {
static constexpr bool value = true;
};
/**
......@@ -84,13 +59,15 @@ struct is_convertible_to_actor<opencl::actor_facade<T>> {
* {@link blocking_actor}, {@link actor_proxy}, or
* {@link io::broker}.
*/
class actor : util::comparable<actor>
, util::comparable<actor, actor_addr>
, util::comparable<actor, invalid_actor_t>
, util::comparable<actor, invalid_actor_addr_t> {
class actor : detail::comparable<actor>,
detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>,
detail::comparable<actor, invalid_actor_addr_t> {
friend class local_actor;
friend class detail::raw_access;
template<typename T, typename U>
friend T actor_cast(const U&);
public:
......@@ -103,12 +80,12 @@ class actor : util::comparable<actor>
template<typename T>
actor(intrusive_ptr<T> ptr,
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0)
: m_ptr(std::move(ptr)) { }
: m_ptr(std::move(ptr)) {}
template<typename T>
actor(T* ptr,
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0)
: m_ptr(ptr) { }
: m_ptr(ptr) {}
actor(const invalid_actor_t&);
......@@ -175,6 +152,10 @@ class actor : util::comparable<actor>
void swap(actor& other);
inline abstract_actor* get() const {
return m_ptr.get();
}
actor(abstract_actor*);
abstract_actor_ptr m_ptr;
......@@ -183,4 +164,15 @@ class actor : util::comparable<actor>
} // namespace cppa
// allow actor to be used in hash maps
namespace std {
template<>
struct hash<cppa::actor> {
inline size_t operator()(const cppa::actor& ref) const {
return ref ? static_cast<size_t>(ref->id()) : 0;
}
};
} // namespace std
#endif // CPPA_ACTOR_HPP
......@@ -16,45 +16,46 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACTOR_ADDR_HPP
#define CPPA_ACTOR_ADDR_HPP
#include <cstddef>
#include <cstdint>
#include <functional>
#include <type_traits>
#include "cppa/intrusive_ptr.hpp"
#include "cppa/fwd.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/util/comparable.hpp"
#include "cppa/detail/comparable.hpp"
namespace cppa {
class actor;
class local_actor;
class actor_namespace;
struct invalid_actor_addr_t {
constexpr invalid_actor_addr_t() {}
namespace detail { class raw_access; }
};
/**
* @brief Identifies an invalid {@link actor_addr}.
* @relates actor_addr
*/
struct invalid_actor_addr_t { constexpr 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.
*/
class actor_addr : util::comparable<actor_addr>
, util::comparable<actor_addr, abstract_actor*>
, util::comparable<actor_addr, abstract_actor_ptr> {
class actor_addr : detail::comparable<actor_addr>,
detail::comparable<actor_addr, abstract_actor*>,
detail::comparable<actor_addr, abstract_actor_ptr> {
friend class actor;
friend class abstract_actor;
friend class detail::raw_access;
template<typename T, typename U>
friend T actor_cast(const U&);
public:
......@@ -72,13 +73,9 @@ class actor_addr : util::comparable<actor_addr>
actor_addr operator=(const invalid_actor_addr_t&);
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; }
intptr_t compare(const actor_addr& other) const;
......@@ -90,7 +87,7 @@ class actor_addr : util::comparable<actor_addr>
actor_id id() const;
const node_id& node() const;
node_id node() const;
/**
* @brief Returns whether this is an address of a
......@@ -98,8 +95,12 @@ class actor_addr : util::comparable<actor_addr>
*/
bool is_remote() const;
std::set<std::string> interface() const;
private:
inline abstract_actor* get() const { return m_ptr.get(); }
explicit actor_addr(abstract_actor*);
abstract_actor_ptr m_ptr;
......@@ -108,4 +109,15 @@ class actor_addr : util::comparable<actor_addr>
} // namespace cppa
// allow actor_addr to be used in hash maps
namespace std {
template<>
struct hash<cppa::actor_addr> {
inline size_t operator()(const cppa::actor_addr& ref) const {
return static_cast<size_t>(ref.id());
}
};
} // namespace std
#endif // CPPA_ACTOR_ADDR_HPP
......@@ -16,16 +16,16 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#include "cppa/detail/functor_based_actor.hpp"
#ifndef CPPA_ACTOR_CAST_HPP
#define CPPA_ACTOR_CAST_HPP
namespace cppa {
namespace detail {
behavior functor_based_actor::make_behavior() {
return m_make_behavior(this);
template<typename T, typename U>
T actor_cast(const U& what) {
return what.get();
}
} // namespace util
} // namespace cppa
#endif // CPPA_ACTOR_CAST_HPP
......@@ -24,15 +24,14 @@
#include <functional>
#include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/behavior_stack_based.hpp"
#include "cppa/detail/memory.hpp"
#include "cppa/mixin/sync_sender.hpp"
#include "cppa/util/shared_spinlock.hpp"
#include "cppa/util/shared_lock_guard.hpp"
#include "cppa/detail/memory.hpp"
#include "cppa/detail/shared_spinlock.hpp"
namespace cppa {
......@@ -43,9 +42,9 @@ namespace cppa {
*/
class actor_companion : public extend<local_actor, actor_companion>::
with<behavior_stack_based<behavior>::impl,
sync_sender<nonblocking_response_handle_tag>::impl> {
mixin::sync_sender<nonblocking_response_handle_tag>::impl> {
typedef util::shared_spinlock lock_type;
typedef detail::shared_spinlock lock_type;
public:
......@@ -65,7 +64,8 @@ class actor_companion : public extend<local_actor, actor_companion>::
*/
void on_enqueue(enqueue_handler handler);
void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override;
void enqueue(const actor_addr& sender, message_id mid,
message content, execution_unit* host) override;
private:
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACTOR_NAMESPACE_HPP
#define CPPA_ACTOR_NAMESPACE_HPP
......@@ -32,8 +31,6 @@ namespace cppa {
class serializer;
class deserializer;
namespace io { class middleman; }
/**
* @brief Groups a (distributed) set of actors and allows actors
* in the same namespace to exchange messages.
......@@ -42,84 +39,84 @@ class actor_namespace {
public:
typedef std::function<actor_proxy_ptr(actor_id, node_id_ptr)>
factory_fun;
using key_type = node_id;
/**
* @brief The backend of an actor namespace is responsible for
* creating proxy actors.
*/
class backend {
public:
typedef std::function<void(actor_id, const node_id&)>
new_element_callback;
virtual ~backend();
inline void set_proxy_factory(factory_fun fun);
/**
* @brief Creates a new proxy instance.
*/
virtual actor_proxy_ptr make_proxy(const key_type&, actor_id) = 0;
inline void set_new_element_callback(new_element_callback fun);
};
actor_namespace(backend& mgm);
/**
* @brief Writes an actor address to @p sink and adds the actor
* to the list of known actors for a later deserialization.
*/
void write(serializer* sink, const actor_addr& ptr);
/**
* @brief Reads an actor address from @p source, creating
* addresses for remote actors on the fly if needed.
*/
actor_addr read(deserializer* source);
/**
* @brief A map that stores weak actor proxy pointers by actor ids.
* @brief A map that stores all proxies for known remote actors.
*/
typedef std::map<actor_id, weak_actor_proxy_ptr> proxy_map;
typedef std::map<actor_id, actor_proxy::anchor_ptr> proxy_map;
/**
* @brief Returns the number of proxies for @p node.
*/
size_t count_proxies(const node_id& node);
size_t count_proxies(const key_type& node);
/**
* @brief Returns the proxy instance identified by @p node and @p aid
* or @p nullptr if the actor is unknown.
* or @p nullptr if the actor either unknown or expired.
*/
actor_proxy_ptr get(const node_id& 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
* or creates a new (default) proxy instance.
*/
actor_proxy_ptr get_or_put(node_id_ptr node, actor_id aid);
actor_proxy_ptr get_or_put(const key_type& node, actor_id aid);
/**
* @brief Stores @p proxy in the list of known actor proxies.
* @brief Deletes all proxies for @p node.
*/
void put(const node_id& parent,
actor_id aid,
const actor_proxy_ptr& proxy);
void erase(const key_type& node);
/**
* @brief Returns the map of known actors for @p node.
* @brief Deletes the proxy with id @p aid for @p node.
*/
proxy_map& proxies(node_id& node);
void erase(const key_type& node, actor_id aid);
/**
* @brief Deletes all proxies for @p node.
* @brief Queries whether there are any proxies left.
*/
void erase(node_id& node);
/**
* @brief Deletes the proxy with id @p aid for @p node.
*/
void erase(node_id& node, actor_id aid);
bool empty() const;
private:
factory_fun m_factory;
new_element_callback m_new_element_callback;
node_id_ptr m_node;
backend& m_backend;
std::map<node_id, proxy_map> m_proxies;
std::map<key_type, proxy_map> m_proxies;
};
inline void actor_namespace::set_proxy_factory(factory_fun fun) {
m_factory = std::move(fun);
}
inline void actor_namespace::set_new_element_callback(new_element_callback fun) {
m_new_element_callback = std::move(fun);
}
} // namespace cppa
#endif
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACTOR_OSTREAM_HPP
#define CPPA_ACTOR_OSTREAM_HPP
......@@ -48,7 +47,7 @@ class actor_ostream {
actor_ostream& flush();
inline actor_ostream& operator<<(std::string arg) {
return write(move(arg));
return write(std::move(arg));
}
inline actor_ostream& operator<<(const message& arg) {
......@@ -61,12 +60,8 @@ class actor_ostream {
}
template<typename T>
inline typename std::enable_if<
!std::is_convertible<T, std::string>::value
&& !std::is_convertible<T, message>::value,
actor_ostream&
>::type
operator<<(T&& arg) {
inline typename std::enable_if<!std::is_convertible<T, std::string>::value && !std::is_convertible<T, message>::value, actor_ostream&>::type operator<<(
T&& arg) {
return write(std::to_string(std::forward<T>(arg)));
}
......
......@@ -16,31 +16,77 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ACTOR_PROXY_HPP
#define CPPA_ACTOR_PROXY_HPP
#include "cppa/extend.hpp"
#include "cppa/abstract_actor.hpp"
#include <atomic>
#include <cstdint>
#include "cppa/abstract_actor.hpp"
#include "cppa/message_header.hpp"
#include "cppa/enable_weak_ptr.hpp"
#include "cppa/weak_intrusive_ptr.hpp"
#include "cppa/detail/shared_spinlock.hpp"
namespace cppa {
class actor_proxy_cache;
class actor_proxy;
/**
* @brief A smart pointer to an {@link actor_proxy} instance.
* @relates actor_proxy
*/
using actor_proxy_ptr = intrusive_ptr<actor_proxy>;
/**
* @brief Represents a remote actor.
* @extends abstract_actor
*/
class actor_proxy : public extend<abstract_actor>::with<enable_weak_ptr> {
class actor_proxy : public abstract_actor {
typedef combined_type super;
typedef abstract_actor super;
public:
/**
* @brief An anchor points to a proxy instance without sharing
* ownership to it, i.e., models a weak ptr.
*/
class anchor : public ref_counted {
friend class actor_proxy;
public:
anchor(actor_proxy* instance = nullptr);
~anchor();
/**
* @brief Queries whether the proxy was already deleted.
*/
bool expired() const;
/**
* @brief Gets a pointer to the proxy or @p nullptr
* if the instance is {@link expired()}.
*/
actor_proxy_ptr get();
private:
/*
* @brief Tries to expire this anchor. Fails if reference
* count of the proxy is nonzero.
*/
bool try_expire();
std::atomic<actor_proxy*> m_ptr;
detail::shared_spinlock m_lock;
};
using anchor_ptr = intrusive_ptr<anchor>;
~actor_proxy();
/**
......@@ -55,33 +101,21 @@ class actor_proxy : public extend<abstract_actor>::with<enable_weak_ptr> {
virtual void local_unlink_from(const actor_addr& other) = 0;
/**
* @brief Delivers given message via this proxy instance.
*
* This function is meant to give the proxy the opportunity to keep track
* of synchronous communication or perform other bookkeeping if needed.
* The member function is called by the protocol from inside the
* middleman's thread.
* @note This function is guaranteed to be called non-concurrently.
* @brief
*/
virtual void deliver(msg_hdr_cref hdr, message msg) = 0;
virtual void kill_proxy(uint32_t reason) = 0;
protected:
void request_deletion() override;
actor_proxy(actor_id mid);
inline anchor_ptr get_anchor() { return m_anchor; }
};
protected:
/**
* @brief A smart pointer to an {@link actor_proxy} instance.
* @relates actor_proxy
*/
typedef intrusive_ptr<actor_proxy> actor_proxy_ptr;
actor_proxy(actor_id aid, node_id nid);
/**
* @brief A weak smart pointer to an {@link actor_proxy} instance.
* @relates actor_proxy
*/
typedef weak_intrusive_ptr<actor_proxy> weak_actor_proxy_ptr;
anchor_ptr m_anchor;
};
} // namespace cppa
......
This diff is collapsed.
......@@ -16,19 +16,20 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ANNOUNCE_HPP
#define CPPA_ANNOUNCE_HPP
#include <memory>
#include <typeinfo>
#include "cppa/string_algorithms.hpp"
#include "cppa/config.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/abstract_uniform_type_info.hpp"
#include "cppa/detail/abstract_uniform_type_info.hpp"
#include "cppa/detail/safe_equal.hpp"
#include "cppa/detail/default_uniform_type_info.hpp"
namespace cppa {
......@@ -85,7 +86,7 @@ namespace cppa {
*/
/**
* @brief Adds a new type mapping to the libcppa type system.
* @brief Adds a new type mapping to the type system.
* @param tinfo C++ RTTI for the new type
* @param utype Corresponding {@link uniform_type_info} instance.
* @returns @c true if @p uniform_type was added as known
......@@ -93,7 +94,7 @@ namespace cppa {
* is returned and @p uniform_type was deleted.
*/
const uniform_type_info* announce(const std::type_info& tinfo,
std::unique_ptr<uniform_type_info> utype);
uniform_type_info_ptr utype);
// deals with member pointer
/**
......@@ -104,7 +105,7 @@ const uniform_type_info* announce(const std::type_info& tinfo,
* @returns A pair of @p c_ptr and the created meta informations.
*/
template<class C, class Parent, typename... Ts>
std::pair<C Parent::*, util::abstract_uniform_type_info<C>*>
std::pair<C Parent::*, detail::abstract_uniform_type_info<C>*>
compound_member(C Parent::*c_ptr, const Ts&... args) {
return {c_ptr, new detail::default_uniform_type_info<C>(args...)};
}
......@@ -119,7 +120,7 @@ compound_member(C Parent::*c_ptr, const Ts&... args) {
* @returns A pair of @p c_ptr and the created meta informations.
*/
template<class C, class Parent, typename... Ts>
std::pair<C& (Parent::*)(), util::abstract_uniform_type_info<C>*>
std::pair<C& (Parent::*)(), detail::abstract_uniform_type_info<C>*>
compound_member(C& (Parent::*getter)(), const Ts&... args) {
return {getter, new detail::default_uniform_type_info<C>(args...)};
}
......@@ -134,19 +135,20 @@ compound_member(C& (Parent::*getter)(), const Ts&... args) {
* @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, typename... Ts>
template<class Parent, typename GRes, typename SRes, typename SArg,
typename... Ts>
std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>,
util::abstract_uniform_type_info<typename util::rm_const_and_ref<GRes>::type>*>
compound_member(const std::pair<GRes (Parent::*)() const,
SRes (Parent::*)(SArg) >& gspair,
const Ts&... args) {
typedef typename util::rm_const_and_ref<GRes>::type mtype;
detail::abstract_uniform_type_info<
typename detail::rm_const_and_ref<GRes>::type>*>
compound_member(
const std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>& gspair,
const Ts&... args) {
typedef typename detail::rm_const_and_ref<GRes>::type mtype;
return {gspair, new detail::default_uniform_type_info<mtype>(args...)};
}
/**
* @brief Adds a new type mapping for @p C to the libcppa type system.
* @brief Adds a new type mapping for @p C to the type system.
* @tparam C A class that is either empty or is default constructible,
* copy constructible, and comparable.
* @param args Members of @p C.
......@@ -155,135 +157,7 @@ compound_member(const std::pair<GRes (Parent::*)() const,
template<class C, typename... Ts>
inline const uniform_type_info* announce(const Ts&... args) {
auto ptr = new detail::default_uniform_type_info<C>(args...);
return announce(typeid(C), std::unique_ptr<uniform_type_info>{ptr});
}
/**
* @}
*/
namespace detail {
template<long Pos, typename Tuple, typename T>
typename std::enable_if<util::is_primitive<T>::value>::type
serialze_single(serializer* sink, const Tuple&, const T& value) {
sink->write_value(value);
}
template<long Pos, typename Tuple, typename T>
typename std::enable_if<not util::is_primitive<T>::value>::type
serialze_single(serializer* sink, const Tuple& tup, const T& value) {
tup.type_at(Pos)->serialize(&value, sink);
}
// end of recursion
template<typename Tuple>
void do_serialize(serializer*, const Tuple&, util::int_list<>) { }
// end of recursion
template<typename Tuple, long I, long... Is>
void do_serialize(serializer* sink, const Tuple& tup, util::int_list<I, Is...>) {
serialze_single<I>(sink, tup, get<I>(tup));
do_serialize(sink, tup, util::int_list<Is...>{});
}
template<long Pos, typename Tuple, typename T>
typename std::enable_if<util::is_primitive<T>::value>::type
deserialze_single(deserializer* source, Tuple&, T& value) {
value = source->read<T>();
}
template<long Pos, typename Tuple, typename T>
typename std::enable_if<not util::is_primitive<T>::value>::type
deserialze_single(deserializer* source, Tuple& tup, T& value) {
tup.type_at(Pos)->deserialize(&value, source);
}
// end of recursion
template<typename Tuple>
void do_deserialize(deserializer*, const Tuple&, util::int_list<>) { }
// end of recursion
template<typename Tuple, long I, long... Is>
void do_deserialize(deserializer* source, Tuple& tup, util::int_list<I, Is...>) {
deserialze_single<I>(source, tup, get_ref<I>(tup));
do_deserialize(source, tup, util::int_list<Is...>{});
}
template<typename T, typename... Ts>
class meta_cow_tuple : public uniform_type_info {
public:
typedef cow_tuple<T, Ts...> tuple_type;
meta_cow_tuple() {
m_name = "@<>+";
m_name += detail::to_uniform_name<T>();
util::splice(m_name, "+", detail::to_uniform_name<Ts>()...);
}
const char* name() const override {
return m_name.c_str();
}
void serialize(const void* instance, serializer* sink) const override {
auto& ref = *cast(instance);
do_serialize(sink, ref, util::get_indices(ref));
}
void deserialize(void* instance, deserializer* source) const override {
auto& ref = *cast(instance);
do_deserialize(source, ref, util::get_indices(ref));
}
uniform_value create(const uniform_value& other) const override {
return create_impl<tuple_type>(other);
}
message as_message(void* instance) const override {
return (instance) ? make_message(*cast(instance)) : message{};
}
bool equal_to(const std::type_info& tinfo) const override {
return typeid(tuple_type) == tinfo;
}
bool equals(const void* instance1, const void* instance2) const override {
return *cast(instance1) == *cast(instance2);
}
private:
inline tuple_type* cast(void* ptr) const {
return reinterpret_cast<tuple_type*>(ptr);
}
inline const tuple_type* cast(const void* ptr) const {
return reinterpret_cast<const tuple_type*>(ptr);
}
std::string m_name;
};
} // namespace detail
/**
* @addtogroup TypeSystem
* @{
*/
/**
* @brief Adds a hint to the type system of libcppa. This type hint can
* increase the network performance, because libcppa
* can use the hint to create tuples with full static type
* information rather than using fully dynamically typed tuples.
*/
template<typename T, typename... Ts>
inline void announce_tuple() {
typedef detail::meta_cow_tuple<T, Ts...> meta_type;
get_uniform_type_info_map()->insert(create_unique<meta_type>());
return announce(typeid(C), uniform_type_info_ptr{ptr});
}
/**
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ANYTHING_HPP
#define CPPA_ANYTHING_HPP
......@@ -27,7 +26,7 @@ namespace cppa {
/**
* @brief Acts as wildcard expression in patterns.
*/
struct anything { };
struct anything {};
/**
* @brief Compares two instances of {@link anything}.
......@@ -49,8 +48,8 @@ inline bool operator!=(const anything&, const anything&) { return false; }
template<typename T>
struct is_anything {
static constexpr bool value = std::is_same<T, anything>::value;
};
};
} // namespace cppa
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ATOM_HPP
#define CPPA_ATOM_HPP
......@@ -29,10 +28,11 @@ namespace cppa {
/**
* @brief The value type of atoms.
*/
enum class atom_value : std::uint64_t {
enum class atom_value : uint64_t {
/** @cond PRIVATE */
dirty_little_hack = 37337
/** @endcond */
};
/**
......@@ -48,7 +48,7 @@ std::string to_string(const atom_value& what);
* @returns A compact representation of @p str.
*/
template<size_t Size>
constexpr atom_value atom(char const (&str) [Size]) {
constexpr atom_value atom(char const (&str)[Size]) {
// last character is the NULL terminator
static_assert(Size <= 11, "only 10 characters are allowed");
return static_cast<atom_value>(detail::atom_val(str, 0xF));
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ATTACHABLE_HPP
#define CPPA_ATTACHABLE_HPP
......@@ -67,7 +66,7 @@ class attachable {
* The default implementation does nothing.
* @param reason The exit rason of the observed actor.
*/
virtual void actor_exited(std::uint32_t reason) = 0;
virtual void actor_exited(uint32_t reason) = 0;
/**
* @brief Selects a group of @c attachable instances by @p what.
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_AWAIT_ALL_ACTORS_DONE_HPP
#define CPPA_AWAIT_ALL_ACTORS_DONE_HPP
#include "cppa/detail/singletons.hpp"
#include "cppa/detail/actor_registry.hpp"
namespace cppa {
/**
* @brief Blocks execution of this actor until all
* other actors finished execution.
* @warning This function will cause a deadlock if called from multiple actors.
* @warning Do not call this function in cooperatively scheduled actors.
*/
inline void await_all_actors_done() {
detail::singletons::get_actor_registry()->await_running_count_equal(0);
}
} // namespace cppa
#endif // CPPA_AWAIT_ALL_ACTORS_DONE_HPP
......@@ -16,19 +16,20 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_BEHAVIOR_HPP
#define CPPA_BEHAVIOR_HPP
#include <functional>
#include <type_traits>
#include "cppa/none.hpp"
#include "cppa/duration.hpp"
#include "cppa/match_expr.hpp"
#include "cppa/timeout_definition.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/type_list.hpp"
#include "cppa/detail/type_traits.hpp"
namespace cppa {
......@@ -43,7 +44,7 @@ class behavior {
public:
typedef std::function<optional<message> (message&)> continuation_fun;
typedef std::function<optional<message>(message&)> continuation_fun;
/** @cond PRIVATE */
......@@ -67,7 +68,7 @@ class behavior {
behavior(const timeout_definition<F>& arg);
template<typename F>
behavior(const util::duration& d, F f);
behavior(const duration& d, F f);
template<typename T, typename... Ts>
behavior(const T& arg, Ts&&... args);
......@@ -81,14 +82,11 @@ class behavior {
* @brief Returns the duration after which receives using
* this behavior should time out.
*/
inline const util::duration& timeout() const;
inline const duration& timeout() const;
/**
* @brief Returns a value if @p arg was matched by one of the
* handler of this behavior, returns @p nothing otherwise.
* @note This member function can return @p nothing even if
* {@link defined_at()} returns @p true, because {@link defined_at()}
* does not evaluate guards.
*/
template<typename T>
inline optional<message> operator()(T&& arg);
......@@ -100,9 +98,7 @@ class behavior {
*/
behavior add_continuation(continuation_fun fun);
inline operator bool() const {
return static_cast<bool>(m_impl);
}
inline operator bool() const { return static_cast<bool>(m_impl); }
private:
......@@ -116,39 +112,34 @@ class behavior {
*/
template<typename... Cs, typename F>
inline behavior operator,(const match_expr<Cs...>& lhs,
const timeout_definition<F>& rhs) {
inline behavior operator, (const match_expr<Cs...>& lhs,
const timeout_definition<F>& rhs) {
return {lhs, rhs};
}
/******************************************************************************
* inline and template member function implementations *
******************************************************************************/
template<typename T, typename... 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))...)) { }
: m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) {}
template<typename F>
behavior::behavior(const timeout_definition<F>& arg)
: m_impl(detail::new_default_behavior(arg.timeout, arg.handler)) { }
: m_impl(detail::new_default_behavior(arg.timeout, arg.handler)) {}
template<typename F>
behavior::behavior(const util::duration& d, F f)
: m_impl(detail::new_default_behavior(d, 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 behavior::behavior(impl_ptr ptr) : m_impl(std::move(ptr)) {}
inline void behavior::handle_timeout() {
m_impl->handle_timeout();
}
inline void behavior::handle_timeout() { m_impl->handle_timeout(); }
inline const util::duration& behavior::timeout() const {
return m_impl->timeout();
}
inline const duration& behavior::timeout() const { return m_impl->timeout(); }
template<typename T>
inline optional<message> behavior::operator()(T&& arg) {
......
......@@ -16,23 +16,25 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_BEHAVIOR_POLICY_HPP
#define CPPA_BEHAVIOR_POLICY_HPP
namespace cppa {
template<bool DiscardBehavior>
struct behavior_policy { static constexpr bool discard_old = DiscardBehavior; };
struct behavior_policy {
static constexpr bool discard_old = DiscardBehavior;
};
template<typename T>
struct is_behavior_policy : std::false_type { };
struct is_behavior_policy : std::false_type {};
template<bool DiscardBehavior>
struct is_behavior_policy<behavior_policy<DiscardBehavior>> : std::true_type { };
struct is_behavior_policy<behavior_policy<DiscardBehavior>> : std::true_type {};
typedef behavior_policy<false> keep_behavior_t;
typedef behavior_policy<true > discard_behavior_t;
typedef behavior_policy<true> discard_behavior_t;
/**
* @brief Policy tag that causes {@link event_based_actor::become} to
......
......@@ -68,7 +68,7 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> {
template<typename T, typename... Ts>
inline typename std::enable_if<
!is_behavior_policy<typename util::rm_const_and_ref<T>::type>::value,
!is_behavior_policy<typename detail::rm_const_and_ref<T>::type>::value,
void
>::type
become(T&& arg, Ts&&... args) {
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_BINARY_DESERIALIZER_HPP
#define CPPA_BINARY_DESERIALIZER_HPP
......@@ -35,21 +34,28 @@ class binary_deserializer : public deserializer {
public:
binary_deserializer(const void* buf, size_t buf_size,
actor_namespace* ns = nullptr,
type_lookup_table* table = nullptr);
actor_namespace* ns = nullptr);
binary_deserializer(const void* begin, const void* m_end,
actor_namespace* ns = nullptr,
type_lookup_table* table = nullptr);
actor_namespace* ns = nullptr);
const uniform_type_info* begin_object() override;
void end_object() override;
size_t begin_sequence() override;
void end_sequence() override;
primitive_variant read_value(primitive_type ptype) override;
void read_tuple(size_t, const primitive_type*, primitive_variant*) override;
void read_value(primitive_variant& storage) override;
void read_raw(size_t num_bytes, void* storage) override;
/**
* @brief Replaces the current read buffer.
*/
void set_rdbuf(const void* buf, size_t buf_size);
/**
* @brief Replaces the current read buffer.
*/
void set_rdbuf(const void* begin, const void* m_end);
private:
const void* m_pos;
......@@ -57,6 +63,12 @@ class binary_deserializer : public deserializer {
};
template<typename T>
inline binary_deserializer& operator>>(binary_deserializer& lhs, T& rhs) {
rhs = lhs.read<T>();
return lhs;
}
} // namespace cppa
#endif // CPPA_BINARY_DESERIALIZER_HPP
......@@ -16,38 +16,54 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_BINARY_SERIALIZER_HPP
#define CPPA_BINARY_SERIALIZER_HPP
#include <utility>
#include <sstream>
#include <iomanip>
#include <functional>
#include <type_traits>
#include "cppa/serializer.hpp"
#include "cppa/util/buffer.hpp"
#include "cppa/primitive_variant.hpp"
namespace cppa {
#include "cppa/detail/ieee_754.hpp"
#include "cppa/detail/type_traits.hpp"
namespace detail { class binary_writer; }
namespace cppa {
/**
* @brief Implements the serializer interface with
* a binary serialization protocol.
* @tparam Buffer A class providing a compatible interface to std::vector<char>.
*/
class binary_serializer : public serializer {
typedef serializer super;
using super = serializer;
public:
using write_fun = std::function<void(const char*, const char*)>;
/**
* @brief Creates a binary serializer writing to @p write_buffer.
* @warning @p write_buffer must be guaranteed to outlive @p this
*/
binary_serializer(util::buffer* write_buffer,
actor_namespace* ns = nullptr,
type_lookup_table* lookup_table = nullptr);
template<typename OutIter>
binary_serializer(OutIter iter, actor_namespace* ns = nullptr) : super(ns) {
struct fun {
fun(OutIter pos) : m_pos(pos) {}
void operator()(const char* first, const char* last) {
m_pos = std::copy(first, last, m_pos);
}
OutIter m_pos;
void begin_object(const uniform_type_info*) override;
};
m_out = fun{iter};
}
void begin_object(const uniform_type_info* uti) override;
void end_object() override;
......@@ -57,16 +73,21 @@ class binary_serializer : public serializer {
void write_value(const primitive_variant& value) override;
void write_tuple(size_t size, const primitive_variant* values) override;
void write_raw(size_t num_bytes, const void* data) override;
private:
util::buffer* m_sink;
write_fun m_out;
};
template<typename T,
class = typename std::enable_if<detail::is_primitive<T>::value>::type>
binary_serializer& operator<<(binary_serializer& bs, const T& value) {
bs.write_value(value);
return bs;
}
} // namespace cppa
#endif // CPPA_BINARY_SERIALIZER_HPP
......@@ -16,21 +16,22 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_BLOCKING_UNTYPED_ACTOR_HPP
#define CPPA_BLOCKING_UNTYPED_ACTOR_HPP
#include "cppa/none.hpp"
#include "cppa/on.hpp"
#include "cppa/extend.hpp"
#include "cppa/behavior.hpp"
#include "cppa/exception.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp"
#include "cppa/typed_actor.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/mixin/sync_sender.hpp"
#include "cppa/mixin/mailbox_based.hpp"
namespace cppa {
/**
......@@ -39,16 +40,18 @@ namespace cppa {
* @extends local_actor
*/
class blocking_actor
: public extend<local_actor, blocking_actor>::
with<mailbox_based,
sync_sender<blocking_response_handle_tag>::impl> {
: public extend<local_actor, blocking_actor>::with<
mixin::mailbox_based,
mixin::sync_sender<blocking_response_handle_tag>::impl> {
public:
class functor_based;
/**************************************************************************
* utility stuff and receive() member function family *
**************************************************************************/
typedef std::chrono::high_resolution_clock::time_point timeout_type;
typedef std::chrono::high_resolution_clock::time_point timeout_type;
struct receive_while_helper {
......@@ -75,7 +78,7 @@ class blocking_actor
template<typename... Ts>
void operator()(Ts&&... args) {
behavior bhvr{std::forward<Ts>(args)...};
for ( ; begin != end; ++begin) m_dq(bhvr);
for (; begin != end; ++begin) m_dq(bhvr);
}
};
......@@ -87,8 +90,13 @@ class blocking_actor
template<typename Statement>
void until(Statement stmt) {
do { m_dq(m_bhvr); }
while (stmt() == false);
do {
m_dq(m_bhvr);
} while (stmt() == false);
}
void until(const bool& bvalue) {
until([&] { return bvalue; });
}
};
......@@ -204,12 +212,12 @@ class blocking_actor
* @brief Unwinds the stack by throwing an actor_exited exception.
* @throws actor_exited
*/
virtual void quit(std::uint32_t reason = exit_reason::normal);
virtual void quit(uint32_t reason = exit_reason::normal);
/** @cond PRIVATE */
// required from invoke_policy; unused in blocking actors
inline void remove_handler(message_id) { }
inline void remove_handler(message_id) {}
// required by receive() member function family
inline void dequeue(behavior&& bhvr) {
......@@ -238,6 +246,49 @@ class blocking_actor
};
class blocking_actor::functor_based : public blocking_actor {
public:
typedef std::function<void(blocking_actor*)> act_fun;
template<typename F, typename... Ts>
functor_based(F f, Ts&&... vs) {
blocking_actor* dummy = nullptr;
create(dummy, f, std::forward<Ts>(vs)...);
}
protected:
void act() override;
private:
void create(blocking_actor*, act_fun);
template<class Actor, typename F, typename T0, typename... Ts>
auto create(Actor* dummy, F f, T0&& v0, Ts&&... vs)
-> typename std::enable_if<std::is_same<
decltype(f(dummy, std::forward<T0>(v0), std::forward<Ts>(vs)...)),
void>::value>::type {
create(dummy, std::bind(f, std::placeholders::_1, std::forward<T0>(v0),
std::forward<Ts>(vs)...));
}
template<class Actor, typename F, typename T0, typename... Ts>
auto create(Actor* dummy, F f, T0&& v0, Ts&&... vs)
-> typename std::enable_if<std::is_same<
decltype(f(std::forward<T0>(v0), std::forward<Ts>(vs)...)),
void>::value>::type {
std::function<void()> fun =
std::bind(f, std::forward<T0>(v0), std::forward<Ts>(vs)...);
create(dummy, [fun](Actor*) { fun(); });
}
act_fun m_act;
};
} // namespace cppa
#endif // CPPA_BLOCKING_UNTYPED_ACTOR_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_CHANNEL_HPP
#define CPPA_CHANNEL_HPP
......@@ -24,9 +23,11 @@
#include <type_traits>
#include "cppa/intrusive_ptr.hpp"
#include "cppa/fwd.hpp"
#include "cppa/abstract_channel.hpp"
#include "cppa/util/comparable.hpp"
#include "cppa/detail/comparable.hpp"
namespace cppa {
......@@ -37,16 +38,15 @@ class execution_unit;
struct invalid_actor_t;
struct invalid_group_t;
namespace detail { class raw_access; }
/**
* @brief A handle to instances of {@link abstract_channel}.
*/
class channel : util::comparable<channel>
, util::comparable<channel, actor>
, util::comparable<channel, abstract_channel*> {
class channel : detail::comparable<channel>,
detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> {
friend class detail::raw_access;
template<typename T, typename U>
friend T actor_cast(const U&);
public:
......@@ -63,27 +63,18 @@ class channel : util::comparable<channel>
template<typename T>
channel(intrusive_ptr<T> ptr,
typename std::enable_if<
std::is_base_of<abstract_channel, T>::value
>::type* = 0)
: m_ptr(ptr) { }
std::is_base_of<abstract_channel, T>::value>::type* = 0)
: m_ptr(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;
......@@ -96,6 +87,8 @@ class channel : util::comparable<channel>
private:
inline abstract_channel* get() const { return m_ptr.get(); }
intrusive_ptr<abstract_channel> m_ptr;
};
......
......@@ -22,9 +22,6 @@
// Config pararameters defined by the build system (usually CMake):
//
// CPPA_ENABLE_CONTEXT_SWITCHING:
// - enables context switching (requires Boost)
//
// CPPA_DEBUG_MODE:
// - check requirements at runtime
//
......@@ -40,7 +37,7 @@
* whereas each number is a two-digit decimal number without
* leading zeros (e.g. 900 is version 0.9.0).
*/
#define CPPA_VERSION 902
#define CPPA_VERSION 1000
#define CPPA_MAJOR_VERSION (CPPA_VERSION / 100000)
#define CPPA_MINOR_VERSION ((CPPA_VERSION / 100) % 1000)
......@@ -66,7 +63,8 @@
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
_Pragma("clang diagnostic ignored \"-Wconversion\"") \
_Pragma("clang diagnostic ignored \"-Wcast-align\"") \
_Pragma("clang diagnostic ignored \"-Wundef\"")
_Pragma("clang diagnostic ignored \"-Wundef\"") \
_Pragma("clang diagnostic ignored \"-Wnested-anon-types\"")
# define CPPA_POP_WARNINGS \
_Pragma("clang diagnostic pop")
# define CPPA_ANNOTATE_FALLTHROUGH [[clang::fallthrough]]
......@@ -77,6 +75,7 @@
# define CPPA_POP_WARNINGS
# define CPPA_ANNOTATE_FALLTHROUGH static_cast<void>(0)
#elif defined(_MSC_VER)
# define CPPA_MSVC
# define CPPA_DEPRECATED __declspec(deprecated)
# define CPPA_PUSH_WARNINGS
# define CPPA_POP_WARNINGS
......@@ -149,57 +148,4 @@ using ::backtrace_symbols_fd;
#define CPPA_CRITICAL(error) CPPA_CRITICAL__(error, __FILE__, __LINE__)
#ifdef CPPA_WINDOWS
# include <w32api.h>
# undef _WIN32_WINNT
# undef WINVER
# define _WIN32_WINNT WindowsVista
# define WINVER WindowsVista
# include <ws2tcpip.h>
# include <winsock2.h>
// remove interface which is defined in rpc.h in files included by
// windows.h as it clashes with name used in own code
# undef interface
#else
# include <unistd.h>
# include <errno.h>
#endif
namespace cppa {
/**
* @brief An alternative for the 'missing' @p std::make_unqiue.
*/
template<typename T, typename... Args>
std::unique_ptr<T> create_unique(Args&&... args) {
return std::unique_ptr<T>{new T(std::forward<Args>(args)...)};
}
// platform-dependent types for sockets and some utility functions
#ifdef CPPA_WINDOWS
typedef SOCKET native_socket_type;
typedef const char* setsockopt_ptr;
typedef const char* socket_send_ptr;
typedef char* socket_recv_ptr;
typedef int socklen_t;
constexpr SOCKET invalid_socket = INVALID_SOCKET;
inline int last_socket_error() { return WSAGetLastError(); }
inline bool would_block_or_temporarily_unavailable(int errcode) {
return errcode == WSAEWOULDBLOCK || errcode == WSATRY_AGAIN;
}
#else
typedef int native_socket_type;
typedef const void* setsockopt_ptr;
typedef const void* socket_send_ptr;
typedef void* socket_recv_ptr;
constexpr int invalid_socket = -1;
inline void closesocket(native_socket_type fd) { close(fd); }
inline int last_socket_error() { return errno; }
inline bool would_block_or_temporarily_unavailable(int errcode) {
return errcode == EAGAIN || errcode == EWOULDBLOCK;
}
#endif
} // namespace cppa
#endif // CPPA_CONFIG_HPP
......@@ -16,34 +16,34 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_CONNECTION_HANDLE_HPP
#define CPPA_CONNECTION_HANDLE_HPP
#ifndef CPPA_IO_CONNECTION_HANDLE_HPP
#define CPPA_IO_CONNECTION_HANDLE_HPP
#include "cppa/detail/handle.hpp"
#include "cppa/io_handle.hpp"
namespace cppa {
namespace io {
class broker;
class connection_handle : public detail::handle<connection_handle> {
/**
* @brief Generic handle type for identifying connections.
*/
class connection_handle : public io_handle<connection_handle> {
friend class detail::handle<connection_handle>;
friend class io_handle<connection_handle>;
typedef detail::handle<connection_handle> super;
typedef io_handle<connection_handle> super;
public:
connection_handle() = default;
constexpr connection_handle() {}
private:
inline connection_handle(int handle_id) : super{handle_id} { }
inline connection_handle(int64_t handle_id) : super{handle_id} {}
};
} // namespace io
constexpr connection_handle invalid_connection_handle = connection_handle{};
} // namespace cppa
#endif // CPPA_IO_CONNECTION_HANDLE_HPP
#endif // CPPA_CONNECTION_HANDLE_HPP
......@@ -16,9 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_CONTINUE_HELPER_HPP
#define CPPA_CONTINUE_HELPER_HPP
#ifndef CONTINUE_HELPER_HPP
#define CONTINUE_HELPER_HPP
#include <functional>
......@@ -50,9 +49,8 @@ class continue_helper {
*/
template<typename F>
continue_helper& continue_with(F fun) {
return continue_with(behavior::continuation_fun{message_handler{
on(any_vals, arg_match) >> fun
}});
return continue_with(behavior::continuation_fun{
message_handler{on(any_vals, arg_match) >> fun}});
}
/**
......@@ -65,9 +63,7 @@ class continue_helper {
/**
* @brief 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:
......@@ -78,4 +74,4 @@ class continue_helper {
} // namespace cppa
#endif // CPPA_CONTINUE_HELPER_HPP
#endif // CONTINUE_HELPER_HPP
......@@ -37,7 +37,7 @@ namespace cppa {
* {@link ref_counted}.
*/
template<typename T>
class cow_ptr : util::comparable<cow_ptr<T> >,
class cow_ptr : util::comparable<cow_ptr<T>>,
util::comparable<cow_ptr<T>, const T*>,
util::comparable<cow_ptr<T>, std::nullptr_t> {
......
......@@ -20,34 +20,33 @@
#ifndef CPPA_COW_TUPLE_HPP
#define CPPA_COW_TUPLE_HPP
// <backward_compatibility version="0.9">
#include <cstddef>
#include <string>
#include <typeinfo>
#include <type_traits>
#include "cppa/get.hpp"
#include "cppa/message.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/limited_vector.hpp"
#include "cppa/util/compare_tuples.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/decorated_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
template<typename... Ts>
class cow_tuple;
/**
* @ingroup CopyOnWrite
* @brief A fixed-length copy-on-write cow_tuple.
* @brief A fixed-length copy-on-write tuple.
*/
template<typename Head, typename... Tail>
class cow_tuple<Head, Tail...> {
static_assert(util::tl_forall<util::type_list<Head, Tail...>,
util::is_legal_tuple_type>::value,
static_assert(detail::tl_forall<detail::type_list<Head, Tail...>,
detail::is_legal_tuple_type>::value,
"illegal types in cow_tuple definition: "
"pointers and references are prohibited");
......@@ -59,11 +58,13 @@ class cow_tuple<Head, Tail...> {
public:
typedef util::type_list<Head, Tail...> types;
typedef detail::type_list<Head, Tail...> types;
static constexpr size_t num_elements = sizeof...(Tail) + 1;
cow_tuple() : m_vals(new data_type) { }
cow_tuple() : m_vals(new data_type) {
// nop
}
/**
* @brief Initializes the cow_tuple with @p args.
......@@ -71,7 +72,9 @@ class cow_tuple<Head, Tail...> {
*/
template<typename... Ts>
cow_tuple(const Head& arg, Ts&&... args)
: m_vals(new data_type(arg, std::forward<Ts>(args)...)) { }
: m_vals(new data_type(arg, std::forward<Ts>(args)...)) {
// nop
}
/**
* @brief Initializes the cow_tuple with @p args.
......@@ -79,7 +82,9 @@ class cow_tuple<Head, Tail...> {
*/
template<typename... Ts>
cow_tuple(Head&& arg, Ts&&... args)
: m_vals(new data_type(std::move(arg), std::forward<Ts>(args)...)) { }
: m_vals(new data_type(std::move(arg), std::forward<Ts>(args)...)) {
// nop
}
cow_tuple(cow_tuple&&) = default;
cow_tuple(const cow_tuple&) = default;
......@@ -141,7 +146,7 @@ template<typename TypeList>
struct cow_tuple_from_type_list;
template<typename... Ts>
struct cow_tuple_from_type_list< util::type_list<Ts...> > {
struct cow_tuple_from_type_list< detail::type_list<Ts...>> {
typedef cow_tuple<Ts...> type;
};
......@@ -160,8 +165,8 @@ struct is_cow_tuple<cow_tuple<Ts...>> { static constexpr bool value = true; };
* @relates cow_tuple
*/
template<size_t N, typename... Ts>
const typename util::type_at<N, Ts...>::type& get(const cow_tuple<Ts...>& tup) {
typedef typename util::type_at<N, Ts...>::type result_type;
const typename detail::type_at<N, Ts...>::type& get(const cow_tuple<Ts...>& tup) {
typedef typename detail::type_at<N, Ts...>::type result_type;
return *reinterpret_cast<const result_type*>(tup.at(N));
}
......@@ -175,8 +180,8 @@ const typename util::type_at<N, Ts...>::type& get(const cow_tuple<Ts...>& tup) {
* @relates cow_tuple
*/
template<size_t N, typename... Ts>
typename util::type_at<N, Ts...>::type& get_ref(cow_tuple<Ts...>& tup) {
typedef typename util::type_at<N, Ts...>::type result_type;
typename detail::type_at<N, Ts...>::type& get_ref(cow_tuple<Ts...>& tup) {
typedef typename detail::type_at<N, Ts...>::type result_type;
return *reinterpret_cast<result_type*>(tup.mutable_at(N));
}
......@@ -193,32 +198,7 @@ make_cow_tuple(Ts&&... args) {
return {std::forward<Ts>(args)...};
}
/**
* @brief Compares two cow_tuples.
* @param lhs First cow_tuple object.
* @param rhs Second cow_tuple object.
* @returns @p true if @p lhs and @p rhs are equal; otherwise @p false.
* @relates cow_tuple
*/
template<typename... LhsTs, typename... RhsTs>
inline bool operator==(const cow_tuple<LhsTs...>& lhs,
const cow_tuple<RhsTs...>& rhs) {
return util::compare_tuples(lhs, rhs);
}
/**
* @brief Compares two cow_tuples.
* @param lhs First cow_tuple object.
* @param rhs Second cow_tuple object.
* @returns @p true if @p lhs and @p rhs are not equal; otherwise @p false.
* @relates cow_tuple
*/
template<typename... LhsTs, typename... RhsTs>
inline bool operator!=(const cow_tuple<LhsTs...>& lhs,
const cow_tuple<RhsTs...>& rhs) {
return !(lhs == rhs);
}
} // namespace cppa
// </backward_compatibility>
#endif // CPPA_COW_TUPLE_HPP
This diff is collapsed.
......@@ -16,23 +16,20 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DESERIALIZER_HPP
#define CPPA_DESERIALIZER_HPP
#include <string>
#include <cstddef>
#include "cppa/primitive_type.hpp"
#include "cppa/primitive_variant.hpp"
#include "cppa/uniform_type_info.hpp"
namespace cppa {
class object;
class actor_namespace;
class type_lookup_table;
namespace util { class buffer; }
class uniform_type_info;
/**
* @ingroup TypeSystem
......@@ -45,17 +42,10 @@ class deserializer {
public:
deserializer(actor_namespace* ns = nullptr,
type_lookup_table* incoming_types = nullptr);
deserializer(actor_namespace* ns = nullptr);
virtual ~deserializer();
/**
* @brief Seeks the beginning of the next object and return
* its uniform type name.
*/
//virtual std::string seek_object() = 0;
/**
* @brief Begins deserialization of a new object.
*/
......@@ -78,53 +68,58 @@ class deserializer {
virtual void end_sequence() = 0;
/**
* @brief Reads a primitive value from the data source of type @p ptype.
* @param ptype Expected primitive data type.
* @returns A primitive value of type @p ptype.
* @brief Reads a primitive value from the data source.
*/
virtual primitive_variant read_value(primitive_type ptype) = 0;
virtual void read_value(primitive_variant& storage) = 0;
/**
* @brief Reads a value of type @p T from the data source of type @p ptype.
* @note @p T must be of a primitive type.
* @returns The read value of type @p T.
* @brief Reads a value of type @p T from the data source.
* @note @p T must be a primitive type.
*/
template<typename T>
inline T read() {
auto val = read_value(detail::type_to_ptype<T>::ptype);
return std::move(get_ref<T>(val));
primitive_variant val{T()};
read_value(val);
return std::move(get<T>(val));
}
/**
* @brief Reads a tuple of primitive values from the data
* source of the types @p ptypes.
* @param num The size of the tuple.
* @param ptypes Array of expected primitive data types.
* @param storage Array of size @p num, storing the result of this function.
*/
virtual void read_tuple(size_t num,
const primitive_type* ptypes,
primitive_variant* storage ) = 0;
template<typename T>
inline T read(const uniform_type_info* uti) {
T result;
uti->deserialize(&result, uti);
return result;
}
template<typename T>
inline deserializer& read(T& storage) {
primitive_variant val{T()};
read_value(val);
storage = std::move(get<T>(val));
return *this;
}
template<typename T>
inline deserializer& read(T& storage, const uniform_type_info* uti) {
uti->deserialize(&storage, this);
return *this;
}
/**
* @brief Reads a raw memory block.
*/
virtual void read_raw(size_t num_bytes, void* storage) = 0;
inline actor_namespace* get_namespace() {
return m_namespace;
}
inline actor_namespace* get_namespace() { return m_namespace; }
inline type_lookup_table* incoming_types() {
return m_incoming_types;
template<class Buffer>
void read_raw(size_t num_bytes, Buffer& storage) {
storage.resize(num_bytes);
read_raw(num_bytes, storage.data());
}
void read_raw(size_t num_bytes, util::buffer& storage);
private:
actor_namespace* m_namespace;
type_lookup_table* m_incoming_types;
};
......
......@@ -16,21 +16,20 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#define CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#ifndef CPPA_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#define CPPA_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#include "cppa/message.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/type_traits.hpp"
#include "cppa/detail/to_uniform_name.hpp"
#include "cppa/detail/uniform_type_info_map.hpp"
namespace cppa {
namespace util {
namespace detail {
/**
* @brief Implements all pure virtual functions of {@link uniform_type_info}
......@@ -45,9 +44,7 @@ class abstract_uniform_type_info : public uniform_type_info {
return typeid(T) == tinfo;
}
const char* name() const {
return m_name.c_str();
}
const char* name() const { return m_name.c_str(); }
message as_message(void* instance) const override {
return make_message(deref(instance));
......@@ -66,23 +63,21 @@ class abstract_uniform_type_info : public uniform_type_info {
abstract_uniform_type_info() {
auto uname = detail::to_uniform_name<T>();
auto cname = detail::mapped_name_by_decorated_name(uname.c_str());
if (cname == uname.c_str()) m_name = std::move(uname);
else m_name = cname;
if (cname == uname.c_str())
m_name = std::move(uname);
else
m_name = cname;
}
static inline const T& deref(const void* ptr) {
return *reinterpret_cast<const T*>(ptr);
}
static inline T& deref(void* ptr) {
return *reinterpret_cast<T*>(ptr);
}
static inline T& deref(void* ptr) { return *reinterpret_cast<T*>(ptr); }
// can be overridden in subclasses to compare POD types
// by comparing each individual member
virtual bool pod_mems_equals(const T&, const T&) const {
return false;
}
virtual bool pod_mems_equals(const T&, const T&) const { return false; }
std::string m_name;
......@@ -95,28 +90,24 @@ class abstract_uniform_type_info : public uniform_type_info {
}
template<class C>
typename std::enable_if<
!std::is_empty<C>::value && is_comparable<C, C>::value,
bool
>::type
typename std::enable_if<!std::is_empty<C>::value &&
detail::is_comparable<C, C>::value,
bool>::type
eq(const C& lhs, const C& rhs) const {
return lhs == rhs;
}
template<class C>
typename std::enable_if<
!std::is_empty<C>::value
&& std::is_pod<C>::value
&& !is_comparable<C, C>::value,
bool
>::type
typename std::enable_if<!std::is_empty<C>::value && std::is_pod<C>::value &&
!detail::is_comparable<C, C>::value,
bool>::type
eq(const C& lhs, const C& rhs) const {
return pod_mems_equals(lhs, rhs);
}
};
} // namespace util
} // namespace detail
} // namespace cppa
#endif // CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#endif // CPPA_DETAIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_ACTOR_REGISTRY_HPP
#define CPPA_DETAIL_ACTOR_REGISTRY_HPP
......@@ -29,14 +28,14 @@
#include "cppa/attachable.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/util/shared_spinlock.hpp"
#include "cppa/detail/shared_spinlock.hpp"
#include "cppa/detail/singleton_mixin.hpp"
namespace cppa {
namespace detail {
class singleton_manager;
class singletons;
class actor_registry : public singleton_mixin<actor_registry> {
......@@ -51,7 +50,7 @@ class actor_registry : public singleton_mixin<actor_registry> {
* exit reason. An entry with a nullptr means the actor has finished
* execution for given reason.
*/
typedef std::pair<abstract_actor_ptr, std::uint32_t> value_type;
typedef std::pair<abstract_actor_ptr, uint32_t> value_type;
/**
* @brief Returns the {nullptr, invalid_exit_reason}.
......@@ -65,7 +64,7 @@ class actor_registry : public singleton_mixin<actor_registry> {
void put(actor_id key, const abstract_actor_ptr& value);
void erase(actor_id key, std::uint32_t reason);
void erase(actor_id key, uint32_t reason);
// gets the next free actor id
actor_id next_id();
......@@ -91,7 +90,7 @@ class actor_registry : public singleton_mixin<actor_registry> {
std::mutex m_running_mtx;
std::condition_variable m_running_cv;
mutable util::shared_spinlock m_instances_mtx;
mutable detail::shared_spinlock m_instances_mtx;
entries m_entries;
actor_registry();
......
......@@ -16,41 +16,41 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CALL_HPP
#define CALL_HPP
#ifndef CPPA_DETAIL_APPLY_ARGS_HPP
#define CPPA_DETAIL_APPLY_ARGS_HPP
#include "cppa/util/int_list.hpp"
#include "cppa/detail/int_list.hpp"
namespace cppa {
namespace detail {
template <typename F, long... Is, class Tuple>
inline auto apply_args(F& f, util::int_list<Is...>, Tuple&& tup)
-> decltype(f(get<Is>(tup)...)) {
template<typename F, long... Is, class Tuple>
inline auto apply_args(F& f, detail::int_list<Is...>, Tuple&& tup)
-> decltype(f(get<Is>(tup)...)) {
return f(get<Is>(tup)...);
}
template <typename F, class Tuple, typename... Ts>
inline auto apply_args_prefixed(F& f, util::int_list<>, Tuple&, Ts&&... args)
-> decltype(f(std::forward<Ts>(args)...)) {
template<typename F, class Tuple, typename... Ts>
inline auto apply_args_prefixed(F& f, detail::int_list<>, Tuple&, Ts&&... args)
-> decltype(f(std::forward<Ts>(args)...)) {
return f(std::forward<Ts>(args)...);
}
template <typename F, long... Is, class Tuple, typename... Ts>
inline auto apply_args_prefixed(F& f, util::int_list<Is...>, Tuple& tup,
template<typename F, long... Is, class Tuple, typename... Ts>
inline auto apply_args_prefixed(F& f, detail::int_list<Is...>, Tuple& tup,
Ts&&... args)
-> decltype(f(std::forward<Ts>(args)..., get<Is>(tup)...)) {
-> decltype(f(std::forward<Ts>(args)..., get<Is>(tup)...)) {
return f(std::forward<Ts>(args)..., get<Is>(tup)...);
}
template <typename F, long... Is, class Tuple, typename... Ts>
inline auto apply_args_suffxied(F& f, util::int_list<Is...>, Tuple& tup,
template<typename F, long... Is, class Tuple, typename... Ts>
inline auto apply_args_suffxied(F& f, detail::int_list<Is...>, Tuple& tup,
Ts&&... args)
-> decltype(f(get<Is>(tup)..., std::forward<Ts>(args)...)) {
-> decltype(f(get<Is>(tup)..., std::forward<Ts>(args)...)) {
return f(get<Is>(tup)..., std::forward<Ts>(args)...);
}
} // namespace detail
} // namespace cppa
#endif // CALL_HPP
#endif // CPPA_DETAIL_APPLY_ARGS_HPP
......@@ -16,8 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_ARG_MATCH_T_HPP
#define CPPA_ARG_MATCH_T_HPP
#ifndef CPPA_DETAIL_ARG_MATCH_T_HPP
#define CPPA_DETAIL_ARG_MATCH_T_HPP
namespace cppa {
namespace detail {
......@@ -27,4 +27,4 @@ struct arg_match_t {};
} // namespace detail
} // namespace cppa
#endif // CPPA_ARG_MATCH_T_HPP
#endif // CPPA_DETAIL_ARG_MATCH_T_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_ATOM_VAL_HPP
#define CPPA_DETAIL_ATOM_VAL_HPP
......@@ -28,15 +27,14 @@ namespace {
// encodes ASCII characters to 6bit encoding
constexpr unsigned char encoding_table[] = {
/* ..0 ..1 ..2 ..3 ..4 ..5 ..6 ..7 ..8 ..9 ..A ..B ..C ..D ..E ..F */
/* 0.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 1.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 2.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 3.. */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0,
/* 4.. */ 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
/* 5.. */ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, 37,
/* 6.. */ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
/* 7.. */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0
};
/* 0.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 1.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 2.. */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 3.. */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0,
/* 4.. */ 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
/* 5.. */ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, 37,
/* 6.. */ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
/* 7.. */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0};
// decodes 6bit characters to ASCII
constexpr char decoding_table[] = " 0123456789"
......@@ -45,15 +43,15 @@ constexpr char decoding_table[] = " 0123456789"
} // namespace <anonymous>
constexpr std::uint64_t next_interim(std::uint64_t current, size_t char_code) {
constexpr uint64_t next_interim(uint64_t current, size_t char_code) {
return (current << 6) | encoding_table[(char_code <= 0x7F) ? char_code : 0];
}
constexpr std::uint64_t atom_val(const char* cstr, std::uint64_t interim = 0) {
return (*cstr == '\0') ? interim
: atom_val(cstr + 1,
next_interim(interim,
static_cast<size_t>(*cstr)));
constexpr uint64_t atom_val(const char* cstr, uint64_t interim = 0) {
return (*cstr == '\0') ?
interim :
atom_val(cstr + 1,
next_interim(interim, static_cast<size_t>(*cstr)));
}
} // namespace detail
......
......@@ -16,8 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef BEHAVIOR_IMPL_HPP
#define BEHAVIOR_IMPL_HPP
#ifndef CPPA_DETAIL_BEHAVIOR_IMPL_HPP
#define CPPA_DETAIL_BEHAVIOR_IMPL_HPP
#include <tuple>
#include <type_traits>
......@@ -29,15 +29,19 @@
#include "cppa/atom.hpp"
#include "cppa/message.hpp"
#include "cppa/duration.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/skip_message.hpp"
#include "cppa/timeout_definition.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/int_list.hpp"
#include "cppa/detail/apply_args.hpp"
#include "cppa/detail/type_traits.hpp"
// <backward_compatibility version="0.9">
#include "cppa/cow_tuple.hpp"
// </backward_compatibility>
namespace cppa {
......@@ -56,66 +60,88 @@ struct is_message_id_wrapper {
template<class U>
static char (&test(...))[2];
static constexpr bool value = sizeof(test<T>(0)) == 1;
};
template<typename T>
struct optional_message_visitor_enable_tpl {
using type = typename std::remove_const<T>::type;
static constexpr bool value =
!detail::is_one_of<type,
none_t,
unit_t,
skip_message_t,
optional<skip_message_t>>::value &&
!is_message_id_wrapper<T>::value;
};
struct optional_message_visitor : static_visitor<bhvr_invoke_result> {
// inline bhvr_invoke_result operator()() const { return message{}; }
inline bhvr_invoke_result operator()(none_t&) const { return none; }
inline bhvr_invoke_result operator()(const none_t&) const { return none; }
inline bhvr_invoke_result operator()(skip_message_t&) const { return none; }
inline bhvr_invoke_result operator()(const skip_message_t&) const {
inline bhvr_invoke_result operator()(const none_t&) const {
return none;
}
inline bhvr_invoke_result operator()(unit_t&) const {
return message{};
inline bhvr_invoke_result operator()(const skip_message_t&) const {
return none;
}
inline bhvr_invoke_result operator()(const unit_t&) const {
return message{};
}
inline bhvr_invoke_result operator()(optional<skip_message_t>& val) const {
if (val) return none;
return message{};
}
inline bhvr_invoke_result
operator()(const optional<skip_message_t>& val) const {
inline bhvr_invoke_result operator()(const optional<skip_message_t>& val) const {
if (val) return none;
return message{};
}
template<typename T, typename... Ts>
inline typename std::enable_if<not is_message_id_wrapper<T>::value,
bhvr_invoke_result>::type
typename std::enable_if<optional_message_visitor_enable_tpl<T>::value,
bhvr_invoke_result>::type
operator()(T& v, Ts&... vs) const {
return make_message(std::move(v), std::move(vs)...);
}
template<typename T>
inline bhvr_invoke_result
operator()(T& value,
typename std::enable_if<is_message_id_wrapper<T>::value>::type* =
0) const {
typename std::enable_if<is_message_id_wrapper<T>::value,
bhvr_invoke_result>::type
operator()(T& value) const {
return make_message(atom("MESSAGE_ID"),
value.get_message_id().integer_value());
}
inline bhvr_invoke_result operator()(message& value) const {
return std::move(value);
}
template<typename... Ts>
inline bhvr_invoke_result operator()(std::tuple<Ts...>& value) const {
return detail::apply_args(*this, util::get_indices(value), value);
return detail::apply_args(*this, detail::get_indices(value), value);
}
// <backward_compatibility version="0.9">
template<typename... Ts>
inline bhvr_invoke_result operator()(cow_tuple<Ts...>& value) const {
return static_cast<message>(value);
}
// </backward_compatibility>
};
template<typename... Ts>
struct has_skip_message {
static constexpr bool value =
util::disjunction<std::is_same<Ts, skip_message_t>::value...>::value;
detail::disjunction<std::is_same<Ts, skip_message_t>::value...>::value;
};
class behavior_impl : public ref_counted {
public:
behavior_impl() = default;
inline behavior_impl(util::duration tout) : m_timeout(tout) {}
inline behavior_impl(duration tout) : m_timeout(tout) {}
virtual bhvr_invoke_result invoke(message&) = 0;
virtual bhvr_invoke_result invoke(const message&) = 0;
......@@ -124,7 +150,7 @@ class behavior_impl : public ref_counted {
return invoke(tmp);
}
virtual void handle_timeout();
inline const util::duration& timeout() const { return m_timeout; }
inline const duration& timeout() const { return m_timeout; }
typedef intrusive_ptr<behavior_impl> pointer;
......@@ -155,13 +181,14 @@ class behavior_impl : public ref_counted {
}
combinator(const pointer& p0, const pointer& p1)
: behavior_impl(p1->timeout()), first(p0), second(p1) {}
};
return new combinator(this, other);
}
private:
util::duration m_timeout;
duration m_timeout;
};
......@@ -169,6 +196,7 @@ struct dummy_match_expr {
inline variant<none_t> invoke(const message&) const { return none; }
inline bool can_invoke(const message&) const { return false; }
inline variant<none_t> operator()(const message&) const { return none; }
};
template<class MatchExpr, typename F>
......@@ -177,6 +205,7 @@ class default_behavior_impl : public behavior_impl {
typedef behavior_impl super;
public:
template<typename Expr>
default_behavior_impl(Expr&& expr, const timeout_definition<F>& d)
: super(d.timeout)
......@@ -184,17 +213,19 @@ class default_behavior_impl : public behavior_impl {
, m_fun(d.handler) {}
template<typename Expr>
default_behavior_impl(Expr&& expr, util::duration tout, F f)
default_behavior_impl(Expr&& expr, duration tout, F f)
: super(tout), m_expr(std::forward<Expr>(expr)), m_fun(f) {}
bhvr_invoke_result invoke(message& tup) {
auto res = m_expr(tup);
return apply_visitor(optional_message_visitor{}, res);
optional_message_visitor omv;
return apply_visitor(omv, res);
}
bhvr_invoke_result invoke(const message& tup) {
auto res = m_expr(tup);
return apply_visitor(optional_message_visitor{}, res);
optional_message_visitor omv;
return apply_visitor(omv, res);
}
typename behavior_impl::pointer
......@@ -206,18 +237,20 @@ class default_behavior_impl : public behavior_impl {
void handle_timeout() { m_fun(); }
private:
MatchExpr m_expr;
F m_fun;
};
template<class MatchExpr, typename F>
default_behavior_impl<MatchExpr, F>*
new_default_behavior(const MatchExpr& mexpr, util::duration d, F f) {
new_default_behavior(const MatchExpr& mexpr, duration d, F f) {
return new default_behavior_impl<MatchExpr, F>(mexpr, d, f);
}
template<typename F>
default_behavior_impl<dummy_match_expr, F>* new_default_behavior(util::duration d,
default_behavior_impl<dummy_match_expr, F>* new_default_behavior(duration d,
F f) {
return new default_behavior_impl<dummy_match_expr, F>(dummy_match_expr{}, d,
f);
......@@ -232,4 +265,4 @@ typedef intrusive_ptr<behavior_impl> behavior_impl_ptr;
} // namespace detail
} // namespace cppa
#endif // BEHAVIOR_IMPL_HPP
#endif // CPPA_DETAIL_BEHAVIOR_IMPL_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_BEHAVIOR_STACK_HPP
#define CPPA_DETAIL_BEHAVIOR_STACK_HPP
......@@ -26,6 +25,7 @@
#include <algorithm>
#include "cppa/optional.hpp"
#include "cppa/config.hpp"
#include "cppa/behavior.hpp"
#include "cppa/message_id.hpp"
......@@ -36,8 +36,7 @@ namespace detail {
struct behavior_stack_mover;
class behavior_stack
{
class behavior_stack {
friend struct behavior_stack_mover;
......@@ -80,9 +79,7 @@ class behavior_stack
m_elements.emplace_back(std::move(what), response_id);
}
inline void cleanup() {
m_erased_elements.clear();
}
inline void cleanup() { m_erased_elements.clear(); }
private:
......
......@@ -16,54 +16,61 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_BOXED_HPP
#define CPPA_DETAIL_BOXED_HPP
#include "cppa/anything.hpp"
#include "cppa/util/wrapped.hpp"
#include "cppa/detail/wrapped.hpp"
namespace cppa {
namespace detail {
template<typename T>
struct boxed {
typedef util::wrapped<T> type;
typedef detail::wrapped<T> type;
};
template<typename T>
struct boxed< util::wrapped<T> > {
typedef util::wrapped<T> type;
struct boxed<detail::wrapped<T>> {
typedef detail::wrapped<T> type;
};
template<>
struct boxed<anything> {
typedef anything type;
};
template<typename T>
struct is_boxed {
static constexpr bool value = false;
};
template<typename T>
struct is_boxed< util::wrapped<T> > {
struct is_boxed<detail::wrapped<T>> {
static constexpr bool value = true;
};
template<typename T>
struct is_boxed<util::wrapped<T>()> {
struct is_boxed<detail::wrapped<T>()> {
static constexpr bool value = true;
};
template<typename T>
struct is_boxed<util::wrapped<T>(&)()> {
struct is_boxed<detail::wrapped<T>(&)()> {
static constexpr bool value = true;
};
template<typename T>
struct is_boxed<util::wrapped<T>(*)()> {
struct is_boxed<detail::wrapped<T>(*)()> {
static constexpr bool value = true;
};
} // namespace detail
......
......@@ -16,12 +16,11 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_UTIL_COMPARABLE_HPP
#define CPPA_UTIL_COMPARABLE_HPP
#ifndef CPPA_COMPARABLE_HPP
#define CPPA_COMPARABLE_HPP
namespace cppa {
namespace util {
namespace detail {
/**
* @brief Barton–Nackman trick implementation.
......@@ -114,7 +113,7 @@ class comparable<Subclass, Subclass> {
};
} // namespace util
} // namespace details
} // namespace cppa
#endif // CPPA_UTIL_COMPARABLE_HPP
#endif // CPPA_COMPARABLE_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_CS_THREAD_HPP
#define CPPA_DETAIL_CS_THREAD_HPP
namespace cppa {
namespace detail {
struct cst_impl;
// A cooperatively scheduled thread implementation
struct cs_thread {
// Queries whether libcppa was compiled without cs threads on this platform.
static const bool is_disabled_feature;
// Creates a new cs_thread storing the context of the calling thread.
cs_thread();
// Creates a cs_thread that executes @p func(arg1)
cs_thread(void (*func)(void*), void* arg1);
~cs_thread();
// Swaps the context from @p source to @p target.
static void swap(cs_thread& source, cs_thread& target);
// pimpl
cst_impl* m_impl;
};
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_CS_THREAD_HPP
......@@ -16,8 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DECORATED_TUPLE_HPP
#define CPPA_DECORATED_TUPLE_HPP
#ifndef CPPA_DETAIL_DECORATED_TUPLE_HPP
#define CPPA_DETAIL_DECORATED_TUPLE_HPP
#include <vector>
#include <algorithm>
......@@ -26,11 +26,10 @@
#include "cppa/ref_counted.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/type_list.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/message_data.hpp"
#include "cppa/detail/serialize_tuple.hpp"
namespace cppa {
namespace detail {
......@@ -108,4 +107,4 @@ class decorated_tuple : public message_data {
} // namespace detail
} // namespace cppa
#endif // CPPA_DECORATED_TUPLE_HPP
#endif // CPPA_DETAIL_DECORATED_TUPLE_HPP
This diff is collapsed.
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_DEMANGLE_HPP
#define CPPA_DETAIL_DEMANGLE_HPP
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_DISABLABLE_DELETE_HPP
#define CPPA_DETAIL_DISABLABLE_DELETE_HPP
......@@ -27,15 +26,11 @@ class disablable_delete {
public:
constexpr disablable_delete() : m_enabled(true) { }
constexpr disablable_delete() : m_enabled(true) {}
inline void disable() {
m_enabled = false;
}
inline void disable() { m_enabled = false; }
inline void enable() {
m_enabled = true;
}
inline void enable() { m_enabled = true; }
template<typename T>
inline void operator()(T* ptr) {
......
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
/******************************************************************************\
* Based on work by the mingw-w64 project; *
* original header: *
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_FD_UTIL_HPP
#define CPPA_DETAIL_FD_UTIL_HPP
#include <string>
#include <utility> // std::pair
#include <unistd.h> // ssize_t
#include "cppa/config.hpp"
namespace cppa {
namespace detail {
namespace fd_util {
std::string last_socket_error_as_string();
// throws network_error and adds errno failure if @p add_errno_failure
void throw_io_failure (const char* what, bool add_errno = true);
// sets fd to nonblocking if <tt>set_nonblocking == true</tt>
// or to blocking if <tt>set_nonblocking == false</tt>
// throws @p network_error on error
void nonblocking(native_socket_type fd, bool new_value);
// returns true if fd is nodelay socket
// throws @p network_error on error
void tcp_nodelay(native_socket_type fd, bool new_value);
// reads @p result and @p errno and throws @p network_error on error
void handle_write_result(ssize_t result, bool is_nonblocking_io);
// reads @p result and @p errno and throws @p network_error on error
void handle_read_result(ssize_t result, bool is_nonblocking_io);
std::pair<native_socket_type, native_socket_type> create_pipe();
} // namespace fd_util
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_FD_UTIL_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_FUNCTOR_BASED_BLOCKING_ACTOR_HPP
#define CPPA_DETAIL_FUNCTOR_BASED_BLOCKING_ACTOR_HPP
#include "cppa/blocking_actor.hpp"
namespace cppa {
namespace detail {
class functor_based_blocking_actor : public blocking_actor {
public:
typedef std::function<void (blocking_actor*)> act_fun;
template<typename F, typename... Ts>
functor_based_blocking_actor(F f, Ts&&... vs) {
blocking_actor* dummy = nullptr;
create(dummy, f, std::forward<Ts>(vs)...);
}
protected:
void act() override;
private:
void create(blocking_actor*, act_fun);
template<class Actor, typename F, typename T0, typename... Ts>
auto create(Actor* dummy, F f, T0&& v0, Ts&&... vs) ->
typename std::enable_if<
std::is_same<
decltype(f(dummy, std::forward<T0>(v0), std::forward<Ts>(vs)...)),
void
>::value
>::type {
create(dummy, std::bind(f, std::placeholders::_1,
std::forward<T0>(v0), std::forward<Ts>(vs)...));
}
template<class Actor, typename F, typename T0, typename... Ts>
auto create(Actor* dummy, F f, T0&& v0, Ts&&... vs) ->
typename std::enable_if<
std::is_same<
decltype(f(std::forward<T0>(v0), std::forward<Ts>(vs)...)),
void
>::value
>::type {
std::function<void()> fun = std::bind(f, std::forward<T0>(v0),
std::forward<Ts>(vs)...);
create(dummy, [fun](Actor*) { fun(); });
}
act_fun m_act;
};
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_FUNCTOR_BASED_BLOCKING_ACTOR_HPP
......@@ -16,19 +16,18 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_UTIL_GET_MAC_ADDRESSES_HPP
#define CPPA_UTIL_GET_MAC_ADDRESSES_HPP
#ifndef CPPA_DETAIL_GET_MAC_ADDRESSES_HPP
#define CPPA_DETAIL_GET_MAC_ADDRESSES_HPP
#include <string>
#include <vector>
namespace cppa {
namespace util {
namespace detail {
std::vector<std::string> get_mac_addresses();
} // namespace util
} // namespace detail
} // namespace cppa
#endif // CPPA_UTIL_GET_MAC_ADDRESSES_HPP
#endif // CPPA_DETAIL_GET_MAC_ADDRESSES_HPP
......@@ -16,18 +16,17 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_UTIL_GET_ROOT_UUID_HPP
#define CPPA_UTIL_GET_ROOT_UUID_HPP
#ifndef CPPA_DETAIL_GET_ROOT_UUID_HPP
#define CPPA_DETAIL_GET_ROOT_UUID_HPP
#include <string>
namespace cppa {
namespace util {
namespace detail {
std::string get_root_uuid();
} // namespace util
} // namespace detail
} // namespace cppa
#endif // CPPA_UTIL_GET_ROOT_UUID_HPP
#endif // CPPA_DETAIL_GET_ROOT_UUID_HPP
......@@ -16,7 +16,6 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_GROUP_MANAGER_HPP
#define CPPA_DETAIL_GROUP_MANAGER_HPP
......@@ -25,7 +24,7 @@
#include <thread>
#include "cppa/abstract_group.hpp"
#include "cppa/util/shared_spinlock.hpp"
#include "cppa/detail/shared_spinlock.hpp"
#include "cppa/detail/singleton_mixin.hpp"
......@@ -51,7 +50,8 @@ class group_manager : public singleton_mixin<group_manager> {
private:
typedef std::map<std::string, abstract_group::unique_module_ptr> modules_map;
typedef std::map<std::string, abstract_group::unique_module_ptr>
modules_map;
modules_map m_mmap;
std::mutex m_mmap_mtx;
......
......@@ -20,11 +20,11 @@
* Based on http://beej.us/guide/bgnet/examples/pack2.c *
\******************************************************************************/
#ifndef CPPA_DETAIL_IEEE_754_HPP
#define CPPA_DETAIL_IEEE_754_HPP
#include <cmath>
#include <cstdint>
namespace cppa {
namespace detail {
......@@ -34,31 +34,33 @@ struct ieee_754_trait;
template<>
struct ieee_754_trait<float> {
static constexpr std::uint32_t bits = 32; // number of bits
static constexpr std::uint32_t expbits = 8; // bits used for exponent
static constexpr float zero = 0.0f; // the value 0
static constexpr float p5 = 0.5f; // the value 0.5
using packed_type = std::uint32_t; // unsigned integer type
using signed_packed_type = std::int32_t; // signed integer type
using float_type = float; // floating point type
static constexpr uint32_t bits = 32; // number of bits
static constexpr uint32_t expbits = 8; // bits used for exponent
static constexpr float zero = 0.0f; // the value 0
static constexpr float p5 = 0.5f; // the value 0.5
using packed_type = uint32_t; // unsigned integer type
using signed_packed_type = int32_t; // signed integer type
using float_type = float; // floating point type
};
template<>
struct ieee_754_trait<std::uint32_t> : ieee_754_trait<float> { };
struct ieee_754_trait<uint32_t> : ieee_754_trait<float> {};
template<>
struct ieee_754_trait<double> {
static constexpr std::uint64_t bits = 64;
static constexpr std::uint64_t expbits = 11;
static constexpr double zero = 0.0;
static constexpr uint64_t bits = 64;
static constexpr uint64_t expbits = 11;
static constexpr double zero = 0.0;
static constexpr double p5 = 0.5;
using packed_type = std::uint64_t;
using signed_packed_type = std::int64_t;
using packed_type = uint64_t;
using signed_packed_type = int64_t;
using float_type = double;
};
template<>
struct ieee_754_trait<std::uint64_t> : ieee_754_trait<double> { };
struct ieee_754_trait<uint64_t> : ieee_754_trait<double> {};
template<typename T>
typename ieee_754_trait<T>::packed_type pack754(T f) {
......@@ -73,8 +75,7 @@ typename ieee_754_trait<T>::packed_type pack754(T f) {
if (f < 0) {
sign = 1;
fnorm = -f;
}
else {
} else {
sign = 0;
fnorm = f;
}
......@@ -96,10 +97,10 @@ typename ieee_754_trait<T>::packed_type pack754(T f) {
// get the biased exponent
auto exp = shift + ((1 << (trait::expbits - 1)) - 1); // shift + bias
// return the final answer
return (sign << (trait::bits - 1)) | (exp << (trait::bits - trait::expbits - 1)) | significand;
return (sign << (trait::bits - 1)) |
(exp << (trait::bits - trait::expbits - 1)) | significand;
}
template<typename T>
typename ieee_754_trait<T>::float_type unpack754(T i) {
typedef ieee_754_trait<T> trait;
......@@ -108,14 +109,16 @@ typename ieee_754_trait<T>::float_type unpack754(T i) {
if (i == 0) return trait::zero;
auto significandbits = trait::bits - trait::expbits - 1; // -1 for sign bit
// pull the significand
result_type result = (i & ((static_cast<T>(1) << significandbits) - 1)); // mask
result_type result =
(i & ((static_cast<T>(1) << significandbits) - 1)); // mask
result /= (static_cast<T>(1) << significandbits); // convert back to float
result += static_cast<result_type>(1); // add the one back on
result += static_cast<result_type>(1); // add the one back on
// deal with the exponent
auto si = static_cast<signed_type>(i);
auto bias = (1 << (trait::expbits - 1)) - 1;
auto pownum = static_cast<signed_type>(1) << trait::expbits;
auto shift = static_cast<signed_type>(((si >> significandbits) & (pownum - 1)) - bias);
auto shift = static_cast<signed_type>(
((si >> significandbits) & (pownum - 1)) - bias);
while (shift > 0) {
result *= static_cast<result_type>(2);
--shift;
......
......@@ -16,16 +16,17 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_DETAIL_IMPLICIT_CONVERSIONS_HPP
#define CPPA_DETAIL_IMPLICIT_CONVERSIONS_HPP
#include <string>
#include <type_traits>
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/type_traits.hpp"
namespace cppa { class local_actor; }
namespace cppa {
class local_actor;
} // namespace cppa
namespace cppa {
namespace detail {
......@@ -33,35 +34,36 @@ namespace detail {
template<typename T>
struct implicit_conversions {
typedef typename util::replace_type<
typedef typename replace_type<
T,
std::string,
std::is_same<T, const char*>,
std::is_same<T, char*>,
util::is_array_of<T, char>,
util::is_array_of<T, const char>
std::is_same<T, char[]>,
is_array_of<T, char>,
is_array_of<T, const char>
>::type
subtype1;
typedef typename util::replace_type<
typedef typename replace_type<
subtype1,
std::u16string,
std::is_same<subtype1, const char16_t*>,
std::is_same<subtype1, char16_t*>,
util::is_array_of<subtype1, char16_t>
is_array_of<subtype1, char16_t>
>::type
subtype2;
typedef typename util::replace_type<
typedef typename replace_type<
subtype2,
std::u32string,
std::is_same<subtype2, const char32_t*>,
std::is_same<subtype2, char32_t*>,
util::is_array_of<subtype2, char32_t>
is_array_of<subtype2, char32_t>
>::type
subtype3;
typedef typename util::replace_type<
typedef typename replace_type<
subtype3,
actor,
std::is_convertible<T, abstract_actor*>,
......@@ -73,8 +75,11 @@ struct implicit_conversions {
template<typename T>
struct strip_and_convert {
typedef typename implicit_conversions<typename util::rm_const_and_ref<T>::type>::type
typedef typename implicit_conversions<
typename rm_const_and_ref<T>::type
>::type
type;
};
} // namespace detail
......
This diff is collapsed.
......@@ -16,9 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_UTIL_LIMITED_VECTOR_HPP
#define CPPA_UTIL_LIMITED_VECTOR_HPP
#ifndef CPPA_DETAIL_LIMITED_VECTOR_HPP
#define CPPA_DETAIL_LIMITED_VECTOR_HPP
#include <cstddef>
#include <iterator>
......@@ -30,7 +29,7 @@
#include "cppa/config.hpp"
namespace cppa {
namespace util {
namespace detail {
/**
* @brief A vector with a fixed maximum size (uses an array internally).
......@@ -260,7 +259,7 @@ class limited_vector {
};
} // namespace util
} // namespace detail
} // namespace cppa
#endif // CPPA_UTIL_LIMITED_VECTOR_HPP
#endif // CPPA_DETAIL_LIMITED_VECTOR_HPP
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -16,8 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_TUPLE_ITERATOR_HPP
#define CPPA_TUPLE_ITERATOR_HPP
#ifndef CPPA_DETAIL_TUPLE_ITERATOR_HPP
#define CPPA_DETAIL_TUPLE_ITERATOR_HPP
#include <cstddef>
......@@ -96,4 +96,4 @@ class message_iterator {
} // namespace detail
} // namespace cppa
#endif // CPPA_TUPLE_ITERATOR_HPP
#endif // CPPA_DETAIL_TUPLE_ITERATOR_HPP
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.
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.
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.
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.
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