Commit a96f232d authored by Dominik Charousset's avatar Dominik Charousset

New terminology, e.g., `any_tuple` => `message`

This patch renames several classes to give programmers without functional
background a better intuition about the purpose of a particular class. For
example, `partial_function` is not a concept familiar to all C++ developers and
has been renamed to `message_handler`. Although the former is a better and more
general name in theory, the latter is a better description for what the class
is actually used for in the library.
parent f83fdfb4
...@@ -119,16 +119,6 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") ...@@ -119,16 +119,6 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo) set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif ("${CMAKE_BUILD_TYPE}" STREQUAL "") endif ("${CMAKE_BUILD_TYPE}" STREQUAL "")
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_epoll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_poll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Window")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_poll.cpp src/execinfo_windows.cpp)
else ()
message(FATAL_ERROR "This platform is not supported by libcppa")
endif()
# get header files; only needed by CMake generators, # get header files; only needed by CMake generators,
# e.g., for creating proper Xcode projects # e.g., for creating proper Xcode projects
file(GLOB LIBCPPA_HDRS "cppa/*.hpp" file(GLOB LIBCPPA_HDRS "cppa/*.hpp"
...@@ -139,13 +129,23 @@ file(GLOB LIBCPPA_HDRS "cppa/*.hpp" ...@@ -139,13 +129,23 @@ file(GLOB LIBCPPA_HDRS "cppa/*.hpp"
"cppa/qtsupport/*.hpp" "cppa/qtsupport/*.hpp"
"cppa/util/*.hpp") "cppa/util/*.hpp")
# list cpp files including platform-dependent files # platform-dependent files
set(LIBCPPA_SRC if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
${LIBCPPA_PLATFORM_SRC} 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()
# list cpp files excluding platform-dependent files
set (LIBCPPA_SRCS
${LIBCPPA_PLATFORM_SRCS}
src/abstract_actor.cpp src/abstract_actor.cpp
src/abstract_channel.cpp src/abstract_channel.cpp
src/abstract_group.cpp src/abstract_group.cpp
src/abstract_tuple.cpp
src/acceptor.cpp src/acceptor.cpp
src/actor.cpp src/actor.cpp
src/actor_addr.cpp src/actor_addr.cpp
...@@ -153,10 +153,8 @@ set(LIBCPPA_SRC ...@@ -153,10 +153,8 @@ set(LIBCPPA_SRC
src/actor_namespace.cpp src/actor_namespace.cpp
src/actor_ostream.cpp src/actor_ostream.cpp
src/actor_proxy.cpp src/actor_proxy.cpp
src/actor_proxy.cpp
src/actor_registry.cpp src/actor_registry.cpp
src/algorithm.cpp src/algorithm.cpp
src/any_tuple.cpp
src/atom.cpp src/atom.cpp
src/attachable.cpp src/attachable.cpp
src/behavior.cpp src/behavior.cpp
...@@ -194,14 +192,18 @@ set(LIBCPPA_SRC ...@@ -194,14 +192,18 @@ set(LIBCPPA_SRC
src/match.cpp src/match.cpp
src/memory.cpp src/memory.cpp
src/memory_managed.cpp src/memory_managed.cpp
src/message.cpp
src/message_builder.cpp
src/message_handler.cpp
src/message_header.cpp src/message_header.cpp
src/middleman.cpp src/middleman.cpp
src/middleman_event_handler.cpp src/middleman_event_handler.cpp
src/node_id.cpp src/node_id.cpp
src/object_array.cpp src/opencl/global.cpp
src/opencl/opencl_metainfo.cpp
src/opencl/program.cpp
src/opt.cpp src/opt.cpp
src/output_stream.cpp src/output_stream.cpp
src/partial_function.cpp
src/peer.cpp src/peer.cpp
src/peer_acceptor.cpp src/peer_acceptor.cpp
src/primitive_variant.cpp src/primitive_variant.cpp
...@@ -279,7 +281,7 @@ endif (ENABLE_CONTEXT_SWITCHING) ...@@ -279,7 +281,7 @@ endif (ENABLE_CONTEXT_SWITCHING)
# build shared library if not compiling static only # build shared library if not compiling static only
if (NOT "${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes") if (NOT "${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes")
add_library(libcppa SHARED ${LIBCPPA_SRC} ${LIBCPPA_HDRS}) add_library(libcppa SHARED ${LIBCPPA_SRCS} ${LIBCPPA_HDRS})
target_link_libraries(libcppa ${LD_FLAGS}) target_link_libraries(libcppa ${LD_FLAGS})
set(LIBRARY_VERSION ${LIBCPPA_VERSION_MAJOR}.${LIBCPPA_VERSION_MINOR}.${LIBCPPA_VERSION_PATCH}) set(LIBRARY_VERSION ${LIBCPPA_VERSION_MAJOR}.${LIBCPPA_VERSION_MINOR}.${LIBCPPA_VERSION_PATCH})
set(LIBRARY_SOVERSION ${LIBCPPA_VERSION_MAJOR}) set(LIBRARY_SOVERSION ${LIBCPPA_VERSION_MAJOR})
...@@ -295,7 +297,7 @@ endif () ...@@ -295,7 +297,7 @@ endif ()
# build static library only if --build-static or --build-static-only was set # build static library only if --build-static or --build-static-only was set
if ("${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes" OR "${CPPA_BUILD_STATIC}" STREQUAL "yes") if ("${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes" OR "${CPPA_BUILD_STATIC}" STREQUAL "yes")
add_library(libcppaStatic STATIC ${LIBCPPA_HDRS} ${LIBCPPA_SRC}) add_library(libcppaStatic STATIC ${LIBCPPA_HDRS} ${LIBCPPA_SRCS})
set_target_properties(libcppaStatic PROPERTIES OUTPUT_NAME cppa_static) set_target_properties(libcppaStatic PROPERTIES OUTPUT_NAME cppa_static)
install(TARGETS libcppaStatic ARCHIVE DESTINATION lib) install(TARGETS libcppaStatic ARCHIVE DESTINATION lib)
endif () endif ()
......
...@@ -46,7 +46,7 @@ class abstract_channel : public ref_counted { ...@@ -46,7 +46,7 @@ class abstract_channel : public ref_counted {
* is not a scheduled actor. * is not a scheduled actor.
*/ */
virtual void enqueue(msg_hdr_cref header, virtual void enqueue(msg_hdr_cref header,
any_tuple content, message content,
execution_unit* host) = 0; execution_unit* host) = 0;
protected: protected:
......
...@@ -47,7 +47,7 @@ class broker; ...@@ -47,7 +47,7 @@ class broker;
} // namespace io } // namespace io
namespace opencl { namespace opencl {
template <typename Signature> template<typename Signature>
class actor_facade; class actor_facade;
} // namespace opencl } // namespace opencl
......
...@@ -65,7 +65,7 @@ class actor_companion : public extend<local_actor, actor_companion>:: ...@@ -65,7 +65,7 @@ class actor_companion : public extend<local_actor, actor_companion>::
*/ */
void on_enqueue(enqueue_handler handler); void on_enqueue(enqueue_handler handler);
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit* eu) override; void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override;
private: private:
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define CPPA_ACTOR_OSTREAM_HPP #define CPPA_ACTOR_OSTREAM_HPP
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
namespace cppa { namespace cppa {
...@@ -51,11 +51,11 @@ class actor_ostream { ...@@ -51,11 +51,11 @@ class actor_ostream {
return write(move(arg)); return write(move(arg));
} }
inline actor_ostream& operator<<(const any_tuple& arg) { inline actor_ostream& operator<<(const message& arg) {
return write(cppa::to_string(arg)); return write(cppa::to_string(arg));
} }
// disambiguate between conversion to string and to any_tuple // disambiguate between conversion to string and to message
inline actor_ostream& operator<<(const char* arg) { inline actor_ostream& operator<<(const char* arg) {
return *this << std::string{arg}; return *this << std::string{arg};
} }
...@@ -63,7 +63,7 @@ class actor_ostream { ...@@ -63,7 +63,7 @@ class actor_ostream {
template<typename T> template<typename T>
inline typename std::enable_if< inline typename std::enable_if<
!std::is_convertible<T, std::string>::value !std::is_convertible<T, std::string>::value
&& !std::is_convertible<T, any_tuple>::value, && !std::is_convertible<T, message>::value,
actor_ostream& actor_ostream&
>::type >::type
operator<<(T&& arg) { operator<<(T&& arg) {
......
...@@ -63,7 +63,7 @@ class actor_proxy : public extend<abstract_actor>::with<enable_weak_ptr> { ...@@ -63,7 +63,7 @@ class actor_proxy : public extend<abstract_actor>::with<enable_weak_ptr> {
* middleman's thread. * middleman's thread.
* @note This function is guaranteed to be called non-concurrently. * @note This function is guaranteed to be called non-concurrently.
*/ */
virtual void deliver(msg_hdr_cref hdr, any_tuple msg) = 0; virtual void deliver(msg_hdr_cref hdr, message msg) = 0;
protected: protected:
......
...@@ -241,8 +241,8 @@ class meta_cow_tuple : public uniform_type_info { ...@@ -241,8 +241,8 @@ class meta_cow_tuple : public uniform_type_info {
return create_impl<tuple_type>(other); return create_impl<tuple_type>(other);
} }
any_tuple as_any_tuple(void* instance) const override { message as_message(void* instance) const override {
return (instance) ? any_tuple{*cast(instance)} : any_tuple{}; return (instance) ? make_message(*cast(instance)) : message{};
} }
bool equal_to(const std::type_info& tinfo) const override { bool equal_to(const std::type_info& tinfo) const override {
......
...@@ -32,18 +32,18 @@ ...@@ -32,18 +32,18 @@
namespace cppa { namespace cppa {
class partial_function; class message_handler;
/** /**
* @brief Describes the behavior of an actor. * @brief Describes the behavior of an actor.
*/ */
class behavior { class behavior {
friend class partial_function; friend class message_handler;
public: public:
typedef std::function<optional<any_tuple> (any_tuple&)> continuation_fun; typedef std::function<optional<message> (message&)> continuation_fun;
/** @cond PRIVATE */ /** @cond PRIVATE */
...@@ -61,7 +61,7 @@ class behavior { ...@@ -61,7 +61,7 @@ class behavior {
behavior& operator=(behavior&&) = default; behavior& operator=(behavior&&) = default;
behavior& operator=(const behavior&) = default; behavior& operator=(const behavior&) = default;
behavior(const partial_function& fun); behavior(const message_handler& fun);
template<typename F> template<typename F>
behavior(const timeout_definition<F>& arg); behavior(const timeout_definition<F>& arg);
...@@ -91,7 +91,7 @@ class behavior { ...@@ -91,7 +91,7 @@ class behavior {
* does not evaluate guards. * does not evaluate guards.
*/ */
template<typename T> template<typename T>
inline optional<any_tuple> operator()(T&& arg); inline optional<message> operator()(T&& arg);
/** /**
* @brief Adds a continuation to this behavior that is executed * @brief Adds a continuation to this behavior that is executed
...@@ -151,7 +151,7 @@ inline const util::duration& behavior::timeout() const { ...@@ -151,7 +151,7 @@ inline const util::duration& behavior::timeout() const {
} }
template<typename T> template<typename T>
inline optional<any_tuple> behavior::operator()(T&& arg) { inline optional<message> behavior::operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none; return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
} }
......
...@@ -46,11 +46,11 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> { ...@@ -46,11 +46,11 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> {
typedef behavior_stack_based_impl combined_type; typedef behavior_stack_based_impl combined_type;
typedef response_handle<behavior_stack_based_impl, typedef response_handle<behavior_stack_based_impl,
any_tuple, message,
nonblocking_response_handle_tag> nonblocking_response_handle_tag>
response_handle_type; response_handle_type;
template <typename... Ts> template<typename... Ts>
behavior_stack_based_impl(Ts&&... vs) : super(std::forward<Ts>(vs)...) { } behavior_stack_based_impl(Ts&&... vs) : super(std::forward<Ts>(vs)...) { }
/************************************************************************** /**************************************************************************
......
...@@ -124,7 +124,7 @@ class blocking_actor ...@@ -124,7 +124,7 @@ class blocking_actor
* @code * @code
* int i = 0; * int i = 0;
* receive_for(i, 10) ( * receive_for(i, 10) (
* on(atom("get")) >> [&]() -> any_tuple { return {"result", i}; } * on(atom("get")) >> [&]() -> message { return {"result", i}; }
* ); * );
* @endcode * @endcode
* @param begin First value in range. * @param begin First value in range.
......
...@@ -135,7 +135,7 @@ using ::backtrace_symbols_fd; ...@@ -135,7 +135,7 @@ using ::backtrace_symbols_fd;
} \ } \
abort() abort()
# define CPPA_REQUIRE(stmt) \ # define CPPA_REQUIRE(stmt) \
if ((stmt) == false) { \ if (static_cast<bool>(stmt) == false) { \
CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \ CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \
}((void) 0) }((void) 0)
#else #else
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/message_id.hpp" #include "cppa/message_id.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
namespace cppa { namespace cppa {
...@@ -50,7 +50,7 @@ class continue_helper { ...@@ -50,7 +50,7 @@ class continue_helper {
*/ */
template<typename F> template<typename F>
continue_helper& continue_with(F fun) { continue_helper& continue_with(F fun) {
return continue_with(behavior::continuation_fun{partial_function{ return continue_with(behavior::continuation_fun{message_handler{
on(any_vals, arg_match) >> fun on(any_vals, arg_match) >> fun
}}); }});
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <type_traits> #include <type_traits>
#include "cppa/get.hpp" #include "cppa/get.hpp"
#include "cppa/cow_ptr.hpp" #include "cppa/message.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
...@@ -39,13 +39,6 @@ ...@@ -39,13 +39,6 @@
namespace cppa { namespace cppa {
// forward declaration
class any_tuple;
class local_actor;
template<typename... ElementTypes>
class cow_tuple;
/** /**
* @ingroup CopyOnWrite * @ingroup CopyOnWrite
* @brief A fixed-length copy-on-write cow_tuple. * @brief A fixed-length copy-on-write cow_tuple.
...@@ -58,22 +51,16 @@ class cow_tuple<Head, Tail...> { ...@@ -58,22 +51,16 @@ class cow_tuple<Head, Tail...> {
"illegal types in cow_tuple definition: " "illegal types in cow_tuple definition: "
"pointers and references are prohibited"); "pointers and references are prohibited");
friend class any_tuple; using data_type = detail::tuple_vals<
typename detail::strip_and_convert<Head>::type,
typedef detail::tuple_vals<Head, Tail...> data_type; typename detail::strip_and_convert<Tail>::type...>;
cow_ptr<detail::abstract_tuple> m_vals;
struct priv_ctor { };
cow_tuple(priv_ctor, cow_ptr<detail::abstract_tuple>&& ptr) : m_vals(std::move(ptr)) { } using data_ptr = detail::message_data::ptr;
public: public:
typedef util::type_list<Head, Tail...> types; typedef util::type_list<Head, Tail...> types;
typedef cow_ptr<detail::abstract_tuple> cow_ptr_type;
static constexpr size_t num_elements = sizeof...(Tail) + 1; static constexpr size_t num_elements = sizeof...(Tail) + 1;
cow_tuple() : m_vals(new data_type) { } cow_tuple() : m_vals(new data_type) { }
...@@ -99,12 +86,6 @@ class cow_tuple<Head, Tail...> { ...@@ -99,12 +86,6 @@ class cow_tuple<Head, Tail...> {
cow_tuple& operator=(cow_tuple&&) = default; cow_tuple& operator=(cow_tuple&&) = default;
cow_tuple& operator=(const cow_tuple&) = default; cow_tuple& operator=(const cow_tuple&) = default;
static cow_tuple offset_subtuple(cow_ptr_type ptr, size_t offset) {
CPPA_REQUIRE(offset > 0);
auto ti = detail::static_type_list<Head, Tail...>::by_offset(offset);
return {priv_ctor{}, detail::decorated_tuple::create(std::move(ptr), ti, offset)};
}
/** /**
* @brief Gets the size of this cow_tuple. * @brief Gets the size of this cow_tuple.
*/ */
...@@ -138,28 +119,21 @@ class cow_tuple<Head, Tail...> { ...@@ -138,28 +119,21 @@ class cow_tuple<Head, Tail...> {
return cow_tuple<Tail...>::offset_subtuple(m_vals, 1); return cow_tuple<Tail...>::offset_subtuple(m_vals, 1);
} }
/** @cond PRIVATE */ inline operator message() {
return message{m_vals};
static cow_tuple from(cow_ptr_type ptr) {
return {priv_ctor{}, std::move(ptr)};
} }
static cow_tuple from(cow_ptr_type ptr, std::vector<size_t> mv) { private:
auto ti = detail::static_type_list<Head, Tail...>::list;
return {priv_ctor{}, detail::decorated_tuple::create(std::move(ptr), ti, std::move(mv))};
}
static cow_tuple from(cow_ptr_type ptr, const util::limited_vector<size_t, num_elements>& mv) { data_type* ptr() {
std::vector<size_t> v(mv.size()); return static_cast<data_type*>(m_vals.get());
std::copy(mv.begin(), mv.end(), v.begin());
return from(ptr, std::move(v));
} }
inline const cow_ptr<detail::abstract_tuple>& vals() const { const data_type* ptr() const {
return m_vals; return static_cast<data_type*>(m_vals.get());
} }
/** @endcond */ data_ptr m_vals;
}; };
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "cppa/sb_actor.hpp" #include "cppa/sb_actor.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/typed_actor.hpp" #include "cppa/typed_actor.hpp"
...@@ -322,7 +322,7 @@ ...@@ -322,7 +322,7 @@
* std::vector<int> vec {1, 2, 3, 4}; * std::vector<int> vec {1, 2, 3, 4};
* auto i = vec.begin(); * auto i = vec.begin();
* receive_for(i, vec.end()) ( * receive_for(i, vec.end()) (
* on(atom("get")) >> [&]() -> any_tuple { return {atom("result"), *i}; } * on(atom("get")) >> [&]() -> message { return {atom("result"), *i}; }
* ); * );
* @endcode * @endcode
* *
...@@ -425,7 +425,7 @@ namespace cppa { ...@@ -425,7 +425,7 @@ namespace cppa {
/** /**
* @brief Sends @p to a message under the identity of @p from. * @brief Sends @p to a message under the identity of @p from.
*/ */
inline void send_tuple_as(const actor& from, const channel& to, any_tuple msg) { inline void send_tuple_as(const actor& from, const channel& to, message msg) {
if (to) to->enqueue({from.address(), to}, std::move(msg), nullptr); if (to) to->enqueue({from.address(), to}, std::move(msg), nullptr);
} }
...@@ -434,13 +434,13 @@ inline void send_tuple_as(const actor& from, const channel& to, any_tuple msg) { ...@@ -434,13 +434,13 @@ inline void send_tuple_as(const actor& from, const channel& to, any_tuple msg) {
*/ */
template<typename... Ts> template<typename... Ts>
void send_as(const actor& from, const channel& to, Ts&&... args) { void send_as(const actor& from, const channel& to, Ts&&... args) {
send_tuple_as(from, to, make_any_tuple(std::forward<Ts>(args)...)); send_tuple_as(from, to, make_message(std::forward<Ts>(args)...));
} }
/** /**
* @brief Anonymously sends @p to a message. * @brief Anonymously sends @p to a message.
*/ */
inline void anon_send_tuple(const channel& to, any_tuple msg) { inline void anon_send_tuple(const channel& to, message msg) {
send_tuple_as(invalid_actor, to, std::move(msg)); send_tuple_as(invalid_actor, to, std::move(msg));
} }
......
...@@ -31,7 +31,7 @@ class channel; ...@@ -31,7 +31,7 @@ class channel;
class node_id; class node_id;
class behavior; class behavior;
class resumable; class resumable;
class any_tuple; class message;
class actor_addr; class actor_addr;
class actor_proxy; class actor_proxy;
class scoped_actor; class scoped_actor;
...@@ -40,7 +40,7 @@ class abstract_actor; ...@@ -40,7 +40,7 @@ class abstract_actor;
class abstract_group; class abstract_group;
class blocking_actor; class blocking_actor;
class message_header; class message_header;
class partial_function; class message_handler;
class uniform_type_info; class uniform_type_info;
class event_based_actor; class event_based_actor;
class primitive_variant; class primitive_variant;
......
...@@ -16,45 +16,41 @@ ...@@ -16,45 +16,41 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CALL_HPP
#define CALL_HPP
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/util/int_list.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
abstract_tuple::abstract_tuple(bool is_dynamic) : m_is_dynamic(is_dynamic) { } template <typename F, long... Is, class Tuple>
inline auto apply_args(F& f, util::int_list<Is...>, Tuple&& tup)
bool abstract_tuple::equals(const abstract_tuple &other) const { -> decltype(f(get<Is>(tup)...)) {
return this == &other return f(get<Is>(tup)...);
|| ( size() == other.size()
&& std::equal(begin(), end(), other.begin(), detail::full_eq));
}
abstract_tuple::abstract_tuple(const abstract_tuple& other)
: m_is_dynamic(other.m_is_dynamic) { }
const std::type_info* abstract_tuple::type_token() const {
return &typeid(void);
} }
const void* abstract_tuple::native_data() const { template <typename F, class Tuple, typename... Ts>
return nullptr; inline auto apply_args_prefixed(F& f, util::int_list<>, Tuple&, Ts&&... args)
-> decltype(f(std::forward<Ts>(args)...)) {
return f(std::forward<Ts>(args)...);
} }
void* abstract_tuple::mutable_native_data() { template <typename F, long... Is, class Tuple, typename... Ts>
return nullptr; inline auto apply_args_prefixed(F& f, util::int_list<Is...>, Tuple& tup,
Ts&&... args)
-> decltype(f(std::forward<Ts>(args)..., get<Is>(tup)...)) {
return f(std::forward<Ts>(args)..., get<Is>(tup)...);
} }
std::string get_tuple_type_names(const detail::abstract_tuple& tup) { template <typename F, long... Is, class Tuple, typename... Ts>
std::string result = "@<>"; inline auto apply_args_suffxied(F& f, util::int_list<Is...>, Tuple& tup,
for (size_t i = 0; i < tup.size(); ++i) { Ts&&... args)
auto uti = tup.type_at(i); -> decltype(f(get<Is>(tup)..., std::forward<Ts>(args)...)) {
result += "+"; return f(get<Is>(tup)..., std::forward<Ts>(args)...);
result += uti->name();
}
return result;
} }
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CALL_HPP
...@@ -16,18 +16,15 @@ ...@@ -16,18 +16,15 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_ARG_MATCH_T_HPP
#include "cppa/logging.hpp" #define CPPA_ARG_MATCH_T_HPP
#include "cppa/io/protocol.hpp"
#include "cppa/io/middleman.hpp"
namespace cppa { namespace cppa {
namespace io { namespace detail {
protocol::protocol(middleman* parent) : m_parent(parent) { struct arg_match_t {};
CPPA_REQUIRE(parent != nullptr);
}
} // namespace io } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_ARG_MATCH_T_HPP
...@@ -16,89 +16,115 @@ ...@@ -16,89 +16,115 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * 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 #include <tuple>
#define CPPA_DETAIL_BEHAVIOR_IMPL_HPP #include <type_traits>
#include "cppa/atom.hpp" #include "cppa/none.hpp"
#include "cppa/variant.hpp" #include "cppa/variant.hpp"
#include "cppa/optional.hpp" #include "cppa/optional.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/atom.hpp"
#include "cppa/message.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/skip_message.hpp" #include "cppa/skip_message.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/timeout_definition.hpp" #include "cppa/timeout_definition.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/detail/apply_args.hpp"
namespace cppa { namespace cppa {
class partial_function; class message_handler;
typedef optional<any_tuple> bhvr_invoke_result; typedef optional<message> bhvr_invoke_result;
} // namespace cppa } // namespace cppa
namespace cppa { namespace cppa {
namespace detail { namespace detail {
template<class T> struct is_message_id_wrapper { template<class T>
template<class U> static char (&test(typename U::message_id_wrapper_tag))[1]; struct is_message_id_wrapper {
template<class U> static char (&test(...))[2]; template<class U>
static char (&test(typename U::message_id_wrapper_tag))[1];
template<class U>
static char (&test(...))[2];
static constexpr bool value = sizeof(test<T>(0)) == 1; static constexpr bool value = sizeof(test<T>(0)) == 1;
}; };
struct optional_any_tuple_visitor : static_visitor<bhvr_invoke_result> { struct optional_message_visitor : static_visitor<bhvr_invoke_result> {
//inline bhvr_invoke_result operator()() const { return any_tuple{}; } // inline bhvr_invoke_result operator()() const { return message{}; }
inline bhvr_invoke_result operator()(none_t&) const { return none; } 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()(const none_t&) const { return none; }
inline bhvr_invoke_result operator()(skip_message_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 { return none; } inline bhvr_invoke_result operator()(const skip_message_t&) const {
inline bhvr_invoke_result operator()(unit_t&) const { return any_tuple{}; } return none;
inline bhvr_invoke_result operator()(const unit_t&) const { return any_tuple{}; }
template<typename T>
inline bhvr_invoke_result operator()(T& value, typename std::enable_if<not is_message_id_wrapper<T>::value>::type* = 0) const {
return make_any_tuple(std::move(value));
} }
template<typename T> inline bhvr_invoke_result operator()(unit_t&) const {
inline bhvr_invoke_result operator()(T& value, typename std::enable_if<is_message_id_wrapper<T>::value>::type* = 0) const { return message{};
return make_any_tuple(atom("MESSAGE_ID"), value.get_message_id().integer_value());
} }
template<typename... Ts> inline bhvr_invoke_result operator()(const unit_t&) const {
inline bhvr_invoke_result operator()(cow_tuple<Ts...>& value) const { return message{};
return any_tuple{std::move(value)}; }
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 {
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
operator()(T& v, Ts&... vs) const {
return make_message(std::move(v), std::move(vs)...);
} }
inline bhvr_invoke_result operator()(any_tuple& value) const { template<typename T>
inline bhvr_invoke_result
operator()(T& value,
typename std::enable_if<is_message_id_wrapper<T>::value>::type* =
0) 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); 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);
}
}; };
template<typename... Ts> template<typename... Ts>
struct has_skip_message { struct has_skip_message {
static constexpr bool value = util::disjunction< static constexpr bool value =
std::is_same<Ts, skip_message_t>::value... util::disjunction<std::is_same<Ts, skip_message_t>::value...>::value;
>::value;
}; };
class behavior_impl : public ref_counted { class behavior_impl : public ref_counted {
public: public:
behavior_impl() = default; behavior_impl() = default;
inline behavior_impl(util::duration tout) : m_timeout(tout) { } inline behavior_impl(util::duration tout) : m_timeout(tout) {}
virtual bhvr_invoke_result invoke(any_tuple&) = 0; virtual bhvr_invoke_result invoke(message&) = 0;
virtual bhvr_invoke_result invoke(const any_tuple&) = 0; virtual bhvr_invoke_result invoke(const message&) = 0;
inline bhvr_invoke_result invoke(any_tuple&& arg) { inline bhvr_invoke_result invoke(message&& arg) {
any_tuple tmp(std::move(arg)); message tmp(std::move(arg));
return invoke(tmp); return invoke(tmp);
} }
virtual bool defined_at(const any_tuple&) = 0;
virtual void handle_timeout(); virtual void handle_timeout();
inline const util::duration& timeout() const { inline const util::duration& timeout() const { return m_timeout; }
return m_timeout;
}
typedef intrusive_ptr<behavior_impl> pointer; typedef intrusive_ptr<behavior_impl> pointer;
...@@ -109,19 +135,16 @@ class behavior_impl : public ref_counted { ...@@ -109,19 +135,16 @@ class behavior_impl : public ref_counted {
struct combinator : behavior_impl { struct combinator : behavior_impl {
pointer first; pointer first;
pointer second; pointer second;
bhvr_invoke_result invoke(any_tuple& arg) { bhvr_invoke_result invoke(message& arg) {
auto res = first->invoke(arg); auto res = first->invoke(arg);
if (!res) return second->invoke(arg); if (!res) return second->invoke(arg);
return res; return res;
} }
bhvr_invoke_result invoke(const any_tuple& arg) { bhvr_invoke_result invoke(const message& arg) {
auto res = first->invoke(arg); auto res = first->invoke(arg);
if (!res) return second->invoke(arg); if (!res) return second->invoke(arg);
return res; return res;
} }
bool defined_at(const any_tuple& arg) {
return first->defined_at(arg) || second->defined_at(arg);
}
void handle_timeout() { void handle_timeout() {
// the second behavior overrides the timeout handling of // the second behavior overrides the timeout handling of
// first behavior // first behavior
...@@ -131,7 +154,7 @@ class behavior_impl : public ref_counted { ...@@ -131,7 +154,7 @@ class behavior_impl : public ref_counted {
return new combinator(first, second->copy(tdef)); return new combinator(first, second->copy(tdef));
} }
combinator(const pointer& p0, const pointer& p1) combinator(const pointer& p0, const pointer& p1)
: behavior_impl(p1->timeout()), first(p0), second(p1) { } : behavior_impl(p1->timeout()), first(p0), second(p1) {}
}; };
return new combinator(this, other); return new combinator(this, other);
} }
...@@ -143,9 +166,9 @@ class behavior_impl : public ref_counted { ...@@ -143,9 +166,9 @@ class behavior_impl : public ref_counted {
}; };
struct dummy_match_expr { struct dummy_match_expr {
inline variant<none_t> invoke(const any_tuple&) const { return none; } inline variant<none_t> invoke(const message&) const { return none; }
inline bool can_invoke(const any_tuple&) const { return false; } inline bool can_invoke(const message&) const { return false; }
inline variant<none_t> operator()(const any_tuple&) const { return none; } inline variant<none_t> operator()(const message&) const { return none; }
}; };
template<class MatchExpr, typename F> template<class MatchExpr, typename F>
...@@ -154,60 +177,59 @@ class default_behavior_impl : public behavior_impl { ...@@ -154,60 +177,59 @@ class default_behavior_impl : public behavior_impl {
typedef behavior_impl super; typedef behavior_impl super;
public: public:
template<typename Expr> template<typename Expr>
default_behavior_impl(Expr&& expr, const timeout_definition<F>& d) default_behavior_impl(Expr&& expr, const timeout_definition<F>& d)
: super(d.timeout), m_expr(std::forward<Expr>(expr)), m_fun(d.handler) { } : super(d.timeout)
, m_expr(std::forward<Expr>(expr))
, m_fun(d.handler) {}
template<typename Expr> template<typename Expr>
default_behavior_impl(Expr&& expr, util::duration tout, F f) default_behavior_impl(Expr&& expr, util::duration tout, F f)
: super(tout), m_expr(std::forward<Expr>(expr)), m_fun(f) { } : super(tout), m_expr(std::forward<Expr>(expr)), m_fun(f) {}
bhvr_invoke_result invoke(any_tuple& tup) { bhvr_invoke_result invoke(message& tup) {
auto res = m_expr(tup); auto res = m_expr(tup);
return apply_visitor(optional_any_tuple_visitor{}, res); return apply_visitor(optional_message_visitor{}, res);
} }
bhvr_invoke_result invoke(const any_tuple& tup) { bhvr_invoke_result invoke(const message& tup) {
auto res = m_expr(tup); auto res = m_expr(tup);
return apply_visitor(optional_any_tuple_visitor{}, res); return apply_visitor(optional_message_visitor{}, res);
}
bool defined_at(const any_tuple& tup) {
return m_expr.can_invoke(tup);
} }
typename behavior_impl::pointer copy(const generic_timeout_definition& tdef) const { typename behavior_impl::pointer
return new default_behavior_impl<MatchExpr, std::function<void()>>(m_expr, tdef); copy(const generic_timeout_definition& tdef) const {
return new default_behavior_impl<MatchExpr, std::function<void()>>(
m_expr, tdef);
} }
void handle_timeout() { m_fun(); } void handle_timeout() { m_fun(); }
private: private:
MatchExpr m_expr; MatchExpr m_expr;
F m_fun; F m_fun;
}; };
template<class MatchExpr, typename F> template<class MatchExpr, typename F>
default_behavior_impl<MatchExpr, F>* new_default_behavior(const MatchExpr& mexpr, util::duration d, F f) { default_behavior_impl<MatchExpr, F>*
new_default_behavior(const MatchExpr& mexpr, util::duration d, F f) {
return new default_behavior_impl<MatchExpr, F>(mexpr, d, f); return new default_behavior_impl<MatchExpr, F>(mexpr, d, f);
} }
template<typename F> template<typename F>
default_behavior_impl<dummy_match_expr, F>* new_default_behavior(util::duration d, F f) { default_behavior_impl<dummy_match_expr, F>* new_default_behavior(util::duration d,
return new default_behavior_impl<dummy_match_expr, F>(dummy_match_expr{}, d, f); F f) {
return new default_behavior_impl<dummy_match_expr, F>(dummy_match_expr{}, d,
f);
} }
typedef intrusive_ptr<behavior_impl> behavior_impl_ptr; typedef intrusive_ptr<behavior_impl> behavior_impl_ptr;
// implemented in partial_function.cpp // implemented in message_handler.cpp
behavior_impl_ptr combine(behavior_impl_ptr, const partial_function&); // message_handler combine(behavior_impl_ptr, behavior_impl_ptr);
behavior_impl_ptr combine(const partial_function&, behavior_impl_ptr); // behavior_impl_ptr extract(const message_handler&);
behavior_impl_ptr extract(const partial_function&);
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_BEHAVIOR_IMPL_HPP #endif // BEHAVIOR_IMPL_HPP
...@@ -16,30 +16,28 @@ ...@@ -16,30 +16,28 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_DECORATED_TUPLE_HPP
#ifndef CPPA_DETAIL_DECORATED_TUPLE_HPP #define CPPA_DECORATED_TUPLE_HPP
#define CPPA_DETAIL_DECORATED_TUPLE_HPP
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tuple_vals.hpp" #include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/message_data.hpp"
#include "cppa/detail/serialize_tuple.hpp" #include "cppa/detail/serialize_tuple.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
class decorated_tuple : public abstract_tuple { class decorated_tuple : public message_data {
typedef abstract_tuple super; typedef message_data super;
decorated_tuple& operator=(const decorated_tuple&) = delete; decorated_tuple& operator=(const decorated_tuple&) = delete;
...@@ -47,7 +45,7 @@ class decorated_tuple : public abstract_tuple { ...@@ -47,7 +45,7 @@ class decorated_tuple : public abstract_tuple {
typedef std::vector<size_t> vector_type; typedef std::vector<size_t> vector_type;
typedef cow_ptr<abstract_tuple> pointer; typedef message_data::ptr pointer;
typedef const std::type_info* rtti; typedef const std::type_info* rtti;
...@@ -110,4 +108,4 @@ class decorated_tuple : public abstract_tuple { ...@@ -110,4 +108,4 @@ class decorated_tuple : public abstract_tuple {
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_DECORATED_TUPLE_HPP #endif // CPPA_DECORATED_TUPLE_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_LIFTED_FUN_HPP
#define CPPA_DETAIL_LIFTED_FUN_HPP
#include "cppa/none.hpp"
#include "cppa/optional.hpp"
#include "cppa/skip_message.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/left_or_right.hpp"
#include "cppa/detail/tuple_zip.hpp"
#include "cppa/detail/apply_args.hpp"
namespace cppa {
namespace detail {
class lifted_fun_zipper {
public:
template <typename F, typename T>
auto operator()(const F& fun, T& arg) -> decltype(fun(arg)) const {
return fun(arg);
}
// forward everything as reference if no guard/transformation is set
template <typename T>
auto operator()(const unit_t&, T& arg) const -> decltype(std::ref(arg)) {
return std::ref(arg);
}
};
template <typename T>
T& unopt(T& v) {
return v;
}
template <typename T>
T& unopt(optional<T>& v) {
return *v;
}
inline bool has_none() { return false; }
template <typename T, typename... Ts>
inline bool has_none(const T&, const Ts&... vs) {
return has_none(vs...);
}
template <typename T, typename... Ts>
inline bool has_none(const optional<T>& v, const Ts&... vs) {
return !v || has_none(vs...);
}
// allows F to have fewer arguments than the lifted_fun calling it
template <typename R, typename F>
class lifted_fun_invoker {
typedef typename util::get_callable_trait<F>::arg_types arg_types;
static constexpr size_t args = util::tl_size<arg_types>::value;
public:
lifted_fun_invoker(F& fun) : f(fun) {}
template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == args, R>::type
operator()(Ts&... args) const {
if (has_none(args...)) return none;
return f(unopt(args)...);
}
template <typename T, typename... Ts>
typename std::enable_if<(sizeof...(Ts) + 1 > args), R>::type
operator()(T& arg, Ts&... args) const {
if (has_none(arg)) return none;
return (*this)(args...);
}
private:
F& f;
};
template <typename F>
class lifted_fun_invoker<bool, F> {
typedef typename util::get_callable_trait<F>::arg_types arg_types;
static constexpr size_t args = util::tl_size<arg_types>::value;
public:
lifted_fun_invoker(F& fun) : f(fun) {}
template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == args, bool>::type
operator()(Ts&&... args) const {
if (has_none(args...)) return false;
f(unopt(args)...);
return true;
}
template <typename T, typename... Ts>
typename std::enable_if<(sizeof...(Ts) + 1 > args), bool>::type
operator()(T&& arg, Ts&&... args) const {
if (has_none(arg)) return false;
return (*this)(args...);
}
private:
F& f;
};
/**
* @brief A lifted functor consists of a set of projections, a plain-old
* functor and its signature. Note that the signature of the lifted
* functor might differ from the underlying functor, because
* of the projections.
*/
template <typename F, class ListOfProjections, typename... Args>
class lifted_fun {
public:
typedef typename util::get_callable_trait<F>::result_type result_type;
// Let F be "R (Ts...)" then lifted_fun<F...> returns optional<R>
// unless R is void in which case bool is returned
typedef typename std::conditional<std::is_same<result_type, void>::value,
bool, optional<result_type>>::type
optional_result_type;
typedef ListOfProjections projections_list;
typedef typename util::tl_apply<projections_list, std::tuple>::type projections;
typedef util::type_list<Args...> arg_types;
lifted_fun() = default;
lifted_fun(lifted_fun&&) = default;
lifted_fun(const lifted_fun&) = default;
lifted_fun& operator=(lifted_fun&&) = default;
lifted_fun& operator=(const lifted_fun&) = default;
lifted_fun(F f) : m_fun(std::move(f)) {}
lifted_fun(F f, projections ps)
: m_fun(std::move(f)), m_ps(std::move(ps)) {}
/**
* @brief Invokes @p fun with a lifted_fun of <tt>args...</tt>.
*/
optional_result_type operator()(Args... args) {
auto indices = util::get_indices(m_ps);
lifted_fun_zipper zip;
lifted_fun_invoker<optional_result_type, F> invoke{m_fun};
return apply_args(
invoke, indices,
tuple_zip(zip, indices, m_ps, std::forward_as_tuple(args...)));
}
private:
F m_fun;
projections m_ps;
};
template <typename F, class ListOfProjections, class List>
struct get_lifted_fun;
template <typename F, class ListOfProjections, typename... Ts>
struct get_lifted_fun<F, ListOfProjections, util::type_list<Ts...>> {
typedef lifted_fun<F, ListOfProjections, Ts...> type;
};
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_LIFTED_FUN_HPP
...@@ -22,10 +22,11 @@ ...@@ -22,10 +22,11 @@
#include <numeric> #include <numeric>
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/wildcard_position.hpp" #include "cppa/wildcard_position.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/limited_vector.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
...@@ -294,9 +295,9 @@ struct match_impl_from_type_list<Tuple, util::type_list<Ts...> > { ...@@ -294,9 +295,9 @@ struct match_impl_from_type_list<Tuple, util::type_list<Ts...> > {
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>. * @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>.
*/ */
template<typename... Ts> template<typename... Ts>
bool matches(const any_tuple& tup) { bool matches(const message& tup) {
typedef util::type_list<Ts...> tl; typedef util::type_list<Ts...> tl;
return match_impl<get_wildcard_position<tl>(), any_tuple, Ts...> return match_impl<get_wildcard_position<tl>(), message, Ts...>
::_(tup); ::_(tup);
} }
...@@ -304,25 +305,25 @@ bool matches(const any_tuple& tup) { ...@@ -304,25 +305,25 @@ bool matches(const any_tuple& tup) {
* @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>. * @brief Returns true if this tuple matches the pattern <tt>{Ts...}</tt>.
*/ */
template<typename... Ts> template<typename... Ts>
bool matches(const any_tuple& tup, bool matches(const message& tup,
util::limited_vector< util::limited_vector<
size_t, size_t,
util::tl_count_not< util::tl_count_not<
util::type_list<Ts...>, util::type_list<Ts...>,
is_anything>::value>& mv) { is_anything>::value>& mv) {
typedef util::type_list<Ts...> tl; typedef util::type_list<Ts...> tl;
return match_impl<get_wildcard_position<tl>(), any_tuple, Ts...> return match_impl<get_wildcard_position<tl>(), message, Ts...>
::_(tup, mv); ::_(tup, mv);
} }
// support for type_list based matching // support for type_list based matching
template<typename... Ts> template<typename... Ts>
inline bool matches(const any_tuple& tup, const util::type_list<Ts...>&) { inline bool matches(const message& tup, const util::type_list<Ts...>&) {
return matches<Ts...>(tup); return matches<Ts...>(tup);
} }
template<typename... Ts> template<typename... Ts>
inline bool matches(const any_tuple& tup, const util::type_list<Ts...>&, inline bool matches(const message& tup, const util::type_list<Ts...>&,
util::limited_vector< util::limited_vector<
size_t, size_t,
util::tl_count_not< util::tl_count_not<
...@@ -332,10 +333,21 @@ inline bool matches(const any_tuple& tup, const util::type_list<Ts...>&, ...@@ -332,10 +333,21 @@ inline bool matches(const any_tuple& tup, const util::type_list<Ts...>&,
} }
template<typename... Ts> template<typename... Ts>
inline bool matches_types(const any_tuple& tup, const util::type_list<Ts...>&) { inline bool matches_types(const message& tup, const util::type_list<Ts...>&) {
return matches<Ts...>(tup); return matches<Ts...>(tup);
} }
template<class Tuple, class List>
struct select_matcher;
template<class Tuple, typename... Ts>
struct select_matcher<Tuple, util::type_list<Ts...> > {
typedef matcher<get_wildcard_position<util::type_list<Ts...>>(),
Tuple,
Ts...>
type;
};
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
......
...@@ -16,31 +16,32 @@ ...@@ -16,31 +16,32 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_ABSTRACT_TUPLE_HPP
#ifndef CPPA_DETAIL_ABSTRACT_TUPLE_HPP #define CPPA_ABSTRACT_TUPLE_HPP
#define CPPA_DETAIL_ABSTRACT_TUPLE_HPP
#include <string> #include <string>
#include <iterator> #include <iterator>
#include <typeinfo> #include <typeinfo>
#include "cppa/intrusive_ptr.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tuple_iterator.hpp" #include "cppa/detail/message_iterator.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
class abstract_tuple : public ref_counted { class message_data : public ref_counted {
public: public:
abstract_tuple(bool dynamically_typed); message_data(bool dynamically_typed);
abstract_tuple(const abstract_tuple& other); message_data(const message_data& other);
// mutators // mutators
virtual void* mutable_at(size_t pos) = 0; virtual void* mutable_at(size_t pos) = 0;
...@@ -48,7 +49,7 @@ class abstract_tuple : public ref_counted { ...@@ -48,7 +49,7 @@ class abstract_tuple : public ref_counted {
// accessors // accessors
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual abstract_tuple* copy() const = 0; virtual message_data* copy() const = 0;
virtual const void* at(size_t pos) const = 0; virtual const void* at(size_t pos) const = 0;
virtual const uniform_type_info* type_at(size_t pos) const = 0; virtual const uniform_type_info* type_at(size_t pos) const = 0;
virtual const std::string* tuple_type_names() const = 0; virtual const std::string* tuple_type_names() const = 0;
...@@ -68,42 +69,84 @@ class abstract_tuple : public ref_counted { ...@@ -68,42 +69,84 @@ class abstract_tuple : public ref_counted {
// (default returns &typeid(void)) // (default returns &typeid(void))
virtual const std::type_info* type_token() const; virtual const std::type_info* type_token() const;
bool equals(const abstract_tuple& other) const; bool equals(const message_data& other) const;
typedef message_iterator<message_data> const_iterator;
inline const_iterator begin() const {
return {this};
}
inline const_iterator cbegin() const {
return {this};
}
typedef tuple_iterator<abstract_tuple> const_iterator; inline const_iterator end() const {
return {this, size()};
}
inline const_iterator cend() const {
return {this, size()};
}
class ptr {
public:
inline const_iterator begin() const { return {this}; } ptr() = default;
inline const_iterator cbegin() const { return {this}; } ptr(ptr&&) = default;
ptr(const ptr&) = default;
ptr& operator=(ptr&&) = default;
ptr& operator=(const ptr&) = default;
inline const_iterator end() const { return {this, size()}; } inline explicit ptr(message_data* p) : m_ptr(p) {}
inline const_iterator cend() const { return {this, size()}; }
inline void detach() { static_cast<void>(get_detached()); }
inline message_data* operator->() { return get_detached(); }
inline message_data& operator*() { return *get_detached(); }
inline const message_data* operator->() const { return m_ptr.get(); }
inline const message_data& operator*() const { return *m_ptr.get(); }
inline void swap(ptr& other) { m_ptr.swap(other.m_ptr); }
inline void reset(message_data* p = nullptr) { m_ptr.reset(p); }
inline const message_data* get() const { return m_ptr.get(); }
inline message_data* get() { return m_ptr.get(); }
inline explicit operator bool() const {
return static_cast<bool>(m_ptr);
}
private: private:
bool m_is_dynamic; message_data* get_detached();
intrusive_ptr<message_data> m_ptr;
};
private:
bool m_is_dynamic;
}; };
struct full_eq_type { struct full_eq_type {
constexpr full_eq_type() { } constexpr full_eq_type() {}
template<class Tuple> template<class Tuple>
inline bool operator()(const tuple_iterator<Tuple>& lhs, inline bool operator()(const message_iterator<Tuple>& lhs,
const tuple_iterator<Tuple>& rhs) const { const message_iterator<Tuple>& rhs) const {
return lhs.type() == rhs.type() return lhs.type() == rhs.type() &&
&& lhs.type()->equals(lhs.value(), rhs.value()); lhs.type()->equals(lhs.value(), rhs.value());
} }
}; };
struct types_only_eq_type { struct types_only_eq_type {
constexpr types_only_eq_type() { } constexpr types_only_eq_type() {}
template<class Tuple> template<class Tuple>
inline bool operator()(const tuple_iterator<Tuple>& lhs, inline bool operator()(const message_iterator<Tuple>& lhs,
const uniform_type_info* rhs ) const { const uniform_type_info* rhs) const {
return lhs.type() == rhs; return lhs.type() == rhs;
} }
template<class Tuple> template<class Tuple>
inline bool operator()(const uniform_type_info* lhs, inline bool operator()(const uniform_type_info* lhs,
const tuple_iterator<Tuple>& rhs) const { const message_iterator<Tuple>& rhs) const {
return lhs == rhs.type(); return lhs == rhs.type();
} }
}; };
...@@ -113,9 +156,9 @@ constexpr full_eq_type full_eq; ...@@ -113,9 +156,9 @@ constexpr full_eq_type full_eq;
constexpr types_only_eq_type types_only_eq; constexpr types_only_eq_type types_only_eq;
} // namespace <anonymous> } // namespace <anonymous>
std::string get_tuple_type_names(const detail::abstract_tuple&); std::string get_tuple_type_names(const detail::message_data&);
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_ABSTRACT_TUPLE_HPP #endif // CPPA_ABSTRACT_TUPLE_HPP
...@@ -16,9 +16,8 @@ ...@@ -16,9 +16,8 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_TUPLE_ITERATOR_HPP
#ifndef CPPA_DETAIL_TUPLE_ITERATOR_HPP #define CPPA_TUPLE_ITERATOR_HPP
#define CPPA_DETAIL_TUPLE_ITERATOR_HPP
#include <cstddef> #include <cstddef>
...@@ -28,56 +27,55 @@ namespace cppa { ...@@ -28,56 +27,55 @@ namespace cppa {
namespace detail { namespace detail {
template<class Tuple> template<class Tuple>
class tuple_iterator { class message_iterator {
size_t m_pos; size_t m_pos;
const Tuple* m_tuple; const Tuple* m_tuple;
public: public:
inline tuple_iterator(const Tuple* tup, size_t pos = 0) inline message_iterator(const Tuple* tup, size_t pos = 0)
: m_pos(pos), m_tuple(tup) { : m_pos(pos), m_tuple(tup) {}
}
tuple_iterator(const tuple_iterator&) = default; message_iterator(const message_iterator&) = default;
tuple_iterator& operator=(const tuple_iterator&) = default; message_iterator& operator=(const message_iterator&) = default;
inline bool operator==(const tuple_iterator& other) const { inline bool operator==(const message_iterator& other) const {
CPPA_REQUIRE(other.m_tuple == other.m_tuple); CPPA_REQUIRE(other.m_tuple == other.m_tuple);
return other.m_pos == m_pos; return other.m_pos == m_pos;
} }
inline bool operator!=(const tuple_iterator& other) const { inline bool operator!=(const message_iterator& other) const {
return !(*this == other); return !(*this == other);
} }
inline tuple_iterator& operator++() { inline message_iterator& operator++() {
++m_pos; ++m_pos;
return *this; return *this;
} }
inline tuple_iterator& operator--() { inline message_iterator& operator--() {
CPPA_REQUIRE(m_pos > 0); CPPA_REQUIRE(m_pos > 0);
--m_pos; --m_pos;
return *this; return *this;
} }
inline tuple_iterator operator+(size_t offset) { inline message_iterator operator+(size_t offset) {
return {m_tuple, m_pos + offset}; return {m_tuple, m_pos + offset};
} }
inline tuple_iterator& operator+=(size_t offset) { inline message_iterator& operator+=(size_t offset) {
m_pos += offset; m_pos += offset;
return *this; return *this;
} }
inline tuple_iterator operator-(size_t offset) { inline message_iterator operator-(size_t offset) {
CPPA_REQUIRE(m_pos >= offset); CPPA_REQUIRE(m_pos >= offset);
return {m_tuple, m_pos - offset}; return {m_tuple, m_pos - offset};
} }
inline tuple_iterator& operator-=(size_t offset) { inline message_iterator& operator-=(size_t offset) {
CPPA_REQUIRE(m_pos >= offset); CPPA_REQUIRE(m_pos >= offset);
m_pos -= offset; m_pos -= offset;
return *this; return *this;
...@@ -85,19 +83,17 @@ class tuple_iterator { ...@@ -85,19 +83,17 @@ class tuple_iterator {
inline size_t position() const { return m_pos; } inline size_t position() const { return m_pos; }
inline const void* value() const { inline const void* value() const { return m_tuple->at(m_pos); }
return m_tuple->at(m_pos);
}
inline const uniform_type_info* type() const { inline const uniform_type_info* type() const {
return m_tuple->type_at(m_pos); return m_tuple->type_at(m_pos);
} }
inline tuple_iterator& operator*() { return *this; } inline message_iterator& operator*() { return *this; }
}; };
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_TUPLE_ITERATOR_HPP #endif // CPPA_TUPLE_ITERATOR_HPP
...@@ -143,17 +143,14 @@ struct is_rd_arg<rd_arg_functor<T> > : std::true_type { }; ...@@ -143,17 +143,14 @@ struct is_rd_arg<rd_arg_functor<T> > : std::true_type { };
template<typename T> template<typename T>
struct is_rd_arg<add_arg_functor<T> > : std::true_type { }; struct is_rd_arg<add_arg_functor<T> > : std::true_type { };
typedef decltype(on<std::string>().when(cppa::placeholders::_x1.in(std::vector<std::string>()))) typedef decltype(on<std::string>()) opt0_rvalue_builder;
opt0_rvalue_builder;
template<bool HasShortOpt = true> template<bool HasShortOpt = true>
class opt1_rvalue_builder { class opt1_rvalue_builder {
public: public:
typedef decltype(on<std::string, std::string>() typedef decltype(on<std::string, std::string>()) left_type;
.when(cppa::placeholders::_x1.in(std::vector<std::string>())))
left_type;
typedef decltype(on(std::function<optional<std::string>(const std::string&)>())) typedef decltype(on(std::function<optional<std::string>(const std::string&)>()))
right_type; right_type;
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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_PROJECTION_HPP
#define CPPA_DETAIL_PROJECTION_HPP
#include "cppa/optional.hpp"
#include "cppa/guard_expr.hpp"
#include "cppa/util/call.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/left_or_right.hpp"
#include "cppa/detail/tdata.hpp"
namespace cppa {
namespace detail {
template<typename Fun, typename Tuple, long... Is>
inline bool is_defined_at(Fun& f, Tuple& tup, util::int_list<Is...>) {
return f.defined_at(get_cv_aware<Is>(tup)...);
}
template<typename ProjectionFuns, typename... Ts>
struct collected_args_tuple {
typedef typename tdata_from_type_list<
typename util::tl_zip<
typename util::tl_map<
ProjectionFuns,
util::map_to_result_type,
util::rm_optional
>::type,
typename util::tl_map<
util::type_list<Ts...>,
mutable_gref_wrapped
>::type,
util::left_or_right
>::type
>::type
type;
};
template<typename Fun>
struct is_void_fun {
static constexpr bool value = std::is_same<typename Fun::result_type, void>::value;
};
/**
* @brief Projection implemented by a set of functors.
*/
template<class ProjectionFuns, typename... Ts>
class projection {
public:
typedef typename tdata_from_type_list<ProjectionFuns>::type fun_container;
typedef util::type_list<typename util::rm_const_and_ref<Ts>::type...> arg_types;
projection() = default;
projection(fun_container&& args) : m_funs(std::move(args)) { }
projection(const fun_container& args) : m_funs(args) { }
projection(const projection&) = default;
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
template<class PartFun>
optional<typename PartFun::result_type> operator()(PartFun& fun, Ts... args) const {
typename collected_args_tuple<ProjectionFuns, Ts...>::type pargs;
auto indices = util::get_indices(pargs);
if (collect(pargs, m_funs, std::forward<Ts>(args)...)) {
if (is_defined_at(fun, pargs, indices)) {
return util::apply_args(fun, pargs, indices);
}
}
return none;
}
private:
template<typename Storage, typename T>
static inline bool store(Storage& storage, T&& value) {
storage = std::forward<T>(value);
return true;
}
template<class Storage>
static inline bool store(Storage& storage, optional<Storage>&& value) {
if (value) {
storage = std::move(*value);
return true;
}
return false;
}
template<typename T>
static inline auto fetch(const unit_t&, T&& arg)
-> decltype(std::forward<T>(arg)) {
return std::forward<T>(arg);
}
template<typename Fun, typename T>
static inline auto fetch(const Fun& fun, T&& arg)
-> decltype(fun(std::forward<T>(arg))) {
return fun(std::forward<T>(arg));
}
static inline bool collect(tdata<>&, const tdata<>&) {
return true;
}
template<class TData, class Trans, typename U, typename... Us>
static inline bool collect(TData& td, const Trans& tr,
U&& arg, Us&&... args) {
return store(td.head, fetch(tr.head, std::forward<U>(arg)))
&& collect(td.tail(), tr.tail(), std::forward<Us>(args)...);
}
fun_container m_funs;
};
template<>
class projection<util::empty_type_list> {
public:
projection() = default;
projection(const tdata<>&) { }
projection(const projection&) = default;
template<class PartFun>
optional<typename PartFun::result_type> operator()(PartFun& fun) const {
if (fun.defined_at()) {
return fun();
}
return none;
}
};
template<class ProjectionFuns, class List>
struct projection_from_type_list;
template<class ProjectionFuns, typename... Ts>
struct projection_from_type_list<ProjectionFuns, util::type_list<Ts...> > {
typedef projection<ProjectionFuns, Ts...> type;
};
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_PROJECTION_HPP
...@@ -26,7 +26,7 @@ class proper_actor_base : public Policies::resume_policy::template mixin<Base, D ...@@ -26,7 +26,7 @@ class proper_actor_base : public Policies::resume_policy::template mixin<Base, D
public: public:
template <typename... Ts> template<typename... Ts>
proper_actor_base(Ts&&... args) : super(std::forward<Ts>(args)...) { proper_actor_base(Ts&&... args) : super(std::forward<Ts>(args)...) {
CPPA_REQUIRE(this->m_hidden == true); CPPA_REQUIRE(this->m_hidden == true);
} }
...@@ -40,7 +40,7 @@ class proper_actor_base : public Policies::resume_policy::template mixin<Base, D ...@@ -40,7 +40,7 @@ class proper_actor_base : public Policies::resume_policy::template mixin<Base, D
typedef typename Policies::scheduling_policy::timeout_type timeout_type; typedef typename Policies::scheduling_policy::timeout_type timeout_type;
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit* eu) override { void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override {
CPPA_PUSH_AID(dptr()->id()); CPPA_PUSH_AID(dptr()->id());
CPPA_LOG_DEBUG(CPPA_TARG(hdr, to_string) CPPA_LOG_DEBUG(CPPA_TARG(hdr, to_string)
<< ", " << CPPA_TARG(msg, to_string)); << ", " << CPPA_TARG(msg, to_string));
...@@ -189,7 +189,7 @@ class proper_actor : public proper_actor_base<Base, ...@@ -189,7 +189,7 @@ class proper_actor : public proper_actor_base<Base,
// that Base is derived from local_actor and uses the // that Base is derived from local_actor and uses the
// behavior_stack_based mixin // behavior_stack_based mixin
template <typename... Ts> template<typename... Ts>
proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { } proper_actor(Ts&&... args) : super(std::forward<Ts>(args)...) { }
// required by event_based_resume::mixin::resume // required by event_based_resume::mixin::resume
...@@ -223,7 +223,7 @@ class proper_actor : public proper_actor_base<Base, ...@@ -223,7 +223,7 @@ class proper_actor : public proper_actor_base<Base,
}; };
// for blocking actors, there's one more member function to implement // for blocking actors, there's one more member function to implement
template <class Base, class Policies> template<class Base, class Policies>
class proper_actor<Base, Policies, true> : public proper_actor_base<Base, class proper_actor<Base, Policies, true> : public proper_actor_base<Base,
proper_actor<Base, proper_actor<Base,
Policies, Policies,
...@@ -234,7 +234,7 @@ class proper_actor<Base, Policies, true> : public proper_actor_base<Base, ...@@ -234,7 +234,7 @@ class proper_actor<Base, Policies, true> : public proper_actor_base<Base,
public: public:
template <typename... Ts> template<typename... Ts>
proper_actor(Ts&&... args) proper_actor(Ts&&... args)
: super(std::forward<Ts>(args)...), m_next_timeout_id(0) { } : super(std::forward<Ts>(args)...), m_next_timeout_id(0) { }
...@@ -304,7 +304,7 @@ class proper_actor<Base, Policies, true> : public proper_actor_base<Base, ...@@ -304,7 +304,7 @@ class proper_actor<Base, Policies, true> : public proper_actor_base<Base,
std::uint32_t request_timeout(const util::duration& d) { std::uint32_t request_timeout(const util::duration& d) {
CPPA_REQUIRE(d.valid()); CPPA_REQUIRE(d.valid());
auto tid = ++m_next_timeout_id; auto tid = ++m_next_timeout_id;
auto msg = make_any_tuple(timeout_msg{tid}); auto msg = make_message(timeout_msg{tid});
if (d.is_zero()) { if (d.is_zero()) {
// immediately enqueue timeout message if duration == 0s // immediately enqueue timeout message if duration == 0s
this->enqueue({this->address(), this}, this->enqueue({this->address(), this},
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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_TDATA_HPP
#define CPPA_DETAIL_TDATA_HPP
#include <typeinfo>
#include <functional>
#include <type_traits>
#include "cppa/get.hpp"
#include "cppa/unit.hpp"
#include "cppa/optional.hpp"
#include "cppa/util/wrapped.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/rebindable_reference.hpp"
#include "cppa/detail/boxed.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/tuple_iterator.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&);
} // namespace cppa
namespace cppa {
namespace detail {
template<typename T>
inline void* ptr_to(T& what) { return &what; }
template<typename T>
inline const void* ptr_to(const T& what) { return &what; }
template<typename T>
inline void* ptr_to(T* what) { return what; }
template<typename T>
inline const void* ptr_to(const T* what) { return what; }
template<typename T>
inline void* ptr_to(const std::reference_wrapper<T>& what) {
return &(what.get());
}
template<typename T>
inline const void* ptr_to(const std::reference_wrapper<const T>& what) {
return &(what.get());
}
template<typename T>
inline const uniform_type_info* utype_of(const T&) {
return static_types_array<T>::arr[0];
}
template<typename T>
inline const uniform_type_info* utype_of(const std::reference_wrapper<T>&) {
return static_types_array<typename util::rm_const_and_ref<T>::type>::arr[0];
}
template<typename T>
inline const uniform_type_info* utype_of(const T* ptr) {
return utype_of(*ptr);
}
template<typename T>
struct boxed_or_void {
static constexpr bool value = is_boxed<T>::value;
};
template<>
struct boxed_or_void<unit_t> {
static constexpr bool value = true;
};
template<typename T>
struct unbox_ref {
typedef T type;
};
template<typename T>
struct unbox_ref<std::reference_wrapper<T> > {
typedef typename std::remove_const<T>::type type;
};
template<typename T>
struct unbox_ref<util::rebindable_reference<T> > {
typedef typename std::remove_const<T>::type type;
};
/*
* "enhanced" std::tuple
*/
template<typename...>
struct tdata;
template<>
struct tdata<> {
typedef tdata super;
unit_t head;
typedef unit_t head_type;
typedef tdata<> tail_type;
typedef unit_t back_type;
typedef util::empty_type_list types;
static constexpr size_t num_elements = 0;
constexpr tdata() { }
// swallow any number of additional boxed or unit_t arguments silently
template<typename... Ts>
tdata(Ts&&...) {
typedef util::type_list<typename util::rm_const_and_ref<Ts>::type...> incoming;
typedef typename util::tl_filter_not_type<incoming, tdata>::type iargs;
static_assert(util::tl_forall<iargs, boxed_or_void>::value,
"Additional unboxed arguments provided");
}
typedef tuple_iterator<tdata> const_iterator;
inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; }
inline const_iterator end() const { return {this}; }
inline const_iterator cend() const { return {this}; }
inline size_t size() const { return num_elements; }
tdata<>& tail() { return *this; }
const tdata<>& tail() const { return *this; }
const tdata<>& ctail() const { return *this; }
inline const void* at(size_t) const {
throw std::out_of_range("tdata<>");
}
inline void* mutable_at(size_t) {
throw std::out_of_range("tdata<>");
}
inline const uniform_type_info* type_at(size_t) const {
throw std::out_of_range("tdata<>");
}
inline void set() { }
inline bool operator==(const tdata&) const { return true; }
inline bool dynamically_typed() const {
return false;
}
};
template<bool IsBoxed, bool IsFunction, typename Head, typename T>
struct td_filter_ {
static inline const T& _(const T& arg) { return arg; }
static inline T&& _(T&& arg) { return std::move(arg); }
static inline T& _(T& arg) { return arg; }
};
template<typename Head, typename T>
struct td_filter_<false, true, Head, T> {
static inline T* _(T* arg) { return arg; }
};
template<typename Head, typename T>
struct td_filter_<true, false, Head, T> {
static inline Head _(const T&) { return Head{}; }
};
template<typename Head, typename T>
struct td_filter_<true, true, Head, T> : td_filter_<true, false, Head, T> { };
template<typename Head, typename T>
auto td_filter(T&& arg)
-> decltype(
td_filter_<
is_boxed<typename util::rm_const_and_ref<T>::type>::value,
std::is_function<typename util::rm_const_and_ref<T>::type>::value,
Head,
typename util::rm_const_and_ref<T>::type
>::_(std::forward<T>(arg))) {
return td_filter_<
is_boxed<typename util::rm_const_and_ref<T>::type>::value,
std::is_function<typename util::rm_const_and_ref<T>::type>::value,
Head,
typename util::rm_const_and_ref<T>::type
>::_(std::forward<T>(arg));
}
template<typename... X, typename... Y>
void tdata_set(tdata<X...>& rhs, const tdata<Y...>& lhs);
template<typename Head, typename... Tail>
struct tdata<Head, Tail...> : tdata<Tail...> {
typedef tdata<Tail...> super;
typedef util::type_list<
typename unbox_ref<Head>::type,
typename unbox_ref<Tail>::type...>
types;
Head head;
static constexpr size_t num_elements = (sizeof...(Tail) + 1);
typedef Head head_type;
typedef tdata<Tail...> tail_type;
typedef typename std::conditional<
(sizeof...(Tail) > 0),
typename tdata<Tail...>::back_type,
Head
>::type
back_type;
inline tdata() : super(), head() { }
//tdata(Head arg) : super(), head(std::move(arg)) { }
tdata(const Head& arg) : super(), head(arg) { }
tdata(Head&& arg) : super(), head(std::move(arg)) { }
template<typename T0, typename T1, typename... Ts>
tdata(T0&& arg0, T1&& arg1, Ts&&... args)
: super(std::forward<T1>(arg1), std::forward<Ts>(args)...)
, head(td_filter<Head>(std::forward<T0>(arg0))) {
}
tdata(const tdata&) = default;
tdata(tdata&& other)
: super(std::move(other.tail())), head(std::move(other.head)) {
}
// allow (partial) initialization from a different tdata
template<typename... Y>
tdata(tdata<Y...>& other) : super(other.tail()), head(other.head) {
}
template<typename... Y>
tdata(const tdata<Y...>& other) : super(other.tail()), head(other.head) {
}
template<typename... Y>
tdata(tdata<Y...>&& other)
: super(std::move(other.tail())), head(std::move(other.head)) {
}
template<typename... Y>
tdata& operator=(const tdata<Y...>& other) {
tdata_set(*this, other);
return *this;
}
template<typename T, typename... Ts>
inline void set(T&& arg, Ts&&... args) {
head = std::forward<T>(arg);
super::set(std::forward<Ts>(args)...);
}
inline size_t size() const { return num_elements; }
typedef tuple_iterator<tdata> const_iterator;
inline const_iterator begin() const { return {this}; }
inline const_iterator cbegin() const { return {this}; }
inline const_iterator end() const { return {this, size()}; }
inline const_iterator cend() const { return {this, size()}; }
// upcast
inline tdata<Tail...>& tail() { return *this; }
inline const tdata<Tail...>& tail() const { return *this; }
inline const tdata<Tail...>& ctail() const { return *this; }
inline const void* at(size_t p) const {
CPPA_REQUIRE(p < num_elements);
switch (p) {
case 0: return ptr_to(head);
case 1: return ptr_to(super::head);
case 2: return ptr_to(super::super::head);
case 3: return ptr_to(super::super::super::head);
case 4: return ptr_to(super::super::super::super::head);
default: return super::super::super::super::super::at(p - 5);
}
}
inline void* mutable_at(size_t p) {
# ifdef CPPA_DETAIL_DEBUG_MODE
if (p == 0) {
if (std::is_same<decltype(ptr_to(head)), const void*>::value) {
throw std::logic_error{"mutable_at with const head"};
}
return const_cast<void*>(ptr_to(head));
}
return super::mutable_at(p - 1);
# else
return const_cast<void*>(at(p));
# endif
}
inline const uniform_type_info* type_at(size_t p) const {
CPPA_REQUIRE(p < num_elements);
switch (p) {
case 0: return utype_of(head);
case 1: return utype_of(super::head);
case 2: return utype_of(super::super::head);
case 3: return utype_of(super::super::super::head);
case 4: return utype_of(super::super::super::super::head);
default: return super::super::super::super::super::type_at(p - 5);
}
}
Head& _back(std::integral_constant<size_t, 0>) {
return head;
}
template<size_t Pos>
back_type& _back(std::integral_constant<size_t, Pos>) {
std::integral_constant<size_t, Pos-1> token;
return super::_back(token);
}
back_type& back() {
std::integral_constant<size_t, sizeof...(Tail)> token;
return _back(token);
}
const Head& _back(std::integral_constant<size_t, 0>) const {
return head;
}
template<size_t Pos>
const back_type& _back(std::integral_constant<size_t, Pos>) const {
std::integral_constant<size_t, Pos-1> token;
return super::_back(token);
}
const back_type& back() const {
std::integral_constant<size_t, sizeof...(Tail)> token;
return _back(token);
}
};
template<typename... X>
void tdata_set(tdata<X...>&, const tdata<>&) { }
template<typename Head, typename... X, typename... Y>
void tdata_set(tdata<Head, X...>& lhs, tdata<Head, const Y...>& rhs) {
lhs.head = rhs.head;
tdata_set(lhs.tail(), rhs.tail());
}
template<size_t N, typename... Tn>
struct tdata_upcast_helper;
template<size_t N, typename Head, typename... Tail>
struct tdata_upcast_helper<N, Head, Tail...> {
typedef typename tdata_upcast_helper<N-1, Tail...>::type type;
};
template<typename Head, typename... Tail>
struct tdata_upcast_helper<0, Head, Tail...> {
typedef tdata<Head, Tail...> type;
};
template<typename T>
struct tdata_from_type_list;
template<typename... Ts>
struct tdata_from_type_list<util::type_list<Ts...>> {
typedef tdata<Ts...> type;
};
template<typename T, typename U>
inline void rebind_value(T& lhs, U& rhs) {
lhs = rhs;
}
template<typename T, typename U>
inline void rebind_value(util::rebindable_reference<T>& lhs, U& rhs) {
lhs.rebind(rhs);
}
template<typename... Ts>
inline void rebind_tdata(tdata<Ts...>&) { }
template<typename... Ts, typename... Vs>
void rebind_tdata(tdata<Ts...>& td, const tdata<>&, const Vs&... args) {
rebind_tdata(td, args...);
}
template<typename... Ts, typename... Us, typename... Vs>
void rebind_tdata(tdata<Ts...>& td, const tdata<Us...>& arg, const Vs&... args) {
rebind_value(td.head, arg.head);
rebind_tdata(td.tail(), arg.tail(), args...);
}
} // namespace detail
} // namespace cppa
namespace cppa {
template<size_t N, typename... Ts>
const typename util::type_at<N, Ts...>::type& get(const detail::tdata<Ts...>& tv) {
static_assert(N < sizeof...(Ts), "N >= tv.size()");
return static_cast<const typename detail::tdata_upcast_helper<N, Ts...>::type&>(tv).head;
}
template<size_t N, typename... Ts>
typename util::type_at<N, Ts...>::type& get_ref(detail::tdata<Ts...>& tv) {
static_assert(N < sizeof...(Ts), "N >= tv.size()");
return static_cast<typename detail::tdata_upcast_helper<N, Ts...>::type&>(tv).head;
}
} // namespace cppa
#endif // CPPA_DETAIL_TDATA_HPP
...@@ -20,12 +20,11 @@ ...@@ -20,12 +20,11 @@
#ifndef CPPA_DETAIL_TUPLE_CAST_IMPL_HPP #ifndef CPPA_DETAIL_TUPLE_CAST_IMPL_HPP
#define CPPA_DETAIL_TUPLE_CAST_IMPL_HPP #define CPPA_DETAIL_TUPLE_CAST_IMPL_HPP
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/detail/matches.hpp" #include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_vals.hpp" #include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
...@@ -46,7 +45,7 @@ struct tuple_cast_impl { ...@@ -46,7 +45,7 @@ struct tuple_cast_impl {
static_cast<size_t>( static_cast<size_t>(
util::tl_find<util::type_list<T...>, anything>::value); util::tl_find<util::type_list<T...>, anything>::value);
typedef util::limited_vector<size_t, size> mapping_vector; typedef util::limited_vector<size_t, size> mapping_vector;
static inline optional<Result> safe(any_tuple& tup) { static inline optional<Result> safe(message& tup) {
mapping_vector mv; mapping_vector mv;
if (matches<T...>(tup, mv)) return {Result::from(std::move(tup.vals()), if (matches<T...>(tup, mv)) return {Result::from(std::move(tup.vals()),
mv)}; mv)};
...@@ -56,7 +55,7 @@ struct tuple_cast_impl { ...@@ -56,7 +55,7 @@ struct tuple_cast_impl {
template<class Result, typename... T> template<class Result, typename... T>
struct tuple_cast_impl<wildcard_position::nil, Result, T...> { struct tuple_cast_impl<wildcard_position::nil, Result, T...> {
static inline optional<Result> safe(any_tuple& tup) { static inline optional<Result> safe(message& tup) {
if (matches<T...>(tup)) return {Result::from(std::move(tup.vals()))}; if (matches<T...>(tup)) return {Result::from(std::move(tup.vals()))};
return none; return none;
} }
...@@ -69,7 +68,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...> ...@@ -69,7 +68,7 @@ struct tuple_cast_impl<wildcard_position::trailing, Result, T...>
template<class Result, typename... T> template<class Result, typename... T>
struct tuple_cast_impl<wildcard_position::leading, Result, T...> { struct tuple_cast_impl<wildcard_position::leading, Result, T...> {
static inline optional<Result> safe(any_tuple& tup) { static inline optional<Result> safe(message& tup) {
size_t o = tup.size() - (sizeof...(T) - 1); size_t o = tup.size() - (sizeof...(T) - 1);
if (matches<T...>(tup)) return {Result::offset_subtuple(tup.vals(), o)}; if (matches<T...>(tup)) return {Result::offset_subtuple(tup.vals(), o)};
return none; return none;
......
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
#include <typeinfo> #include <typeinfo>
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tuple_iterator.hpp" #include "cppa/detail/message_iterator.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
struct tuple_dummy { struct tuple_dummy {
typedef util::empty_type_list types; typedef util::empty_type_list types;
typedef detail::tuple_iterator<tuple_dummy> const_iterator; typedef detail::message_iterator<tuple_dummy> const_iterator;
inline size_t size() const { inline size_t size() const {
return 0; return 0;
} }
......
...@@ -16,68 +16,77 @@ ...@@ -16,68 +16,77 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_TUPLE_VALS_HPP
#define CPPA_TUPLE_VALS_HPP
#ifndef CPPA_DETAIL_TUPLE_VALS_HPP #include <tuple>
#define CPPA_DETAIL_TUPLE_VALS_HPP
#include <stdexcept> #include <stdexcept>
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/message_data.hpp"
#include "cppa/detail/serialize_tuple.hpp" #include "cppa/detail/serialize_tuple.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
template<size_t Pos, size_t Max, bool InRange = (Pos < Max)>
struct tup_ptr_access {
template<class T>
static inline typename std::conditional<std::is_const<T>::value,
const void*, void*>::type
get(size_t pos, T& tup) {
if (pos == Pos) return &std::get<Pos>(tup);
return tup_ptr_access<Pos + 1, Max>::get(pos, tup);
}
};
template<size_t Pos, size_t Max>
struct tup_ptr_access<Pos, Max, false> {
template<class T>
static inline typename std::conditional<std::is_const<T>::value,
const void*, void*>::type
get(size_t, T&) {
// end of recursion
return nullptr;
}
};
template<typename... Ts> template<typename... Ts>
class tuple_vals : public abstract_tuple { class tuple_vals : public message_data {
static_assert(sizeof...(Ts) > 0, static_assert(sizeof...(Ts) > 0, "tuple_vals is not allowed to be empty");
"tuple_vals is not allowed to be empty");
typedef abstract_tuple super; typedef message_data super;
public: public:
typedef tdata<Ts...> data_type; typedef std::tuple<Ts...> data_type;
typedef types_array<Ts...> element_types; typedef types_array<Ts...> element_types;
tuple_vals(const tuple_vals&) = default; tuple_vals(const tuple_vals&) = default;
template<typename... Us> template<typename... Us>
tuple_vals(Us&&... args) : super(false), m_data(std::forward<Us>(args)...) { } tuple_vals(Us&&... args)
: super(false), m_data(std::forward<Us>(args)...) {}
const void* native_data() const { const void* native_data() const { return &m_data; }
return &m_data;
}
void* mutable_native_data() { void* mutable_native_data() { return &m_data; }
return &m_data;
}
inline data_type& data() { inline data_type& data() { return m_data; }
return m_data;
}
inline const data_type& data() const { inline const data_type& data() const { return m_data; }
return m_data;
}
size_t size() const { size_t size() const { return sizeof...(Ts); }
return sizeof...(Ts);
}
tuple_vals* copy() const { tuple_vals* copy() const { return new tuple_vals(*this); }
return new tuple_vals(*this);
}
const void* at(size_t pos) const { const void* at(size_t pos) const {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
return m_data.at(pos); return tup_ptr_access<0, sizeof...(Ts)>::get(pos, m_data);
} }
void* mutable_at(size_t pos) { void* mutable_at(size_t pos) {
...@@ -90,13 +99,13 @@ class tuple_vals : public abstract_tuple { ...@@ -90,13 +99,13 @@ class tuple_vals : public abstract_tuple {
return m_types[pos]; return m_types[pos];
} }
bool equals(const abstract_tuple& other) const { bool equals(const message_data& other) const {
if (size() != other.size()) return false; if (size() != other.size()) return false;
const tuple_vals* o = dynamic_cast<const tuple_vals*>(&other); const tuple_vals* o = dynamic_cast<const tuple_vals*>(&other);
if (o) { if (o) {
return m_data == (o->m_data); return m_data == (o->m_data);
} }
return abstract_tuple::equals(other); return message_data::equals(other);
} }
const std::type_info* type_token() const { const std::type_info* type_token() const {
...@@ -120,15 +129,7 @@ class tuple_vals : public abstract_tuple { ...@@ -120,15 +129,7 @@ class tuple_vals : public abstract_tuple {
template<typename... Ts> template<typename... Ts>
types_array<Ts...> tuple_vals<Ts...>::m_types; types_array<Ts...> tuple_vals<Ts...>::m_types;
template<typename TypeList>
struct tuple_vals_from_type_list;
template<typename... Ts>
struct tuple_vals_from_type_list< util::type_list<Ts...> > {
typedef tuple_vals<Ts...> type;
};
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_TUPLE_VALS_HPP #endif // CPPA_TUPLE_VALS_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_TUPLE_VIEW_HPP
#define CPPA_DETAIL_TUPLE_VIEW_HPP
#include "cppa/guard_expr.hpp"
#include "cppa/util/rebindable_reference.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa {
namespace detail {
struct tuple_view_copy_helper {
size_t pos;
abstract_tuple* target;
tuple_view_copy_helper(abstract_tuple* trgt) : pos(0), target(trgt) { }
template<typename T>
void operator()(const T* value) {
*(reinterpret_cast<T*>(target->mutable_at(pos++))) = *value;
}
};
template<typename... Ts>
class tuple_view : public abstract_tuple {
static_assert(sizeof...(Ts) > 0,
"tuple_vals is not allowed to be empty");
typedef abstract_tuple super;
public:
typedef tdata<util::rebindable_reference<Ts>...> data_type;
typedef types_array<Ts...> element_types;
tuple_view() = delete;
tuple_view(const tuple_view&) = delete;
/**
* @warning @p tuple_view does @b NOT takes ownership for given pointers
*/
tuple_view(Ts*... args) : super(false), m_data(args...) { }
inline data_type& data() {
return m_data;
}
inline const data_type& data() const {
return m_data;
}
size_t size() const {
return sizeof...(Ts);
}
abstract_tuple* copy() const {
return new tuple_vals<Ts...>{m_data};
}
const void* at(size_t pos) const {
CPPA_REQUIRE(pos < size());
return m_data.at(pos).get_ptr();
}
void* mutable_at(size_t pos) {
CPPA_REQUIRE(pos < size());
return m_data.mutable_at(pos).get_ptr();
}
const uniform_type_info* type_at(size_t pos) const {
CPPA_REQUIRE(pos < size());
return m_types[pos];
}
const std::type_info* type_token() const {
return detail::static_type_list<Ts...>::list;
}
private:
data_type m_data;
static types_array<Ts...> m_types;
tuple_view(const data_type& data) : m_data(data) { }
};
template<typename... Ts>
types_array<Ts...> tuple_view<Ts...>::m_types;
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_TUPLE_VIEW_HPP
...@@ -16,53 +16,23 @@ ...@@ -16,53 +16,23 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_DETAIL_TUPLE_ZIP_HPP
#define CPPA_DETAIL_TUPLE_ZIP_HPP
#ifndef CPPA_DETAIL_OBJECT_ARRAY_HPP #include <tuple>
#define CPPA_DETAIL_OBJECT_ARRAY_HPP
#include <vector> #include "cppa/util/int_list.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
class object_array : public abstract_tuple { template <typename F, long... Is, class Tup0, class Tup1>
auto tuple_zip(F& f, util::int_list<Is...>, Tup0&& tup0, Tup1&& tup1)
typedef abstract_tuple super; -> decltype(std::make_tuple(f(std::get<Is>(tup0), std::get<Is>(tup1))...)) {
return std::make_tuple(f(std::get<Is>(tup0), std::get<Is>(tup1))...);
public: }
using abstract_tuple::const_iterator;
object_array();
object_array(object_array&&) = default;
object_array(const object_array&);
~object_array();
void push_back(uniform_value what);
void* mutable_at(size_t pos) override;
size_t size() const override;
object_array* copy() const override;
const void* at(size_t pos) const override;
const uniform_type_info* type_at(size_t pos) const override;
const std::string* tuple_type_names() const override;
private:
std::vector<uniform_value> m_elements;
};
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_DETAIL_OBJECT_ARRAY_HPP #endif // CPPA_DETAIL_TUPLE_ZIP_HPP
...@@ -62,14 +62,6 @@ struct deduce_signature { ...@@ -62,14 +62,6 @@ struct deduce_signature {
typedef typename deduce_signature_helper<result_type, arg_types>::type type; typedef typename deduce_signature_helper<result_type, arg_types>::type type;
}; };
template<typename T>
struct match_expr_has_no_guard {
static constexpr bool value = std::is_same<
typename T::second_type::guard_type,
detail::empty_value_guard
>::value;
};
template<typename Arguments> template<typename Arguments>
struct input_is { struct input_is {
template<typename Signature> template<typename Signature>
......
...@@ -54,7 +54,6 @@ using mapped_type_list = util::type_list< ...@@ -54,7 +54,6 @@ using mapped_type_list = util::type_list<
acceptor_closed_msg, acceptor_closed_msg,
actor, actor,
actor_addr, actor_addr,
any_tuple,
atom_value, atom_value,
channel, channel,
connection_closed_msg, connection_closed_msg,
...@@ -65,6 +64,7 @@ using mapped_type_list = util::type_list< ...@@ -65,6 +64,7 @@ using mapped_type_list = util::type_list<
node_id_ptr, node_id_ptr,
io::accept_handle, io::accept_handle,
io::connection_handle, io::connection_handle,
message,
message_header, message_header,
new_connection_msg, new_connection_msg,
new_data_msg, new_data_msg,
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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_VALUE_GUARD_HPP
#define CPPA_DETAIL_VALUE_GUARD_HPP
#include <type_traits>
#include "cppa/unit.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/tdata.hpp"
namespace cppa {
namespace detail {
// 'absorbs' callables and instances of `anything`
template<typename T>
const T& vg_fwd(const T& arg, typename std::enable_if<not util::is_callable<T>::value>::type* = 0) {
return arg;
}
inline unit_t vg_fwd(const anything&) {
return unit;
}
template<typename T>
unit_t vg_fwd(const T&, typename std::enable_if<util::is_callable<T>::value>::type* = 0) {
return unit;
}
template<typename T>
struct vg_cmp {
template<typename U>
inline static bool _(const T& lhs, const U& rhs) {
return util::safe_equal(lhs, rhs);
}
};
template<>
struct vg_cmp<unit_t> {
template<typename T>
inline static bool _(const unit_t&, const T&) {
return true;
}
};
template<typename FilteredPattern>
class value_guard {
public:
value_guard() = default;
value_guard(const value_guard&) = default;
template<typename... Ts>
value_guard(const Ts&... args) : m_args(vg_fwd(args)...) { }
template<typename... Ts>
inline bool operator()(const Ts&... args) const {
return _eval(m_args.head, m_args.tail(), args...);
}
private:
typename tdata_from_type_list<FilteredPattern>::type m_args;
template<typename T, typename U>
static inline bool cmp(const T& lhs, const U& rhs) {
return vg_cmp<T>::_(lhs, rhs);
}
template<typename T, typename U>
static inline bool cmp(const T& lhs, const std::reference_wrapper<U>& rhs) {
return vg_cmp<T>::_(lhs, rhs.get());
}
static inline bool _eval(const unit_t&, const tdata<>&) {
return true;
}
template<typename T, typename U, typename... Us>
static inline bool _eval(const T& head, const tdata<>&,
const U& arg, const Us&...) {
return cmp(head, arg);
}
template<typename T0, typename T1, typename... Ts,
typename U, typename... Us>
static inline bool _eval(const T0& head, const tdata<T1, Ts...>& tail,
const U& arg, const Us&... args) {
return cmp(head, arg) && _eval(tail.head, tail.tail(), args...);
}
};
typedef value_guard<util::empty_type_list> empty_value_guard;
} // namespace detail
} // namespace cppa
#endif // CPPA_DETAIL_VALUE_GUARD_HPP
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
namespace cppa { namespace cppa {
class channel; class channel;
class any_tuple; class message;
class message_header; class message_header;
struct invalid_group_t { constexpr invalid_group_t() { } }; struct invalid_group_t { constexpr invalid_group_t() { } };
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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_GUARD_EXPR_HPP
#define CPPA_GUARD_EXPR_HPP
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <type_traits>
#include "cppa/unit.hpp"
#include "cppa/config.hpp"
#include "cppa/optional.hpp"
#include "cppa/util/call.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/util/rebindable_reference.hpp"
#include "cppa/detail/tdata.hpp"
namespace cppa {
enum operator_id {
// arithmetic operators
addition_op, subtraction_op, multiplication_op, division_op, modulo_op,
// comparison operators
less_op, less_eq_op, greater_op, greater_eq_op, equal_op, not_equal_op,
// logical operators
logical_and_op, logical_or_op,
// pseudo operators for function invocation
exec_fun1_op, exec_fun2_op, exec_fun3_op,
// operator to invoke a given functor with all arguments forwarded
exec_xfun_op,
// pseudo operator to store function parameters
dummy_op
};
// {operator, lhs, rhs} expression
template<operator_id OP, typename First, typename Second>
struct guard_expr {
typedef First first_type;
typedef Second second_type;
std::pair<First, Second> m_args;
//guard_expr() = default;
template<typename T0, typename T1>
guard_expr(T0&& a0, T1&& a1)
: m_args(std::forward<T0>(a0), std::forward<T1>(a1)) {
}
// {operator, {operator, a0, a1}, a2}
template<typename T0, typename T1, typename T2>
guard_expr(T0&& a0, T1&& a1, T2&& a2)
: m_args(First{std::forward<T0>(a0), std::forward<T1>(a1)},
std::forward<T2>(a2)) {
}
// {operator, {operator, a0, a1}, {operator, a2, a3}}
template<typename T0, typename T1, typename T2, typename T3>
guard_expr(T0&& a0, T1&& a1, T2&& a2, T3&& a3)
: m_args(First{std::forward<T0>(a0), std::forward<T1>(a1)},
Second{std::forward<T2>(a2), std::forward<T3>(a3)}) {
}
guard_expr(const guard_expr&) = default;
guard_expr(guard_expr&& other) : m_args(std::move(other.m_args)) { }
template<typename... Ts>
bool operator()(const Ts&... args) const;
};
/*
* @brief Invokes SubMacro for "+", "-", "*", "/", "%", "<", "<=", ">" and ">=".
**/
#define CPPA_FORALL_DEFAULT_OPS(SubMacro) \
SubMacro (addition_op, +) SubMacro (subtraction_op, -) \
SubMacro (multiplication_op, *) SubMacro (division_op, /) \
SubMacro (modulo_op, %) SubMacro (less_op, <) \
SubMacro (less_eq_op, <=) SubMacro (greater_op, >) \
SubMacro (greater_eq_op, >=)
/**
* @brief Creates a reference wrapper similar to std::reference_wrapper<const T>
* that could be used in guard expressions or to enforce lazy evaluation.
*/
template<typename T>
util::rebindable_reference<const T> gref(const T& value) {
return {value};
}
//ge_reference_wrapper<T> gref(const T& value) { return {value}; }
// bind utility for placeholders
template<typename Fun, typename T1>
struct gcall1 {
typedef guard_expr<exec_fun1_op, Fun, T1> result;
};
template<typename Fun, typename T1, typename T2>
struct gcall2 {
typedef guard_expr<exec_fun2_op, guard_expr<dummy_op, Fun, T1>, T2> result;
};
template<typename Fun, typename T1, typename T2, typename T3>
struct gcall3 {
typedef guard_expr<exec_fun3_op, guard_expr<dummy_op, Fun, T1>,
guard_expr<dummy_op, T2, T3> >
result;
};
/**
* @brief Call wrapper for guard placeholders and lazy evaluation.
*/
template<typename Fun, typename T1>
typename gcall1<Fun, T1>::result gcall(Fun fun, T1 t1) {
return {fun, t1};
}
/**
* @brief Call wrapper for guard placeholders and lazy evaluation.
*/
template<typename Fun, typename T1, typename T2>
typename gcall2<Fun, T1, T2>::result gcall(Fun fun, T1 t1, T2 t2) {
return {fun, t1, t2};
}
/**
* @brief Call wrapper for guard placeholders and lazy evaluation.
*/
template<typename Fun, typename T1, typename T2, typename T3>
typename gcall3<Fun, T1, T2, T3>::result gcall(Fun fun, T1 t1, T2 t2, T3 t3) {
return {fun, t1, t2, t3};
}
/**
* @brief Calls @p fun with all arguments given to the guard expression.
* The functor @p fun must return a boolean.
*/
template<typename Fun>
guard_expr<exec_xfun_op, Fun, unit_t> ge_sub_function(Fun fun) {
return {fun, unit};
}
struct ge_search_container {
bool sc;
ge_search_container(bool should_contain) : sc(should_contain) { }
template<class C>
bool operator()(const C& haystack,
const typename C::value_type& needle) const {
typedef typename C::value_type vtype;
if (sc)
return std::any_of(haystack.begin(), haystack.end(),
[&](const vtype& val) { return needle == val; });
return std::none_of(haystack.begin(), haystack.end(),
[&](const vtype& val) { return needle == val; });
}
};
struct ge_get_size {
template<class C>
inline auto operator()(const C& what) const -> decltype(what.size()) {
return what.size();
}
};
struct ge_is_empty {
bool expected;
ge_is_empty(bool expected_value) : expected(expected_value) { }
template<class C>
inline bool operator()(const C& what) const {
return what.empty() == expected;
}
};
struct ge_get_front {
template<class C>
inline auto operator()(const C& what,
typename std::enable_if<
std::is_reference<
decltype(what.front())
>::value
>::type* = 0) const
-> optional<
std::reference_wrapper<
const typename util::rm_const_and_ref<decltype(what.front())>::type> > {
if (what.empty() == false) return {what.front()};
return none;
}
template<class C>
inline auto operator()(const C& what,
typename std::enable_if<
std::is_reference<
decltype(what.front())
>::value == false
>::type* = 0) const
-> optional<decltype(what.front())> {
if (what.empty() == false) return {what.front()};
return none;
}
};
/**
* @brief A placeholder for guard expression.
*/
template<int X>
struct guard_placeholder {
constexpr guard_placeholder() { }
/**
* @brief Convenient way to call <tt>gcall(fun, guard_placeholder)</tt>.
*/
template<typename Fun>
typename gcall1<Fun, guard_placeholder>::result operator()(Fun fun) const {
return gcall(fun, *this);
}
// utility function for starts_with()
static bool u8_starts_with(const std::string& lhs, const std::string& rhs) {
return std::equal(rhs.begin(), rhs.end(), lhs.begin());
}
/**
* @brief Evaluates to the size of a container.
*/
typename gcall1<ge_get_size, guard_placeholder>::result size() const {
return gcall(ge_get_size{}, *this);
}
typename gcall1<ge_is_empty, guard_placeholder>::result empty() const {
return gcall(ge_is_empty{true}, *this);
}
typename gcall1<ge_is_empty, guard_placeholder>::result not_empty() const {
return gcall(ge_is_empty{false}, *this);
}
/**
* @brief Evaluates to the first element of a container if it's not empty.
*/
typename gcall1<ge_get_front, guard_placeholder>::result front() const {
return gcall(ge_get_front{}, *this);
}
/**
* @brief Evaluates to true if unbound argument starts with @p str.
*/
typename gcall2<decltype(&guard_placeholder::u8_starts_with),
guard_placeholder,
std::string
>::result
starts_with(std::string str) const {
return gcall(&guard_placeholder::u8_starts_with, *this, std::move(str));
}
/**
* @brief Evaluates to true if unbound argument
* is contained in @p container.
*/
template<class C>
typename gcall2<ge_search_container, C, guard_placeholder>::result
in(C container) const {
return gcall(ge_search_container{true}, std::move(container), *this);
}
/**
* @brief Evaluates to true if unbound argument
* is contained in @p list.
*/
template<typename T>
typename gcall2<ge_search_container,
std::vector<typename detail::strip_and_convert<T>::type>,
guard_placeholder
>::result
in(std::initializer_list<T> list) const {
std::vector<typename detail::strip_and_convert<T>::type> vec;
for (auto& i : list) vec.emplace_back(i);
return in(std::move(vec));
}
/**
* @brief Evaluates to true if unbound argument
* is not contained in @p container.
*/
template<class C>
typename gcall2<ge_search_container, C, guard_placeholder>::result
not_in(C container) const {
return gcall(ge_search_container{false}, std::move(container), *this);
}
/**
* @brief Evaluates to true if unbound argument
* is not contained in @p list.
*/
template<typename T>
typename gcall2<ge_search_container,
std::vector<typename detail::strip_and_convert<T>::type>,
guard_placeholder
>::result
not_in(std::initializer_list<T> list) const {
std::vector<typename detail::strip_and_convert<T>::type> vec;
for (auto& i : list) vec.emplace_back(i);
return not_in(vec);
}
};
template<typename T>
struct ge_value {
T value;
};
template<typename T>
ge_value<T> gval(T val) { return {std::move(val)}; }
// result type computation
template<typename T, class Tuple>
struct ge_unbound { typedef T type; };
template<typename T, class Tuple>
struct ge_unbound<util::rebindable_reference<const T>, Tuple> { typedef T type; };
template<typename T, class Tuple>
struct ge_unbound<std::reference_wrapper<T>, Tuple> { typedef T type; };
template<typename T, class Tuple>
struct ge_unbound<std::reference_wrapper<const T>, Tuple> { typedef T type; };
template<typename T, class Tuple>
struct ge_unbound<ge_value<T>, Tuple> { typedef T type; };
// unbound type of placeholder
template<int X, typename... Ts>
struct ge_unbound<guard_placeholder<X>, detail::tdata<Ts...> > {
static_assert(X < sizeof...(Ts),
"Cannot unbind placeholder (too few arguments)");
typedef typename ge_unbound<
typename util::type_at<X, Ts...>::type,
detail::tdata<std::reference_wrapper<Ts>...>
>::type
type;
};
// operators, operators, operators
template<typename T>
struct is_ge_type {
static constexpr bool value = false;
};
template<int X>
struct is_ge_type<guard_placeholder<X> > {
static constexpr bool value = true;
};
template<typename T>
struct is_ge_type<util::rebindable_reference<T> > {
static constexpr bool value = true;
};
template<operator_id OP, typename First, typename Second>
struct is_ge_type<guard_expr<OP, First, Second> > {
static constexpr bool value = true;
};
template<typename T>
struct is_ge_type<ge_value<T>> {
static constexpr bool value = true;
};
template<operator_id OP, typename T1, typename T2>
guard_expr<OP, typename detail::strip_and_convert<T1>::type,
typename detail::strip_and_convert<T2>::type>
ge_concatenate(T1 first, T2 second,
typename std::enable_if<
is_ge_type<T1>::value || is_ge_type<T2>::value
>::type* = 0) {
return {first, second};
}
#define CPPA_GE_OPERATOR(EnumValue, Operator) \
template<typename T1, typename T2> \
auto operator Operator (T1 v1, T2 v2) \
-> decltype(ge_concatenate< EnumValue >(v1, v2)) { \
return ge_concatenate< EnumValue >(v1, v2); \
}
CPPA_FORALL_DEFAULT_OPS(CPPA_GE_OPERATOR)
CPPA_GE_OPERATOR(equal_op, ==)
CPPA_GE_OPERATOR(not_equal_op, !=)
template<operator_id OP>
struct ge_eval_op;
#define CPPA_EVAL_OP_IMPL(EnumValue, Operator) \
template<> struct ge_eval_op< EnumValue > { \
template<typename T1, typename T2> \
static inline auto _(const T1& lhs, const T2& rhs) \
-> decltype(lhs Operator rhs) { return lhs Operator rhs; } \
};
CPPA_FORALL_DEFAULT_OPS(CPPA_EVAL_OP_IMPL)
CPPA_EVAL_OP_IMPL(logical_and_op, &&)
CPPA_EVAL_OP_IMPL(logical_or_op, ||)
template<> struct ge_eval_op<equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return util::safe_equal(lhs, rhs);
}
};
template<> struct ge_eval_op<not_equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return !util::safe_equal(lhs, rhs);
}
};
template<typename T, class Tuple>
struct ge_result_ {
typedef typename ge_unbound<T, Tuple>::type type;
};
template<operator_id OP, typename First, typename Second, class Tuple>
struct ge_result_<guard_expr<OP, First, Second>, Tuple> {
typedef typename ge_result_<First, Tuple>::type lhs_type;
typedef typename ge_result_<Second, Tuple>::type rhs_type;
typedef decltype(
ge_eval_op<OP>::_(*static_cast<const lhs_type*>(nullptr),
*static_cast<const rhs_type*>(nullptr))) type;
};
template<typename Fun, class Tuple>
struct ge_result_<guard_expr<exec_xfun_op, Fun, unit_t>, Tuple> {
typedef bool type;
};
template<typename First, typename Second, class Tuple>
struct ge_result_<guard_expr<exec_fun1_op, First, Second>, Tuple> {
typedef First type0;
typedef typename ge_unbound<Second, Tuple>::type type1;
typedef decltype( (*static_cast<const type0*>(nullptr))(
*static_cast<const type1*>(nullptr)
)) type;
};
template<typename First, typename Second, class Tuple>
struct ge_result_<guard_expr<exec_fun2_op, First, Second>, Tuple> {
typedef typename First::first_type type0;
typedef typename ge_unbound<typename First::second_type, Tuple>::type type1;
typedef typename ge_unbound<Second, Tuple>::type type2;
typedef decltype( (*static_cast<const type0*>(nullptr))(
*static_cast<const type1*>(nullptr),
*static_cast<const type2*>(nullptr)
)) type;
};
template<typename First, typename Second, class Tuple>
struct ge_result_<guard_expr<exec_fun3_op, First, Second>, Tuple> {
typedef typename First::first_type type0;
typedef typename ge_unbound<typename First::second_type, Tuple>::type type1;
typedef typename ge_unbound<typename Second::first_type, Tuple>::type type2;
typedef typename ge_unbound<typename Second::second_type, Tuple>::type type3;
typedef decltype( (*static_cast<const type0*>(nullptr))(
*static_cast<const type1*>(nullptr),
*static_cast<const type2*>(nullptr),
*static_cast<const type3*>(nullptr)
)) type;
};
template<operator_id OP, typename First, typename Second, class Tuple>
struct ge_result {
typedef typename ge_result_<guard_expr<OP, First, Second>, Tuple>::type
type;
};
template<operator_id OP1, typename F1, typename S1,
operator_id OP2, typename F2, typename S2>
guard_expr<logical_and_op, guard_expr<OP1, F1, S1>, guard_expr<OP2, F2, S2>>
operator&&(guard_expr<OP1, F1, S1> lhs,
guard_expr<OP2, F2, S2> rhs) {
return {lhs, rhs};
}
template<operator_id OP1, typename F1, typename S1,
operator_id OP2, typename F2, typename S2>
guard_expr<logical_or_op, guard_expr<OP1, F1, S1>, guard_expr<OP2, F2, S2>>
operator||(guard_expr<OP1, F1, S1> lhs,
guard_expr<OP2, F2, S2> rhs) {
return {lhs, rhs};
}
// evaluation of guard_expr
template<class Tuple, typename T>
inline const T& ge_resolve(const Tuple&, const T& value) {
return value;
}
template<class Tuple, typename T>
inline const T& ge_resolve(const Tuple&, const std::reference_wrapper<T>& value) {
return value.get();
}
template<class Tuple, typename T>
inline const T& ge_resolve(const Tuple&, const std::reference_wrapper<const T>& value) {
return value.get();
}
template<class Tuple, typename T>
inline const T& ge_resolve(const Tuple&, const util::rebindable_reference<const T>& value) {
return value.get();
}
template<class Tuple, typename T>
inline const T& ge_resolve(const Tuple&, const ge_value<T>& wrapped_value) {
return wrapped_value.value;
}
template<class Tuple, int X>
inline auto ge_resolve(const Tuple& tup, guard_placeholder<X>)
-> decltype(get<X>(tup).get()) {
return get<X>(tup).get();
}
template<class Tuple, operator_id OP, typename First, typename Second>
auto ge_resolve(const Tuple& tup,
const guard_expr<OP, First, Second>& ge)
-> typename ge_result<OP, First, Second, Tuple>::type;
template<operator_id OP, class Tuple, typename First, typename Second>
struct ge_eval_ {
static inline typename ge_result<OP, First, Second, Tuple>::type
_(const Tuple& tup, const First& lhs, const Second& rhs) {
return ge_eval_op<OP>::_(ge_resolve(tup, lhs), ge_resolve(tup, rhs));
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<logical_and_op, Tuple, First, Second> {
static inline bool _(const Tuple& tup, const First& lhs, const Second& rhs) {
// emulate short-circuit evaluation
if (ge_resolve(tup, lhs)) return ge_resolve(tup, rhs);
return false;
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<logical_or_op, Tuple, First, Second> {
static inline bool _(const Tuple& tup, const First& lhs, const Second& rhs) {
// emulate short-circuit evaluation
if (ge_resolve(tup, lhs)) return true;
return ge_resolve(tup, rhs);
}
};
template<class Tuple, typename Fun>
struct ge_eval_<exec_xfun_op, Tuple, Fun, unit_t> {
static inline bool _(const Tuple& tup, const Fun& fun, const unit_t&) {
return util::apply_args(fun, tup, util::get_indices(tup));
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<exec_fun1_op, Tuple, First, Second> {
static inline auto _(const Tuple& tup, const First& fun, const Second& arg0)
-> decltype(fun(ge_resolve(tup, arg0))) {
return fun(ge_resolve(tup, arg0));
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<exec_fun2_op, Tuple, First, Second> {
static inline auto _(const Tuple& tup, const First& lhs, const Second& rhs)
-> decltype(lhs.m_args.first(ge_resolve(tup, lhs.m_args.second),
ge_resolve(tup, rhs))) {
return lhs.m_args.first(ge_resolve(tup, lhs.m_args.second),
ge_resolve(tup, rhs));
}
};
template<class Tuple, typename First, typename Second>
struct ge_eval_<exec_fun3_op, Tuple, First, Second> {
static inline auto _(const Tuple& tup, const First& lhs, const Second& rhs)
-> decltype(lhs.m_args.first(ge_resolve(tup, lhs.m_args.second),
ge_resolve(tup, rhs.m_args.first),
ge_resolve(tup, rhs.m_args.second))) {
return lhs.m_args.first(ge_resolve(tup, lhs.m_args.second),
ge_resolve(tup, rhs.m_args.first),
ge_resolve(tup, rhs.m_args.second));
}
};
template<operator_id OP, class Tuple, typename First, typename Second>
inline typename ge_result<OP, First, Second, Tuple>::type
ge_eval(const Tuple& tup, const First& lhs, const Second& rhs) {
return ge_eval_<OP, Tuple, First, Second>::_(tup, lhs, rhs);
}
template<class Tuple, operator_id OP, typename First, typename Second>
auto ge_resolve(const Tuple& tup,
const guard_expr<OP, First, Second>& ge)
-> typename ge_result<OP, First, Second, Tuple>::type {
return ge_eval<OP>(tup, ge.m_args.first, ge.m_args.second);
}
template<operator_id OP, typename First, typename Second, typename... Ts>
auto ge_invoke_step2(const guard_expr<OP, First, Second>& ge,
const detail::tdata<Ts...>& tup)
-> typename ge_result<OP, First, Second, detail::tdata<Ts...>>::type {
return ge_eval<OP>(tup, ge.m_args.first, ge.m_args.second);
}
template<operator_id OP, typename First, typename Second, typename... Ts>
auto ge_invoke(const guard_expr<OP, First, Second>& ge,
const Ts&... args)
-> typename ge_result<OP, First, Second,
detail::tdata<std::reference_wrapper<const Ts>...>>::type {
detail::tdata<std::reference_wrapper<const Ts>...> tup{args...};
return ge_invoke_step2(ge, tup);
}
template<class GuardExpr>
struct ge_invoke_helper {
const GuardExpr& ge;
ge_invoke_helper(const GuardExpr& arg) : ge(arg) { }
template<typename... Ts>
bool operator()(Ts&&... args) const {
return ge_invoke(ge, std::forward<Ts>(args)...);
}
};
template<operator_id OP, typename First, typename Second>
template<typename... Ts>
bool guard_expr<OP, First, Second>::operator()(const Ts&... args) const {
static_assert(std::is_same<decltype(ge_invoke(*this, args...)), bool>::value,
"guard expression does not return a boolean");
return ge_invoke(*this, args...);
}
// some utility functions
template<typename T>
struct gref_wrapped {
typedef util::rebindable_reference<const typename util::rm_const_and_ref<T>::type> type;
};
template<typename T>
struct mutable_gref_wrapped {
typedef util::rebindable_reference<T> type;
};
template<typename T>
struct mutable_gref_wrapped<T&> {
typedef util::rebindable_reference<T> type;
};
// finally ...
namespace placeholders {
constexpr guard_placeholder<0> _x1;
constexpr guard_placeholder<1> _x2;
constexpr guard_placeholder<2> _x3;
constexpr guard_placeholder<3> _x4;
constexpr guard_placeholder<4> _x5;
constexpr guard_placeholder<5> _x6;
constexpr guard_placeholder<6> _x7;
constexpr guard_placeholder<7> _x8;
constexpr guard_placeholder<8> _x9;
} // namespace placeholders
} // namespace cppa
#endif // CPPA_GUARD_EXPR_HPP
...@@ -146,7 +146,7 @@ class broker : public extend<local_actor>:: ...@@ -146,7 +146,7 @@ class broker : public extend<local_actor>::
return add_acceptor(tcp_acceptor::from_sockfd(tcp_sockfd)); return add_acceptor(tcp_acceptor::from_sockfd(tcp_sockfd));
} }
void enqueue(msg_hdr_cref, any_tuple, execution_unit*) override; void enqueue(msg_hdr_cref, message, execution_unit*) override;
template<typename F> template<typename F>
static broker_ptr from(F fun) { static broker_ptr from(F fun) {
...@@ -192,7 +192,7 @@ class broker : public extend<local_actor>:: ...@@ -192,7 +192,7 @@ class broker : public extend<local_actor>::
static broker_ptr from_impl(std::function<behavior (broker*)> fun); static broker_ptr from_impl(std::function<behavior (broker*)> fun);
void invoke_message(msg_hdr_cref hdr, any_tuple msg); void invoke_message(msg_hdr_cref hdr, message msg);
bool invoke_message_from_cache(); bool invoke_message_from_cache();
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <vector> #include <vector>
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
...@@ -33,7 +33,7 @@ class default_message_queue : public ref_counted { ...@@ -33,7 +33,7 @@ class default_message_queue : public ref_counted {
public: public:
typedef std::pair<message_header, any_tuple> value_type; typedef std::pair<message_header, message> value_type;
typedef value_type& reference; typedef value_type& reference;
......
...@@ -134,7 +134,7 @@ class middleman { ...@@ -134,7 +134,7 @@ class middleman {
*/ */
virtual void deliver(const node_id& node, virtual void deliver(const node_id& node,
msg_hdr_cref hdr, msg_hdr_cref hdr,
any_tuple msg ) = 0; message msg ) = 0;
/** /**
* @brief This callback is invoked by {@link peer} implementations * @brief This callback is invoked by {@link peer} implementations
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "cppa/extend.hpp" #include "cppa/extend.hpp"
#include "cppa/node_id.hpp" #include "cppa/node_id.hpp"
#include "cppa/actor_proxy.hpp" #include "cppa/actor_proxy.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
#include "cppa/type_lookup_table.hpp" #include "cppa/type_lookup_table.hpp"
#include "cppa/weak_intrusive_ptr.hpp" #include "cppa/weak_intrusive_ptr.hpp"
...@@ -63,7 +63,7 @@ class peer : public extend<continuable>::with<buffered_writing> { ...@@ -63,7 +63,7 @@ class peer : public extend<continuable>::with<buffered_writing> {
void io_failed(event_bitmask mask) override; void io_failed(event_bitmask mask) override;
void enqueue(msg_hdr_cref hdr, const any_tuple& msg); void enqueue(msg_hdr_cref hdr, const message& msg);
inline bool stop_on_last_proxy_exited() const { inline bool stop_on_last_proxy_exited() const {
return m_stop_on_last_proxy_exited; return m_stop_on_last_proxy_exited;
...@@ -109,7 +109,7 @@ class peer : public extend<continuable>::with<buffered_writing> { ...@@ -109,7 +109,7 @@ class peer : public extend<continuable>::with<buffered_writing> {
// point to the published actor of the remote node // point to the published actor of the remote node
bool m_stop_on_last_proxy_exited; bool m_stop_on_last_proxy_exited;
partial_function m_content_handler; message_handler m_content_handler;
type_lookup_table m_incoming_types; type_lookup_table m_incoming_types;
type_lookup_table m_outgoing_types; type_lookup_table m_outgoing_types;
...@@ -122,13 +122,13 @@ class peer : public extend<continuable>::with<buffered_writing> { ...@@ -122,13 +122,13 @@ class peer : public extend<continuable>::with<buffered_writing> {
void unlink(const actor_addr& sender, const actor_addr& ptr); void unlink(const actor_addr& sender, const actor_addr& ptr);
void deliver(msg_hdr_cref hdr, any_tuple msg); void deliver(msg_hdr_cref hdr, message msg);
inline void enqueue(const any_tuple& msg) { inline void enqueue(const message& msg) {
enqueue({invalid_actor_addr, nullptr}, msg); enqueue({invalid_actor_addr, nullptr}, msg);
} }
void enqueue_impl(msg_hdr_cref hdr, const any_tuple& msg); void enqueue_impl(msg_hdr_cref hdr, const message& msg);
void add_type_if_needed(const std::string& tname); void add_type_if_needed(const std::string& tname);
......
...@@ -72,7 +72,7 @@ class remote_actor_proxy : public actor_proxy { ...@@ -72,7 +72,7 @@ class remote_actor_proxy : public actor_proxy {
node_id_ptr pinfo, node_id_ptr pinfo,
middleman* parent); middleman* parent);
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit*) override; void enqueue(msg_hdr_cref hdr, message msg, execution_unit*) override;
void link_to(const actor_addr& other) override; void link_to(const actor_addr& other) override;
...@@ -86,7 +86,7 @@ class remote_actor_proxy : public actor_proxy { ...@@ -86,7 +86,7 @@ class remote_actor_proxy : public actor_proxy {
void local_unlink_from(const actor_addr& other) override; void local_unlink_from(const actor_addr& other) override;
void deliver(msg_hdr_cref hdr, any_tuple msg) override; void deliver(msg_hdr_cref hdr, message msg) override;
protected: protected:
...@@ -94,7 +94,7 @@ class remote_actor_proxy : public actor_proxy { ...@@ -94,7 +94,7 @@ class remote_actor_proxy : public actor_proxy {
private: private:
void forward_msg(msg_hdr_cref hdr, any_tuple msg); void forward_msg(msg_hdr_cref hdr, message msg);
middleman* m_parent; middleman* m_parent;
intrusive::single_reader_queue<sync_request_info, detail::disposer> m_pending_requests; intrusive::single_reader_queue<sync_request_info, detail::disposer> m_pending_requests;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "cppa/extend.hpp" #include "cppa/extend.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/spawn_fwd.hpp" #include "cppa/spawn_fwd.hpp"
#include "cppa/message_id.hpp" #include "cppa/message_id.hpp"
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include "cppa/mailbox_element.hpp" #include "cppa/mailbox_element.hpp"
#include "cppa/response_promise.hpp" #include "cppa/response_promise.hpp"
#include "cppa/message_priority.hpp" #include "cppa/message_priority.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
...@@ -147,12 +147,12 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -147,12 +147,12 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
/** /**
* @brief Sends @p what to the receiver specified in @p dest. * @brief Sends @p what to the receiver specified in @p dest.
*/ */
void send_tuple(message_priority prio, const channel& whom, any_tuple what); void send_tuple(message_priority prio, const channel& whom, message what);
/** /**
* @brief Sends @p what to the receiver specified in @p dest. * @brief Sends @p what to the receiver specified in @p dest.
*/ */
inline void send_tuple(const channel& whom, any_tuple what) { inline void send_tuple(const channel& whom, message what) {
send_tuple(message_priority::normal, whom, std::move(what)); send_tuple(message_priority::normal, whom, std::move(what));
} }
...@@ -166,7 +166,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -166,7 +166,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
template<typename... Ts> template<typename... Ts>
inline void send(message_priority prio, const channel& whom, Ts&&... what) { inline void send(message_priority prio, const channel& whom, Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "sizeof...(Ts) == 0"); static_assert(sizeof...(Ts) > 0, "sizeof...(Ts) == 0");
send_tuple(prio, whom, make_any_tuple(std::forward<Ts>(what)...)); send_tuple(prio, whom, make_message(std::forward<Ts>(what)...));
} }
/** /**
...@@ -179,7 +179,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -179,7 +179,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
inline void send(const channel& whom, Ts&&... what) { inline void send(const channel& whom, Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "sizeof...(Ts) == 0"); static_assert(sizeof...(Ts) > 0, "sizeof...(Ts) == 0");
send_tuple(message_priority::normal, whom, send_tuple(message_priority::normal, whom,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
/** /**
...@@ -193,7 +193,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -193,7 +193,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
const typed_actor<Rs...>& whom, const typed_actor<Rs...>& whom,
cow_tuple<Ts...> what) { cow_tuple<Ts...> what) {
check_typed_input(whom, what); check_typed_input(whom, what);
send_tuple(prio, whom.m_ptr, any_tuple{std::move(what)}); send_tuple(prio, whom.m_ptr, message{std::move(what)});
} }
/** /**
...@@ -265,7 +265,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -265,7 +265,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
void delayed_send_tuple(message_priority prio, void delayed_send_tuple(message_priority prio,
const channel& whom, const channel& whom,
const util::duration& rtime, const util::duration& rtime,
any_tuple data); message data);
/** /**
* @brief Sends a message to @p whom that is delayed by @p rel_time. * @brief Sends a message to @p whom that is delayed by @p rel_time.
...@@ -276,7 +276,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -276,7 +276,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
*/ */
inline void delayed_send_tuple(const channel& whom, inline void delayed_send_tuple(const channel& whom,
const util::duration& rtime, const util::duration& rtime,
any_tuple data) { message data) {
delayed_send_tuple(message_priority::normal, whom, delayed_send_tuple(message_priority::normal, whom,
rtime, std::move(data)); rtime, std::move(data));
} }
...@@ -293,7 +293,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -293,7 +293,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
void delayed_send(message_priority prio, const channel& whom, void delayed_send(message_priority prio, const channel& whom,
const util::duration& rtime, Ts&&... args) { const util::duration& rtime, Ts&&... args) {
delayed_send_tuple(prio, whom, rtime, delayed_send_tuple(prio, whom, rtime,
make_any_tuple(std::forward<Ts>(args)...)); make_message(std::forward<Ts>(args)...));
} }
/** /**
...@@ -307,7 +307,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -307,7 +307,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
void delayed_send(const channel& whom, const util::duration& rtime, void delayed_send(const channel& whom, const util::duration& rtime,
Ts&&... args) { Ts&&... args) {
delayed_send_tuple(message_priority::normal, whom, rtime, delayed_send_tuple(message_priority::normal, whom, rtime,
make_any_tuple(std::forward<Ts>(args)...)); make_message(std::forward<Ts>(args)...));
} }
/************************************************************************** /**************************************************************************
...@@ -371,7 +371,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -371,7 +371,7 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
* from the actor's mailbox. * from the actor's mailbox.
* @warning Only set during callback invocation. * @warning Only set during callback invocation.
*/ */
inline any_tuple& last_dequeued(); inline message& last_dequeued();
/** /**
* @brief Returns the address of the last sender of the * @brief Returns the address of the last sender of the
...@@ -502,12 +502,12 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -502,12 +502,12 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
message_id timed_sync_send_tuple_impl(message_priority mp, message_id timed_sync_send_tuple_impl(message_priority mp,
const actor& whom, const actor& whom,
const util::duration& rel_time, const util::duration& rel_time,
any_tuple&& what); message&& what);
// returns the response ID // returns the response ID
message_id sync_send_tuple_impl(message_priority mp, message_id sync_send_tuple_impl(message_priority mp,
const actor& whom, const actor& whom,
any_tuple&& what); message&& what);
// returns the response ID // returns the response ID
template<typename... Rs, typename... Ts> template<typename... Rs, typename... Ts>
...@@ -517,14 +517,14 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> { ...@@ -517,14 +517,14 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
check_typed_input(whom, what); check_typed_input(whom, what);
return sync_send_tuple_impl(mp, return sync_send_tuple_impl(mp,
actor{whom.m_ptr.get()}, actor{whom.m_ptr.get()},
any_tuple{std::move(what)}); message{std::move(what)});
} }
// returns 0 if last_dequeued() is an asynchronous or sync request message, // returns 0 if last_dequeued() is an asynchronous or sync request message,
// a response id generated from the request id otherwise // a response id generated from the request id otherwise
inline message_id get_response_id(); inline message_id get_response_id();
void reply_message(any_tuple&& what); void reply_message(message&& what);
void forward_message(const actor& new_receiver, message_priority prio); void forward_message(const actor& new_receiver, message_priority prio);
...@@ -616,7 +616,7 @@ inline void local_actor::trap_exit(bool new_value) { ...@@ -616,7 +616,7 @@ inline void local_actor::trap_exit(bool new_value) {
m_trap_exit = new_value; m_trap_exit = new_value;
} }
inline any_tuple& local_actor::last_dequeued() { inline message& local_actor::last_dequeued() {
return m_current_node->msg; return m_current_node->msg;
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <cstdint> #include <cstdint>
#include "cppa/extend.hpp" #include "cppa/extend.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/actor_addr.hpp" #include "cppa/actor_addr.hpp"
#include "cppa/message_id.hpp" #include "cppa/message_id.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
...@@ -45,7 +45,7 @@ class mailbox_element : public extend<memory_managed>::with<memory_cached> { ...@@ -45,7 +45,7 @@ class mailbox_element : public extend<memory_managed>::with<memory_cached> {
mailbox_element* next; // intrusive next pointer mailbox_element* next; // intrusive next pointer
bool marked; // denotes if this node is currently processed bool marked; // denotes if this node is currently processed
actor_addr sender; actor_addr sender;
any_tuple msg; // 'content field' message msg; // 'content field'
message_id mid; message_id mid;
~mailbox_element(); ~mailbox_element();
...@@ -64,7 +64,7 @@ class mailbox_element : public extend<memory_managed>::with<memory_cached> { ...@@ -64,7 +64,7 @@ class mailbox_element : public extend<memory_managed>::with<memory_cached> {
mailbox_element() = default; mailbox_element() = default;
mailbox_element(msg_hdr_cref hdr, any_tuple data); mailbox_element(msg_hdr_cref hdr, message data);
}; };
......
...@@ -25,10 +25,11 @@ ...@@ -25,10 +25,11 @@
#include <iterator> #include <iterator>
#include <type_traits> #include <type_traits>
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/match_expr.hpp" #include "cppa/match_expr.hpp"
#include "cppa/skip_message.hpp" #include "cppa/skip_message.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
#include "cppa/message_builder.hpp"
#include "cppa/util/tbind.hpp" #include "cppa/util/tbind.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
...@@ -45,11 +46,11 @@ class match_helper { ...@@ -45,11 +46,11 @@ class match_helper {
match_helper(match_helper&&) = default; match_helper(match_helper&&) = default;
inline match_helper(any_tuple t) : tup(std::move(t)) { } inline match_helper(message t) : tup(std::move(t)) { }
template<typename... Ts> template<typename... Ts>
auto operator()(Ts&&... args) auto operator()(Ts&&... args)
-> decltype(match_expr_collect(std::forward<Ts>(args)...)(any_tuple{})) { -> decltype(match_expr_collect(std::forward<Ts>(args)...)(message{})) {
static_assert(sizeof...(Ts) > 0, "at least one argument required"); static_assert(sizeof...(Ts) > 0, "at least one argument required");
auto tmp = match_expr_collect(std::forward<Ts>(args)...); auto tmp = match_expr_collect(std::forward<Ts>(args)...);
return tmp(tup); return tmp(tup);
...@@ -57,7 +58,7 @@ class match_helper { ...@@ -57,7 +58,7 @@ class match_helper {
private: private:
any_tuple tup; message tup;
}; };
...@@ -301,7 +302,7 @@ namespace cppa { ...@@ -301,7 +302,7 @@ namespace cppa {
* @param what Tuple that should be matched against a pattern. * @param what Tuple that should be matched against a pattern.
* @returns A helper object providing <tt>operator(...)</tt>. * @returns A helper object providing <tt>operator(...)</tt>.
*/ */
inline detail::match_helper match(any_tuple what) { inline detail::match_helper match(message what) {
return what; return what;
} }
...@@ -312,7 +313,7 @@ inline detail::match_helper match(any_tuple what) { ...@@ -312,7 +313,7 @@ inline detail::match_helper match(any_tuple what) {
*/ */
template<typename T> template<typename T>
detail::match_helper match(T&& what) { detail::match_helper match(T&& what) {
return any_tuple::view(std::forward<T>(what)); return message_builder{std::forward<T>(what)}.to_message();
} }
/** /**
......
...@@ -16,28 +16,25 @@ ...@@ -16,28 +16,25 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_MATCH_EXPR_HPP #ifndef CPPA_MATCH_EXPR_HPP
#define CPPA_MATCH_EXPR_HPP #define CPPA_MATCH_EXPR_HPP
#include "cppa/unit.hpp" #include <vector>
#include "cppa/none.hpp"
#include "cppa/variant.hpp" #include "cppa/variant.hpp"
#include "cppa/optional.hpp"
#include "cppa/lift_void.hpp"
#include "cppa/guard_expr.hpp"
#include "cppa/tpartial_function.hpp"
#include "cppa/util/call.hpp" #include "cppa/unit.hpp"
#include "cppa/util/int_list.hpp" #include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/purge_refs.hpp" #include "cppa/util/purge_refs.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/util/left_or_right.hpp" #include "cppa/util/left_or_right.hpp"
#include "cppa/util/rebindable_reference.hpp"
#include "cppa/detail/matches.hpp" #include "cppa/detail/matches.hpp"
#include "cppa/detail/projection.hpp" #include "cppa/detail/apply_args.hpp"
#include "cppa/detail/value_guard.hpp" #include "cppa/detail/lifted_fun.hpp"
#include "cppa/detail/tuple_dummy.hpp" #include "cppa/detail/tuple_dummy.hpp"
#include "cppa/detail/pseudo_tuple.hpp" #include "cppa/detail/pseudo_tuple.hpp"
#include "cppa/detail/behavior_impl.hpp" #include "cppa/detail/behavior_impl.hpp"
...@@ -46,20 +43,25 @@ namespace cppa { ...@@ -46,20 +43,25 @@ namespace cppa {
namespace detail { namespace detail {
template<long N> template<long N>
struct long_constant { static constexpr long value = N; }; struct long_constant {
static constexpr long value = N;
};
typedef long_constant<-1l> minus1l; typedef long_constant<-1l> minus1l;
template<typename T1, typename T2> template<typename T1, typename T2>
inline T2& deduce_const(T1&, T2& rhs) { return rhs; } inline T2& deduce_const(T1&, T2& rhs) {
return rhs;
}
template<typename T1, typename T2> template<typename T1, typename T2>
inline const T2& deduce_const(const T1&, T2& rhs) { return rhs; } inline const T2& deduce_const(const T1&, T2& rhs) {
return rhs;
}
template<class FilteredPattern> template<class FilteredPattern>
struct invoke_util_base { struct invoke_util_base {
typedef FilteredPattern filtered_pattern; typedef typename util::tl_apply<FilteredPattern, pseudo_tuple>::type
typedef typename pseudo_tuple_from_type_list<filtered_pattern>::type
tuple_type; tuple_type;
}; };
...@@ -70,54 +72,45 @@ struct invoke_util_impl : invoke_util_base<FilteredPattern> { ...@@ -70,54 +72,45 @@ struct invoke_util_impl : invoke_util_base<FilteredPattern> {
typedef invoke_util_base<FilteredPattern> super; typedef invoke_util_base<FilteredPattern> super;
template<class Tuple> template<class Tuple>
static bool can_invoke(const std::type_info& type_token, static bool can_invoke(const std::type_info& type_token, const Tuple& tup) {
const Tuple& tup) { typename select_matcher<Tuple, Pattern>::type mimpl;
typedef typename match_impl_from_type_list<Tuple, Pattern>::type mimpl; return type_token == typeid(FilteredPattern) || mimpl(tup);
return type_token == typeid(FilteredPattern) || mimpl::_(tup);
} }
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(typename super::tuple_type& result, static bool prepare_invoke(typename super::tuple_type& result,
const std::type_info& type_token, const std::type_info& type_token, bool, PtrType*,
bool,
PtrType*,
Tuple& tup) { Tuple& tup) {
typedef typename match_impl_from_type_list< typename select_matcher<typename std::remove_const<Tuple>::type,
typename std::remove_const<Tuple>::type, Pattern>::type mimpl;
Pattern std::vector<size_t> mv;
>::type
mimpl;
util::limited_vector<size_t, util::tl_size<FilteredPattern>::value> mv;
if (type_token == typeid(FilteredPattern)) { if (type_token == typeid(FilteredPattern)) {
for (size_t i = 0; i < util::tl_size<FilteredPattern>::value; ++i) { for (size_t i = 0; i < util::tl_size<FilteredPattern>::value;
++i) {
result[i] = const_cast<void*>(tup.at(i)); result[i] = const_cast<void*>(tup.at(i));
} }
return true; return true;
} } else if (mimpl(tup, mv)) {
else if (mimpl::_(tup, mv)) { for (size_t i = 0; i < util::tl_size<FilteredPattern>::value;
for (size_t i = 0; i < util::tl_size<FilteredPattern>::value; ++i) { ++i) {
result[i] = const_cast<void*>(tup.at(mv[i])); result[i] = const_cast<void*>(tup.at(mv[i]));
} }
return true; return true;
} }
return false; return false;
} }
}; };
template<> template<>
struct invoke_util_impl<wildcard_position::nil, struct invoke_util_impl<
util::empty_type_list, wildcard_position::nil, util::empty_type_list,
util::empty_type_list > util::empty_type_list> : invoke_util_base<util::empty_type_list> {
: invoke_util_base<util::empty_type_list> {
typedef invoke_util_base<util::empty_type_list> super; typedef invoke_util_base<util::empty_type_list> super;
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(typename super::tuple_type&, static bool prepare_invoke(typename super::tuple_type&,
const std::type_info& type_token, const std::type_info& type_token, bool, PtrType*,
bool,
PtrType*,
Tuple& tup) { Tuple& tup) {
return can_invoke(type_token, tup); return can_invoke(type_token, tup);
} }
...@@ -126,20 +119,18 @@ struct invoke_util_impl<wildcard_position::nil, ...@@ -126,20 +119,18 @@ struct invoke_util_impl<wildcard_position::nil,
static bool can_invoke(const std::type_info& arg_types, const Tuple&) { static bool can_invoke(const std::type_info& arg_types, const Tuple&) {
return arg_types == typeid(util::empty_type_list); return arg_types == typeid(util::empty_type_list);
} }
}; };
template<class Pattern, typename... Ts> template<class Pattern, typename... Ts>
struct invoke_util_impl<wildcard_position::nil, struct invoke_util_impl<
Pattern, wildcard_position::nil, Pattern,
util::type_list<Ts...>> util::type_list<Ts...>> : invoke_util_base<util::type_list<Ts...>> {
: invoke_util_base<util::type_list<Ts...>> {
typedef invoke_util_base<util::type_list<Ts...>> super; typedef invoke_util_base<util::type_list<Ts...>> super;
typedef typename super::tuple_type tuple_type; typedef typename super::tuple_type tuple_type;
typedef detail::tdata<Ts...> native_data_type; typedef std::tuple<Ts...> native_data_type;
typedef typename detail::static_types_array<Ts...> arr_type; typedef typename detail::static_types_array<Ts...> arr_type;
...@@ -157,58 +148,40 @@ struct invoke_util_impl<wildcard_position::nil, ...@@ -157,58 +148,40 @@ struct invoke_util_impl<wildcard_position::nil,
} }
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(tuple_type& result, static bool prepare_invoke(
const std::type_info&, tuple_type& result, const std::type_info&, bool, PtrType*, Tuple& tup,
bool,
PtrType*,
Tuple& tup,
typename std::enable_if< typename std::enable_if<
std::is_same< std::is_same<typename std::remove_const<Tuple>::type,
typename std::remove_const<Tuple>::type, detail::message_data>::value == false>::type* = 0) {
detail::abstract_tuple std::integral_constant<
>::value == false bool, util::tl_binary_forall<
>::type* = 0) { typename util::tl_map<typename Tuple::types,
std::integral_constant<bool, util::purge_refs>::type,
util::tl_binary_forall< util::type_list<Ts...>, std::is_same>::value> token;
typename util::tl_map<
typename Tuple::types,
util::purge_refs
>::type,
util::type_list<Ts...>,
std::is_same
>::value > token;
return prepare_invoke(token, result, tup); return prepare_invoke(token, result, tup);
} }
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(typename super::tuple_type& result, static bool prepare_invoke(
const std::type_info& arg_types, typename super::tuple_type& result, const std::type_info& arg_types,
bool dynamically_typed, bool dynamically_typed, PtrType* native_arg, Tuple& tup,
PtrType* native_arg,
Tuple& tup,
typename std::enable_if< typename std::enable_if<
std::is_same< std::is_same<typename std::remove_const<Tuple>::type,
typename std::remove_const<Tuple>::type, detail::message_data>::value == true>::type* = 0) {
detail::abstract_tuple
>::value == true
>::type* = 0) {
if (arg_types == typeid(util::type_list<Ts...>)) { if (arg_types == typeid(util::type_list<Ts...>)) {
if (native_arg) { if (native_arg) {
typedef typename std::conditional< typedef typename std::conditional<
std::is_const<PtrType>::value, std::is_const<PtrType>::value, const native_data_type*,
const native_data_type*, native_data_type*>::type cast_type;
native_data_type*
>::type
cast_type;
auto arg = reinterpret_cast<cast_type>(native_arg); auto arg = reinterpret_cast<cast_type>(native_arg);
for (size_t i = 0; i < sizeof...(Ts); ++i) { for (size_t i = 0; i < sizeof...(Ts); ++i) {
result[i] = const_cast<void*>(arg->at(i)); result[i] = const_cast<void*>(
tup_ptr_access<0, sizeof...(Ts)>::get(i, *arg));
} }
return true; return true;
} }
// 'fall through' // 'fall through'
} } else if (dynamically_typed) {
else if (dynamically_typed) {
auto& arr = arr_type::arr; auto& arr = arr_type::arr;
if (tup.size() != sizeof...(Ts)) { if (tup.size() != sizeof...(Ts)) {
return false; return false;
...@@ -219,8 +192,8 @@ struct invoke_util_impl<wildcard_position::nil, ...@@ -219,8 +192,8 @@ struct invoke_util_impl<wildcard_position::nil,
} }
} }
// 'fall through' // 'fall through'
} } else
else return false; return false;
for (size_t i = 0; i < sizeof...(Ts); ++i) { for (size_t i = 0; i < sizeof...(Ts); ++i) {
result[i] = const_cast<void*>(tup.at(i)); result[i] = const_cast<void*>(tup.at(i));
} }
...@@ -231,14 +204,12 @@ struct invoke_util_impl<wildcard_position::nil, ...@@ -231,14 +204,12 @@ struct invoke_util_impl<wildcard_position::nil,
static bool can_invoke(const std::type_info& arg_types, const Tuple&) { static bool can_invoke(const std::type_info& arg_types, const Tuple&) {
return arg_types == typeid(util::type_list<Ts...>); return arg_types == typeid(util::type_list<Ts...>);
} }
}; };
template<> template<>
struct invoke_util_impl<wildcard_position::leading, struct invoke_util_impl<
util::type_list<anything>, wildcard_position::leading, util::type_list<anything>,
util::empty_type_list> util::empty_type_list> : invoke_util_base<util::empty_type_list> {
: invoke_util_base<util::empty_type_list> {
typedef invoke_util_base<util::empty_type_list> super; typedef invoke_util_base<util::empty_type_list> super;
...@@ -249,26 +220,21 @@ struct invoke_util_impl<wildcard_position::leading, ...@@ -249,26 +220,21 @@ struct invoke_util_impl<wildcard_position::leading,
template<typename PtrType, typename Tuple> template<typename PtrType, typename Tuple>
static inline bool prepare_invoke(typename super::tuple_type&, static inline bool prepare_invoke(typename super::tuple_type&,
const std::type_info&, const std::type_info&, bool, PtrType*,
bool,
PtrType*,
Tuple&) { Tuple&) {
return true; return true;
} }
}; };
template<class Pattern, typename... Ts> template<class Pattern, typename... Ts>
struct invoke_util_impl<wildcard_position::trailing, struct invoke_util_impl<
Pattern, wildcard_position::trailing, Pattern,
util::type_list<Ts...>> util::type_list<Ts...>> : invoke_util_base<util::type_list<Ts...>> {
: invoke_util_base<util::type_list<Ts...>> {
typedef invoke_util_base<util::type_list<Ts...>> super; typedef invoke_util_base<util::type_list<Ts...>> super;
template<class Tuple> template<class Tuple>
static bool can_invoke(const std::type_info& arg_types, static bool can_invoke(const std::type_info& arg_types, const Tuple& tup) {
const Tuple& tup) {
if (arg_types == typeid(util::type_list<Ts...>)) { if (arg_types == typeid(util::type_list<Ts...>)) {
return true; return true;
} }
...@@ -287,9 +253,7 @@ struct invoke_util_impl<wildcard_position::trailing, ...@@ -287,9 +253,7 @@ struct invoke_util_impl<wildcard_position::trailing,
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(typename super::tuple_type& result, static bool prepare_invoke(typename super::tuple_type& result,
const std::type_info& arg_types, const std::type_info& arg_types, bool, PtrType*,
bool,
PtrType*,
Tuple& tup) { Tuple& tup) {
if (!can_invoke(arg_types, tup)) return false; if (!can_invoke(arg_types, tup)) return false;
for (size_t i = 0; i < sizeof...(Ts); ++i) { for (size_t i = 0; i < sizeof...(Ts); ++i) {
...@@ -297,20 +261,17 @@ struct invoke_util_impl<wildcard_position::trailing, ...@@ -297,20 +261,17 @@ struct invoke_util_impl<wildcard_position::trailing,
} }
return true; return true;
} }
}; };
template<class Pattern, typename... Ts> template<class Pattern, typename... Ts>
struct invoke_util_impl<wildcard_position::leading, struct invoke_util_impl<
Pattern, wildcard_position::leading, Pattern,
util::type_list<Ts...>> util::type_list<Ts...>> : invoke_util_base<util::type_list<Ts...>> {
: invoke_util_base<util::type_list<Ts...>> {
typedef invoke_util_base<util::type_list<Ts...>> super; typedef invoke_util_base<util::type_list<Ts...>> super;
template<class Tuple> template<class Tuple>
static bool can_invoke(const std::type_info& arg_types, static bool can_invoke(const std::type_info& arg_types, const Tuple& tup) {
const Tuple& tup) {
if (arg_types == typeid(util::type_list<Ts...>)) { if (arg_types == typeid(util::type_list<Ts...>)) {
return true; return true;
} }
...@@ -329,9 +290,7 @@ struct invoke_util_impl<wildcard_position::leading, ...@@ -329,9 +290,7 @@ struct invoke_util_impl<wildcard_position::leading,
template<typename PtrType, class Tuple> template<typename PtrType, class Tuple>
static bool prepare_invoke(typename super::tuple_type& result, static bool prepare_invoke(typename super::tuple_type& result,
const std::type_info& arg_types, const std::type_info& arg_types, bool, PtrType*,
bool,
PtrType*,
Tuple& tup) { Tuple& tup) {
if (!can_invoke(arg_types, tup)) return false; if (!can_invoke(arg_types, tup)) return false;
size_t i = tup.size() - sizeof...(Ts); size_t i = tup.size() - sizeof...(Ts);
...@@ -341,129 +300,85 @@ struct invoke_util_impl<wildcard_position::leading, ...@@ -341,129 +300,85 @@ struct invoke_util_impl<wildcard_position::leading,
} }
return true; return true;
} }
}; };
template<class Pattern> template<class Pattern>
struct invoke_util struct invoke_util
: invoke_util_impl< : invoke_util_impl<
get_wildcard_position<Pattern>(), get_wildcard_position<Pattern>(), Pattern,
Pattern, typename util::tl_filter_not_type<Pattern, anything>::type> {};
typename util::tl_filter_not_type<Pattern, anything>::type> {
}; template<class Expr, class Projections, class Signature, class Pattern>
class match_expr_case
: public get_lifted_fun<Expr, Projections, Signature>::type {
template<class Pattern, class Projection, class PartialFun> typedef typename get_lifted_fun<Expr, Projections, Signature>::type super;
struct projection_partial_function_pair : std::pair<Projection, PartialFun> {
public:
template<typename... Ts> template<typename... Ts>
projection_partial_function_pair(Ts&&... args) match_expr_case(Ts&&... args)
: std::pair<Projection, PartialFun>(std::forward<Ts>(args)...) { } : super(std::forward<Ts>(args)...) {}
typedef Pattern pattern_type; typedef Pattern pattern_type;
}; };
template<class Expr, class Guard, class Transformers, class Pattern> template<class Expr, class Transformers, class Pattern>
struct get_case_ { struct get_case_ {
typedef typename util::get_callable_trait<Expr>::type ctrait; typedef typename util::get_callable_trait<Expr>::type ctrait;
typedef typename util::tl_filter_not_type< typedef typename util::tl_filter_not_type<Pattern, anything>::type
Pattern,
anything
>::type
filtered_pattern; filtered_pattern;
typedef typename util::tl_pad_right< typedef typename util::tl_pad_right<
Transformers, Transformers, util::tl_size<filtered_pattern>::value>::type
util::tl_size<filtered_pattern>::value
>::type
padded_transformers; padded_transformers;
typedef typename util::tl_map< typedef typename util::tl_map<filtered_pattern, std::add_const,
filtered_pattern, std::add_lvalue_reference>::type
std::add_const,
std::add_lvalue_reference
>::type
base_signature; base_signature;
typedef typename util::tl_map_conditional< typedef typename util::tl_map_conditional<
typename util::tl_pad_left< typename util::tl_pad_left<
typename ctrait::arg_types, typename ctrait::arg_types,
util::tl_size<filtered_pattern>::value util::tl_size<filtered_pattern>::value>::type,
>::type, std::is_lvalue_reference, false, std::add_const,
std::is_lvalue_reference, std::add_lvalue_reference>::type padded_expr_args;
false,
std::add_const,
std::add_lvalue_reference
>::type
padded_expr_args;
// override base signature with required argument types of Expr // override base signature with required argument types of Expr
// and result types of transformation // and result types of transformation
typedef typename util::tl_zip< typedef typename util::tl_zip<
typename util::tl_map< typename util::tl_map<padded_transformers, util::map_to_result_type,
padded_transformers,
util::map_to_result_type,
util::rm_optional, util::rm_optional,
std::add_lvalue_reference std::add_lvalue_reference>::type,
>::type, typename util::tl_zip<padded_expr_args, base_signature,
typename util::tl_zip< util::left_or_right>::type,
padded_expr_args, util::left_or_right>::type partial_fun_signature;
base_signature,
util::left_or_right
>::type,
util::left_or_right
>::type
partial_fun_signature;
// 'inherit' mutable references from partial_fun_signature // 'inherit' mutable references from partial_fun_signature
// for arguments without transformation // for arguments without transformation
typedef typename util::tl_zip< typedef typename util::tl_zip<
typename util::tl_zip< typename util::tl_zip<padded_transformers, partial_fun_signature,
padded_transformers, util::if_not_left>::type,
partial_fun_signature, base_signature, util::deduce_ref_type>::type projection_signature;
util::if_not_left
>::type,
base_signature,
util::deduce_ref_type
>::type
projection_signature;
typedef typename projection_from_type_list<
padded_transformers,
projection_signature
>::type
type1;
typedef typename get_tpartial_function<
Expr,
Guard,
partial_fun_signature
>::type
type2;
typedef projection_partial_function_pair<Pattern, type1, type2> type;
typedef match_expr_case<Expr, padded_transformers, projection_signature,
Pattern> type;
}; };
template<bool Complete, class Expr, class Guard, class Trans, class Pattern> template<bool Complete, class Expr, class Trans, class Pattern>
struct get_case { struct get_case {
typedef typename get_case_<Expr, Guard, Trans, Pattern>::type type; typedef typename get_case_<Expr, Trans, Pattern>::type type;
}; };
template<class Expr, class Guard, class Trans, class Pattern> template<class Expr, class Trans, class Pattern>
struct get_case<false, Expr, Guard, Trans, Pattern> { struct get_case<false, Expr, Trans, Pattern> {
typedef typename util::tl_pop_back<Pattern>::type lhs_pattern; typedef typename util::tl_pop_back<Pattern>::type lhs_pattern;
typedef typename util::tl_map< typedef typename util::tl_map<
typename util::get_callable_trait<Expr>::arg_types, typename util::get_callable_trait<Expr>::arg_types,
util::rm_const_and_ref util::rm_const_and_ref>::type rhs_pattern;
>::type
rhs_pattern;
typedef typename get_case_< typedef typename get_case_<
Expr, Expr, Trans,
Guard, typename util::tl_concat<lhs_pattern, rhs_pattern>::type>::type type;
Trans,
typename util::tl_concat<lhs_pattern, rhs_pattern>::type
>::type
type;
}; };
template<typename Fun> template<typename Fun>
...@@ -483,9 +398,9 @@ inline bool unroll_expr_result_valid(const optional<T>& opt) { ...@@ -483,9 +398,9 @@ inline bool unroll_expr_result_valid(const optional<T>& opt) {
return static_cast<bool>(opt); return static_cast<bool>(opt);
} }
template<typename T> inline variant<none_t, unit_t> unroll_expr_result_unbox(bool& value) {
inline T& unroll_expr_result_unbox(T& value) { if (value) return unit;
return value; return none;
} }
template<typename T> template<typename T>
...@@ -494,21 +409,17 @@ inline T& unroll_expr_result_unbox(optional<T>& opt) { ...@@ -494,21 +409,17 @@ inline T& unroll_expr_result_unbox(optional<T>& opt) {
} }
template<typename Result, class PPFPs, typename PtrType, class Tuple> template<typename Result, class PPFPs, typename PtrType, class Tuple>
Result unroll_expr(PPFPs&, std::uint64_t, minus1l, const std::type_info&, Result unroll_expr(PPFPs&, uint64_t, minus1l, const std::type_info&, bool,
bool, PtrType*, Tuple&) { PtrType*, Tuple&) {
return none; return none;
} }
template<typename Result, class PPFPs, long N, typename PtrType, class Tuple> template<typename Result, class PPFPs, long N, typename PtrType, class Tuple>
Result unroll_expr(PPFPs& fs, Result unroll_expr(PPFPs& fs, uint64_t bitmask, long_constant<N>,
std::uint64_t bitmask, const std::type_info& type_token, bool is_dynamic,
long_constant<N>, PtrType* ptr, Tuple& tup) {
const std::type_info& type_token,
bool is_dynamic,
PtrType* ptr,
Tuple& tup) {
/* recursively evaluate sub expressions */ { /* recursively evaluate sub expressions */ {
Result res = unroll_expr<Result>(fs, bitmask, long_constant<N-1>{}, Result res = unroll_expr<Result>(fs, bitmask, long_constant<N - 1>{},
type_token, is_dynamic, ptr, tup); type_token, is_dynamic, ptr, tup);
if (!get<none_t>(&res)) return res; if (!get<none_t>(&res)) return res;
} }
...@@ -520,10 +431,7 @@ Result unroll_expr(PPFPs& fs, ...@@ -520,10 +431,7 @@ Result unroll_expr(PPFPs& fs,
typename policy::tuple_type targs; typename policy::tuple_type targs;
if (policy::prepare_invoke(targs, type_token, is_dynamic, ptr, tup)) { if (policy::prepare_invoke(targs, type_token, is_dynamic, ptr, tup)) {
auto is = util::get_indices(targs); auto is = util::get_indices(targs);
auto res = util::apply_args_prefixed(f.first, auto res = detail::apply_args(f, is, deduce_const(tup, targs));
deduce_const(tup, targs),
is,
f.second);
if (unroll_expr_result_valid(res)) { if (unroll_expr_result_valid(res)) {
return std::move(unroll_expr_result_unbox(res)); return std::move(unroll_expr_result_unbox(res));
} }
...@@ -531,46 +439,21 @@ Result unroll_expr(PPFPs& fs, ...@@ -531,46 +439,21 @@ Result unroll_expr(PPFPs& fs,
return none; return none;
} }
// PPFP = projection_partial_function_pair
template<class PPFPs, class T>
inline bool can_unroll_expr(PPFPs&, minus1l, const std::type_info&, const T&) {
return false;
}
template<class PPFPs, long N, class Tuple>
inline bool can_unroll_expr(PPFPs& fs,
long_constant<N>,
const std::type_info& arg_types,
const Tuple& tup) {
if (can_unroll_expr(fs, long_constant<N-1l>(), arg_types, tup)) {
return true;
}
auto& f = get<N>(fs);
typedef typename util::rm_const_and_ref<decltype(f)>::type Fun;
typedef typename Fun::pattern_type pattern_type;
typedef detail::invoke_util<pattern_type> policy;
return policy::can_invoke(arg_types, tup);
}
template<class PPFPs, class Tuple> template<class PPFPs, class Tuple>
inline std::uint64_t calc_bitmask(PPFPs&, inline uint64_t calc_bitmask(PPFPs&, minus1l, const std::type_info&,
minus1l,
const std::type_info&,
const Tuple&) { const Tuple&) {
return 0x00; return 0x00;
} }
template<class PPFPs, long N, class Tuple> template<class Case, long N, class Tuple>
inline std::uint64_t calc_bitmask(PPFPs& fs, inline uint64_t calc_bitmask(Case& fs, long_constant<N>,
long_constant<N>, const std::type_info& tinf, const Tuple& tup) {
const std::type_info& tinf,
const Tuple& tup) {
auto& f = get<N>(fs); auto& f = get<N>(fs);
typedef typename util::rm_const_and_ref<decltype(f)>::type Fun; typedef typename util::rm_const_and_ref<decltype(f)>::type Fun;
typedef typename Fun::pattern_type pattern_type; typedef typename Fun::pattern_type pattern_type;
typedef detail::invoke_util<pattern_type> policy; typedef detail::invoke_util<pattern_type> policy;
std::uint64_t result = policy::can_invoke(tinf, tup) ? (0x01 << N) : 0x00; uint64_t result = policy::can_invoke(tinf, tup) ? (0x01 << N) : 0x00;
return result | calc_bitmask(fs, long_constant<N-1l>(), tinf, tup); return result | calc_bitmask(fs, long_constant<N - 1l>(), tinf, tup);
} }
template<bool IsManipulator, typename T0, typename T1> template<bool IsManipulator, typename T0, typename T1>
...@@ -591,28 +474,24 @@ struct mexpr_fwd_<true, T&, T> { ...@@ -591,28 +474,24 @@ struct mexpr_fwd_<true, T&, T> {
template<bool IsManipulator, typename T> template<bool IsManipulator, typename T>
struct mexpr_fwd { struct mexpr_fwd {
typedef typename mexpr_fwd_< typedef typename mexpr_fwd_<
IsManipulator, IsManipulator, T,
T,
typename detail::implicit_conversions< typename detail::implicit_conversions<
typename util::rm_const_and_ref<T>::type typename util::rm_const_and_ref<T>::type>::type>::type type;
>::type
>::type
type;
}; };
// detach_if_needed(any_tuple tup, bool do_detach) // detach_if_needed(message tup, bool do_detach)
inline any_tuple& detach_if_needed(any_tuple& tup, std::true_type) { inline message& detach_if_needed(message& tup, std::true_type) {
tup.force_detach(); tup.force_detach();
return tup; return tup;
} }
inline any_tuple detach_if_needed(const any_tuple& tup, std::true_type) { inline message detach_if_needed(const message& tup, std::true_type) {
any_tuple cpy{tup}; message cpy{tup};
cpy.force_detach(); cpy.force_detach();
return cpy; return cpy;
} }
inline const any_tuple& detach_if_needed(const any_tuple& tup, std::false_type) { inline const message& detach_if_needed(const message& tup, std::false_type) {
return tup; return tup;
} }
...@@ -628,12 +507,16 @@ inline const void* fetch_native_data(const Ptr& ptr, std::false_type) { ...@@ -628,12 +507,16 @@ inline const void* fetch_native_data(const Ptr& ptr, std::false_type) {
template<typename T> template<typename T>
struct is_manipulator_case { struct is_manipulator_case {
static constexpr bool value = T::second_type::manipulates_args; // static constexpr bool value = T::second_type::manipulates_args;
typedef typename T::arg_types arg_types;
static constexpr bool value = util::tl_exists<arg_types,
util::is_mutable_ref>::value;
}; };
template<typename T> template<typename T>
struct get_case_result { struct get_case_result {
typedef typename T::second_type::result_type type; // typedef typename T::second_type::result_type type;
typedef typename T::result_type type;
}; };
} // namespace detail } // namespace detail
...@@ -651,7 +534,7 @@ struct match_result_from_type_list<util::type_list<Ts...>> { ...@@ -651,7 +534,7 @@ struct match_result_from_type_list<util::type_list<Ts...>> {
/** /**
* @brief A match expression encapsulating cases <tt>Cs...</tt>, whereas * @brief A match expression encapsulating cases <tt>Cs...</tt>, whereas
* each case is a @p detail::projection_partial_function_pair. * each case is a @p util::match_expr_case<...>.
*/ */
template<class... Cs> template<class... Cs>
class match_expr { class match_expr {
...@@ -659,25 +542,17 @@ class match_expr { ...@@ -659,25 +542,17 @@ class match_expr {
static_assert(sizeof...(Cs) < 64, "too many functions"); static_assert(sizeof...(Cs) < 64, "too many functions");
public: public:
typedef util::type_list<Cs...> cases_list; typedef util::type_list<Cs...> cases_list;
typedef typename match_result_from_type_list< typedef typename match_result_from_type_list<
typename util::tl_distinct< typename util::tl_distinct<typename util::tl_map<
typename util::tl_map< cases_list, detail::get_case_result>::type>::type>::type
cases_list,
detail::get_case_result
>::type
>::type
>::type
result_type; result_type;
static constexpr bool has_manipulator = util::tl_exists< static constexpr bool has_manipulator =
cases_list, util::tl_exists<cases_list, detail::is_manipulator_case>::value;
detail::is_manipulator_case
>::value;
typedef detail::long_constant<sizeof...(Cs)-1l> idx_token_type; typedef detail::long_constant<sizeof...(Cs) - 1l> idx_token_type;
static constexpr idx_token_type idx_token = idx_token_type{}; static constexpr idx_token_type idx_token = idx_token_type{};
...@@ -691,101 +566,29 @@ class match_expr { ...@@ -691,101 +566,29 @@ class match_expr {
init(); init();
} }
match_expr(const match_expr& other) : m_cases(other.m_cases) { match_expr(const match_expr& other) : m_cases(other.m_cases) { init(); }
init();
}
bool can_invoke(const any_tuple& tup) {
auto type_token = tup.type_token();
if (not tup.dynamically_typed()) {
auto bitmask = get_cache_entry(type_token, tup);
return bitmask != 0;
}
return can_unroll_expr(m_cases,
idx_token,
*type_token,
tup);
}
inline result_type operator()(const any_tuple& tup) { inline result_type operator()(const message& tup) { return apply(tup); }
return apply(tup);
}
inline result_type operator()(any_tuple& tup) { inline result_type operator()(message& tup) { return apply(tup); }
return apply(tup);
}
inline result_type operator()(any_tuple&& tup) { inline result_type operator()(message&& tup) {
any_tuple tmp{tup}; message tmp{tup};
return apply(tmp); return apply(tmp);
} }
template<typename T, typename... Ts>
typename std::enable_if<
not std::is_same<
typename util::rm_const_and_ref<T>::type,
any_tuple
>::value
&& not is_cow_tuple<T>::value,
result_type
>::type
operator()(T&& arg0, Ts&&... args) {
// wraps and applies implicit conversions to args
typedef detail::tdata<
typename detail::mexpr_fwd<
has_manipulator,
T
>::type,
typename detail::mexpr_fwd<
has_manipulator,
Ts
>::type...
>
tuple_type;
tuple_type tup{std::forward<T>(arg0), std::forward<Ts>(args)...};
auto& type_token = typeid(typename tuple_type::types);
auto bitmask = get_cache_entry(&type_token, tup);
// ref_type keeps track of whether this match_expr is a mutator
typedef typename std::conditional<
has_manipulator,
tuple_type&,
const tuple_type&
>::type
ref_type;
// same here
typedef typename std::conditional<
has_manipulator,
void*,
const void*
>::type
ptr_type;
// iterate over cases and return if any case was invoked
return detail::unroll_expr<result_type>(m_cases,
bitmask,
idx_token,
type_token,
false, // not dynamically_typed
static_cast<ptr_type>(nullptr),
static_cast<ref_type>(tup));
}
template<class... Ds> template<class... Ds>
match_expr<Cs..., Ds...> or_else(const match_expr<Ds...>& other) const { match_expr<Cs..., Ds...> or_else(const match_expr<Ds...>& other) const {
detail::tdata<util::rebindable_reference<const Cs>..., return {tuple_cat(m_cases, other.cases())};
util::rebindable_reference<const Ds>... > all_cases;
rebind_tdata(all_cases, m_cases, other.cases());
return {all_cases};
} }
/** @cond PRIVATE */ /** @cond PRIVATE */
inline const detail::tdata<Cs...>& cases() const { inline const std::tuple<Cs...>& cases() const { return m_cases; }
return m_cases;
}
intrusive_ptr<detail::behavior_impl> as_behavior_impl() const { intrusive_ptr<detail::behavior_impl> as_behavior_impl() const {
//return new pfun_impl(*this); // return new pfun_impl(*this);
auto lvoid = [] { }; auto lvoid = [] {};
using impl = detail::default_behavior_impl<match_expr, decltype(lvoid)>; using impl = detail::default_behavior_impl<match_expr, decltype(lvoid)>;
return new impl(*this, util::duration{}, lvoid); return new impl(*this, util::duration{}, lvoid);
} }
...@@ -794,16 +597,16 @@ class match_expr { ...@@ -794,16 +597,16 @@ class match_expr {
private: private:
// structure: tdata< tdata<type_list<...>, ...>, // structure: std::tuple< std::tuple<type_list<...>, ...>,
// tdata<type_list<...>, ...>, // std::tuple<type_list<...>, ...>,
// ...> // ...>
detail::tdata<Cs...> m_cases; std::tuple<Cs...> m_cases;
static constexpr size_t cache_size = 10; static constexpr size_t cache_size = 10;
typedef std::pair<const std::type_info*, std::uint64_t> cache_element; typedef std::pair<const std::type_info*, uint64_t> cache_element;
util::limited_vector<cache_element, cache_size> m_cache; std::vector<cache_element> m_cache;
// ring buffer like access to m_cache // ring buffer like access to m_cache
size_t m_cache_begin; size_t m_cache_begin;
...@@ -811,19 +614,17 @@ class match_expr { ...@@ -811,19 +614,17 @@ class match_expr {
cache_element m_dummy; cache_element m_dummy;
static inline void advance_(size_t& i) { static inline void advance_(size_t& i) { i = (i + 1) % cache_size; }
i = (i + 1) % cache_size;
}
inline size_t find_token_pos(const std::type_info* type_token) { inline size_t find_token_pos(const std::type_info* type_token) {
for (size_t i = m_cache_begin ; i != m_cache_end; advance_(i)) { for (size_t i = m_cache_begin; i != m_cache_end; advance_(i)) {
if (m_cache[i].first == type_token) return i; if (m_cache[i].first == type_token) return i;
} }
return m_cache_end; return m_cache_end;
} }
template<class Tuple> template<class Tuple>
std::uint64_t get_cache_entry(const std::type_info* type_token, uint64_t get_cache_entry(const std::type_info* type_token,
const Tuple& value) { const Tuple& value) {
CPPA_REQUIRE(type_token != nullptr); CPPA_REQUIRE(type_token != nullptr);
if (value.dynamically_typed()) { if (value.dynamically_typed()) {
...@@ -836,18 +637,18 @@ class match_expr { ...@@ -836,18 +637,18 @@ class match_expr {
advance_(m_cache_end); advance_(m_cache_end);
if (m_cache_end == m_cache_begin) advance_(m_cache_begin); if (m_cache_end == m_cache_begin) advance_(m_cache_begin);
m_cache[i].first = type_token; m_cache[i].first = type_token;
m_cache[i].second = calc_bitmask(m_cases, m_cache[i].second =
idx_token, calc_bitmask(m_cases, idx_token, *type_token, value);
*type_token,
value);
} }
return m_cache[i].second; return m_cache[i].second;
} }
void init() { void init() {
m_dummy.second = std::numeric_limits<std::uint64_t>::max(); m_dummy.second = std::numeric_limits<uint64_t>::max();
m_cache.resize(cache_size); m_cache.resize(cache_size);
for (auto& entry : m_cache) { entry.first = nullptr; } for (auto& entry : m_cache) {
entry.first = nullptr;
}
m_cache_begin = m_cache_end = 0; m_cache_begin = m_cache_end = 0;
} }
...@@ -857,13 +658,9 @@ class match_expr { ...@@ -857,13 +658,9 @@ class match_expr {
detail::tuple_dummy td; detail::tuple_dummy td;
auto td_token_ptr = td.type_token(); auto td_token_ptr = td.type_token();
auto td_bitmask = get_cache_entry(td_token_ptr, td); auto td_bitmask = get_cache_entry(td_token_ptr, td);
return detail::unroll_expr<result_type>(m_cases, return detail::unroll_expr<result_type>(
td_bitmask, m_cases, td_bitmask, idx_token, *td_token_ptr, false,
idx_token, static_cast<void*>(nullptr), td);
*td_token_ptr,
false,
static_cast<void*>(nullptr),
td);
} }
std::integral_constant<bool, has_manipulator> mutator_token; std::integral_constant<bool, has_manipulator> mutator_token;
// returns either a reference or a new object // returns either a reference or a new object
...@@ -874,13 +671,9 @@ class match_expr { ...@@ -874,13 +671,9 @@ class match_expr {
auto token_ptr = vals->type_token(); auto token_ptr = vals->type_token();
auto bitmask = get_cache_entry(token_ptr, *vals); auto bitmask = get_cache_entry(token_ptr, *vals);
auto dynamically_typed = vals->dynamically_typed(); auto dynamically_typed = vals->dynamically_typed();
return detail::unroll_expr<result_type>(m_cases, return detail::unroll_expr<result_type>(m_cases, bitmask, idx_token,
bitmask, *token_ptr, dynamically_typed,
idx_token, ndp, *vals);
*token_ptr,
dynamically_typed,
ndp,
*vals);
} }
}; };
...@@ -895,16 +688,8 @@ struct is_match_expr<match_expr<Cs...>> { ...@@ -895,16 +688,8 @@ struct is_match_expr<match_expr<Cs...>> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<class List>
struct match_expr_from_type_list;
template<typename... Ts>
struct match_expr_from_type_list<util::type_list<Ts...> > {
typedef match_expr<Ts...> type;
};
template<typename... Lhs, typename... Rhs> template<typename... Lhs, typename... Rhs>
inline match_expr<Lhs..., Rhs...> operator,(const match_expr<Lhs...>& lhs, inline match_expr<Lhs..., Rhs...> operator, (const match_expr<Lhs...>& lhs,
const match_expr<Rhs...>& rhs) { const match_expr<Rhs...>& rhs) {
return lhs.or_else(rhs); return lhs.or_else(rhs);
} }
...@@ -925,158 +710,88 @@ const match_expr<Cs...>& match_expr_collect(const match_expr<Cs...>& arg) { ...@@ -925,158 +710,88 @@ const match_expr<Cs...>& match_expr_collect(const match_expr<Cs...>& arg) {
} }
template<typename T, typename... Ts> template<typename T, typename... Ts>
typename match_expr_from_type_list< typename util::tl_apply<
typename util::tl_concat< typename util::tl_concat<typename T::cases_list,
typename T::cases_list, typename Ts::cases_list...>::type,
typename Ts::cases_list... match_expr>::type
>::type
>::type
match_expr_collect(const T& arg, const Ts&... args) { match_expr_collect(const T& arg, const Ts&... args) {
typename detail::tdata_from_type_list< return {std::tuple_cat(arg.cases(), args.cases()...)};
typename util::tl_map<
typename util::tl_concat<
typename T::cases_list,
typename Ts::cases_list...
>::type,
gref_wrapped
>::type
>::type
all_cases;
detail::rebind_tdata(all_cases, arg.cases(), args.cases()...);
return {all_cases};
} }
namespace detail { namespace detail {
//typedef std::true_type with_timeout; // implemented in message_handler.cpp
//typedef std::false_type without_timeout; message_handler combine(behavior_impl_ptr, behavior_impl_ptr);
behavior_impl_ptr extract(const message_handler&);
// end of recursion template<typename... Cs>
template<class Data, class Token> behavior_impl_ptr extract(const match_expr<Cs...>& arg) {
behavior_impl_ptr concat_rec(const Data& data, Token) { return arg.as_behavior_impl();
typedef typename match_expr_from_type_list<Token>::type combined_type;
auto lvoid = [] { };
typedef default_behavior_impl<combined_type, decltype(lvoid)> impl_type;
return new impl_type(data, util::duration{}, lvoid);
} }
// end of recursion with nothing but a partial function template<typename... As, typename... Bs>
inline behavior_impl_ptr concat_rec(const tdata<>&, match_expr<As..., Bs...> combine(const match_expr<As...>& lhs,
util::empty_type_list, const match_expr<Bs...>& rhs) {
const partial_function& pfun) { return lhs.or_else(rhs);
return extract(pfun);
} }
// end of recursion with timeout // forwards match_expr as match_expr as long as combining two match_expr,
template<class Data, class Token, typename F> // otherwise turns everything into behavior_impl_ptr
behavior_impl_ptr concat_rec(const Data& data, template<typename... As, typename... Bs>
Token, const match_expr<As...>& combine_fwd(const match_expr<As...>& lhs,
const timeout_definition<F>& arg) { const match_expr<Bs...>&) {
typedef typename match_expr_from_type_list<Token>::type combined_type; return lhs;
return new default_behavior_impl<combined_type, F>{data, arg};
} }
// recursive concatenation function template<typename T, typename U>
template<class Data, class Token, typename T, typename... Ts> behavior_impl_ptr combine_fwd(T& lhs, U&) {
behavior_impl_ptr concat_rec(const Data& data, return extract(lhs);
Token,
const T& arg,
const Ts&... args) {
typedef typename util::tl_concat<
Token,
typename T::cases_list
>::type
next_token_type;
typename tdata_from_type_list<
typename util::tl_map<
next_token_type,
gref_wrapped
>::type
>::type
next_data;
next_token_type next_token;
rebind_tdata(next_data, data, arg.cases());
return concat_rec(next_data, next_token, args...);
} }
// handle partial functions at end of recursion template<typename T>
template<class Data, class Token> behavior_impl_ptr match_expr_concat(const T& arg) {
behavior_impl_ptr concat_rec(const Data& data, return arg.as_behavior_impl();
Token token,
const partial_function& pfun) {
return combine(concat_rec(data, token), pfun);
} }
// handle partial functions in between template<typename F>
template<class Data, class Token, typename T, typename... Ts> behavior_impl_ptr match_expr_concat(const message_handler& arg0,
behavior_impl_ptr concat_rec(const Data& data, const timeout_definition<F>& arg) {
Token token, return extract(arg0)->copy(arg);
const partial_function& pfun,
const T& arg,
const Ts&... args) {
auto lhs = concat_rec(data, token);
detail::tdata<> dummy;
auto rhs = concat_rec(dummy, util::empty_type_list{}, arg, args...);
return combine(lhs, pfun)->or_else(rhs);
} }
// handle partial functions at recursion start template<typename... Cs, typename F>
template<typename T, typename... Ts> behavior_impl_ptr match_expr_concat(const match_expr<Cs...>& arg0,
behavior_impl_ptr concat_rec(const tdata<>& data, const timeout_definition<F>& arg) {
util::empty_type_list token, return new default_behavior_impl<match_expr<Cs...>, F>{arg0, arg};
const partial_function& pfun,
const T& arg,
const Ts&... args) {
return combine(pfun, concat_rec(data, token, arg, args...));
} }
template<typename T0, typename T1, typename... Ts> template<typename T0, typename T1, typename... Ts>
behavior_impl_ptr match_expr_concat(const T0& arg0, behavior_impl_ptr match_expr_concat(const T0& arg0, const T1& arg1,
const T1& arg1,
const Ts&... args) { const Ts&... args) {
detail::tdata<> dummy; return match_expr_concat(
return concat_rec(dummy, util::empty_type_list{}, arg0, arg1, args...); combine(combine_fwd(arg0, arg1), combine_fwd(arg1, arg0)), args...);
}
template<typename T>
behavior_impl_ptr match_expr_concat(const T& arg) {
return arg.as_behavior_impl();
} }
// some more convenience functions // some more convenience functions
template<typename F, template<typename F, class E = typename std::enable_if<
class E = typename std::enable_if<util::is_callable<F>::value>::type> util::is_callable<F>::value>::type>
match_expr< match_expr<typename get_case<false, F, util::empty_type_list,
typename get_case< util::empty_type_list>::type>
false,
F,
empty_value_guard,
util::empty_type_list,
util::empty_type_list
>::type>
lift_to_match_expr(F fun) { lift_to_match_expr(F fun) {
typedef typename get_case< typedef typename get_case<false, F, util::empty_type_list,
false, util::empty_type_list>::type result_type;
F, return result_type{std::move(fun)};
empty_value_guard,
util::empty_type_list,
util::empty_type_list
>::type
result_type;
return result_type{typename result_type::first_type{},
typename result_type::second_type{
std::move(fun),
empty_value_guard{}}};
} }
template<typename T, template<typename T, class E = typename std::enable_if<
class E = typename std::enable_if<!util::is_callable<T>::value>::type> !util::is_callable<T>::value>::type>
inline T lift_to_match_expr(T arg) { inline T lift_to_match_expr(T arg) {
return arg; return arg;
} }
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
#endif // CPPA_MATCH_EXPR_HPP #endif // CPPA_MATCH_EXPR_HPP
...@@ -16,92 +16,73 @@ ...@@ -16,92 +16,73 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_ANY_TUPLE_HPP #ifndef CPPA_ANY_TUPLE_HPP
#define CPPA_ANY_TUPLE_HPP #define CPPA_ANY_TUPLE_HPP
#include <type_traits> #include <type_traits>
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/util/int_list.hpp"
#include "cppa/util/comparable.hpp" #include "cppa/util/comparable.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/detail/tuple_view.hpp" #include "cppa/detail/apply_args.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/container_tuple_view.hpp" #include "cppa/detail/message_data.hpp"
#include "cppa/detail/implicit_conversions.hpp" #include "cppa/detail/implicit_conversions.hpp"
namespace cppa { namespace cppa {
class message_handler;
/** /**
* @brief Describes a fixed-length copy-on-write tuple * @brief Describes a fixed-length copy-on-write tuple
* with elements of any type. * with elements of any type.
*/ */
class any_tuple { class message {
public: public:
/** /**
* @brief A raw pointer to the data. * @brief A raw pointer to the data.
*/ */
typedef detail::abstract_tuple* raw_ptr; using raw_ptr = detail::message_data*;
/** /**
* @brief A smart pointer to the data. * @brief A (COW) smart pointer to the data.
*/ */
typedef cow_ptr<detail::abstract_tuple> data_ptr; using data_ptr = detail::message_data::ptr;
/** /**
* @brief An iterator to access each element as <tt>const void*</tt>. * @brief An iterator to access each element as <tt>const void*</tt>.
*/ */
typedef detail::abstract_tuple::const_iterator const_iterator; using const_iterator = detail::message_data::const_iterator;
/** /**
* @brief Creates an empty tuple. * @brief Creates an empty tuple.
*/ */
any_tuple() = default; message() = default;
/**
* @brief Creates a tuple from @p t.
*/
template<typename... Ts>
any_tuple(const cow_tuple<Ts...>& arg) : m_vals(arg.vals()) { }
/**
* @brief Creates a tuple and moves the content from @p t.
*/
template<typename... Ts>
any_tuple(cow_tuple<Ts...>&& arg) : m_vals(std::move(arg.m_vals)) { }
/**
* @brief Creates a tuple from a set of values.
*/
template<typename T, typename... Ts>
explicit any_tuple(T v0, Ts&&... vs)
: m_vals(make_cow_tuple(std::move(v0), std::forward<Ts>(vs)...).vals()) { }
/** /**
* @brief Move constructor. * @brief Move constructor.
*/ */
any_tuple(any_tuple&&); message(message&&);
/** /**
* @brief Copy constructor. * @brief Copy constructor.
*/ */
any_tuple(const any_tuple&) = default; message(const message&) = default;
/** /**
* @brief Move assignment. * @brief Move assignment.
*/ */
any_tuple& operator=(any_tuple&&); message& operator=(message&&);
/** /**
* @brief Copy assignment. * @brief Copy assignment.
*/ */
any_tuple& operator=(const any_tuple&) = default; message& operator=(const message&) = default;
/** /**
* @brief Gets the size of this tuple. * @brief Gets the size of this tuple.
...@@ -111,22 +92,22 @@ class any_tuple { ...@@ -111,22 +92,22 @@ class any_tuple {
/** /**
* @brief Creates a new tuple with all but the first n values. * @brief Creates a new tuple with all but the first n values.
*/ */
any_tuple drop(size_t n) const; message drop(size_t n) const;
/** /**
* @brief Creates a new tuple with all but the last n values. * @brief Creates a new tuple with all but the last n values.
*/ */
any_tuple drop_right(size_t n) const; message drop_right(size_t n) const;
/** /**
* @brief Creates a new tuple from the first n values. * @brief Creates a new tuple from the first n values.
*/ */
inline any_tuple take(size_t n) const; inline message take(size_t n) const;
/** /**
* @brief Creates a new tuple from the last n values. * @brief Creates a new tuple from the last n values.
*/ */
inline any_tuple take_right(size_t n) const; inline message take_right(size_t n) const;
/** /**
* @brief Gets a mutable pointer to the element at position @p p. * @brief Gets a mutable pointer to the element at position @p p.
...@@ -144,10 +125,16 @@ class any_tuple { ...@@ -144,10 +125,16 @@ class any_tuple {
*/ */
const uniform_type_info* type_at(size_t p) const; const uniform_type_info* type_at(size_t p) const;
/**
* @brief Returns true if this message has the types @p Ts.
*/
template<typename... Ts>
bool has_types() const;
/** /**
* @brief Returns @c true if <tt>*this == other</tt>, otherwise false. * @brief Returns @c true if <tt>*this == other</tt>, otherwise false.
*/ */
bool equals(const any_tuple& other) const; bool equals(const message& other) const;
/** /**
* @brief Returns true if <tt>size() == 0</tt>, otherwise false. * @brief Returns true if <tt>size() == 0</tt>, otherwise false.
...@@ -192,7 +179,7 @@ class any_tuple { ...@@ -192,7 +179,7 @@ class any_tuple {
inline const data_ptr& cvals() const; inline const data_ptr& cvals() const;
/** /**
* @brief Returns either <tt>&typeid(util::type_list<Ts...>)</tt>, where * @brief Returns either <tt>&typeid(detail::type_list<Ts...>)</tt>, where
* <tt>Ts...</tt> are the element types, or <tt>&typeid(void)</tt>. * <tt>Ts...</tt> are the element types, or <tt>&typeid(void)</tt>.
* *
* The type token @p &typeid(void) indicates that this tuple is dynamically * The type token @p &typeid(void) indicates that this tuple is dynamically
...@@ -208,221 +195,143 @@ class any_tuple { ...@@ -208,221 +195,143 @@ class any_tuple {
/** @cond PRIVATE */ /** @cond PRIVATE */
template<typename T>
static inline any_tuple view(T&& value);
inline void force_detach(); inline void force_detach();
void reset(); void reset();
explicit any_tuple(raw_ptr); explicit message(raw_ptr);
inline const std::string* tuple_type_names() const; inline const std::string* tuple_type_names() const;
/** @endcond */ explicit message(const data_ptr& vals);
private:
data_ptr m_vals;
explicit any_tuple(const data_ptr& vals); template<typename... Ts>
static inline message move_from_tuple(std::tuple<Ts...>&&);
template<typename T, typename CanOptimize>
static any_tuple view(T&& value, std::true_type, CanOptimize token);
template<typename T, typename CanOptimize>
static any_tuple view(T&& value, std::false_type, CanOptimize token);
template<typename T, typename U>
static any_tuple view(std::pair<T, U> p, std::false_type);
template<typename T> /**
static auto simple_view(T& value, std::true_type) -> raw_ptr; * @brief Applies @p handler to this message and returns the result
* of <tt>handler(*this)</tt>.
*/
optional<message> apply(message_handler handler);
template<typename T, typename U> bool apply_iterative(message_handler handler);
static auto simple_view(std::pair<T, U>& p, std::true_type) -> raw_ptr;
template<typename T> /** @endcond */
static auto simple_view(T&& value, std::false_type) -> raw_ptr;
template<typename T> private:
static auto container_view(T& value, std::true_type) -> raw_ptr;
template<typename T> data_ptr m_vals;
static auto container_view(T&& value, std::false_type) -> raw_ptr;
}; };
/** /**
* @relates any_tuple * @relates message
*/ */
inline bool operator==(const any_tuple& lhs, const any_tuple& rhs) { inline bool operator==(const message& lhs, const message& rhs) {
return lhs.equals(rhs); return lhs.equals(rhs);
} }
/** /**
* @relates any_tuple * @relates message
*/ */
inline bool operator!=(const any_tuple& lhs, const any_tuple& rhs) { inline bool operator!=(const message& lhs, const message& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
/** /**
* @brief Creates an {@link any_tuple} containing the elements @p args. * @brief Creates an {@link message} containing the elements @p args.
* @param args Values to initialize the tuple elements. * @param args Values to initialize the tuple elements.
*/ */
template<typename... Ts> template<typename T, typename... Ts>
inline any_tuple make_any_tuple(Ts&&... args) { typename std::enable_if<
return make_cow_tuple(std::forward<Ts>(args)...); !std::is_same<message, typename util::rm_const_and_ref<T>::type>::value ||
(sizeof...(Ts) > 0),
message>::type
make_message(T&& arg, Ts&&... args) {
using namespace detail;
typedef tuple_vals<typename strip_and_convert<T>::type,
typename strip_and_convert<Ts>::type...> data;
auto ptr = new data(std::forward<T>(arg), std::forward<Ts>(args)...);
return message{detail::message_data::ptr{ptr}};
} }
inline message make_message(message other) { return std::move(other); }
/****************************************************************************** /******************************************************************************
* inline and template member function implementations * * inline and template member function implementations *
******************************************************************************/ ******************************************************************************/
inline bool any_tuple::empty() const { inline bool message::empty() const { return size() == 0; }
return size() == 0;
}
template<typename T> template<typename T>
inline const T& any_tuple::get_as(size_t p) const { inline const T& message::get_as(size_t p) const {
CPPA_REQUIRE(*(type_at(p)) == typeid(T)); CPPA_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<const T*>(at(p)); return *reinterpret_cast<const T*>(at(p));
} }
template<typename T> template<typename T>
inline T& any_tuple::get_as_mutable(size_t p) { inline T& message::get_as_mutable(size_t p) {
CPPA_REQUIRE(*(type_at(p)) == typeid(T)); CPPA_REQUIRE(*(type_at(p)) == typeid(T));
return *reinterpret_cast<T*>(mutable_at(p)); return *reinterpret_cast<T*>(mutable_at(p));
} }
inline any_tuple::const_iterator any_tuple::begin() const { inline message::const_iterator message::begin() const {
return m_vals->begin(); return m_vals->begin();
} }
inline any_tuple::const_iterator any_tuple::end() const { inline message::const_iterator message::end() const { return m_vals->end(); }
return m_vals->end();
}
inline any_tuple::data_ptr& any_tuple::vals() { inline message::data_ptr& message::vals() { return m_vals; }
return m_vals;
}
inline const any_tuple::data_ptr& any_tuple::vals() const { inline const message::data_ptr& message::vals() const { return m_vals; }
return m_vals;
}
inline const any_tuple::data_ptr& any_tuple::cvals() const { inline const message::data_ptr& message::cvals() const { return m_vals; }
return m_vals;
}
inline const std::type_info* any_tuple::type_token() const { inline const std::type_info* message::type_token() const {
return m_vals->type_token(); return m_vals->type_token();
} }
inline bool any_tuple::dynamically_typed() const { inline bool message::dynamically_typed() const {
return m_vals->dynamically_typed(); return m_vals->dynamically_typed();
} }
inline void any_tuple::force_detach() { inline void message::force_detach() { m_vals.detach(); }
m_vals.detach();
}
inline const std::string* any_tuple::tuple_type_names() const { inline const std::string* message::tuple_type_names() const {
return m_vals->tuple_type_names(); return m_vals->tuple_type_names();
} }
inline size_t message::size() const { return m_vals ? m_vals->size() : 0; }
inline size_t any_tuple::size() const { inline message message::take(size_t n) const {
return m_vals ? m_vals->size() : 0;
}
inline any_tuple any_tuple::take(size_t n) const {
return n >= size() ? *this : drop_right(size() - n); return n >= size() ? *this : drop_right(size() - n);
} }
inline any_tuple any_tuple::take_right(size_t n) const { inline message message::take_right(size_t n) const {
return n >= size() ? *this : drop(size() - n); return n >= size() ? *this : drop(size() - n);
} }
template<typename T, bool IsIterable = true> struct move_from_tuple_helper {
struct any_tuple_view_trait_impl { template<typename... Ts>
static constexpr bool is_mutable_ref = std::is_reference<T>::value inline message operator()(Ts&... vs) {
&& !std::is_const<T>::value; return make_message(std::move(vs)...);
typedef std::integral_constant<bool, is_mutable_ref> can_optimize; }
typedef std::integral_constant<bool, true> is_container;
};
template<typename T>
struct any_tuple_view_trait_impl<T, false> {
typedef typename util::rm_const_and_ref<T>::type type;
typedef typename detail::implicit_conversions<type>::type mapped;
static_assert(util::is_legal_tuple_type<mapped>::value,
"T is not a valid tuple type");
static constexpr bool is_mutable_ref = std::is_same<mapped, type>::value
&& std::is_reference<T>::value
&& not std::is_const<T>::value;
typedef std::integral_constant<bool, is_mutable_ref> can_optimize;
typedef std::integral_constant<bool, false> is_container;
};
template<typename T>
struct any_tuple_view_trait {
typedef typename util::rm_const_and_ref<T>::type type;
typedef any_tuple_view_trait_impl<T, util::is_iterable<type>::value> impl;
typedef typename impl::can_optimize can_optimize;
typedef typename impl::is_container is_container;
}; };
template<typename T> template<typename... Ts>
inline any_tuple any_tuple::view(T&& value) { inline message message::move_from_tuple(std::tuple<Ts...>&& tup) {
typedef any_tuple_view_trait<T> trait; move_from_tuple_helper f;
typename trait::can_optimize can_optimize; return detail::apply_args(f, util::get_indices(tup), tup);
typename trait::is_container is_container;
return view(std::forward<T>(value), is_container, can_optimize);
}
template<typename T, typename CanOptimize>
any_tuple any_tuple::view(T&& v, std::true_type, CanOptimize t) {
return any_tuple{container_view(std::forward<T>(v), t)};
}
template<typename T, typename CanOptimize>
any_tuple any_tuple::view(T&& v, std::false_type, CanOptimize t) {
return any_tuple{simple_view(std::forward<T>(v), t)};
}
template<typename T>
auto any_tuple::simple_view(T& v, std::true_type) -> raw_ptr {
return new detail::tuple_view<T>(&v);
}
template<typename T, typename U>
auto any_tuple::simple_view(std::pair<T, U>& p, std::true_type) -> raw_ptr {
return new detail::tuple_view<T, U>(&p.first, &p.second);
}
template<typename T>
auto any_tuple::simple_view(T&& v, std::false_type) -> raw_ptr {
typedef typename util::rm_const_and_ref<T>::type vtype;
typedef typename detail::implicit_conversions<vtype>::type converted;
return new detail::tuple_vals<converted>(std::forward<T>(v));
}
template<typename T, typename U>
any_tuple any_tuple::view(std::pair<T, U> p, std::false_type) {
return new detail::tuple_vals<T, U>(std::move(p.first), std::move(p.second));
}
template<typename T>
auto any_tuple::container_view(T& v, std::true_type) -> raw_ptr {
return new detail::container_tuple_view<T>(&v);
} }
template<typename T> template<typename... Ts>
auto any_tuple::container_view(T&& v, std::false_type) -> raw_ptr { bool message::has_types() const {
auto vptr = new typename util::rm_const_and_ref<T>::type(std::forward<T>(v)); if (size() != sizeof...(Ts)) return false;
return new detail::container_tuple_view<T>(vptr, true); const std::type_info* ts[] = {&typeid(Ts)...};
for (size_t i = 0; i < sizeof...(Ts); ++i) {
if (!type_at(i)->equal_to(*ts[i])) return false;
}
return true;
} }
} // namespace cppa } // namespace cppa
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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_MESSAGE_BUILDER_HPP
#define CPPA_MESSAGE_BUILDER_HPP
#include <vector>
#include "cppa/message.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/message_data.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
class message_builder {
public:
message_builder() = default;
message_builder(const message_builder&) = delete;
message_builder& operator=(const message_builder&) = delete;
template<typename Iter>
message_builder(Iter first, Iter last) {
append(first, last);
}
template<typename T>
message_builder& append(T what) {
return append_impl<T>(std::move(what));
}
template<typename Iter>
message_builder& append(Iter first, Iter last) {
using vtype = typename util::rm_const_and_ref<decltype(*first)>::type;
using converted = typename detail::implicit_conversions<vtype>::type;
auto uti = uniform_typeid<converted>();
for (; first != last; ++first) {
auto uval = uti->create();
*reinterpret_cast<converted*>(uval->val) = *first;
append(std::move(uval));
}
return *this;
}
message_builder& append(uniform_value what);
message to_message();
optional<message> apply(message_handler handler);
private:
template<typename T>
message_builder&
append_impl(typename detail::implicit_conversions<T>::type what) {
typedef decltype(what) type;
auto uti = uniform_typeid<type>();
auto uval = uti->create();
*reinterpret_cast<type*>(uval->val) = std::move(what);
return append(std::move(uval));
}
std::vector<uniform_value> m_elements;
};
} // namespace cppa
#endif // CPPA_MESSAGE_BUILDER_HPP
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/may_have_timeout.hpp" #include "cppa/may_have_timeout.hpp"
...@@ -44,9 +44,9 @@ class behavior; ...@@ -44,9 +44,9 @@ class behavior;
/** /**
* @brief A partial function implementation * @brief A partial function implementation
* for {@link cppa::any_tuple any_tuples}. * for {@link cppa::message messages}.
*/ */
class partial_function { class message_handler {
friend class behavior; friend class behavior;
...@@ -58,24 +58,18 @@ class partial_function { ...@@ -58,24 +58,18 @@ class partial_function {
inline auto as_behavior_impl() const -> impl_ptr; inline auto as_behavior_impl() const -> impl_ptr;
partial_function(impl_ptr ptr); message_handler(impl_ptr ptr);
/** @endcond */ /** @endcond */
partial_function() = default; message_handler() = default;
partial_function(partial_function&&) = default; message_handler(message_handler&&) = default;
partial_function(const partial_function&) = default; message_handler(const message_handler&) = default;
partial_function& operator=(partial_function&&) = default; message_handler& operator=(message_handler&&) = default;
partial_function& operator=(const partial_function&) = default; message_handler& operator=(const message_handler&) = default;
template<typename T, typename... Ts> template<typename T, typename... Ts>
partial_function(const T& arg, Ts&&... args); message_handler(const T& arg, Ts&&... args);
/**
* @brief Returns @p true if this partial function is defined for the
* types of @p value, false otherwise.
*/
inline bool defined_at(const any_tuple& value);
/** /**
* @brief Returns a value if @p arg was matched by one of the * @brief Returns a value if @p arg was matched by one of the
...@@ -85,7 +79,7 @@ class partial_function { ...@@ -85,7 +79,7 @@ class partial_function {
* does not evaluate guards. * does not evaluate guards.
*/ */
template<typename T> template<typename T>
inline optional<any_tuple> operator()(T&& arg); inline optional<message> operator()(T&& arg);
/** /**
* @brief Adds a fallback which is used where * @brief Adds a fallback which is used where
...@@ -97,7 +91,7 @@ class partial_function { ...@@ -97,7 +91,7 @@ class partial_function {
may_have_timeout<typename util::rm_const_and_ref<Ts>::type>::value... may_have_timeout<typename util::rm_const_and_ref<Ts>::type>::value...
>::value, >::value,
behavior, behavior,
partial_function message_handler
>::type >::type
or_else(Ts&&... args) const; or_else(Ts&&... args) const;
...@@ -108,13 +102,13 @@ class partial_function { ...@@ -108,13 +102,13 @@ class partial_function {
}; };
template<typename... Cases> template<typename... Cases>
partial_function operator,(const match_expr<Cases...>& mexpr, message_handler operator,(const match_expr<Cases...>& mexpr,
const partial_function& pfun) { const message_handler& pfun) {
return mexpr.as_behavior_impl()->or_else(pfun.as_behavior_impl()); return mexpr.as_behavior_impl()->or_else(pfun.as_behavior_impl());
} }
template<typename... Cases> template<typename... Cases>
partial_function operator,(const partial_function& pfun, message_handler operator,(const message_handler& pfun,
const match_expr<Cases...>& mexpr) { const match_expr<Cases...>& mexpr) {
return pfun.as_behavior_impl()->or_else(mexpr.as_behavior_impl()); return pfun.as_behavior_impl()->or_else(mexpr.as_behavior_impl());
} }
...@@ -124,17 +118,13 @@ partial_function operator,(const partial_function& pfun, ...@@ -124,17 +118,13 @@ partial_function operator,(const partial_function& pfun,
******************************************************************************/ ******************************************************************************/
template<typename T, typename... Ts> template<typename T, typename... Ts>
partial_function::partial_function(const T& arg, Ts&&... args) message_handler::message_handler(const T& arg, Ts&&... args)
: m_impl(detail::match_expr_concat( : m_impl(detail::match_expr_concat(
detail::lift_to_match_expr(arg), detail::lift_to_match_expr(arg),
detail::lift_to_match_expr(std::forward<Ts>(args))...)) { } detail::lift_to_match_expr(std::forward<Ts>(args))...)) { }
inline bool partial_function::defined_at(const any_tuple& value) {
return (m_impl) && m_impl->defined_at(value);
}
template<typename T> template<typename T>
inline optional<any_tuple> partial_function::operator()(T&& arg) { inline optional<message> message_handler::operator()(T&& arg) {
return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none; return (m_impl) ? m_impl->invoke(std::forward<T>(arg)) : none;
} }
...@@ -144,16 +134,16 @@ typename std::conditional< ...@@ -144,16 +134,16 @@ typename std::conditional<
may_have_timeout<typename util::rm_const_and_ref<Ts>::type>::value... may_have_timeout<typename util::rm_const_and_ref<Ts>::type>::value...
>::value, >::value,
behavior, behavior,
partial_function message_handler
>::type >::type
partial_function::or_else(Ts&&... args) const { message_handler::or_else(Ts&&... args) const {
// using a behavior is safe here, because we "cast" // using a behavior is safe here, because we "cast"
// it back to a partial_function when appropriate // it back to a partial_function when appropriate
behavior tmp{std::forward<Ts>(args)...}; behavior tmp{std::forward<Ts>(args)...};
return m_impl->or_else(tmp.as_behavior_impl()); return m_impl->or_else(tmp.as_behavior_impl());
} }
inline auto partial_function::as_behavior_impl() const -> impl_ptr { inline auto message_handler::as_behavior_impl() const -> impl_ptr {
return m_impl; return m_impl;
} }
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
namespace cppa { namespace cppa {
class any_tuple; class message;
/** /**
* @brief Encapsulates information about sender, receiver and (synchronous) * @brief Encapsulates information about sender, receiver and (synchronous)
* message ID of a message. The message itself is usually an any_tuple. * message ID of a message. The message itself is usually an message.
*/ */
class message_header { class message_header {
...@@ -54,7 +54,7 @@ class message_header { ...@@ -54,7 +54,7 @@ class message_header {
channel dest, channel dest,
message_id mid = message_id::invalid); message_id mid = message_id::invalid);
void deliver(any_tuple msg) const; void deliver(message msg) const;
}; };
......
...@@ -16,20 +16,18 @@ ...@@ -16,20 +16,18 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#ifndef CPPA_ON_HPP #ifndef CPPA_ON_HPP
#define CPPA_ON_HPP #define CPPA_ON_HPP
#include <chrono> #include <chrono>
#include <memory> #include <memory>
#include <functional>
#include <type_traits> #include <type_traits>
#include "cppa/unit.hpp" #include "cppa/unit.hpp"
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
#include "cppa/arg_match.hpp" #include "cppa/message.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/guard_expr.hpp"
#include "cppa/match_expr.hpp" #include "cppa/match_expr.hpp"
#include "cppa/skip_message.hpp" #include "cppa/skip_message.hpp"
#include "cppa/may_have_timeout.hpp" #include "cppa/may_have_timeout.hpp"
...@@ -41,40 +39,50 @@ ...@@ -41,40 +39,50 @@
#include "cppa/detail/boxed.hpp" #include "cppa/detail/boxed.hpp"
#include "cppa/detail/unboxed.hpp" #include "cppa/detail/unboxed.hpp"
#include "cppa/detail/value_guard.hpp" #include "cppa/detail/arg_match_t.hpp"
#include "cppa/detail/implicit_conversions.hpp" #include "cppa/detail/implicit_conversions.hpp"
namespace cppa { namespace cppa {
namespace detail { namespace detail {
template<bool IsFun, typename T> template<bool IsFun, typename T>
struct add_ptr_to_fun_ { typedef T* type; }; struct add_ptr_to_fun_ {
typedef T* type;
};
template<typename T> template<typename T>
struct add_ptr_to_fun_<false, T> { typedef T type; }; struct add_ptr_to_fun_<false, T> {
typedef T type;
};
template<typename T> template<typename T>
struct add_ptr_to_fun : add_ptr_to_fun_<std::is_function<T>::value, T> { }; struct add_ptr_to_fun : add_ptr_to_fun_<std::is_function<T>::value, T> {};
template<bool ToVoid, typename T> template<bool ToVoid, typename T>
struct to_void_impl { typedef unit_t type; }; struct to_void_impl {
typedef unit_t type;
};
template<typename T> template<typename T>
struct to_void_impl<false, T> { typedef typename add_ptr_to_fun<T>::type type; }; struct to_void_impl<false, T> {
typedef typename add_ptr_to_fun<T>::type type;
};
template<typename T>
struct boxed_to_void : to_void_impl<is_boxed<T>::value, T> {};
template<typename T> template<typename T>
struct boxed_and_not_callable_to_void struct boxed_to_void<std::function<
: to_void_impl<is_boxed<T>::value || !util::is_callable<T>::value, T> { }; optional<T>(const T&)>> : to_void_impl<is_boxed<T>::value, T> {};
template<typename T> template<typename T>
struct boxed_and_callable_to_void struct boxed_and_callable_to_void
: to_void_impl<is_boxed<T>::value || util::is_callable<T>::value, T> { }; : to_void_impl<is_boxed<T>::value || util::is_callable<T>::value, T> {};
class behavior_rvalue_builder { class behavior_rvalue_builder {
public: public:
constexpr behavior_rvalue_builder(const util::duration& d) : m_tout(d) {}
constexpr behavior_rvalue_builder(const util::duration& d) : m_tout(d) { }
template<typename F> template<typename F>
timeout_definition<F> operator>>(F&& f) const { timeout_definition<F> operator>>(F&& f) const {
...@@ -82,115 +90,97 @@ class behavior_rvalue_builder { ...@@ -82,115 +90,97 @@ class behavior_rvalue_builder {
} }
private: private:
util::duration m_tout; util::duration m_tout;
}; };
struct rvalue_builder_args_ctor { }; struct rvalue_builder_args_ctor {};
template<class Left, class Right> template<class Left, class Right>
struct disjunct_rvalue_builders { struct disjunct_rvalue_builders {
public: public:
disjunct_rvalue_builders(Left l, Right r) disjunct_rvalue_builders(Left l, Right r)
: m_left(std::move(l)), m_right(std::move(r)) { } : m_left(std::move(l)), m_right(std::move(r)) {}
template<typename Expr> template<typename Expr>
auto operator>>(Expr expr) auto operator>>(Expr expr)
-> decltype((*(static_cast<Left*>(nullptr)) >> expr).or_else( -> decltype((*(static_cast<Left*>(nullptr)) >> expr)
*(static_cast<Right*>(nullptr)) >> expr)) const { .or_else(*(static_cast<Right*>(nullptr)) >>
expr)) const {
return (m_left >> expr).or_else(m_right >> expr); return (m_left >> expr).or_else(m_right >> expr);
} }
private: private:
Left m_left; Left m_left;
Right m_right; Right m_right;
};
struct tuple_maker {
template<typename... Ts>
inline auto operator()(Ts&&... args)
-> decltype(std::make_tuple(std::forward<Ts>(args)...)) {
return std::make_tuple(std::forward<Ts>(args)...);
}
}; };
template<class Guard, class Transformers, class Pattern> template<class Transformers, class Pattern>
struct rvalue_builder { struct rvalue_builder {
typedef typename util::tl_back<Pattern>::type back_type; typedef typename util::tl_back<Pattern>::type back_type;
static constexpr bool is_complete = static constexpr bool is_complete =
!std::is_same<arg_match_t, back_type>::value; !std::is_same<detail::arg_match_t, back_type>::value;
typedef typename util::tl_apply<Transformers, tdata>::type fun_container; typedef typename util::tl_apply<Transformers, std::tuple>::type
fun_container;
Guard m_guard;
fun_container m_funs; fun_container m_funs;
public: public:
rvalue_builder() = default; rvalue_builder() = default;
template<typename... Ts> template<typename... Ts>
rvalue_builder(rvalue_builder_args_ctor, const Ts&... args) rvalue_builder(rvalue_builder_args_ctor, const Ts&... args)
: m_guard(args...), m_funs(args...) { } : m_funs(args...) {}
rvalue_builder(Guard arg0, fun_container arg1)
: m_guard(std::move(arg0)), m_funs(std::move(arg1)) { }
template<typename NewGuard>
rvalue_builder<
guard_expr<
logical_and_op,
guard_expr<exec_xfun_op, Guard, unit_t>,
NewGuard>,
Transformers,
Pattern>
when(NewGuard ng,
typename std::enable_if<
std::is_same<NewGuard, NewGuard>::value
&& !std::is_same<Guard, empty_value_guard>::value
>::type* = 0 ) const {
return {(ge_sub_function(m_guard) && ng), std::move(m_funs)};
}
template<typename NewGuard> rvalue_builder(fun_container arg1) : m_funs(std::move(arg1)) {}
rvalue_builder<NewGuard, Transformers, Pattern>
when(NewGuard ng,
typename std::enable_if<
std::is_same<NewGuard, NewGuard>::value
&& std::is_same<Guard, empty_value_guard>::value
>::type* = 0 ) const {
return {std::move(ng), std::move(m_funs)};
}
template<typename Expr> template<typename Expr>
match_expr<typename get_case<is_complete, Expr, Guard, Transformers, Pattern>::type> match_expr<
typename get_case<is_complete, Expr, Transformers, Pattern>::type>
operator>>(Expr expr) const { operator>>(Expr expr) const {
typedef typename get_case< typedef typename get_case<is_complete, Expr, Transformers,
is_complete, Pattern>::type lifted_expr;
Expr, // adjust m_funs to exactly match expected projections in match case
Guard, typedef typename lifted_expr::projections_list target;
Transformers, typedef typename util::tl_trim<Transformers>::type trimmed_projections;
Pattern tuple_maker f;
>::type auto lhs = apply_args(f, get_indices(trimmed_projections{}), m_funs);
tpair; typename util::tl_apply<
return tpair{typename tpair::first_type{m_funs}, typename util::tl_slice<target,
typename tpair::second_type{std::move(expr), util::tl_size<trimmed_projections>::value,
std::move(m_guard)}}; util::tl_size<target>::value>::type,
std::tuple>::type
rhs;
// done
return lifted_expr{std::move(expr), std::tuple_cat(lhs, rhs)};
} }
template<class G, class T, class P> template<class T, class P>
disjunct_rvalue_builders<rvalue_builder, rvalue_builder<G, T, P> > disjunct_rvalue_builders<rvalue_builder, rvalue_builder<T, P>>
operator||(rvalue_builder<G, T, P> other) const { operator||(rvalue_builder<T, P> other) const {
return {*this, std::move(other)}; return {*this, std::move(other)};
} }
}; };
template<bool IsCallable, typename T> template<bool IsCallable, typename T>
struct pattern_type_ { struct pattern_type_ {
typedef util::get_callable_trait<T> ctrait; typedef util::get_callable_trait<T> ctrait;
typedef typename ctrait::arg_types args; typedef typename ctrait::arg_types args;
static_assert(util::tl_size<args>::value == 1, "only unary functions allowed"); static_assert(util::tl_size<args>::value == 1,
typedef typename util::rm_const_and_ref<typename util::tl_head<args>::type>::type type; "only unary functions allowed");
typedef typename util::rm_const_and_ref<
typename util::tl_head<args>::type>::type type;
}; };
template<typename T> template<typename T>
...@@ -204,9 +194,9 @@ struct pattern_type_<false, T> { ...@@ -204,9 +194,9 @@ struct pattern_type_<false, T> {
}; };
template<typename T> template<typename T>
struct pattern_type : pattern_type_<util::is_callable<T>::value && !detail::is_boxed<T>::value, T> { struct pattern_type
}; : pattern_type_<
util::is_callable<T>::value && !is_boxed<T>::value, T> {};
} // namespace detail } // namespace detail
} // namespace cppa } // namespace cppa
...@@ -284,44 +274,86 @@ constexpr typename detail::boxed<T>::type val() { ...@@ -284,44 +274,86 @@ constexpr typename detail::boxed<T>::type val() {
return typename detail::boxed<T>::type(); return typename detail::boxed<T>::type();
} }
typedef typename detail::boxed<arg_match_t>::type boxed_arg_match_t; typedef typename detail::boxed<detail::arg_match_t>::type boxed_arg_match_t;
constexpr boxed_arg_match_t arg_match = boxed_arg_match_t();
//constexpr boxed_arg_match_t arg_match = boxed_arg_match_t(); template<typename T, typename Predicate>
std::function<optional<T>(const T&)> guarded(Predicate p, T value) {
return[=](const T & other)->optional<T> {
if (p(other, value)) return value;
return none;
};
}
// special case covering arg_match as argument to guarded()
template<typename T, typename Predicate>
unit_t guarded(Predicate, const util::wrapped<T>&) {
return {};
}
template<typename T, bool Callable = util::is_callable<T>::value>
struct to_guard {
static std::function<optional<T>(const T&)> _(const T& value) {
return guarded<T>(std::equal_to<T>{}, value);
}
};
template<>
struct to_guard<anything, false> {
template<typename U>
static unit_t _(const U&) {
return {};
}
};
template<typename T>
struct to_guard<util::wrapped<T>, false> : to_guard<anything> {};
template<typename T>
struct is_optional : std::false_type {};
template<typename T>
struct is_optional<optional<T>> : std::true_type {};
template<typename T>
struct to_guard<T, true> {
typedef typename util::get_callable_trait<T>::type ct;
typedef typename ct::arg_types arg_types;
static_assert(util::tl_size<arg_types>::value == 1,
"projection/guard must take exactly one argument");
static_assert(is_optional<typename ct::result_type>::value,
"projection/guard must return an optional value");
typedef typename std::conditional<std::is_function<T>::value, T*, T>::type
value_type;
static value_type _(value_type val) { return val; }
};
template<typename T>
struct to_guard<util::wrapped<T>(), true> : to_guard<anything> {};
template<typename T, typename... Ts> template<typename T, typename... Ts>
detail::rvalue_builder< auto on(const T& arg, const Ts&... args)
detail::value_guard< -> detail::rvalue_builder<
typename util::tl_filter_not< util::type_list<
typename util::tl_trim< decltype(to_guard<typename detail::strip_and_convert<T>::type>::_(
typename util::tl_map< arg)),
util::type_list<T, Ts...>, decltype(to_guard<
detail::boxed_and_callable_to_void, typename detail::strip_and_convert<Ts>::type>::_(args))...>,
detail::implicit_conversions
>::type
>::type,
is_anything
>::type
>,
typename util::tl_map<
util::type_list<T, Ts...>,
detail::boxed_and_not_callable_to_void
>::type,
util::type_list<typename detail::pattern_type<T>::type, util::type_list<typename detail::pattern_type<T>::type,
typename detail::pattern_type<Ts>::type...> > typename detail::pattern_type<Ts>::type...>> {
on(const T& arg, const Ts&... args) { return {detail::rvalue_builder_args_ctor{},
return {detail::rvalue_builder_args_ctor{}, arg, args...}; to_guard<typename detail::strip_and_convert<T>::type>::_(arg),
to_guard<typename detail::strip_and_convert<Ts>::type>::_(args)...};
} }
inline detail::rvalue_builder<detail::empty_value_guard, inline detail::rvalue_builder<util::empty_type_list, util::empty_type_list>
util::empty_type_list, on() {
util::empty_type_list > on() {
return {}; return {};
} }
template<typename T0, typename... Ts> template<typename T0, typename... Ts>
detail::rvalue_builder<detail::empty_value_guard, detail::rvalue_builder<util::empty_type_list, util::type_list<T0, Ts...>>
util::empty_type_list,
util::type_list<T0, Ts...> >
on() { on() {
return {}; return {};
} }
...@@ -350,12 +382,10 @@ decltype(on(A0, A1, A2, A3, val<Ts>()...)) on() { ...@@ -350,12 +382,10 @@ decltype(on(A0, A1, A2, A3, val<Ts>()...)) on() {
template<class Rep, class Period> template<class Rep, class Period>
constexpr detail::behavior_rvalue_builder constexpr detail::behavior_rvalue_builder
after(const std::chrono::duration<Rep, Period>& d) { after(const std::chrono::duration<Rep, Period>& d) {
return { util::duration(d) }; return {duration(d)};
} }
inline decltype(on<anything>()) others() { inline decltype(on<anything>()) others() { return on<anything>(); }
return on<anything>();
}
// some more convenience // some more convenience
...@@ -364,38 +394,16 @@ namespace detail { ...@@ -364,38 +394,16 @@ namespace detail {
class on_the_fly_rvalue_builder { class on_the_fly_rvalue_builder {
public: public:
constexpr on_the_fly_rvalue_builder() {}
constexpr on_the_fly_rvalue_builder() { }
template<typename Guard>
auto when(Guard g) const -> decltype(on(arg_match).when(g)) {
return on(arg_match).when(g);
}
template<typename Expr> template<typename Expr>
match_expr< match_expr<typename get_case<false, Expr, util::empty_type_list,
typename get_case< util::empty_type_list>::type>
false,
Expr,
empty_value_guard,
util::empty_type_list,
util::empty_type_list
>::type>
operator>>(Expr expr) const { operator>>(Expr expr) const {
typedef typename get_case< typedef typename get_case<false, Expr, util::empty_type_list,
false, util::empty_type_list>::type result_type;
Expr, return result_type{std::move(expr)};
empty_value_guard,
util::empty_type_list,
util::empty_type_list
>::type
result_type;
return result_type{typename result_type::first_type{},
typename result_type::second_type{
std::move(expr),
empty_value_guard{}}};
} }
}; };
} // namespace detail } // namespace detail
......
...@@ -77,7 +77,7 @@ struct cl_spawn_helper<R (Ts...), void> { ...@@ -77,7 +77,7 @@ struct cl_spawn_helper<R (Ts...), void> {
Us&&... args) const { Us&&... args) const {
using std::move; using std::move;
using std::forward; using std::forward;
map_arg_fun f0 = [] (any_tuple msg) { map_arg_fun f0 = [] (message msg) {
return tuple_cast< return tuple_cast<
typename util::rm_const_and_ref< typename util::rm_const_and_ref<
typename carr_to_vec<Ts>::type typename carr_to_vec<Ts>::type
...@@ -85,7 +85,7 @@ struct cl_spawn_helper<R (Ts...), void> { ...@@ -85,7 +85,7 @@ struct cl_spawn_helper<R (Ts...), void> {
>(msg); >(msg);
}; };
map_res_fun f1 = [] (result_type& result) { map_res_fun f1 = [] (result_type& result) {
return make_any_tuple(move(result)); return make_message(move(result));
}; };
return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...); return impl::create(p, fname, move(f0), move(f1), forward<Us>(args)...);
} }
...@@ -93,8 +93,8 @@ struct cl_spawn_helper<R (Ts...), void> { ...@@ -93,8 +93,8 @@ struct cl_spawn_helper<R (Ts...), void> {
}; };
template<typename R, typename... Ts> template<typename R, typename... Ts>
struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>> (any_tuple)>, struct cl_spawn_helper<std::function<optional<cow_tuple<Ts...>> (message)>,
std::function<any_tuple (R&)>> std::function<message (R&)>>
: cl_spawn_helper<R (Ts...)> { }; : cl_spawn_helper<R (Ts...)> { };
} // namespace detail } // namespace detail
......
...@@ -59,10 +59,10 @@ namespace opencl { ...@@ -59,10 +59,10 @@ namespace opencl {
class opencl_metainfo; class opencl_metainfo;
template <typename Signature> template<typename Signature>
class actor_facade; class actor_facade;
template <typename Ret, typename... Args> template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public abstract_actor { class actor_facade<Ret(Args...)> : public abstract_actor {
friend class command<actor_facade, Ret>; friend class command<actor_facade, Ret>;
...@@ -72,8 +72,8 @@ class actor_facade<Ret(Args...)> : public abstract_actor { ...@@ -72,8 +72,8 @@ class actor_facade<Ret(Args...)> : public abstract_actor {
typedef cow_tuple<typename util::rm_const_and_ref<Args>::type...> typedef cow_tuple<typename util::rm_const_and_ref<Args>::type...>
args_tuple; args_tuple;
typedef std::function<optional<args_tuple>(any_tuple)> arg_mapping; typedef std::function<optional<args_tuple>(message)> arg_mapping;
typedef std::function<any_tuple(Ret&)> result_mapping; typedef std::function<message(Ret&)> result_mapping;
static intrusive_ptr<actor_facade> static intrusive_ptr<actor_facade>
create(const program& prog, const char* kernel_name, create(const program& prog, const char* kernel_name,
...@@ -120,7 +120,7 @@ class actor_facade<Ret(Args...)> : public abstract_actor { ...@@ -120,7 +120,7 @@ class actor_facade<Ret(Args...)> : public abstract_actor {
}; };
} }
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit*) override { void enqueue(msg_hdr_cref hdr, message msg, execution_unit*) override {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
typename util::il_indices<util::type_list<Args...>>::type indices; typename util::il_indices<util::type_list<Args...>>::type indices;
enqueue_impl(hdr.sender, std::move(msg), hdr.id, indices); enqueue_impl(hdr.sender, std::move(msg), hdr.id, indices);
...@@ -149,8 +149,8 @@ class actor_facade<Ret(Args...)> : public abstract_actor { ...@@ -149,8 +149,8 @@ class actor_facade<Ret(Args...)> : public abstract_actor {
CPPA_LOG_TRACE("id: " << this->id()); CPPA_LOG_TRACE("id: " << this->id());
} }
template <long... Is> template<long... Is>
void enqueue_impl(const actor_addr& sender, any_tuple msg, message_id id, void enqueue_impl(const actor_addr& sender, message msg, message_id id,
util::int_list<Is...>) { util::int_list<Is...>) {
auto opt = m_map_args(std::move(msg)); auto opt = m_map_args(std::move(msg));
if (opt) { if (opt) {
......
...@@ -57,7 +57,7 @@ class command : public ref_counted { ...@@ -57,7 +57,7 @@ class command : public ref_counted {
std::vector<cl_event> events, std::vector<cl_event> events,
std::vector<mem_ptr> arguments, std::vector<mem_ptr> arguments,
size_t result_size, size_t result_size,
any_tuple msg) message msg)
: m_result_size(result_size) : m_result_size(result_size)
, m_handle(handle) , m_handle(handle)
, m_actor_facade(actor_facade) , m_actor_facade(actor_facade)
...@@ -151,7 +151,7 @@ class command : public ref_counted { ...@@ -151,7 +151,7 @@ class command : public ref_counted {
std::vector<cl_event> m_events; std::vector<cl_event> m_events;
std::vector<mem_ptr> m_arguments; std::vector<mem_ptr> m_arguments;
R m_result; R m_result;
any_tuple m_msg; // required to keep the argument buffers alive (for async copy) message m_msg; // required to keep the argument buffers alive (for async copy)
void handle_results () { void handle_results () {
m_handle.deliver(m_actor_facade->m_map_result(m_result)); m_handle.deliver(m_actor_facade->m_map_result(m_result));
......
...@@ -33,11 +33,6 @@ ...@@ -33,11 +33,6 @@
namespace cppa { namespace cppa {
//template<typename T>
//optional<T> conv_arg(const std::string& arg) {
// return detail::conv_arg_impl<T>::_(arg);
//}
/** /**
* @brief Right-hand side of a match expression for a program option * @brief Right-hand side of a match expression for a program option
* reading an argument of type @p T. * reading an argument of type @p T.
...@@ -74,11 +69,15 @@ struct option_info { ...@@ -74,11 +69,15 @@ struct option_info {
typedef std::map<std::string, std::map<std::pair<char, std::string>, option_info> > typedef std::map<std::string, std::map<std::pair<char, std::string>, option_info> >
options_description; options_description;
using opt_rvalue_builder = decltype(on(std::function<optional<std::string> (const std::string&)>{}) || on(std::string{}, val<std::string>));
using opt0_rvalue_builder = decltype(on(std::string{}) || on(std::string{}));
/** /**
* @brief Left-hand side of a match expression for a program option with * @brief Left-hand side of a match expression for a program option with
* one argument. * one argument.
*/ */
detail::opt1_rvalue_builder<true> on_opt1(char short_opt, opt_rvalue_builder on_opt1(char short_opt,
std::string long_opt, std::string long_opt,
options_description* desc = nullptr, options_description* desc = nullptr,
std::string help_text = "", std::string help_text = "",
...@@ -88,7 +87,7 @@ detail::opt1_rvalue_builder<true> on_opt1(char short_opt, ...@@ -88,7 +87,7 @@ detail::opt1_rvalue_builder<true> on_opt1(char short_opt,
* @brief Left-hand side of a match expression for a program option with * @brief Left-hand side of a match expression for a program option with
* no argument. * no argument.
*/ */
detail::opt0_rvalue_builder on_opt0(char short_opt, opt0_rvalue_builder on_opt0(char short_opt,
std::string long_opt, std::string long_opt,
options_description* desc = nullptr, options_description* desc = nullptr,
std::string help_text = "", std::string help_text = "",
......
...@@ -287,13 +287,6 @@ class optional<void> { ...@@ -287,13 +287,6 @@ class optional<void> {
}; };
/** @relates option */
template<typename T>
struct is_optional { static constexpr bool value = false; };
template<typename T>
struct is_optional<optional<T>> { static constexpr bool value = true; };
/** @relates option */ /** @relates option */
template<typename T, typename U> template<typename T, typename U>
bool operator==(const optional<T>& lhs, const optional<U>& rhs) { bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <atomic> #include <atomic>
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
...@@ -50,7 +50,7 @@ class cooperative_scheduling { ...@@ -50,7 +50,7 @@ class cooperative_scheduling {
template<class Actor> template<class Actor>
void enqueue(Actor* self, msg_hdr_cref hdr, void enqueue(Actor* self, msg_hdr_cref hdr,
any_tuple& msg, execution_unit* host) { message& msg, execution_unit* host) {
auto e = self->new_mailbox_element(hdr, std::move(msg)); auto e = self->new_mailbox_element(hdr, std::move(msg));
switch (self->mailbox().enqueue(e)) { switch (self->mailbox().enqueue(e)) {
case intrusive::enqueue_result::unblocked_reader: { case intrusive::enqueue_result::unblocked_reader: {
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "cppa/exit_reason.hpp" #include "cppa/exit_reason.hpp"
#include "cppa/mailbox_element.hpp" #include "cppa/mailbox_element.hpp"
#include "cppa/system_messages.hpp" #include "cppa/system_messages.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
#include "cppa/response_promise.hpp" #include "cppa/response_promise.hpp"
#include "cppa/detail/memory.hpp" #include "cppa/detail/memory.hpp"
...@@ -113,7 +113,7 @@ class invoke_policy { ...@@ -113,7 +113,7 @@ class invoke_policy {
std::list<std::unique_ptr<mailbox_element, detail::disposer> > m_cache; std::list<std::unique_ptr<mailbox_element, detail::disposer> > m_cache;
inline void handle_timeout(partial_function&) { inline void handle_timeout(message_handler&) {
CPPA_CRITICAL("handle_timeout(partial_function&)"); CPPA_CRITICAL("handle_timeout(partial_function&)");
} }
...@@ -136,7 +136,7 @@ class invoke_policy { ...@@ -136,7 +136,7 @@ class invoke_policy {
template<class Actor> template<class Actor>
msg_type filter_msg(Actor* self, mailbox_element* node) { msg_type filter_msg(Actor* self, mailbox_element* node) {
const any_tuple& msg = node->msg; const message& msg = node->msg;
auto mid = node->mid; auto mid = node->mid;
auto& arr = detail::static_types_array<exit_msg, auto& arr = detail::static_types_array<exit_msg,
timeout_msg, timeout_msg,
...@@ -187,8 +187,8 @@ class invoke_policy { ...@@ -187,8 +187,8 @@ class invoke_policy {
// - extracts response message from handler // - extracts response message from handler
// - returns true if fun was successfully invoked // - returns true if fun was successfully invoked
template<class Actor, class Fun, class MaybeResponseHandle = int> template<class Actor, class Fun, class MaybeResponseHandle = int>
optional<any_tuple> invoke_fun(Actor* self, optional<message> invoke_fun(Actor* self,
any_tuple& msg, message& msg,
message_id& mid, message_id& mid,
Fun& fun, Fun& fun,
MaybeResponseHandle hdl = MaybeResponseHandle{}) { MaybeResponseHandle hdl = MaybeResponseHandle{}) {
...@@ -209,7 +209,7 @@ class invoke_policy { ...@@ -209,7 +209,7 @@ class invoke_policy {
<< " did not reply to a " << " did not reply to a "
"synchronous request message"); "synchronous request message");
auto fhdl = fetch_response_promise(self, hdl); auto fhdl = fetch_response_promise(self, hdl);
if (fhdl) fhdl.deliver(make_any_tuple(unit)); if (fhdl) fhdl.deliver(make_message(unit));
} }
} else { } else {
if ( detail::matches<atom_value, std::uint64_t>(*res) if ( detail::matches<atom_value, std::uint64_t>(*res)
...@@ -226,11 +226,11 @@ class invoke_policy { ...@@ -226,11 +226,11 @@ class invoke_policy {
if (ref_opt) { if (ref_opt) {
behavior cpy = *ref_opt; behavior cpy = *ref_opt;
*ref_opt = cpy.add_continuation( *ref_opt = cpy.add_continuation(
[=](any_tuple& intermediate) -> optional<any_tuple> { [=](message& intermediate) -> optional<message> {
if (!intermediate.empty()) { if (!intermediate.empty()) {
// do no use lamba expresion type to // do no use lamba expresion type to
// avoid recursive template instantiaton // avoid recursive template instantiaton
behavior::continuation_fun f2 = [=](any_tuple& m) -> optional<any_tuple> { behavior::continuation_fun f2 = [=](message& m) -> optional<message> {
return std::move(m); return std::move(m);
}; };
auto mutable_mid = mid; auto mutable_mid = mid;
...@@ -257,7 +257,7 @@ class invoke_policy { ...@@ -257,7 +257,7 @@ class invoke_policy {
if (fhdl) { if (fhdl) {
fhdl.deliver(std::move(*res)); fhdl.deliver(std::move(*res));
// inform caller about success // inform caller about success
return any_tuple{}; return message{};
} }
} }
} }
......
...@@ -44,7 +44,7 @@ class middleman_scheduling { ...@@ -44,7 +44,7 @@ class middleman_scheduling {
typedef intrusive_ptr<Actor> pointer; typedef intrusive_ptr<Actor> pointer;
continuation(pointer ptr, msg_hdr_cref hdr, any_tuple&& msg) continuation(pointer ptr, msg_hdr_cref hdr, message&& msg)
: m_self(std::move(ptr)), m_hdr(hdr), m_data(std::move(msg)) { } : m_self(std::move(ptr)), m_hdr(hdr), m_data(std::move(msg)) { }
inline void operator()() const { inline void operator()() const {
...@@ -55,7 +55,7 @@ class middleman_scheduling { ...@@ -55,7 +55,7 @@ class middleman_scheduling {
pointer m_self; pointer m_self;
message_header m_hdr; message_header m_hdr;
any_tuple m_data; message m_data;
}; };
...@@ -80,7 +80,7 @@ class middleman_scheduling { ...@@ -80,7 +80,7 @@ class middleman_scheduling {
} }
template<class Actor> template<class Actor>
void enqueue(Actor* self, msg_hdr_cref hdr, any_tuple& msg) { void enqueue(Actor* self, msg_hdr_cref hdr, message& msg) {
get_middleman()->run_later(continuation<Actor>{self, hdr, std::move(msg)}); get_middleman()->run_later(continuation<Actor>{self, hdr, std::move(msg)});
} }
......
...@@ -53,7 +53,7 @@ class no_scheduling { ...@@ -53,7 +53,7 @@ class no_scheduling {
template<class Actor> template<class Actor>
void enqueue(Actor* self, msg_hdr_cref hdr, void enqueue(Actor* self, msg_hdr_cref hdr,
any_tuple& msg, execution_unit*) { message& msg, execution_unit*) {
auto ptr = self->new_mailbox_element(hdr, std::move(msg)); auto ptr = self->new_mailbox_element(hdr, std::move(msg));
// returns false if mailbox has been closed // returns false if mailbox has been closed
if (!self->mailbox().synchronized_enqueue(m_mtx, m_cv, ptr)) { if (!self->mailbox().synchronized_enqueue(m_mtx, m_cv, ptr)) {
......
...@@ -90,7 +90,7 @@ class scheduling_policy { ...@@ -90,7 +90,7 @@ class scheduling_policy {
template<class Actor> template<class Actor>
void enqueue(Actor* self, void enqueue(Actor* self,
msg_hdr_cref hdr, msg_hdr_cref hdr,
any_tuple& msg, message& msg,
execution_unit* host); execution_unit* host);
/** /**
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <QApplication> #include <QApplication>
#include "cppa/actor_companion.hpp" #include "cppa/actor_companion.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
#include "cppa/policy/sequential_invoke.hpp" #include "cppa/policy/sequential_invoke.hpp"
......
...@@ -53,7 +53,7 @@ struct blocking_response_handle_tag { }; ...@@ -53,7 +53,7 @@ struct blocking_response_handle_tag { };
* and enables <tt>sync_send(...).then(...)</tt>. * and enables <tt>sync_send(...).then(...)</tt>.
* *
* @tparam Self The type of the actor this handle belongs to. * @tparam Self The type of the actor this handle belongs to.
* @tparam Result Either any_tuple or type_list<R1, R2, ... Rn>. * @tparam Result Either message or type_list<R1, R2, ... Rn>.
* @tparam Tag Either {@link nonblocking_response_handle_tag} or * @tparam Tag Either {@link nonblocking_response_handle_tag} or
* {@link blocking_response_handle_tag}. * {@link blocking_response_handle_tag}.
*/ */
...@@ -64,7 +64,7 @@ class response_handle; ...@@ -64,7 +64,7 @@ class response_handle;
* nonblocking + untyped * * nonblocking + untyped *
******************************************************************************/ ******************************************************************************/
template<class Self> template<class Self>
class response_handle<Self, any_tuple, nonblocking_response_handle_tag> { class response_handle<Self, message, nonblocking_response_handle_tag> {
public: public:
...@@ -149,7 +149,7 @@ class response_handle<Self, util::type_list<Ts...>, nonblocking_response_handle_ ...@@ -149,7 +149,7 @@ class response_handle<Self, util::type_list<Ts...>, nonblocking_response_handle_
* blocking + untyped * * blocking + untyped *
******************************************************************************/ ******************************************************************************/
template<class Self> template<class Self>
class response_handle<Self, any_tuple, blocking_response_handle_tag> { class response_handle<Self, message, blocking_response_handle_tag> {
public: public:
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define CPPA_RESPONSE_PROMISE_HPP #define CPPA_RESPONSE_PROMISE_HPP
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/actor_addr.hpp" #include "cppa/actor_addr.hpp"
#include "cppa/message_id.hpp" #include "cppa/message_id.hpp"
...@@ -58,7 +58,7 @@ class response_promise { ...@@ -58,7 +58,7 @@ class response_promise {
/** /**
* @brief Sends @p response_message and invalidates this handle afterwards. * @brief Sends @p response_message and invalidates this handle afterwards.
*/ */
void deliver(any_tuple response_message); void deliver(message response_message);
private: private:
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/attachable.hpp" #include "cppa/attachable.hpp"
#include "cppa/scoped_actor.hpp" #include "cppa/scoped_actor.hpp"
...@@ -160,8 +160,8 @@ class coordinator { ...@@ -160,8 +160,8 @@ class coordinator {
template<typename Duration, typename... Data> template<typename Duration, typename... Data>
void delayed_send(message_header hdr, void delayed_send(message_header hdr,
const Duration& rel_time, const Duration& rel_time,
any_tuple data ) { message data ) {
auto tup = make_any_tuple(atom("SEND"), auto tup = make_message(atom("SEND"),
util::duration{rel_time}, util::duration{rel_time},
std::move(hdr), std::move(hdr),
std::move(data)); std::move(data));
...@@ -171,9 +171,9 @@ class coordinator { ...@@ -171,9 +171,9 @@ class coordinator {
template<typename Duration, typename... Data> template<typename Duration, typename... Data>
void delayed_reply(message_header hdr, void delayed_reply(message_header hdr,
const Duration& rel_time, const Duration& rel_time,
any_tuple data ) { message data ) {
CPPA_REQUIRE(hdr.id.valid() && hdr.id.is_response()); CPPA_REQUIRE(hdr.id.valid() && hdr.id.is_response());
auto tup = make_any_tuple(atom("SEND"), auto tup = make_message(atom("SEND"),
util::duration{rel_time}, util::duration{rel_time},
std::move(hdr), std::move(hdr),
std::move(data)); std::move(data));
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#ifndef CPPA_SINGLE_TIMEOUT_HPP #ifndef CPPA_SINGLE_TIMEOUT_HPP
#define CPPA_SINGLE_TIMEOUT_HPP #define CPPA_SINGLE_TIMEOUT_HPP
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/system_messages.hpp" #include "cppa/system_messages.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
...@@ -39,7 +39,7 @@ class single_timeout : public Base { ...@@ -39,7 +39,7 @@ class single_timeout : public Base {
typedef single_timeout combined_type; typedef single_timeout combined_type;
template <typename... Ts> template<typename... Ts>
single_timeout(Ts&&... args) single_timeout(Ts&&... args)
: super(std::forward<Ts>(args)...), m_has_timeout(false) : super(std::forward<Ts>(args)...), m_has_timeout(false)
, m_timeout_id(0) { } , m_timeout_id(0) { }
...@@ -48,7 +48,7 @@ class single_timeout : public Base { ...@@ -48,7 +48,7 @@ class single_timeout : public Base {
if (d.valid()) { if (d.valid()) {
m_has_timeout = true; m_has_timeout = true;
auto tid = ++m_timeout_id; auto tid = ++m_timeout_id;
auto msg = make_any_tuple(timeout_msg{tid}); auto msg = make_message(timeout_msg{tid});
if (d.is_zero()) { if (d.is_zero()) {
// immediately enqueue timeout message if duration == 0s // immediately enqueue timeout message if duration == 0s
this->enqueue({this->address(), this}, std::move(msg), this->enqueue({this->address(), this}, std::move(msg),
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define CPPA_SYNC_SENDER_HPP #define CPPA_SYNC_SENDER_HPP
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/response_handle.hpp" #include "cppa/response_handle.hpp"
#include "cppa/message_priority.hpp" #include "cppa/message_priority.hpp"
...@@ -35,7 +35,7 @@ class sync_sender_impl : public Base { ...@@ -35,7 +35,7 @@ class sync_sender_impl : public Base {
public: public:
typedef response_handle<Subtype, typedef response_handle<Subtype,
any_tuple, message,
ResponseHandleTag> ResponseHandleTag>
response_handle_type; response_handle_type;
...@@ -54,12 +54,12 @@ class sync_sender_impl : public Base { ...@@ -54,12 +54,12 @@ class sync_sender_impl : public Base {
*/ */
response_handle_type sync_send_tuple(message_priority prio, response_handle_type sync_send_tuple(message_priority prio,
const actor& dest, const actor& dest,
any_tuple what) { message what) {
return {dptr()->sync_send_tuple_impl(prio, dest, std::move(what)), return {dptr()->sync_send_tuple_impl(prio, dest, std::move(what)),
dptr()}; dptr()};
} }
response_handle_type sync_send_tuple(const actor& dest, any_tuple what) { response_handle_type sync_send_tuple(const actor& dest, message what) {
return sync_send_tuple(message_priority::normal, dest, std::move(what)); return sync_send_tuple(message_priority::normal, dest, std::move(what));
} }
...@@ -79,14 +79,14 @@ class sync_sender_impl : public Base { ...@@ -79,14 +79,14 @@ class sync_sender_impl : public Base {
Ts&&... what) { Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return sync_send_tuple(prio, dest, return sync_send_tuple(prio, dest,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
template<typename... Ts> template<typename... Ts>
response_handle_type sync_send(const actor& dest, Ts&&... what) { response_handle_type sync_send(const actor& dest, Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return sync_send_tuple(message_priority::normal, return sync_send_tuple(message_priority::normal,
dest, make_any_tuple(std::forward<Ts>(what)...)); dest, make_message(std::forward<Ts>(what)...));
} }
/************************************************************************** /**************************************************************************
...@@ -96,7 +96,7 @@ class sync_sender_impl : public Base { ...@@ -96,7 +96,7 @@ class sync_sender_impl : public Base {
response_handle_type timed_sync_send_tuple(message_priority prio, response_handle_type timed_sync_send_tuple(message_priority prio,
const actor& dest, const actor& dest,
const util::duration& rtime, const util::duration& rtime,
any_tuple what) { message what) {
return {dptr()->timed_sync_send_tuple_impl(prio, dest, rtime, return {dptr()->timed_sync_send_tuple_impl(prio, dest, rtime,
std::move(what)), std::move(what)),
dptr()}; dptr()};
...@@ -104,7 +104,7 @@ class sync_sender_impl : public Base { ...@@ -104,7 +104,7 @@ class sync_sender_impl : public Base {
response_handle_type timed_sync_send_tuple(const actor& dest, response_handle_type timed_sync_send_tuple(const actor& dest,
const util::duration& rtime, const util::duration& rtime,
any_tuple what) { message what) {
return {dptr()->timed_sync_send_tuple_impl(message_priority::normal, return {dptr()->timed_sync_send_tuple_impl(message_priority::normal,
dest, rtime, dest, rtime,
std::move(what)), std::move(what)),
...@@ -118,7 +118,7 @@ class sync_sender_impl : public Base { ...@@ -118,7 +118,7 @@ class sync_sender_impl : public Base {
Ts&&... what) { Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return timed_sync_send_tuple(prio, dest, rtime, return timed_sync_send_tuple(prio, dest, rtime,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
template<typename... Ts> template<typename... Ts>
...@@ -127,7 +127,7 @@ class sync_sender_impl : public Base { ...@@ -127,7 +127,7 @@ class sync_sender_impl : public Base {
Ts&&... what) { Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return timed_sync_send_tuple(message_priority::normal, dest, rtime, return timed_sync_send_tuple(message_priority::normal, dest, rtime,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
/************************************************************************** /**************************************************************************
...@@ -263,7 +263,7 @@ class sync_sender_impl : public Base { ...@@ -263,7 +263,7 @@ class sync_sender_impl : public Base {
Ts&&... what) { Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return timed_sync_send_tuple(prio, dest, rtime, return timed_sync_send_tuple(prio, dest, rtime,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
template<typename... Rs, typename... Ts> template<typename... Rs, typename... Ts>
...@@ -284,7 +284,7 @@ class sync_sender_impl : public Base { ...@@ -284,7 +284,7 @@ class sync_sender_impl : public Base {
Ts&&... what) { Ts&&... what) {
static_assert(sizeof...(Ts) > 0, "no message to send"); static_assert(sizeof...(Ts) > 0, "no message to send");
return timed_sync_send_tuple(message_priority::normal, dest, rtime, return timed_sync_send_tuple(message_priority::normal, dest, rtime,
make_any_tuple(std::forward<Ts>(what)...)); make_message(std::forward<Ts>(what)...));
} }
private: private:
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/node_id.hpp" #include "cppa/node_id.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/abstract_group.hpp" #include "cppa/abstract_group.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
...@@ -49,7 +49,7 @@ inline std::string to_string_impl(const T& what) { ...@@ -49,7 +49,7 @@ inline std::string to_string_impl(const T& what) {
} // namespace detail } // namespace detail
inline std::string to_string(const any_tuple& what) { inline std::string to_string(const message& what) {
return detail::to_string_impl(what); return detail::to_string_impl(what);
} }
......
...@@ -39,10 +39,10 @@ namespace cppa { ...@@ -39,10 +39,10 @@ namespace cppa {
* @param tup Dynamically typed tuple. * @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types * @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}. * deduced from {T...}.
* @relates any_tuple * @relates message
*/ */
template<typename... T> template<typename... T>
auto moving_tuple_cast(any_tuple& tup); auto moving_tuple_cast(message& tup);
/** /**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>} and moves * @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>} and moves
...@@ -50,35 +50,35 @@ auto moving_tuple_cast(any_tuple& tup); ...@@ -50,35 +50,35 @@ auto moving_tuple_cast(any_tuple& tup);
* @param tup Dynamically typed tuple. * @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types * @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}. * deduced from {T...}.
* @relates any_tuple * @relates message
*/ */
template<typename... T> template<typename... T>
auto moving_tuple_cast(any_tuple& tup, const util::type_list<T...>&); auto moving_tuple_cast(message& tup, const util::type_list<T...>&);
/** /**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}. * @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}.
* @param tup Dynamically typed tuple. * @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types * @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}. * deduced from {T...}.
* @relates any_tuple * @relates message
*/ */
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple tup); auto tuple_cast(message tup);
/** /**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}. * @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}.
* @param tup Dynamically typed tuple. * @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types * @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}. * deduced from {T...}.
* @relates any_tuple * @relates message
*/ */
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple tup, const util::type_list<T...>&); auto tuple_cast(message tup, const util::type_list<T...>&);
#else #else
template<typename... T> template<typename... T>
auto moving_tuple_cast(any_tuple& tup) auto moving_tuple_cast(message& tup)
-> optional< -> optional<
typename cow_tuple_from_type_list< typename cow_tuple_from_type_list<
typename util::tl_filter_not<util::type_list<T...>, typename util::tl_filter_not<util::type_list<T...>,
...@@ -92,13 +92,13 @@ auto moving_tuple_cast(any_tuple& tup) ...@@ -92,13 +92,13 @@ auto moving_tuple_cast(any_tuple& tup)
} }
template<typename... T> template<typename... T>
auto moving_tuple_cast(any_tuple& tup, const util::type_list<T...>&) auto moving_tuple_cast(message& tup, const util::type_list<T...>&)
-> decltype(moving_tuple_cast<T...>(tup)) { -> decltype(moving_tuple_cast<T...>(tup)) {
return moving_tuple_cast<T...>(tup); return moving_tuple_cast<T...>(tup);
} }
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple tup) auto tuple_cast(message tup)
-> optional< -> optional<
typename cow_tuple_from_type_list< typename cow_tuple_from_type_list<
typename util::tl_filter_not<util::type_list<T...>, typename util::tl_filter_not<util::type_list<T...>,
...@@ -108,7 +108,7 @@ auto tuple_cast(any_tuple tup) ...@@ -108,7 +108,7 @@ auto tuple_cast(any_tuple tup)
} }
template<typename... T> template<typename... T>
auto tuple_cast(any_tuple tup, const util::type_list<T...>&) auto tuple_cast(message tup, const util::type_list<T...>&)
-> decltype(tuple_cast<T...>(tup)) { -> decltype(tuple_cast<T...>(tup)) {
return moving_tuple_cast<T...>(tup); return moving_tuple_cast<T...>(tup);
} }
...@@ -116,7 +116,7 @@ auto tuple_cast(any_tuple tup, const util::type_list<T...>&) ...@@ -116,7 +116,7 @@ auto tuple_cast(any_tuple tup, const util::type_list<T...>&)
// ************************ for in-library use only! ************************ // // ************************ for in-library use only! ************************ //
template<typename... T> template<typename... T>
auto unsafe_tuple_cast(any_tuple& tup, const util::type_list<T...>&) auto unsafe_tuple_cast(message& tup, const util::type_list<T...>&)
-> decltype(tuple_cast<T...>(tup)) { -> decltype(tuple_cast<T...>(tup)) {
return tuple_cast<T...>(tup); return tuple_cast<T...>(tup);
} }
......
...@@ -206,11 +206,6 @@ class typed_behavior { ...@@ -206,11 +206,6 @@ class typed_behavior {
template<typename... Cs> template<typename... Cs>
void set(match_expr<Cs...>&& expr) { void set(match_expr<Cs...>&& expr) {
// check for (the lack of) guards
static_assert(util::conjunction<
detail::match_expr_has_no_guard<Cs>::value...
>::value,
"typed actors are not allowed to use guard expressions");
// do some transformation before type-checking the input signatures // do some transformation before type-checking the input signatures
typedef typename util::tl_map< typedef typename util::tl_map<
util::type_list< util::type_list<
......
...@@ -246,9 +246,9 @@ class uniform_type_info { ...@@ -246,9 +246,9 @@ class uniform_type_info {
virtual void deserialize(void* instance, deserializer* source) const = 0; virtual void deserialize(void* instance, deserializer* source) const = 0;
/** /**
* @brief Returns @p instance encapsulated as an @p any_tuple. * @brief Returns @p instance encapsulated as an @p message.
*/ */
virtual any_tuple as_any_tuple(void* instance) const = 0; virtual message as_message(void* instance) const = 0;
protected: protected:
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#ifndef CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP #ifndef CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#define CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP #define CPPA_UTIL_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
...@@ -49,8 +49,8 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -49,8 +49,8 @@ class abstract_uniform_type_info : public uniform_type_info {
return m_name.c_str(); return m_name.c_str();
} }
any_tuple as_any_tuple(void* instance) const override { message as_message(void* instance) const override {
return make_any_tuple(deref(instance)); return make_message(deref(instance));
} }
bool equals(const void* lhs, const void* rhs) const override { bool equals(const void* lhs, const void* rhs) const override {
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <functional> #include <functional>
#include "cppa/guard_expr.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/util/rebindable_reference.hpp" #include "cppa/util/rebindable_reference.hpp"
......
...@@ -152,7 +152,7 @@ struct is_builtin { ...@@ -152,7 +152,7 @@ struct is_builtin {
std::u16string, std::u16string,
std::u32string, std::u32string,
atom_value, atom_value,
any_tuple, message,
message_header, message_header,
actor, actor,
group, group,
......
...@@ -14,7 +14,7 @@ using namespace cppa; ...@@ -14,7 +14,7 @@ using namespace cppa;
ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f) ChatWidget::ChatWidget(QWidget* parent, Qt::WindowFlags f)
: super(parent, f), m_input(nullptr), m_output(nullptr) { : super(parent, f), m_input(nullptr), m_output(nullptr) {
set_message_handler ([=](local_actor* self) -> partial_function { set_message_handler ([=](local_actor* self) -> message_handler {
return { return {
on(atom("join"), arg_match) >> [=](const group& what) { on(atom("join"), arg_match) >> [=](const group& what) {
if (m_chatroom) { if (m_chatroom) {
......
...@@ -39,16 +39,16 @@ istream& operator>>(istream& is, line& l) { ...@@ -39,16 +39,16 @@ istream& operator>>(istream& is, line& l) {
return is; return is;
} }
any_tuple s_last_line; message s_last_line;
any_tuple split_line(const line& l) { message split_line(const line& l) {
vector<string> result; vector<string> result;
stringstream strs(l.str); stringstream strs(l.str);
string tmp; string tmp;
while (getline(strs, tmp, ' ')) { while (getline(strs, tmp, ' ')) {
if (!tmp.empty()) result.push_back(std::move(tmp)); if (!tmp.empty()) result.push_back(std::move(tmp));
} }
s_last_line = any_tuple::view(std::move(result)); s_last_line = message::view(std::move(result));
return s_last_line; return s_last_line;
} }
......
...@@ -28,11 +28,11 @@ using namespace cppa::placeholders; ...@@ -28,11 +28,11 @@ using namespace cppa::placeholders;
// our "service" // our "service"
void calculator(event_based_actor* self) { void calculator(event_based_actor* self) {
self->become ( self->become (
on(atom("plus"), arg_match) >> [](int a, int b) -> any_tuple { on(atom("plus"), arg_match) >> [](int a, int b) -> message {
return make_any_tuple(atom("result"), a + b); return make_message(atom("result"), a + b);
}, },
on(atom("minus"), arg_match) >> [](int a, int b) -> any_tuple { on(atom("minus"), arg_match) >> [](int a, int b) -> message {
return make_any_tuple(atom("result"), a - b); return make_message(atom("result"), a - b);
}, },
on(atom("quit")) >> [=] { on(atom("quit")) >> [=] {
self->quit(); self->quit();
......
...@@ -31,7 +31,7 @@ istream& operator>>(istream& is, line& l) { ...@@ -31,7 +31,7 @@ istream& operator>>(istream& is, line& l) {
namespace { string s_last_line; } namespace { string s_last_line; }
any_tuple split_line(const line& l) { message split_line(const line& l) {
istringstream strs(l.str); istringstream strs(l.str);
s_last_line = move(l.str); s_last_line = move(l.str);
string tmp; string tmp;
...@@ -39,7 +39,7 @@ any_tuple split_line(const line& l) { ...@@ -39,7 +39,7 @@ any_tuple split_line(const line& l) {
while (getline(strs, tmp, ' ')) { while (getline(strs, tmp, ' ')) {
if (!tmp.empty()) result.push_back(std::move(tmp)); if (!tmp.empty()) result.push_back(std::move(tmp));
} }
return any_tuple::view(std::move(result)); return message::view(std::move(result));
} }
void client(event_based_actor* self, const string& name) { void client(event_based_actor* self, const string& name) {
......
...@@ -40,9 +40,9 @@ behavior ping(event_based_actor* self, size_t num_pings) { ...@@ -40,9 +40,9 @@ behavior ping(event_based_actor* self, size_t num_pings) {
on(atom("kickoff"), arg_match) >> [=](const actor& pong) { on(atom("kickoff"), arg_match) >> [=](const actor& pong) {
self->send(pong, atom("ping"), int32_t(1)); self->send(pong, atom("ping"), int32_t(1));
self->become ( self->become (
on(atom("pong"), arg_match) >> [=](int32_t value) -> any_tuple { on(atom("pong"), arg_match) >> [=](int32_t value) -> message {
if (++*count >= num_pings) self->quit(); if (++*count >= num_pings) self->quit();
return make_any_tuple(atom("ping"), value + 1); return make_message(atom("ping"), value + 1);
} }
); );
} }
...@@ -52,7 +52,7 @@ behavior ping(event_based_actor* self, size_t num_pings) { ...@@ -52,7 +52,7 @@ behavior ping(event_based_actor* self, size_t num_pings) {
behavior pong() { behavior pong() {
return { return {
on(atom("ping"), arg_match) >> [](int32_t value) { on(atom("ping"), arg_match) >> [](int32_t value) {
return make_any_tuple(atom("pong"), value); return make_message(atom("pong"), value);
} }
}; };
} }
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/actor_addr.hpp" #include "cppa/actor_addr.hpp"
#include "cppa/abstract_actor.hpp" #include "cppa/abstract_actor.hpp"
...@@ -67,7 +67,7 @@ bool abstract_actor::link_to_impl(const actor_addr& other) { ...@@ -67,7 +67,7 @@ bool abstract_actor::link_to_impl(const actor_addr& other) {
// send exit message if already exited // send exit message if already exited
if (exited()) { if (exited()) {
ptr->enqueue({address(), ptr}, ptr->enqueue({address(), ptr},
make_any_tuple(exit_msg{address(), exit_reason()}), make_message(exit_msg{address(), exit_reason()}),
m_host); m_host);
} }
// add link if not already linked to other // add link if not already linked to other
...@@ -151,7 +151,7 @@ bool abstract_actor::establish_backlink(const actor_addr& other) { ...@@ -151,7 +151,7 @@ bool abstract_actor::establish_backlink(const actor_addr& other) {
if (reason != exit_reason::not_exited) { if (reason != exit_reason::not_exited) {
auto ptr = detail::raw_access::unsafe_cast(other); auto ptr = detail::raw_access::unsafe_cast(other);
ptr->enqueue({address(), ptr}, ptr->enqueue({address(), ptr},
make_any_tuple(exit_msg{address(), exit_reason()}), make_message(exit_msg{address(), exit_reason()}),
m_host); m_host);
} }
return false; return false;
...@@ -202,7 +202,7 @@ void abstract_actor::cleanup(std::uint32_t reason) { ...@@ -202,7 +202,7 @@ void abstract_actor::cleanup(std::uint32_t reason) {
<< " attached functors; exit reason = " << reason << " attached functors; exit reason = " << reason
<< ", class = " << detail::demangle(typeid(*this))); << ", class = " << detail::demangle(typeid(*this)));
// send exit messages // send exit messages
auto msg = make_any_tuple(exit_msg{address(), reason}); auto msg = make_message(exit_msg{address(), reason});
CPPA_LOGM_DEBUG("cppa::actor", "send EXIT to " << mlinks.size() << " links"); CPPA_LOGM_DEBUG("cppa::actor", "send EXIT to " << mlinks.size() << " links");
for (auto& aptr : mlinks) { for (auto& aptr : mlinks) {
aptr->enqueue({address(), aptr, message_id{}.with_high_priority()}, aptr->enqueue({address(), aptr, message_id{}.with_high_priority()},
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/abstract_group.hpp" #include "cppa/abstract_group.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/util/shared_spinlock.hpp" #include "cppa/util/shared_spinlock.hpp"
#include "cppa/util/shared_lock_guard.hpp" #include "cppa/util/shared_lock_guard.hpp"
...@@ -81,7 +81,7 @@ void publish_local_groups(std::uint16_t port, const char* addr) { ...@@ -81,7 +81,7 @@ void publish_local_groups(std::uint16_t port, const char* addr) {
} }
catch (std::exception&) { catch (std::exception&) {
gn->enqueue({invalid_actor_addr, nullptr}, gn->enqueue({invalid_actor_addr, nullptr},
make_any_tuple(atom("SHUTDOWN")), make_message(atom("SHUTDOWN")),
nullptr); nullptr);
throw; throw;
} }
......
...@@ -35,7 +35,7 @@ void actor_companion::on_enqueue(enqueue_handler handler) { ...@@ -35,7 +35,7 @@ void actor_companion::on_enqueue(enqueue_handler handler) {
m_on_enqueue = std::move(handler); m_on_enqueue = std::move(handler);
} }
void actor_companion::enqueue(msg_hdr_cref hdr, any_tuple ct, execution_unit*) { void actor_companion::enqueue(msg_hdr_cref hdr, message ct, execution_unit*) {
message_pointer ptr; message_pointer ptr;
ptr.reset(detail::memory::create<mailbox_element>(hdr, std::move(ct))); ptr.reset(detail::memory::create<mailbox_element>(hdr, std::move(ct)));
util::shared_lock_guard<lock_type> guard(m_lock); util::shared_lock_guard<lock_type> guard(m_lock);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/actor_proxy.hpp" #include "cppa/actor_proxy.hpp"
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
namespace cppa { namespace cppa {
...@@ -45,18 +45,14 @@ class continuation_decorator : public detail::behavior_impl { ...@@ -45,18 +45,14 @@ class continuation_decorator : public detail::behavior_impl {
return none; return none;
} }
bhvr_invoke_result invoke(any_tuple& tup) { bhvr_invoke_result invoke(message& tup) {
return invoke_impl(tup); return invoke_impl(tup);
} }
bhvr_invoke_result invoke(const any_tuple& tup) { bhvr_invoke_result invoke(const message& tup) {
return invoke_impl(tup); return invoke_impl(tup);
} }
bool defined_at(const any_tuple& tup) {
return m_decorated->defined_at(tup);
}
pointer copy(const generic_timeout_definition& tdef) const { pointer copy(const generic_timeout_definition& tdef) const {
return new continuation_decorator(m_fun, m_decorated->copy(tdef)); return new continuation_decorator(m_fun, m_decorated->copy(tdef));
} }
...@@ -71,7 +67,7 @@ class continuation_decorator : public detail::behavior_impl { ...@@ -71,7 +67,7 @@ class continuation_decorator : public detail::behavior_impl {
}; };
} // namespace <anonymous> } // namespace <anonymous>
behavior::behavior(const partial_function& fun) : m_impl(fun.m_impl) { } behavior::behavior(const message_handler& fun) : m_impl(fun.m_impl) { }
behavior behavior::add_continuation(continuation_fun fun) { behavior behavior::add_continuation(continuation_fun fun) {
return behavior::impl_ptr{new continuation_decorator(std::move(fun), return behavior::impl_ptr{new continuation_decorator(std::move(fun),
......
...@@ -70,7 +70,7 @@ class broker::continuation { ...@@ -70,7 +70,7 @@ class broker::continuation {
public: public:
continuation(broker_ptr ptr, msg_hdr_cref hdr, any_tuple&& msg) continuation(broker_ptr ptr, msg_hdr_cref hdr, message&& msg)
: m_self(move(ptr)), m_hdr(hdr), m_data(move(msg)) { } : m_self(move(ptr)), m_hdr(hdr), m_data(move(msg)) { }
inline void operator()() { inline void operator()() {
...@@ -83,7 +83,7 @@ class broker::continuation { ...@@ -83,7 +83,7 @@ class broker::continuation {
broker_ptr m_self; broker_ptr m_self;
message_header m_hdr; message_header m_hdr;
any_tuple m_data; message m_data;
}; };
...@@ -125,7 +125,7 @@ class broker::servant : public continuable { ...@@ -125,7 +125,7 @@ class broker::servant : public continuable {
} }
} }
virtual any_tuple disconnect_message() = 0; virtual message disconnect_message() = 0;
bool m_disconnected; bool m_disconnected;
...@@ -216,9 +216,9 @@ class broker::scribe : public extend<broker::servant>::with<buffered_writing> { ...@@ -216,9 +216,9 @@ class broker::scribe : public extend<broker::servant>::with<buffered_writing> {
protected: protected:
any_tuple disconnect_message() override { message disconnect_message() override {
auto hdl = connection_handle::from_int(m_in->read_handle()); auto hdl = connection_handle::from_int(m_in->read_handle());
return make_any_tuple(connection_closed_msg{hdl}); return make_message(connection_closed_msg{hdl});
} }
private: private:
...@@ -270,9 +270,9 @@ class broker::doorman : public broker::servant { ...@@ -270,9 +270,9 @@ class broker::doorman : public broker::servant {
protected: protected:
any_tuple disconnect_message() override { message disconnect_message() override {
auto hdl = accept_handle::from_int(m_ptr->file_handle()); auto hdl = accept_handle::from_int(m_ptr->file_handle());
return make_any_tuple(acceptor_closed_msg{hdl}); return make_message(acceptor_closed_msg{hdl});
} }
private: private:
...@@ -285,7 +285,7 @@ class broker::doorman : public broker::servant { ...@@ -285,7 +285,7 @@ class broker::doorman : public broker::servant {
// avoid weak-vtables warning by providing dtor out-of-line // avoid weak-vtables warning by providing dtor out-of-line
broker::doorman::~doorman() { } broker::doorman::~doorman() { }
void broker::invoke_message(msg_hdr_cref hdr, any_tuple msg) { void broker::invoke_message(msg_hdr_cref hdr, message msg) {
CPPA_LOG_TRACE(CPPA_TARG(msg, to_string)); CPPA_LOG_TRACE(CPPA_TARG(msg, to_string));
if (planned_exit_reason() != exit_reason::not_exited || bhvr_stack().empty()) { if (planned_exit_reason() != exit_reason::not_exited || bhvr_stack().empty()) {
CPPA_LOG_DEBUG("actor already finished execution" CPPA_LOG_DEBUG("actor already finished execution"
...@@ -372,7 +372,7 @@ bool broker::invoke_message_from_cache() { ...@@ -372,7 +372,7 @@ bool broker::invoke_message_from_cache() {
return false; return false;
} }
void broker::enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit*) { void broker::enqueue(msg_hdr_cref hdr, message msg, execution_unit*) {
get_middleman()->run_later(continuation{this, hdr, move(msg)}); get_middleman()->run_later(continuation{this, hdr, move(msg)});
} }
...@@ -441,7 +441,7 @@ broker_ptr init_and_launch(broker_ptr ptr) { ...@@ -441,7 +441,7 @@ broker_ptr init_and_launch(broker_ptr ptr) {
} }
); );
ptr->enqueue({invalid_actor_addr, ptr}, ptr->enqueue({invalid_actor_addr, ptr},
make_any_tuple(atom("INITMSG")), make_message(atom("INITMSG")),
nullptr); nullptr);
return ptr; return ptr;
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/detail/raw_access.hpp" #include "cppa/detail/raw_access.hpp"
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "cppa/group.hpp" #include "cppa/group.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
#include "cppa/detail/group_manager.hpp" #include "cppa/detail/group_manager.hpp"
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/group.hpp" #include "cppa/group.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
...@@ -60,7 +60,7 @@ class local_group : public abstract_group { ...@@ -60,7 +60,7 @@ class local_group : public abstract_group {
public: public:
void send_all_subscribers(msg_hdr_cref hdr, const any_tuple& msg, void send_all_subscribers(msg_hdr_cref hdr, const message& msg,
execution_unit* eu) { execution_unit* eu) {
CPPA_LOG_TRACE(CPPA_TARG(hdr.sender, to_string) << ", " CPPA_LOG_TRACE(CPPA_TARG(hdr.sender, to_string) << ", "
<< CPPA_TARG(msg, to_string)); << CPPA_TARG(msg, to_string));
...@@ -70,7 +70,7 @@ class local_group : public abstract_group { ...@@ -70,7 +70,7 @@ class local_group : public abstract_group {
} }
} }
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit* eu) override { void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override {
CPPA_LOG_TRACE(CPPA_TARG(hdr, to_string) << ", " CPPA_LOG_TRACE(CPPA_TARG(hdr, to_string) << ", "
<< CPPA_TARG(msg, to_string)); << CPPA_TARG(msg, to_string));
send_all_subscribers(hdr, msg, eu); send_all_subscribers(hdr, msg, eu);
...@@ -146,7 +146,7 @@ class local_broker : public event_based_actor { ...@@ -146,7 +146,7 @@ class local_broker : public event_based_actor {
demonitor(other); demonitor(other);
} }
}, },
on(atom("FORWARD"), arg_match) >> [=](const any_tuple& what) { on(atom("FORWARD"), arg_match) >> [=](const message& what) {
CPPA_LOGC_TRACE("cppa::local_broker", "init$FORWARD", CPPA_LOGC_TRACE("cppa::local_broker", "init$FORWARD",
CPPA_TARG(what, to_string)); CPPA_TARG(what, to_string));
// local forwarding // local forwarding
...@@ -179,7 +179,7 @@ class local_broker : public event_based_actor { ...@@ -179,7 +179,7 @@ class local_broker : public event_based_actor {
private: private:
void send_to_acquaintances(const any_tuple& what) { void send_to_acquaintances(const message& what) {
// send to all remote subscribers // send to all remote subscribers
auto sender = last_sender(); auto sender = last_sender();
CPPA_LOG_DEBUG("forward message to " << m_acquaintances.size() CPPA_LOG_DEBUG("forward message to " << m_acquaintances.size()
...@@ -240,9 +240,9 @@ class local_group_proxy : public local_group { ...@@ -240,9 +240,9 @@ class local_group_proxy : public local_group {
} }
} }
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit* eu) override { void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override {
// forward message to the broker // forward message to the broker
m_broker->enqueue(hdr, make_any_tuple(atom("FORWARD"), move(msg)), eu); m_broker->enqueue(hdr, make_message(atom("FORWARD"), move(msg)), eu);
} }
private: private:
...@@ -369,7 +369,7 @@ class remote_group : public abstract_group { ...@@ -369,7 +369,7 @@ class remote_group : public abstract_group {
CPPA_LOG_ERROR("should never be called"); CPPA_LOG_ERROR("should never be called");
} }
void enqueue(msg_hdr_cref hdr, any_tuple msg, execution_unit* eu) override { void enqueue(msg_hdr_cref hdr, message msg, execution_unit* eu) override {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
m_decorated->enqueue(hdr, std::move(msg), eu); m_decorated->enqueue(hdr, std::move(msg), eu);
} }
...@@ -380,7 +380,7 @@ class remote_group : public abstract_group { ...@@ -380,7 +380,7 @@ class remote_group : public abstract_group {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
group_down_msg gdm{group{this}}; group_down_msg gdm{group{this}};
m_decorated->send_all_subscribers({invalid_actor_addr, nullptr}, m_decorated->send_all_subscribers({invalid_actor_addr, nullptr},
make_any_tuple(gdm), nullptr); make_message(gdm), nullptr);
} }
private: private:
......
...@@ -46,7 +46,7 @@ class down_observer : public attachable { ...@@ -46,7 +46,7 @@ class down_observer : public attachable {
void actor_exited(std::uint32_t reason) { void actor_exited(std::uint32_t reason) {
auto ptr = detail::raw_access::get(m_observer); auto ptr = detail::raw_access::get(m_observer);
message_header hdr{m_observed, ptr, message_id{}.with_high_priority()}; message_header hdr{m_observed, ptr, message_id{}.with_high_priority()};
hdr.deliver(make_any_tuple(down_msg{m_observed, reason})); hdr.deliver(make_message(down_msg{m_observed, reason}));
} }
bool matches(const attachable::token& match_token) { bool matches(const attachable::token& match_token) {
...@@ -104,7 +104,7 @@ std::vector<group> local_actor::joined_groups() const { ...@@ -104,7 +104,7 @@ std::vector<group> local_actor::joined_groups() const {
return result; return result;
} }
void local_actor::reply_message(any_tuple&& what) { void local_actor::reply_message(message&& what) {
auto& whom = m_current_node->sender; auto& whom = m_current_node->sender;
if (!whom) return; if (!whom) return;
auto& id = m_current_node->mid; auto& id = m_current_node->mid;
...@@ -130,7 +130,7 @@ void local_actor::forward_message(const actor& dest, message_priority prio) { ...@@ -130,7 +130,7 @@ void local_actor::forward_message(const actor& dest, message_priority prio) {
m_current_node->mid = message_id::invalid; m_current_node->mid = message_id::invalid;
} }
void local_actor::send_tuple(message_priority prio, const channel& dest, any_tuple what) { void local_actor::send_tuple(message_priority prio, const channel& dest, message what) {
if (!dest) return; if (!dest) return;
message_id id; message_id id;
if (prio == message_priority::high) id = id.with_high_priority(); if (prio == message_priority::high) id = id.with_high_priority();
...@@ -144,7 +144,7 @@ void local_actor::send_exit(const actor_addr& whom, std::uint32_t reason) { ...@@ -144,7 +144,7 @@ void local_actor::send_exit(const actor_addr& whom, std::uint32_t reason) {
void local_actor::delayed_send_tuple(message_priority prio, void local_actor::delayed_send_tuple(message_priority prio,
const channel& dest, const channel& dest,
const util::duration& rel_time, const util::duration& rel_time,
cppa::any_tuple msg) { cppa::message msg) {
message_id mid; message_id mid;
if (prio == message_priority::high) mid = mid.with_high_priority(); if (prio == message_priority::high) mid = mid.with_high_priority();
get_scheduling_coordinator()->delayed_send({address(), dest, mid}, get_scheduling_coordinator()->delayed_send({address(), dest, mid},
...@@ -173,7 +173,7 @@ void local_actor::quit(std::uint32_t reason) { ...@@ -173,7 +173,7 @@ void local_actor::quit(std::uint32_t reason) {
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp, message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
const actor& dest, const actor& dest,
const util::duration& rtime, const util::duration& rtime,
any_tuple&& what) { message&& what) {
if (!dest) { if (!dest) {
throw std::invalid_argument("cannot send synchronous message " throw std::invalid_argument("cannot send synchronous message "
"to invalid_actor"); "to invalid_actor");
...@@ -183,13 +183,13 @@ message_id local_actor::timed_sync_send_tuple_impl(message_priority mp, ...@@ -183,13 +183,13 @@ message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
dest->enqueue({address(), dest, nri}, std::move(what), m_host); dest->enqueue({address(), dest, nri}, std::move(what), m_host);
auto rri = nri.response_id(); auto rri = nri.response_id();
get_scheduling_coordinator()->delayed_send({address(), this, rri}, rtime, get_scheduling_coordinator()->delayed_send({address(), this, rri}, rtime,
make_any_tuple(sync_timeout_msg{})); make_message(sync_timeout_msg{}));
return rri; return rri;
} }
message_id local_actor::sync_send_tuple_impl(message_priority mp, message_id local_actor::sync_send_tuple_impl(message_priority mp,
const actor& dest, const actor& dest,
any_tuple&& what) { message&& what) {
if (!dest) { if (!dest) {
throw std::invalid_argument("cannot send synchronous message " throw std::invalid_argument("cannot send synchronous message "
"to invalid_actor"); "to invalid_actor");
...@@ -204,7 +204,7 @@ void anon_send_exit(const actor_addr& whom, std::uint32_t reason) { ...@@ -204,7 +204,7 @@ void anon_send_exit(const actor_addr& whom, std::uint32_t reason) {
if (!whom) return; if (!whom) return;
auto ptr = detail::raw_access::get(whom); auto ptr = detail::raw_access::get(whom);
ptr->enqueue({invalid_actor_addr, ptr, message_id{}.with_high_priority()}, ptr->enqueue({invalid_actor_addr, ptr, message_id{}.with_high_priority()},
make_any_tuple(exit_msg{invalid_actor_addr, reason}), nullptr); make_message(exit_msg{invalid_actor_addr, reason}), nullptr);
} }
} // namespace cppa } // namespace cppa
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
namespace cppa { namespace cppa {
mailbox_element::mailbox_element(msg_hdr_cref hdr, any_tuple data) mailbox_element::mailbox_element(msg_hdr_cref hdr, message data)
: next(nullptr), marked(false), sender(hdr.sender) : next(nullptr), marked(false), sender(hdr.sender)
, msg(std::move(data)), mid(hdr.id) { } , msg(std::move(data)), mid(hdr.id) { }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include "cppa/match.hpp" #include "cppa/match.hpp"
using namespace std; using namespace std;
...@@ -27,13 +28,13 @@ using namespace std; ...@@ -27,13 +28,13 @@ using namespace std;
namespace cppa { namespace cppa {
detail::match_helper match_split(const std::string& str, char delim, bool keep_empties) { detail::match_helper match_split(const std::string& str, char delim, bool keep_empties) {
vector<string> result; message_builder result;
stringstream strs(str); stringstream strs(str);
string tmp; string tmp;
while (getline(strs, tmp, delim)) { while (getline(strs, tmp, delim)) {
if (!tmp.empty() && !keep_empties) result.push_back(std::move(tmp)); if (!tmp.empty() && !keep_empties) result.append(std::move(tmp));
} }
return match(any_tuple::view(std::move(result))); return result.to_message();
} }
} // namespace cppa } // namespace cppa
...@@ -16,63 +16,78 @@ ...@@ -16,63 +16,78 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#include "cppa/message.hpp"
#include "cppa/message_handler.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/detail/decorated_tuple.hpp"
#include "cppa/singletons.hpp"
namespace cppa { namespace cppa {
any_tuple::any_tuple(detail::abstract_tuple* ptr) : m_vals(ptr) { } message::message(detail::message_data* ptr) : m_vals(ptr) {}
any_tuple::any_tuple(any_tuple&& other) : m_vals(std::move(other.m_vals)) { } message::message(message&& other) : m_vals(std::move(other.m_vals)) {}
any_tuple::any_tuple(const data_ptr& vals) : m_vals(vals) { } message::message(const data_ptr& vals) : m_vals(vals) {}
any_tuple& any_tuple::operator=(any_tuple&& other) { message& message::operator=(message&& other) {
m_vals.swap(other.m_vals); m_vals.swap(other.m_vals);
return *this; return *this;
} }
void any_tuple::reset() { void message::reset() { m_vals.reset(); }
m_vals.reset();
}
void* any_tuple::mutable_at(size_t p) { void* message::mutable_at(size_t p) {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
return m_vals->mutable_at(p); return m_vals->mutable_at(p);
} }
const void* any_tuple::at(size_t p) const { const void* message::at(size_t p) const {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
return m_vals->at(p); return m_vals->at(p);
} }
const uniform_type_info* any_tuple::type_at(size_t p) const { const uniform_type_info* message::type_at(size_t p) const {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
return m_vals->type_at(p); return m_vals->type_at(p);
} }
bool any_tuple::equals(const any_tuple& other) const { bool message::equals(const message& other) const {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
return m_vals->equals(*other.vals()); return m_vals->equals(*other.vals());
} }
any_tuple any_tuple::drop(size_t n) const { message message::drop(size_t n) const {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
if (n == 0) return *this; if (n == 0) return *this;
if (n >= size()) return any_tuple{}; if (n >= size()) return message{};
return any_tuple{detail::decorated_tuple::create(m_vals, n)}; return message{detail::decorated_tuple::create(m_vals, n)};
} }
any_tuple any_tuple::drop_right(size_t n) const { message message::drop_right(size_t n) const {
CPPA_REQUIRE(m_vals != nullptr); CPPA_REQUIRE(m_vals);
using namespace std;
if (n == 0) return *this; if (n == 0) return *this;
if (n >= size()) return any_tuple{}; if (n >= size()) return message{};
vector<size_t> mapping(size() - n); std::vector<size_t> mapping(size() - n);
size_t i = 0; size_t i = 0;
generate(mapping.begin(), mapping.end(), [&] { return i++; }); std::generate(mapping.begin(), mapping.end(), [&] { return i++; });
return any_tuple{detail::decorated_tuple::create(m_vals, move(mapping))}; return message{detail::decorated_tuple::create(m_vals, std::move(mapping))};
}
optional<message> message::apply(message_handler handler) {
return handler(*this);
}
bool message::apply_iterative(message_handler handler) {
if (empty()) return true;
for (size_t chunk_size = 1; chunk_size <= size(); ++chunk_size) {
auto chunk = take(chunk_size);
auto remainder = drop(chunk_size);
if (handler(chunk)) {
return remainder.empty() ? true
: remainder.apply_iterative(std::move(handler));
}
}
return false;
} }
} // namespace cppa } // namespace cppa
...@@ -16,76 +16,77 @@ ...@@ -16,76 +16,77 @@
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt * * accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/ \******************************************************************************/
#include <vector>
#ifndef CPPA_DETAIL_CONTAINER_TUPLE_VIEW_HPP #include "cppa/message_builder.hpp"
#define CPPA_DETAIL_CONTAINER_TUPLE_VIEW_HPP #include "cppa/message_handler.hpp"
#include "cppa/uniform_type_info.hpp"
#include <iostream>
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/disablable_delete.hpp"
namespace cppa { namespace cppa {
namespace detail {
template<class Container> namespace {
class container_tuple_view : public abstract_tuple {
typedef abstract_tuple super; class dynamic_msg_data : public detail::message_data {
typedef typename Container::difference_type difference_type; typedef message_data super;
public: public:
typedef typename Container::value_type value_type; using message_data::const_iterator;
container_tuple_view(Container* c, bool take_ownership = false) dynamic_msg_data(const dynamic_msg_data& other) : super(true) {
: super(true), m_ptr(c) { for (auto& d : other.m_data) {
CPPA_REQUIRE(c != nullptr); m_data.push_back(d->copy());
if (!take_ownership) m_ptr.get_deleter().disable();
} }
size_t size() const override {
return m_ptr->size();
} }
abstract_tuple* copy() const override { dynamic_msg_data(std::vector<uniform_value>&& data)
return new container_tuple_view{new Container(*m_ptr), true}; : super(true), m_data(std::move(data)) {}
}
const void* at(size_t pos) const override { const void* at(size_t pos) const override {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0); return m_data[pos]->val;
auto i = m_ptr->cbegin();
std::advance(i, static_cast<difference_type>(pos));
return &(*i);
} }
void* mutable_at(size_t pos) override { void* mutable_at(size_t pos) override {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0); return m_data[pos]->val;
auto i = m_ptr->begin();
std::advance(i, static_cast<difference_type>(pos));
return &(*i);
} }
const uniform_type_info* type_at(size_t) const override { size_t size() const override { return m_data.size(); }
return static_types_array<value_type>::arr[0];
dynamic_msg_data* copy() const override {
return new dynamic_msg_data(*this);
}
const uniform_type_info* type_at(size_t pos) const override {
CPPA_REQUIRE(pos < size());
return m_data[pos]->ti;
} }
const std::string* tuple_type_names() const override { const std::string* tuple_type_names() const override {
static std::string result = demangle<value_type>(); return nullptr; // get_tuple_type_names(*this);
return &result;
} }
private: private:
std::unique_ptr<Container, disablable_delete> m_ptr; std::vector<uniform_value> m_data;
}; };
} // namespace detail } // namespace <anonymous>
} // namespace cppa
message_builder& message_builder::append(uniform_value what) {
m_elements.push_back(std::move(what));
return *this;
}
#endif // CPPA_DETAIL_CONTAINER_TUPLE_VIEW_HPP message message_builder::to_message() {
return message{new dynamic_msg_data(std::move(m_elements))};
}
optional<message> message_builder::apply(message_handler handler) {
return to_message().apply(std::move(handler));
}
} // namespace cppa
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/config.hpp" #include "cppa/config.hpp"
#include "cppa/partial_function.hpp" #include "cppa/message_handler.hpp"
namespace cppa { namespace cppa {
partial_function::partial_function(impl_ptr ptr) : m_impl(std::move(ptr)) { } message_handler::message_handler(impl_ptr ptr) : m_impl(std::move(ptr)) { }
void detail::behavior_impl::handle_timeout() { } void detail::behavior_impl::handle_timeout() { }
...@@ -33,15 +33,15 @@ void detail::behavior_impl::handle_timeout() { } ...@@ -33,15 +33,15 @@ void detail::behavior_impl::handle_timeout() { }
namespace cppa { namespace cppa {
namespace detail { namespace detail {
behavior_impl_ptr combine(behavior_impl_ptr lhs, const partial_function& rhs) { behavior_impl_ptr combine(behavior_impl_ptr lhs, const message_handler& rhs) {
return lhs->or_else(rhs.as_behavior_impl()); return lhs->or_else(rhs.as_behavior_impl());
} }
behavior_impl_ptr combine(const partial_function& lhs, behavior_impl_ptr rhs) { behavior_impl_ptr combine(const message_handler& lhs, behavior_impl_ptr rhs) {
return lhs.as_behavior_impl()->or_else(rhs); return lhs.as_behavior_impl()->or_else(rhs);
} }
behavior_impl_ptr extract(const partial_function& arg) { behavior_impl_ptr extract(const message_handler& arg) {
return arg.as_behavior_impl(); return arg.as_behavior_impl();
} }
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
\******************************************************************************/ \******************************************************************************/
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
namespace cppa { namespace cppa {
...@@ -37,7 +37,7 @@ bool operator!=(const message_header& lhs, const message_header& rhs) { ...@@ -37,7 +37,7 @@ bool operator!=(const message_header& lhs, const message_header& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
void message_header::deliver(any_tuple msg) const { void message_header::deliver(message msg) const {
if (receiver) receiver->enqueue(*this, std::move(msg), nullptr); if (receiver) receiver->enqueue(*this, std::move(msg), nullptr);
} }
......
...@@ -221,7 +221,7 @@ class middleman_impl : public middleman { ...@@ -221,7 +221,7 @@ class middleman_impl : public middleman {
void deliver(const node_id& node, void deliver(const node_id& node,
msg_hdr_cref hdr, msg_hdr_cref hdr,
any_tuple msg ) override { message msg ) override {
auto& entry = m_peers[node]; auto& entry = m_peers[node];
if (entry.impl) { if (entry.impl) {
CPPA_REQUIRE(entry.queue != nullptr); CPPA_REQUIRE(entry.queue != nullptr);
...@@ -295,7 +295,7 @@ class middleman_impl : public middleman { ...@@ -295,7 +295,7 @@ class middleman_impl : public middleman {
const node_id& node) { const node_id& node) {
deliver(node, deliver(node,
{invalid_actor_addr, nullptr}, {invalid_actor_addr, nullptr},
make_any_tuple(atom("MONITOR"), make_message(atom("MONITOR"),
m_node, m_node,
aid)); aid));
}); });
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 *
\******************************************************************************/
#include "cppa/detail/object_array.hpp"
namespace cppa {
namespace detail {
object_array::object_array() : super(true) {
// nop
}
object_array::object_array(const object_array& other) : super(true) {
m_elements.reserve(other.m_elements.size());
for (auto& e : other.m_elements) m_elements.push_back(e->copy());
}
object_array::~object_array() {
// nop
}
void object_array::push_back(uniform_value what) {
CPPA_REQUIRE(what && what->val != nullptr && what->ti != nullptr);
m_elements.push_back(std::move(what));
}
void* object_array::mutable_at(size_t pos) {
CPPA_REQUIRE(pos < size());
return m_elements[pos]->val;
}
size_t object_array::size() const {
return m_elements.size();
}
object_array* object_array::copy() const {
return new object_array(*this);
}
const void* object_array::at(size_t pos) const {
CPPA_REQUIRE(pos < size());
return m_elements[pos]->val;
}
const uniform_type_info* object_array::type_at(size_t pos) const {
CPPA_REQUIRE(pos < size());
return m_elements[pos]->ti;
}
const std::string* object_array::tuple_type_names() const {
return nullptr; // get_tuple_type_names(*this);
}
} // namespace util
} // namespace cppa
...@@ -22,11 +22,21 @@ ...@@ -22,11 +22,21 @@
#include "cppa/opt.hpp" #include "cppa/opt.hpp"
using namespace std; using namespace std;
using cppa::placeholders::_x1;
namespace cppa { namespace cppa {
detail::opt1_rvalue_builder<true> on_opt1(char short_opt, using string_proj = function<optional<string> (const string&)>;
string_proj extract_longopt_arg(const string& prefix) {
return [prefix](const string& arg) -> optional<string> {
if (arg.compare(0, prefix.size(), prefix)) {
return string(arg.begin() + prefix.size(), arg.end());
}
return none;
};
}
opt_rvalue_builder on_opt1(char short_opt,
string long_opt, string long_opt,
options_description* desc, options_description* desc,
string help_text, string help_text,
...@@ -53,11 +63,11 @@ detail::opt1_rvalue_builder<true> on_opt1(char short_opt, ...@@ -53,11 +63,11 @@ detail::opt1_rvalue_builder<true> on_opt1(char short_opt,
opts.push_back(lhs_str); opts.push_back(lhs_str);
opts.push_back("--" + long_opt); opts.push_back("--" + long_opt);
opts.push_back("-" + long_opt); opts.push_back("-" + long_opt);
return {short_opt, long_opt, on<string, string>().when(_x1.in(opts)), on(kvp)}; return on(extract_longopt_arg(prefix)) || on(lhs_str, val<string>);
//return {short_opt, long_opt, on<string, string>().when(_x1.in(opts)), on(kvp)};
} }
decltype(on<string>().when(_x1.in(vector<string>()))) opt0_rvalue_builder on_opt0(char short_opt,
on_opt0(char short_opt,
string long_opt, string long_opt,
options_description* desc, options_description* desc,
string help_text, string help_text,
...@@ -67,10 +77,8 @@ on_opt0(char short_opt, ...@@ -67,10 +77,8 @@ on_opt0(char short_opt,
(*desc)[help_group].insert(make_pair(make_pair(short_opt, long_opt), move(oinf))); (*desc)[help_group].insert(make_pair(make_pair(short_opt, long_opt), move(oinf)));
} }
const char short_flag_arr[] = {'-', short_opt, '\0' }; const char short_flag_arr[] = {'-', short_opt, '\0' };
vector<string> opt_strs = { short_flag_arr }; string short_opt_string = short_flag_arr;
opt_strs.push_back("-" + long_opt); return on(long_opt) || on(short_opt_string);
opt_strs.push_back("--" + move(long_opt));
return on<string>().when(_x1.in(move(opt_strs)));
} }
function<void()> print_desc(options_description* desc, ostream& out) { function<void()> print_desc(options_description* desc, ostream& out) {
......
...@@ -63,7 +63,7 @@ peer::peer(middleman* parent, ...@@ -63,7 +63,7 @@ peer::peer(middleman* parent,
// in this case, this peer must be erased if no proxy of it remains // in this case, this peer must be erased if no proxy of it remains
m_stop_on_last_proxy_exited = m_state == wait_for_msg_size; m_stop_on_last_proxy_exited = m_state == wait_for_msg_size;
m_meta_hdr = uniform_typeid<message_header>(); m_meta_hdr = uniform_typeid<message_header>();
m_meta_msg = uniform_typeid<any_tuple>(); m_meta_msg = uniform_typeid<message>();
} }
void peer::io_failed(event_bitmask mask) { void peer::io_failed(event_bitmask mask) {
...@@ -133,7 +133,7 @@ continue_reading_result peer::continue_reading() { ...@@ -133,7 +133,7 @@ continue_reading_result peer::continue_reading() {
case read_message: { case read_message: {
//DEBUG("peer_connection::continue_reading: read_message"); //DEBUG("peer_connection::continue_reading: read_message");
message_header hdr; message_header hdr;
any_tuple msg; message msg;
binary_deserializer bd(m_rd_buf.data(), m_rd_buf.size(), binary_deserializer bd(m_rd_buf.data(), m_rd_buf.size(),
&(parent()->get_namespace()), &m_incoming_types); &(parent()->get_namespace()), &m_incoming_types);
try { try {
...@@ -208,7 +208,7 @@ void peer::monitor(const actor_addr&, ...@@ -208,7 +208,7 @@ void peer::monitor(const actor_addr&,
// this actor already finished execution; // this actor already finished execution;
// reply with KILL_PROXY message // reply with KILL_PROXY message
// get corresponding peer // get corresponding peer
enqueue(make_any_tuple(atom("KILL_PROXY"), pself, aid, entry.second)); enqueue(make_message(atom("KILL_PROXY"), pself, aid, entry.second));
} }
} }
else { else {
...@@ -220,7 +220,7 @@ void peer::monitor(const actor_addr&, ...@@ -220,7 +220,7 @@ void peer::monitor(const actor_addr&,
"monitor$kill_proxy_helper", "monitor$kill_proxy_helper",
"reason = " << reason); "reason = " << reason);
auto p = mm->get_peer(*node); auto p = mm->get_peer(*node);
if (p) p->enqueue(make_any_tuple(atom("KILL_PROXY"), pself, aid, reason)); if (p) p->enqueue(make_message(atom("KILL_PROXY"), pself, aid, reason));
}); });
}); });
} }
...@@ -256,7 +256,7 @@ void peer::kill_proxy(const actor_addr& sender, ...@@ -256,7 +256,7 @@ void peer::kill_proxy(const actor_addr& sender,
} }
} }
void peer::deliver(msg_hdr_cref hdr, any_tuple msg) { void peer::deliver(msg_hdr_cref hdr, message msg) {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
if (hdr.sender && hdr.sender.is_remote()) { if (hdr.sender && hdr.sender.is_remote()) {
// is_remote() is guaranteed to return true if and only if // is_remote() is guaranteed to return true if and only if
...@@ -347,11 +347,11 @@ void peer::add_type_if_needed(const std::string& tname) { ...@@ -347,11 +347,11 @@ void peer::add_type_if_needed(const std::string& tname) {
auto imap = get_uniform_type_info_map(); auto imap = get_uniform_type_info_map();
auto uti = imap->by_uniform_name(tname); auto uti = imap->by_uniform_name(tname);
m_outgoing_types.emplace(id, uti); m_outgoing_types.emplace(id, uti);
enqueue_impl({invalid_actor_addr, nullptr}, make_any_tuple(atom("ADD_TYPE"), id, tname)); enqueue_impl({invalid_actor_addr, nullptr}, make_message(atom("ADD_TYPE"), id, tname));
} }
} }
void peer::enqueue_impl(msg_hdr_cref hdr, const any_tuple& msg) { void peer::enqueue_impl(msg_hdr_cref hdr, const message& msg) {
CPPA_LOG_TRACE(""); CPPA_LOG_TRACE("");
auto tname = msg.tuple_type_names(); auto tname = msg.tuple_type_names();
add_type_if_needed((tname) ? *tname : detail::get_tuple_type_names(*msg.vals())); add_type_if_needed((tname) ? *tname : detail::get_tuple_type_names(*msg.vals()));
...@@ -372,7 +372,7 @@ void peer::enqueue_impl(msg_hdr_cref hdr, const any_tuple& msg) { ...@@ -372,7 +372,7 @@ void peer::enqueue_impl(msg_hdr_cref hdr, const any_tuple& msg) {
memcpy(wbuf.offset_data(before), &size, sizeof(std::uint32_t)); memcpy(wbuf.offset_data(before), &size, sizeof(std::uint32_t));
} }
void peer::enqueue(msg_hdr_cref hdr, const any_tuple& msg) { void peer::enqueue(msg_hdr_cref hdr, const message& msg) {
enqueue_impl(hdr, msg); enqueue_impl(hdr, msg);
register_for_writing(); register_for_writing();
} }
......
...@@ -73,7 +73,7 @@ remote_actor_proxy::~remote_actor_proxy() { ...@@ -73,7 +73,7 @@ remote_actor_proxy::~remote_actor_proxy() {
}); });
} }
void remote_actor_proxy::deliver(msg_hdr_cref hdr, any_tuple msg) { void remote_actor_proxy::deliver(msg_hdr_cref hdr, message msg) {
// this member function is exclusively called from default_peer from inside // this member function is exclusively called from default_peer from inside
// the middleman's thread, therefore we can safely access // the middleman's thread, therefore we can safely access
// m_pending_requests here // m_pending_requests here
...@@ -87,7 +87,7 @@ void remote_actor_proxy::deliver(msg_hdr_cref hdr, any_tuple msg) { ...@@ -87,7 +87,7 @@ void remote_actor_proxy::deliver(msg_hdr_cref hdr, any_tuple msg) {
hdr.deliver(std::move(msg)); hdr.deliver(std::move(msg));
} }
void remote_actor_proxy::forward_msg(msg_hdr_cref hdr, any_tuple msg) { void remote_actor_proxy::forward_msg(msg_hdr_cref hdr, message msg) {
CPPA_LOG_TRACE(CPPA_ARG(m_id) << ", " << CPPA_TSARG(hdr) CPPA_LOG_TRACE(CPPA_ARG(m_id) << ", " << CPPA_TSARG(hdr)
<< ", " << CPPA_TSARG(msg)); << ", " << CPPA_TSARG(msg));
if (hdr.receiver != this) { if (hdr.receiver != this) {
...@@ -129,7 +129,7 @@ void remote_actor_proxy::forward_msg(msg_hdr_cref hdr, any_tuple msg) { ...@@ -129,7 +129,7 @@ void remote_actor_proxy::forward_msg(msg_hdr_cref hdr, any_tuple msg) {
}); });
} }
void remote_actor_proxy::enqueue(msg_hdr_cref hdr, any_tuple msg, void remote_actor_proxy::enqueue(msg_hdr_cref hdr, message msg,
execution_unit*) { execution_unit*) {
CPPA_REQUIRE(m_parent != nullptr); CPPA_REQUIRE(m_parent != nullptr);
CPPA_LOG_TRACE(CPPA_TARG(hdr, to_string) CPPA_LOG_TRACE(CPPA_TARG(hdr, to_string)
...@@ -166,21 +166,21 @@ void remote_actor_proxy::link_to(const actor_addr& other) { ...@@ -166,21 +166,21 @@ void remote_actor_proxy::link_to(const actor_addr& other) {
if (link_to_impl(other)) { if (link_to_impl(other)) {
// causes remote actor to link to (proxy of) other // causes remote actor to link to (proxy of) other
// receiving peer will call: this->local_link_to(other) // receiving peer will call: this->local_link_to(other)
forward_msg({address(), this}, make_any_tuple(atom("LINK"), other)); forward_msg({address(), this}, make_message(atom("LINK"), other));
} }
} }
void remote_actor_proxy::unlink_from(const actor_addr& other) { void remote_actor_proxy::unlink_from(const actor_addr& other) {
if (unlink_from_impl(other)) { if (unlink_from_impl(other)) {
// causes remote actor to unlink from (proxy of) other // causes remote actor to unlink from (proxy of) other
forward_msg({address(), this}, make_any_tuple(atom("UNLINK"), other)); forward_msg({address(), this}, make_message(atom("UNLINK"), other));
} }
} }
bool remote_actor_proxy::establish_backlink(const actor_addr& other) { bool remote_actor_proxy::establish_backlink(const actor_addr& other) {
if (super::establish_backlink(other)) { if (super::establish_backlink(other)) {
// causes remote actor to unlink from (proxy of) other // causes remote actor to unlink from (proxy of) other
forward_msg({address(), this}, make_any_tuple(atom("LINK"), other)); forward_msg({address(), this}, make_message(atom("LINK"), other));
return true; return true;
} }
return false; return false;
...@@ -189,7 +189,7 @@ bool remote_actor_proxy::establish_backlink(const actor_addr& other) { ...@@ -189,7 +189,7 @@ bool remote_actor_proxy::establish_backlink(const actor_addr& other) {
bool remote_actor_proxy::remove_backlink(const actor_addr& other) { bool remote_actor_proxy::remove_backlink(const actor_addr& other) {
if (super::remove_backlink(other)) { if (super::remove_backlink(other)) {
// causes remote actor to unlink from (proxy of) other // causes remote actor to unlink from (proxy of) other
forward_msg({address(), this}, make_any_tuple(atom("UNLINK"), other)); forward_msg({address(), this}, make_message(atom("UNLINK"), other));
return true; return true;
} }
return false; return false;
......
...@@ -35,7 +35,7 @@ response_promise::response_promise(const actor_addr& from, ...@@ -35,7 +35,7 @@ response_promise::response_promise(const actor_addr& from,
CPPA_REQUIRE(id.is_response() || !id.valid()); CPPA_REQUIRE(id.is_response() || !id.valid());
} }
void response_promise::deliver(any_tuple msg) { void response_promise::deliver(message msg) {
if (m_to) { if (m_to) {
auto to = detail::raw_access::get(m_to); auto to = detail::raw_access::get(m_to);
auto from = detail::raw_access::get(m_from); auto from = detail::raw_access::get(m_from);
......
...@@ -64,7 +64,7 @@ class delayed_msg { ...@@ -64,7 +64,7 @@ class delayed_msg {
public: public:
delayed_msg(message_header&& arg1, delayed_msg(message_header&& arg1,
any_tuple&& arg2) message&& arg2)
: hdr(move(arg1)), msg(move(arg2)) { } : hdr(move(arg1)), msg(move(arg2)) { }
delayed_msg(delayed_msg&&) = default; delayed_msg(delayed_msg&&) = default;
...@@ -79,13 +79,13 @@ class delayed_msg { ...@@ -79,13 +79,13 @@ class delayed_msg {
private: private:
message_header hdr; message_header hdr;
any_tuple msg; message msg;
}; };
template<class Map> template<class Map>
inline void insert_dmsg(Map& storage, const util::duration& d, inline void insert_dmsg(Map& storage, const util::duration& d,
message_header&& hdr, any_tuple&& tup) { message_header&& hdr, message&& tup) {
auto tout = hrc::now(); auto tout = hrc::now();
tout += d; tout += d;
delayed_msg dmsg{move(hdr), move(tup)}; delayed_msg dmsg{move(hdr), move(tup)};
...@@ -119,13 +119,13 @@ class timer_actor final : public detail::proper_actor<blocking_actor, ...@@ -119,13 +119,13 @@ class timer_actor final : public detail::proper_actor<blocking_actor,
auto mfun = ( auto mfun = (
on(atom("SEND"), arg_match) >> [&](const util::duration& d, on(atom("SEND"), arg_match) >> [&](const util::duration& d,
message_header& hdr, message_header& hdr,
any_tuple& tup) { message& tup) {
insert_dmsg(messages, d, move(hdr), move(tup)); insert_dmsg(messages, d, move(hdr), move(tup));
}, },
on(atom("DIE")) >> [&] { on(atom("DIE")) >> [&] {
done = true; done = true;
}, },
others() >> [&]() { others() >> [&] {
CPPA_LOG_WARNING("coordinator::timer_loop: UNKNOWN MESSAGE: " CPPA_LOG_WARNING("coordinator::timer_loop: UNKNOWN MESSAGE: "
<< to_string(msg_ptr->msg)); << to_string(msg_ptr->msg));
} }
...@@ -175,7 +175,7 @@ void printer_loop(blocking_actor* self) { ...@@ -175,7 +175,7 @@ void printer_loop(blocking_actor* self) {
} }
}; };
bool running = true; bool running = true;
self->receive_while (gref(running)) ( self->receive_while ([&] { return running; }) (
on(atom("add"), arg_match) >> [&](std::string& str) { on(atom("add"), arg_match) >> [&](std::string& str) {
auto s = self->last_sender(); auto s = self->last_sender();
if (!str.empty() && s) { if (!str.empty() && s) {
...@@ -285,7 +285,7 @@ void coordinator::destroy() { ...@@ -285,7 +285,7 @@ void coordinator::destroy() {
} }
// shutdown utility actors // shutdown utility actors
CPPA_LOG_DEBUG("send 'DIE' messages to timer & printer"); CPPA_LOG_DEBUG("send 'DIE' messages to timer & printer");
auto msg = make_any_tuple(atom("DIE")); auto msg = make_message(atom("DIE"));
m_timer->enqueue({invalid_actor_addr, nullptr}, msg, nullptr); m_timer->enqueue({invalid_actor_addr, nullptr}, msg, nullptr);
m_printer->enqueue({invalid_actor_addr, nullptr}, msg, nullptr); m_printer->enqueue({invalid_actor_addr, nullptr}, msg, nullptr);
CPPA_LOG_DEBUG("join threads of utility actors"); CPPA_LOG_DEBUG("join threads of utility actors");
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/io/middleman.hpp" #include "cppa/io/middleman.hpp"
......
...@@ -46,7 +46,7 @@ namespace cppa { ...@@ -46,7 +46,7 @@ namespace cppa {
namespace { namespace {
bool isbuiltin(const string& type_name) { bool isbuiltin(const string& type_name) {
return type_name == "@str" || type_name == "@atom" || type_name == "@tuple"; return type_name == "@str" || type_name == "@atom" || type_name == "@msg";
} }
// serializes types as type_name(...) except: // serializes types as type_name(...) except:
...@@ -289,7 +289,7 @@ class string_deserializer : public deserializer { ...@@ -289,7 +289,7 @@ class string_deserializer : public deserializer {
type_name = "@atom"; type_name = "@atom";
} }
else if (*m_pos == '{') { else if (*m_pos == '{') {
type_name = "@tuple"; type_name = "@msg";
} }
else { else {
auto substr_end = next_delimiter(); auto substr_end = next_delimiter();
......
...@@ -39,7 +39,7 @@ void sync_request_bouncer::operator()(const actor_addr& sender, ...@@ -39,7 +39,7 @@ void sync_request_bouncer::operator()(const actor_addr& sender,
if (sender && mid.is_request()) { if (sender && mid.is_request()) {
auto ptr = detail::raw_access::get(sender); auto ptr = detail::raw_access::get(sender);
ptr->enqueue({invalid_actor_addr, ptr, mid.response_id()}, ptr->enqueue({invalid_actor_addr, ptr, mid.response_id()},
make_any_tuple(sync_exited_msg{sender, rsn}), make_message(sync_exited_msg{sender, rsn}),
// TODO: this breaks out of the execution unit // TODO: this breaks out of the execution unit
nullptr); nullptr);
} }
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/abstract_group.hpp" #include "cppa/abstract_group.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
#include "cppa/util/algorithm.hpp" #include "cppa/util/algorithm.hpp"
......
...@@ -32,9 +32,9 @@ ...@@ -32,9 +32,9 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
......
...@@ -28,9 +28,10 @@ ...@@ -28,9 +28,10 @@
#include "cppa/group.hpp" #include "cppa/group.hpp"
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
#include "cppa/abstract_group.hpp" #include "cppa/abstract_group.hpp"
#include "cppa/message_builder.hpp"
#include "cppa/actor_namespace.hpp" #include "cppa/actor_namespace.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
...@@ -41,7 +42,6 @@ ...@@ -41,7 +42,6 @@
#include "cppa/util/shared_lock_guard.hpp" #include "cppa/util/shared_lock_guard.hpp"
#include "cppa/detail/raw_access.hpp" #include "cppa/detail/raw_access.hpp"
#include "cppa/detail/object_array.hpp"
#include "cppa/detail/uniform_type_info_map.hpp" #include "cppa/detail/uniform_type_info_map.hpp"
#include "cppa/detail/default_uniform_type_info.hpp" #include "cppa/detail/default_uniform_type_info.hpp"
...@@ -55,7 +55,6 @@ namespace detail { ...@@ -55,7 +55,6 @@ namespace detail {
{ "cppa::acceptor_closed_msg", "@acceptor_closed" }, { "cppa::acceptor_closed_msg", "@acceptor_closed" },
{ "cppa::actor", "@actor" }, { "cppa::actor", "@actor" },
{ "cppa::actor_addr", "@addr" }, { "cppa::actor_addr", "@addr" },
{ "cppa::any_tuple", "@tuple" },
{ "cppa::atom_value", "@atom" }, { "cppa::atom_value", "@atom" },
{ "cppa::channel", "@channel" }, { "cppa::channel", "@channel" },
{ "cppa::connection_closed_msg", "@conn_closed" }, { "cppa::connection_closed_msg", "@conn_closed" },
...@@ -66,6 +65,7 @@ namespace detail { ...@@ -66,6 +65,7 @@ namespace detail {
{ "cppa::intrusive_ptr<cppa::node_id>", "@proc" }, { "cppa::intrusive_ptr<cppa::node_id>", "@proc" },
{ "cppa::io::accept_handle", "@ac_hdl" }, { "cppa::io::accept_handle", "@ac_hdl" },
{ "cppa::io::connection_handle", "@cn_hdl" }, { "cppa::io::connection_handle", "@cn_hdl" },
{ "cppa::message", "@msg" },
{ "cppa::message_header", "@header" }, { "cppa::message_header", "@header" },
{ "cppa::new_connection_msg", "@new_conn" }, { "cppa::new_connection_msg", "@new_conn" },
{ "cppa::new_data_msg", "@new_data" }, { "cppa::new_data_msg", "@new_data" },
...@@ -276,7 +276,7 @@ void deserialize_impl(channel& ptrref, deserializer* source) { ...@@ -276,7 +276,7 @@ void deserialize_impl(channel& ptrref, deserializer* source) {
} }
} }
void serialize_impl(const any_tuple& tup, serializer* sink) { void serialize_impl(const message& tup, serializer* sink) {
std::string dynamic_name; // used if tup holds an object_array std::string dynamic_name; // used if tup holds an object_array
// ttn can be nullptr even if tuple is not empty (in case of object_array) // ttn can be nullptr even if tuple is not empty (in case of object_array)
const std::string* ttn = tup.empty() ? nullptr : tup.tuple_type_names(); const std::string* ttn = tup.empty() ? nullptr : tup.tuple_type_names();
...@@ -301,12 +301,12 @@ void serialize_impl(const any_tuple& tup, serializer* sink) { ...@@ -301,12 +301,12 @@ void serialize_impl(const any_tuple& tup, serializer* sink) {
sink->end_object(); sink->end_object();
} }
void deserialize_impl(any_tuple& atref, deserializer* source) { void deserialize_impl(message& atref, deserializer* source) {
auto uti = source->begin_object(); auto uti = source->begin_object();
auto uval = uti->create(); auto uval = uti->create();
uti->deserialize(uval->val, source); uti->deserialize(uval->val, source);
source->end_object(); source->end_object();
atref = uti->as_any_tuple(uval->val); atref = uti->as_message(uval->val);
} }
void serialize_impl(msg_hdr_cref hdr, serializer* sink) { void serialize_impl(msg_hdr_cref hdr, serializer* sink) {
...@@ -492,8 +492,8 @@ class uti_base : public uniform_type_info { ...@@ -492,8 +492,8 @@ class uti_base : public uniform_type_info {
return create_impl<T>(other); return create_impl<T>(other);
} }
any_tuple as_any_tuple(void* instance) const override { message as_message(void* instance) const override {
return make_any_tuple(deref(instance)); return make_message(deref(instance));
} }
static inline const T& deref(const void* ptr) { static inline const T& deref(const void* ptr) {
...@@ -580,8 +580,8 @@ class int_tinfo : public abstract_int_tinfo { ...@@ -580,8 +580,8 @@ class int_tinfo : public abstract_int_tinfo {
return static_name(); return static_name();
} }
any_tuple as_any_tuple(void* instance) const override { message as_message(void* instance) const override {
return make_any_tuple(deref(instance)); return make_message(deref(instance));
} }
protected: protected:
...@@ -637,8 +637,8 @@ class buffer_type_info_impl : public uniform_type_info { ...@@ -637,8 +637,8 @@ class buffer_type_info_impl : public uniform_type_info {
return static_name(); return static_name();
} }
any_tuple as_any_tuple(void* instance) const override { message as_message(void* instance) const override {
return make_any_tuple(deref(instance)); return make_message(deref(instance));
} }
protected: protected:
...@@ -675,13 +675,13 @@ class buffer_type_info_impl : public uniform_type_info { ...@@ -675,13 +675,13 @@ class buffer_type_info_impl : public uniform_type_info {
}; };
class default_meta_tuple : public uniform_type_info { class default_meta_message : public uniform_type_info {
public: public:
default_meta_tuple(const std::string& name) { default_meta_message(const std::string& name) {
m_name = name; m_name = name;
auto elements = util::split(name, '+', false); std::vector<std::string> elements = util::split(name, '+');
auto uti_map = get_uniform_type_info_map(); auto uti_map = get_uniform_type_info_map();
CPPA_REQUIRE(elements.size() > 0 && elements.front() == "@<>"); CPPA_REQUIRE(elements.size() > 0 && elements.front() == "@<>");
// ignore first element, because it's always "@<>" // ignore first element, because it's always "@<>"
...@@ -694,17 +694,18 @@ class default_meta_tuple : public uniform_type_info { ...@@ -694,17 +694,18 @@ class default_meta_tuple : public uniform_type_info {
} }
uniform_value create(const uniform_value& other) const override { uniform_value create(const uniform_value& other) const override {
auto res = create_impl<object_array>(other); auto res = create_impl<message>(other);
if (!other) { if (!other) {
// res is not a copy => fill it with values // res is not a copy => fill with values
auto& oarr = *cast(res->val); message_builder mb;
for (auto uti : m_elements) oarr.push_back(uti->create()); for (auto& e : m_elements) mb.append(e->create());
*cast(res->val) = mb.to_message();
} }
return res; return res;
} }
any_tuple as_any_tuple(void* ptr) const override { message as_message(void* ptr) const override {
return any_tuple{static_cast<any_tuple::raw_ptr>(cast(ptr))}; return *cast(ptr);
} }
const char* name() const override { const char* name() const override {
...@@ -712,17 +713,19 @@ class default_meta_tuple : public uniform_type_info { ...@@ -712,17 +713,19 @@ class default_meta_tuple : public uniform_type_info {
} }
void serialize(const void* ptr, serializer* sink) const override { void serialize(const void* ptr, serializer* sink) const override {
auto& oarr = *cast(ptr); auto& msg = *cast(ptr);
CPPA_REQUIRE(msg.size() == m_elements.size());
for (size_t i = 0; i < m_elements.size(); ++i) { for (size_t i = 0; i < m_elements.size(); ++i) {
m_elements[i]->serialize(oarr.at(i), sink); m_elements[i]->serialize(msg.at(i), sink);
} }
} }
void deserialize(void* ptr, deserializer* source) const override { void deserialize(void* ptr, deserializer* source) const override {
auto& oarr = *cast(ptr); message_builder mb;
for (size_t i = 0; i < m_elements.size(); ++i) { for (size_t i = 0; i < m_elements.size(); ++i) {
m_elements[i]->deserialize(oarr.mutable_at(i), source); mb.append(m_elements[i]->deserialize(source));
} }
*cast(ptr) = mb.to_message();
} }
bool equal_to(const std::type_info&) const override { bool equal_to(const std::type_info&) const override {
...@@ -741,12 +744,12 @@ class default_meta_tuple : public uniform_type_info { ...@@ -741,12 +744,12 @@ class default_meta_tuple : public uniform_type_info {
std::string m_name; std::string m_name;
std::vector<const uniform_type_info*> m_elements; std::vector<const uniform_type_info*> m_elements;
inline object_array* cast(void* ptr) const { inline message* cast(void* ptr) const {
return reinterpret_cast<object_array*>(ptr); return reinterpret_cast<message*>(ptr);
} }
inline const object_array* cast(const void* ptr) const { inline const message* cast(const void* ptr) const {
return reinterpret_cast<const object_array*>(ptr); return reinterpret_cast<const message*>(ptr);
} }
}; };
...@@ -845,7 +848,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -845,7 +848,7 @@ class utim_impl : public uniform_type_info_map {
*i++ = &m_type_sync_exited; // @sync_exited *i++ = &m_type_sync_exited; // @sync_exited
*i++ = &m_type_sync_timeout; // @sync_timeout *i++ = &m_type_sync_timeout; // @sync_timeout
*i++ = &m_type_timeout; // @timeout *i++ = &m_type_timeout; // @timeout
*i++ = &m_type_tuple; // @tuple *i++ = &m_type_tuple; // @msg
*i++ = &m_type_u16; // @u16 *i++ = &m_type_u16; // @u16
*i++ = &m_type_u16str; // @u16str *i++ = &m_type_u16str; // @u16str
*i++ = &m_type_u32; // @u32 *i++ = &m_type_u32; // @u32
...@@ -903,7 +906,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -903,7 +906,7 @@ class utim_impl : public uniform_type_info_map {
} }
if (!result && name.compare(0, 3, "@<>") == 0) { if (!result && name.compare(0, 3, "@<>") == 0) {
// create tuple UTI on-the-fly // create tuple UTI on-the-fly
result = insert(create_unique<default_meta_tuple>(name)); result = insert(create_unique<default_meta_message>(name));
} }
return result; //(res) ? res : find_name(m_user_types, name); return result; //(res) ? res : find_name(m_user_types, name);
} }
...@@ -963,7 +966,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -963,7 +966,7 @@ class utim_impl : public uniform_type_info_map {
// 10-19 // 10-19
uti_impl<group_down_msg> m_type_group_down; uti_impl<group_down_msg> m_type_group_down;
uti_impl<any_tuple> m_type_tuple; uti_impl<message> m_type_tuple;
uti_impl<util::duration> m_type_duration; uti_impl<util::duration> m_type_duration;
uti_impl<sync_exited_msg> m_type_sync_exited; uti_impl<sync_exited_msg> m_type_sync_exited;
uti_impl<sync_timeout_msg> m_type_sync_timeout; uti_impl<sync_timeout_msg> m_type_sync_timeout;
......
...@@ -18,7 +18,7 @@ size_t s_pongs = 0; ...@@ -18,7 +18,7 @@ size_t s_pongs = 0;
behavior ping_behavior(local_actor* self, size_t num_pings) { behavior ping_behavior(local_actor* self, size_t num_pings) {
return ( return (
on(atom("pong"), arg_match) >> [=](int value) -> any_tuple { on(atom("pong"), arg_match) >> [=](int value) -> message {
if (!self->last_sender()) { if (!self->last_sender()) {
CPPA_PRINT("last_sender() invalid!"); CPPA_PRINT("last_sender() invalid!");
} }
...@@ -30,7 +30,7 @@ behavior ping_behavior(local_actor* self, size_t num_pings) { ...@@ -30,7 +30,7 @@ behavior ping_behavior(local_actor* self, size_t num_pings) {
self->send_exit(self->last_sender(), exit_reason::user_shutdown); self->send_exit(self->last_sender(), exit_reason::user_shutdown);
self->quit(); self->quit();
} }
return make_any_tuple(atom("ping"), value); return make_message(atom("ping"), value);
}, },
others() >> [=] { others() >> [=] {
CPPA_LOGF_ERROR("unexpected message; " CPPA_LOGF_ERROR("unexpected message; "
...@@ -42,9 +42,9 @@ behavior ping_behavior(local_actor* self, size_t num_pings) { ...@@ -42,9 +42,9 @@ behavior ping_behavior(local_actor* self, size_t num_pings) {
behavior pong_behavior(local_actor* self) { behavior pong_behavior(local_actor* self) {
return ( return (
on(atom("ping"), arg_match) >> [](int value) -> any_tuple { on(atom("ping"), arg_match) >> [](int value) -> message {
CPPA_PRINT("received {'ping', " << value << "}"); CPPA_PRINT("received {'ping', " << value << "}");
return make_any_tuple(atom("pong"), value + 1); return make_message(atom("pong"), value + 1);
}, },
others() >> [=] { others() >> [=] {
CPPA_LOGF_ERROR("unexpected message; " CPPA_LOGF_ERROR("unexpected message; "
......
...@@ -33,7 +33,7 @@ const char* cppa_strip_path(const char* file) { ...@@ -33,7 +33,7 @@ const char* cppa_strip_path(const char* file) {
return res; return res;
} }
void cppa_unexpected_message(const char* file, size_t line, cppa::any_tuple t) { void cppa_unexpected_message(const char* file, size_t line, cppa::message t) {
CPPA_PRINTERRC(file, line, "unexpected message: " << to_string(t)); CPPA_PRINTERRC(file, line, "unexpected message: " << to_string(t));
} }
......
...@@ -28,7 +28,7 @@ size_t cppa_error_count(); ...@@ -28,7 +28,7 @@ size_t cppa_error_count();
void cppa_inc_error_count(); void cppa_inc_error_count();
std::string cppa_fill4(size_t value); std::string cppa_fill4(size_t value);
const char* cppa_strip_path(const char* file); const char* cppa_strip_path(const char* file);
void cppa_unexpected_message(const char* file, size_t line, cppa::any_tuple t); void cppa_unexpected_message(const char* file, size_t line, cppa::message t);
void cppa_unexpected_timeout(const char* file, size_t line); void cppa_unexpected_timeout(const char* file, size_t line);
#define CPPA_STREAMIFY(fname, line, message) \ #define CPPA_STREAMIFY(fname, line, message) \
......
...@@ -167,19 +167,19 @@ void test_gref() { ...@@ -167,19 +167,19 @@ void test_gref() {
on<anything>().when(gref(enable_case1) == false) >> [] { return 1; }, on<anything>().when(gref(enable_case1) == false) >> [] { return 1; },
on<anything>() >> [] { return 2; } on<anything>() >> [] { return 2; }
); );
any_tuple expr19_tup = make_cow_tuple("hello guard!"); message expr19_tup = make_cow_tuple("hello guard!");
auto res19 = expr19(expr19_tup); auto res19 = expr19(expr19_tup);
CPPA_CHECK(get<int>(&res19) && get<int>(res19) == 2); CPPA_CHECK(get<int>(&res19) && get<int>(res19) == 2);
partial_function expr20 = expr19; message_handler expr20 = expr19;
enable_case1 = false; enable_case1 = false;
CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1)); CPPA_CHECK(expr20(expr19_tup) == make_message(1));
partial_function expr21 { message_handler expr21 {
on(atom("add"), arg_match) >> [](int a, int b) { on(atom("add"), arg_match) >> [](int a, int b) {
return a + b; return a + b;
} }
}; };
CPPA_CHECK(expr21(make_any_tuple(atom("add"), 1, 2)) == make_any_tuple(3)); CPPA_CHECK(expr21(make_message(atom("add"), 1, 2)) == make_message(3));
CPPA_CHECK(!expr21(make_any_tuple(atom("sub"), 1, 2))); CPPA_CHECK(!expr21(make_message(atom("sub"), 1, 2)));
} }
void test_match_function() { void test_match_function() {
...@@ -305,11 +305,11 @@ void test_behavior() { ...@@ -305,11 +305,11 @@ void test_behavior() {
last_invoked_fun = "<*>@4"; last_invoked_fun = "<*>@4";
} }
}; };
bhvr_check(bhvr1, make_any_tuple(42), true, "<int>@3"); bhvr_check(bhvr1, make_message(42), true, "<int>@3");
bhvr_check(bhvr1, make_any_tuple(24), true, "<int>@1"); bhvr_check(bhvr1, make_message(24), true, "<int>@1");
bhvr_check(bhvr1, make_any_tuple(2.f), true, "<float>@2"); bhvr_check(bhvr1, make_message(2.f), true, "<float>@2");
bhvr_check(bhvr1, make_any_tuple(""), true, "<*>@4"); bhvr_check(bhvr1, make_message(""), true, "<*>@4");
partial_function pf0 { message_handler pf0 {
on<int, int>() >> [&] { last_invoked_fun = "<int, int>@1"; }, on<int, int>() >> [&] { last_invoked_fun = "<int, int>@1"; },
on<float>() >> [&] { last_invoked_fun = "<float>@2"; } on<float>() >> [&] { last_invoked_fun = "<float>@2"; }
}; };
...@@ -317,24 +317,24 @@ void test_behavior() { ...@@ -317,24 +317,24 @@ void test_behavior() {
on<int, int>() >> [&] { last_invoked_fun = "<int, int>@3"; }, on<int, int>() >> [&] { last_invoked_fun = "<int, int>@3"; },
on<string>() >> [&] { last_invoked_fun = "<string>@4"; } on<string>() >> [&] { last_invoked_fun = "<string>@4"; }
); );
bhvr_check(pf0, make_any_tuple(1, 2), true, "<int, int>@1"); bhvr_check(pf0, make_message(1, 2), true, "<int, int>@1");
bhvr_check(pf1, make_any_tuple(1, 2), true, "<int, int>@1"); bhvr_check(pf1, make_message(1, 2), true, "<int, int>@1");
bhvr_check(pf0, make_any_tuple("hi"), false, ""); bhvr_check(pf0, make_message("hi"), false, "");
bhvr_check(pf1, make_any_tuple("hi"), true, "<string>@4"); bhvr_check(pf1, make_message("hi"), true, "<string>@4");
partial_function pf11 { message_handler pf11 {
on_arg_match >> [&](int) { last_invoked_fun = "<int>@1"; } on_arg_match >> [&](int) { last_invoked_fun = "<int>@1"; }
}; };
partial_function pf12 { message_handler pf12 {
on_arg_match >> [&](int) { last_invoked_fun = "<int>@2"; }, on_arg_match >> [&](int) { last_invoked_fun = "<int>@2"; },
on_arg_match >> [&](float) { last_invoked_fun = "<float>@2"; } on_arg_match >> [&](float) { last_invoked_fun = "<float>@2"; }
}; };
auto pf13 = pf11.or_else(pf12); auto pf13 = pf11.or_else(pf12);
bhvr_check(pf13, make_any_tuple(42), true, "<int>@1"); bhvr_check(pf13, make_message(42), true, "<int>@1");
bhvr_check(pf13, make_any_tuple(42.24f), true, "<float>@2"); bhvr_check(pf13, make_message(42.24f), true, "<float>@2");
} }
void test_pattern_matching() { void test_pattern_matching() {
auto res = match(make_any_tuple(42, 4.2f)) ( auto res = match(make_message(42, 4.2f)) (
on(42, arg_match) >> [](double d) { on(42, arg_match) >> [](double d) {
return d; return d;
}, },
...@@ -343,7 +343,7 @@ void test_pattern_matching() { ...@@ -343,7 +343,7 @@ void test_pattern_matching() {
} }
); );
CPPA_CHECK(get<float>(&res) && util::safe_equal(get<float>(res), 4.2f)); CPPA_CHECK(get<float>(&res) && util::safe_equal(get<float>(res), 4.2f));
auto res2 = match(make_any_tuple(23, 4.2f)) ( auto res2 = match(make_message(23, 4.2f)) (
on(42, arg_match) >> [](double d) { on(42, arg_match) >> [](double d) {
return d; return d;
}, },
...@@ -365,10 +365,10 @@ void make_dynamically_typed_impl(detail::object_array& arr, T0&& arg0, Ts&&... a ...@@ -365,10 +365,10 @@ void make_dynamically_typed_impl(detail::object_array& arr, T0&& arg0, Ts&&... a
} }
template<typename... Ts> template<typename... Ts>
any_tuple make_dynamically_typed(Ts&&... args) { message make_dynamically_typed(Ts&&... args) {
auto oarr = new detail::object_array; auto oarr = new detail::object_array;
make_dynamically_typed_impl(*oarr, std::forward<Ts>(args)...); make_dynamically_typed_impl(*oarr, std::forward<Ts>(args)...);
return any_tuple{static_cast<any_tuple::raw_ptr>(oarr)}; return message{static_cast<message::raw_ptr>(oarr)};
} }
void test_wildcards() { void test_wildcards() {
...@@ -382,88 +382,88 @@ void test_wildcards() { ...@@ -382,88 +382,88 @@ void test_wildcards() {
CPPA_CHECK_NOT(expr0(1)); CPPA_CHECK_NOT(expr0(1));
CPPA_CHECK(expr0(1, 2)); CPPA_CHECK(expr0(1, 2));
CPPA_CHECK(expr0(0, 1, 2)); CPPA_CHECK(expr0(0, 1, 2));
partial_function pf0 = expr0; message_handler pf0 = expr0;
CPPA_CHECK(not pf0(make_any_tuple(1))); CPPA_CHECK(not pf0(make_message(1)));
CPPA_CHECK(pf0(make_any_tuple(1, 2))); CPPA_CHECK(pf0(make_message(1, 2)));
CPPA_CHECK(pf0(make_any_tuple(0, 1, 2))); CPPA_CHECK(pf0(make_message(0, 1, 2)));
CPPA_CHECK(not pf0(make_dynamically_typed(1))); CPPA_CHECK(not pf0(make_dynamically_typed(1)));
CPPA_CHECK(pf0(make_dynamically_typed(1, 2))); CPPA_CHECK(pf0(make_dynamically_typed(1, 2)));
CPPA_CHECK(pf0(make_dynamically_typed(0, 1, 2))); CPPA_CHECK(pf0(make_dynamically_typed(0, 1, 2)));
behavior bhvr0 = expr0; behavior bhvr0 = expr0;
CPPA_CHECK(bhvr0(make_any_tuple(1, 2))); CPPA_CHECK(bhvr0(make_message(1, 2)));
CPPA_CHECK(bhvr0(make_any_tuple(0, 1, 2))); CPPA_CHECK(bhvr0(make_message(0, 1, 2)));
CPPA_CHECK(bhvr0(make_dynamically_typed(1, 2))); CPPA_CHECK(bhvr0(make_dynamically_typed(1, 2)));
CPPA_CHECK(bhvr0(make_dynamically_typed(0, 1, 2))); CPPA_CHECK(bhvr0(make_dynamically_typed(0, 1, 2)));
// wildcard in between // wildcard in between
partial_function pf1 { message_handler pf1 {
on<int, anything, int>() >> [](int a, int b) { on<int, anything, int>() >> [](int a, int b) {
CPPA_CHECK_EQUAL(a, 10); CPPA_CHECK_EQUAL(a, 10);
CPPA_CHECK_EQUAL(b, 20); CPPA_CHECK_EQUAL(b, 20);
} }
}; };
CPPA_CHECK(pf1(make_any_tuple(10, 20))); CPPA_CHECK(pf1(make_message(10, 20)));
CPPA_CHECK(pf1(make_any_tuple(10, 15, 20))); CPPA_CHECK(pf1(make_message(10, 15, 20)));
CPPA_CHECK(pf1(make_any_tuple(10, "hello world", 15, 20))); CPPA_CHECK(pf1(make_message(10, "hello world", 15, 20)));
CPPA_CHECK(pf1(make_dynamically_typed(10, 20))); CPPA_CHECK(pf1(make_dynamically_typed(10, 20)));
CPPA_CHECK(pf1(make_dynamically_typed(10, 15, 20))); CPPA_CHECK(pf1(make_dynamically_typed(10, 15, 20)));
CPPA_CHECK(pf1(make_dynamically_typed(10, "hello world", 15, 20))); CPPA_CHECK(pf1(make_dynamically_typed(10, "hello world", 15, 20)));
// multiple wildcards: one leading // multiple wildcards: one leading
partial_function pf2 { message_handler pf2 {
on<anything, int, anything, int>() >> [](int a, int b) { on<anything, int, anything, int>() >> [](int a, int b) {
CPPA_CHECK_EQUAL(a, 10); CPPA_CHECK_EQUAL(a, 10);
CPPA_CHECK_EQUAL(b, 20); CPPA_CHECK_EQUAL(b, 20);
} }
}; };
CPPA_CHECK(pf2(make_any_tuple(10, 20))); CPPA_CHECK(pf2(make_message(10, 20)));
CPPA_CHECK(pf2(make_any_tuple(10, 15, 20))); CPPA_CHECK(pf2(make_message(10, 15, 20)));
CPPA_CHECK(pf2(make_any_tuple(10, "hello world", 15, 20))); CPPA_CHECK(pf2(make_message(10, "hello world", 15, 20)));
CPPA_CHECK(pf2(make_any_tuple("hello world", 10, 20))); CPPA_CHECK(pf2(make_message("hello world", 10, 20)));
CPPA_CHECK(pf2(make_any_tuple("hello", 10, "world", 15, 20))); CPPA_CHECK(pf2(make_message("hello", 10, "world", 15, 20)));
CPPA_CHECK(pf2(make_dynamically_typed(10, 20))); CPPA_CHECK(pf2(make_dynamically_typed(10, 20)));
CPPA_CHECK(pf2(make_dynamically_typed(10, 15, 20))); CPPA_CHECK(pf2(make_dynamically_typed(10, 15, 20)));
CPPA_CHECK(pf2(make_dynamically_typed(10, "hello world", 15, 20))); CPPA_CHECK(pf2(make_dynamically_typed(10, "hello world", 15, 20)));
CPPA_CHECK(pf2(make_dynamically_typed("hello world", 10, 20))); CPPA_CHECK(pf2(make_dynamically_typed("hello world", 10, 20)));
CPPA_CHECK(pf2(make_dynamically_typed("hello", 10, "world", 15, 20))); CPPA_CHECK(pf2(make_dynamically_typed("hello", 10, "world", 15, 20)));
// multiple wildcards: in between // multiple wildcards: in between
partial_function pf3 { message_handler pf3 {
on<int, anything, int, anything, int>() >> [](int a, int b, int c) { on<int, anything, int, anything, int>() >> [](int a, int b, int c) {
CPPA_CHECK_EQUAL(a, 10); CPPA_CHECK_EQUAL(a, 10);
CPPA_CHECK_EQUAL(b, 20); CPPA_CHECK_EQUAL(b, 20);
CPPA_CHECK_EQUAL(c, 30); CPPA_CHECK_EQUAL(c, 30);
} }
}; };
CPPA_CHECK(pf3(make_any_tuple(10, 20, 30))); CPPA_CHECK(pf3(make_message(10, 20, 30)));
CPPA_CHECK(pf3(make_any_tuple(10, 20, 25, 30))); CPPA_CHECK(pf3(make_message(10, 20, 25, 30)));
CPPA_CHECK(pf3(make_any_tuple(10, "hello", 20, "world", 30))); CPPA_CHECK(pf3(make_message(10, "hello", 20, "world", 30)));
CPPA_CHECK(pf3(make_any_tuple(10, "hello", 20, "world", 1, 2, 30))); CPPA_CHECK(pf3(make_message(10, "hello", 20, "world", 1, 2, 30)));
CPPA_CHECK(pf3(make_dynamically_typed(10, 20, 30))); CPPA_CHECK(pf3(make_dynamically_typed(10, 20, 30)));
CPPA_CHECK(pf3(make_dynamically_typed(10, 20, 25, 30))); CPPA_CHECK(pf3(make_dynamically_typed(10, 20, 25, 30)));
CPPA_CHECK(pf3(make_dynamically_typed(10, "hello", 20, "world", 30))); CPPA_CHECK(pf3(make_dynamically_typed(10, "hello", 20, "world", 30)));
CPPA_CHECK(pf3(make_dynamically_typed(10, "hello", 20, "world", 1, 2, 30))); CPPA_CHECK(pf3(make_dynamically_typed(10, "hello", 20, "world", 1, 2, 30)));
// multiple wildcards: one trailing // multiple wildcards: one trailing
partial_function pf4 { message_handler pf4 {
on<int, anything, int, anything>() >> [](int a, int b) { on<int, anything, int, anything>() >> [](int a, int b) {
CPPA_CHECK_EQUAL(a, 10); CPPA_CHECK_EQUAL(a, 10);
CPPA_CHECK_EQUAL(b, 20); CPPA_CHECK_EQUAL(b, 20);
} }
}; };
CPPA_CHECK(pf4(make_any_tuple(10, 20, 30))); CPPA_CHECK(pf4(make_message(10, 20, 30)));
CPPA_CHECK(pf4(make_any_tuple(10, 20, 25, 30))); CPPA_CHECK(pf4(make_message(10, 20, 25, 30)));
CPPA_CHECK(pf4(make_any_tuple(10, "hello", 20, "world", 30))); CPPA_CHECK(pf4(make_message(10, "hello", 20, "world", 30)));
CPPA_CHECK(pf4(make_any_tuple(10, "hello", 20, "world", 1, 2, 30))); CPPA_CHECK(pf4(make_message(10, "hello", 20, "world", 1, 2, 30)));
CPPA_CHECK(pf4(make_dynamically_typed(10, 20, 30))); CPPA_CHECK(pf4(make_dynamically_typed(10, 20, 30)));
CPPA_CHECK(pf4(make_dynamically_typed(10, 20, 25, 30))); CPPA_CHECK(pf4(make_dynamically_typed(10, 20, 25, 30)));
CPPA_CHECK(pf4(make_dynamically_typed(10, "hello", 20, "world", 30))); CPPA_CHECK(pf4(make_dynamically_typed(10, "hello", 20, "world", 30)));
CPPA_CHECK(pf4(make_dynamically_typed(10, "hello", 20, "world", 1, 2, 30))); CPPA_CHECK(pf4(make_dynamically_typed(10, "hello", 20, "world", 1, 2, 30)));
// multiple wildcards: leading and trailing // multiple wildcards: leading and trailing
partial_function pf5 { message_handler pf5 {
on<anything, int, anything>() >> [](int a) { on<anything, int, anything>() >> [](int a) {
CPPA_CHECK_EQUAL(a, 10); CPPA_CHECK_EQUAL(a, 10);
} }
}; };
CPPA_CHECK(pf5(make_any_tuple(10, 20, 30))); CPPA_CHECK(pf5(make_message(10, 20, 30)));
CPPA_CHECK(pf5(make_any_tuple("hello", 10, "world", 30))); CPPA_CHECK(pf5(make_message("hello", 10, "world", 30)));
CPPA_CHECK(pf5(make_any_tuple("hello", "world", 10))); CPPA_CHECK(pf5(make_message("hello", "world", 10)));
CPPA_CHECK(pf5(make_dynamically_typed(10, 20, 30))); CPPA_CHECK(pf5(make_dynamically_typed(10, 20, 30)));
CPPA_CHECK(pf5(make_dynamically_typed("hello", 10, "world", 30))); CPPA_CHECK(pf5(make_dynamically_typed("hello", 10, "world", 30)));
CPPA_CHECK(pf5(make_dynamically_typed("hello", "world", 10))); CPPA_CHECK(pf5(make_dynamically_typed("hello", "world", 10)));
......
...@@ -122,13 +122,13 @@ void spawn5_client(event_based_actor* self) { ...@@ -122,13 +122,13 @@ void spawn5_client(event_based_actor* self) {
CPPA_PRINT("received {'GetGroup'}"); CPPA_PRINT("received {'GetGroup'}");
return group::get("local", "foobar"); return group::get("local", "foobar");
}, },
on(atom("Spawn5"), arg_match) >> [=](const group& grp) -> any_tuple { on(atom("Spawn5"), arg_match) >> [=](const group& grp) -> message {
CPPA_PRINT("received {'Spawn5'}"); CPPA_PRINT("received {'Spawn5'}");
actor_vector vec; actor_vector vec;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
vec.push_back(spawn_in_group(grp, reflector)); vec.push_back(spawn_in_group(grp, reflector));
} }
return make_any_tuple(atom("ok"), std::move(vec)); return make_message(atom("ok"), std::move(vec));
}, },
on(atom("Spawn5Done")) >> [=] { on(atom("Spawn5Done")) >> [=] {
CPPA_PRINT("received {'Spawn5Done'}"); CPPA_PRINT("received {'Spawn5Done'}");
...@@ -216,7 +216,7 @@ class client : public event_based_actor { ...@@ -216,7 +216,7 @@ class client : public event_based_actor {
void test_group_comm_inverted() { void test_group_comm_inverted() {
CPPA_PRINT("test group communication via network (inverted setup)"); CPPA_PRINT("test group communication via network (inverted setup)");
become ( become (
on(atom("GClient")) >> [=]() -> any_tuple { on(atom("GClient")) >> [=]() -> message {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto cptr = last_sender(); auto cptr = last_sender();
auto s5c = spawn<monitored>(spawn5_client); auto s5c = spawn<monitored>(spawn5_client);
...@@ -225,7 +225,7 @@ class client : public event_based_actor { ...@@ -225,7 +225,7 @@ class client : public event_based_actor {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
quit(); quit();
}); });
return make_any_tuple(atom("GClient"), s5c); return make_message(atom("GClient"), s5c);
} }
); );
} }
...@@ -247,7 +247,7 @@ class server : public event_based_actor { ...@@ -247,7 +247,7 @@ class server : public event_based_actor {
behavior await_spawn_ping() { behavior await_spawn_ping() {
CPPA_PRINT("await {'SpawnPing'}"); CPPA_PRINT("await {'SpawnPing'}");
return ( return (
on(atom("SpawnPing")) >> [=]() -> any_tuple { on(atom("SpawnPing")) >> [=]() -> message {
CPPA_PRINT("received {'SpawnPing'}"); CPPA_PRINT("received {'SpawnPing'}");
auto client = last_sender(); auto client = last_sender();
if (!client) { if (!client) {
...@@ -260,7 +260,7 @@ class server : public event_based_actor { ...@@ -260,7 +260,7 @@ class server : public event_based_actor {
CPPA_CHECK_EQUAL(pongs(), num_pings); CPPA_CHECK_EQUAL(pongs(), num_pings);
await_sync_msg(); await_sync_msg();
}); });
return make_any_tuple(atom("PingPtr"), pptr); return make_message(atom("PingPtr"), pptr);
} }
); );
} }
...@@ -281,7 +281,7 @@ class server : public event_based_actor { ...@@ -281,7 +281,7 @@ class server : public event_based_actor {
CPPA_PRINT("await foobars"); CPPA_PRINT("await foobars");
auto foobars = make_shared<int>(0); auto foobars = make_shared<int>(0);
become ( become (
on(atom("foo"), atom("bar"), arg_match) >> [=](int i) -> any_tuple { on(atom("foo"), atom("bar"), arg_match) >> [=](int i) -> message {
++*foobars; ++*foobars;
if (i == 99) { if (i == 99) {
CPPA_CHECK_EQUAL(*foobars, 100); CPPA_CHECK_EQUAL(*foobars, 100);
...@@ -295,7 +295,7 @@ class server : public event_based_actor { ...@@ -295,7 +295,7 @@ class server : public event_based_actor {
void test_group_comm() { void test_group_comm() {
CPPA_PRINT("test group communication via network"); CPPA_PRINT("test group communication via network");
become ( become (
on(atom("GClient")) >> [=]() -> any_tuple { on(atom("GClient")) >> [=]() -> message {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto cptr = last_sender(); auto cptr = last_sender();
auto s5c = spawn<monitored>(spawn5_client); auto s5c = spawn<monitored>(spawn5_client);
...@@ -303,7 +303,7 @@ class server : public event_based_actor { ...@@ -303,7 +303,7 @@ class server : public event_based_actor {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
test_group_comm_inverted(detail::raw_access::unsafe_cast(cptr)); test_group_comm_inverted(detail::raw_access::unsafe_cast(cptr));
}); });
return make_any_tuple(atom("GClient"), s5c); return make_message(atom("GClient"), s5c);
} }
); );
} }
......
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
#include "test.hpp" #include "test.hpp"
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/tuple_cast.hpp" #include "cppa/tuple_cast.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/from_string.hpp" #include "cppa/from_string.hpp"
...@@ -151,7 +151,7 @@ int main() { ...@@ -151,7 +151,7 @@ int main() {
oarr->push_back(object::from(static_cast<uint32_t>(42))); oarr->push_back(object::from(static_cast<uint32_t>(42)));
oarr->push_back(object::from("foo" )); oarr->push_back(object::from("foo" ));
any_tuple atuple1{static_cast<any_tuple::raw_ptr>(oarr)}; message atuple1{static_cast<message::raw_ptr>(oarr)};
try { try {
auto opt = tuple_cast<uint32_t, string>(atuple1); auto opt = tuple_cast<uint32_t, string>(atuple1);
CPPA_CHECK(opt.valid()); CPPA_CHECK(opt.valid());
...@@ -204,29 +204,29 @@ int main() { ...@@ -204,29 +204,29 @@ int main() {
//try { //try {
scoped_actor self; scoped_actor self;
auto ttup = make_any_tuple(1, 2, actor{self.get()}); auto ttup = make_message(1, 2, actor{self.get()});
util::buffer wr_buf; util::buffer wr_buf;
binary_serializer bs(&wr_buf, &addressing); binary_serializer bs(&wr_buf, &addressing);
bs << ttup; bs << ttup;
binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing); binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing);
any_tuple ttup2; message ttup2;
uniform_typeid<any_tuple>()->deserialize(&ttup2, &bd); uniform_typeid<message>()->deserialize(&ttup2, &bd);
CPPA_CHECK(ttup == ttup2); CPPA_CHECK(ttup == ttup2);
//} //}
//catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); } //catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); }
try { try {
scoped_actor self; scoped_actor self;
auto ttup = make_any_tuple(1, 2, actor{self.get()}); auto ttup = make_message(1, 2, actor{self.get()});
util::buffer wr_buf; util::buffer wr_buf;
binary_serializer bs(&wr_buf, &addressing); binary_serializer bs(&wr_buf, &addressing);
bs << ttup; bs << ttup;
bs << ttup; bs << ttup;
binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing); binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing);
any_tuple ttup2; message ttup2;
any_tuple ttup3; message ttup3;
uniform_typeid<any_tuple>()->deserialize(&ttup2, &bd); uniform_typeid<message>()->deserialize(&ttup2, &bd);
uniform_typeid<any_tuple>()->deserialize(&ttup3, &bd); uniform_typeid<message>()->deserialize(&ttup3, &bd);
CPPA_CHECK(ttup == ttup2); CPPA_CHECK(ttup == ttup2);
CPPA_CHECK(ttup == ttup3); CPPA_CHECK(ttup == ttup3);
CPPA_CHECK(ttup2 == ttup3); CPPA_CHECK(ttup2 == ttup3);
...@@ -240,8 +240,8 @@ int main() { ...@@ -240,8 +240,8 @@ int main() {
bs << atuple1; bs << atuple1;
// deserialize b2 from buf // deserialize b2 from buf
binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing); binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing);
any_tuple atuple2; message atuple2;
uniform_typeid<any_tuple>()->deserialize(&atuple2, &bd); uniform_typeid<message>()->deserialize(&atuple2, &bd);
auto opt = tuple_cast<uint32_t, string>(atuple2); auto opt = tuple_cast<uint32_t, string>(atuple2);
CPPA_CHECK(opt.valid()); CPPA_CHECK(opt.valid());
if (opt.valid()) { if (opt.valid()) {
...@@ -274,15 +274,15 @@ int main() { ...@@ -274,15 +274,15 @@ int main() {
// test serialization of enums // test serialization of enums
try { try {
auto enum_tuple = make_any_tuple(test_enum::b); auto enum_tuple = make_message(test_enum::b);
// serialize b1 to buf // serialize b1 to buf
util::buffer wr_buf; util::buffer wr_buf;
binary_serializer bs(&wr_buf, &addressing); binary_serializer bs(&wr_buf, &addressing);
bs << enum_tuple; bs << enum_tuple;
// deserialize b2 from buf // deserialize b2 from buf
binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing); binary_deserializer bd(wr_buf.data(), wr_buf.size(), &addressing);
any_tuple enum_tuple2; message enum_tuple2;
uniform_typeid<any_tuple>()->deserialize(&enum_tuple2, &bd); uniform_typeid<message>()->deserialize(&enum_tuple2, &bd);
auto opt = tuple_cast<test_enum>(enum_tuple2); auto opt = tuple_cast<test_enum>(enum_tuple2);
CPPA_CHECK(opt.valid()); CPPA_CHECK(opt.valid());
if (opt.valid()) { if (opt.valid()) {
......
...@@ -254,7 +254,7 @@ class fixed_stack : public sb_actor<fixed_stack> { ...@@ -254,7 +254,7 @@ class fixed_stack : public sb_actor<fixed_stack> {
behavior echo_actor(event_based_actor* self) { behavior echo_actor(event_based_actor* self) {
return ( return (
others() >> [=]() -> any_tuple { others() >> [=]() -> message {
self->quit(exit_reason::normal); self->quit(exit_reason::normal);
return self->last_dequeued(); return self->last_dequeued();
} }
...@@ -268,7 +268,7 @@ struct simple_mirror : sb_actor<simple_mirror> { ...@@ -268,7 +268,7 @@ struct simple_mirror : sb_actor<simple_mirror> {
simple_mirror() { simple_mirror() {
init_state = ( init_state = (
others() >> [=]() -> any_tuple { others() >> [=]() -> message {
return last_dequeued(); return last_dequeued();
} }
); );
...@@ -332,7 +332,7 @@ struct slave : event_based_actor { ...@@ -332,7 +332,7 @@ struct slave : event_based_actor {
void test_serial_reply() { void test_serial_reply() {
auto mirror_behavior = [=](event_based_actor* self) { auto mirror_behavior = [=](event_based_actor* self) {
self->become(others() >> [=]() -> any_tuple { self->become(others() >> [=]() -> message {
CPPA_PRINT("return self->last_dequeued()"); CPPA_PRINT("return self->last_dequeued()");
return self->last_dequeued(); return self->last_dequeued();
}); });
...@@ -394,13 +394,13 @@ void test_serial_reply() { ...@@ -394,13 +394,13 @@ void test_serial_reply() {
void test_or_else() { void test_or_else() {
scoped_actor self; scoped_actor self;
partial_function handle_a { message_handler handle_a {
on("a") >> [] { return 1; } on("a") >> [] { return 1; }
}; };
partial_function handle_b { message_handler handle_b {
on("b") >> [] { return 2; } on("b") >> [] { return 2; }
}; };
partial_function handle_c { message_handler handle_c {
on("c") >> [] { return 3; } on("c") >> [] { return 3; }
}; };
auto run_testee([&](actor testee) { auto run_testee([&](actor testee) {
...@@ -469,8 +469,8 @@ void test_continuation() { ...@@ -469,8 +469,8 @@ void test_continuation() {
void test_simple_reply_response() { void test_simple_reply_response() {
auto s = spawn([](event_based_actor* self) -> behavior { auto s = spawn([](event_based_actor* self) -> behavior {
return ( return (
others() >> [=]() -> any_tuple { others() >> [=]() -> message {
CPPA_CHECK(self->last_dequeued() == make_any_tuple(atom("hello"))); CPPA_CHECK(self->last_dequeued() == make_message(atom("hello")));
self->quit(); self->quit();
return self->last_dequeued(); return self->last_dequeued();
} }
...@@ -480,7 +480,7 @@ void test_simple_reply_response() { ...@@ -480,7 +480,7 @@ void test_simple_reply_response() {
self->send(s, atom("hello")); self->send(s, atom("hello"));
self->receive( self->receive(
others() >> [&] { others() >> [&] {
CPPA_CHECK(self->last_dequeued() == make_any_tuple(atom("hello"))); CPPA_CHECK(self->last_dequeued() == make_message(atom("hello")));
} }
); );
self->await_all_other_actors_done(); self->await_all_other_actors_done();
...@@ -507,7 +507,7 @@ void test_spawn() { ...@@ -507,7 +507,7 @@ void test_spawn() {
CPPA_PRINT("test self->send()"); CPPA_PRINT("test self->send()");
self->send(self, 1, 2, 3, true); self->send(self, 1, 2, 3, true);
self->receive(on(1, 2, 3, true) >> [] { }); self->receive(on(1, 2, 3, true) >> [] { });
self->send_tuple(self, any_tuple{}); self->send_tuple(self, message{});
self->receive(on() >> [] { }); self->receive(on() >> [] { });
self->await_all_other_actors_done(); self->await_all_other_actors_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
...@@ -775,7 +775,7 @@ void test_spawn() { ...@@ -775,7 +775,7 @@ void test_spawn() {
others() >> CPPA_UNEXPECTED_MSG_CB_REF(self) others() >> CPPA_UNEXPECTED_MSG_CB_REF(self)
); );
// kill joe and bob // kill joe and bob
auto poison_pill = make_any_tuple(atom("done")); auto poison_pill = make_message(atom("done"));
anon_send_tuple(joe, poison_pill); anon_send_tuple(joe, poison_pill);
anon_send_tuple(bob, poison_pill); anon_send_tuple(bob, poison_pill);
self->await_all_other_actors_done(); self->await_all_other_actors_done();
......
...@@ -121,7 +121,7 @@ struct D : popular_actor { ...@@ -121,7 +121,7 @@ struct D : popular_actor {
quit(); quit();
}); });
//*/ //*/
return sync_send_tuple(buddy(), last_dequeued()).then([=]() -> any_tuple { return sync_send_tuple(buddy(), last_dequeued()).then([=]() -> message {
quit(); quit();
return last_dequeued(); return last_dequeued();
});//*/ });//*/
......
...@@ -14,20 +14,17 @@ ...@@ -14,20 +14,17 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/cow_tuple.hpp" #include "cppa/cow_tuple.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp" #include "cppa/tuple_cast.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/tpartial_function.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/detail/matches.hpp" #include "cppa/detail/matches.hpp"
#include "cppa/detail/projection.hpp"
#include "cppa/detail/types_array.hpp" #include "cppa/detail/types_array.hpp"
#include "cppa/detail/value_guard.hpp" #include "cppa/detail/value_guard.hpp"
#include "cppa/detail/object_array.hpp"
using std::cout; using std::cout;
using std::endl; using std::endl;
...@@ -212,7 +209,7 @@ void check_guards() { ...@@ -212,7 +209,7 @@ void check_guards() {
auto f08 = on<int>() >> [&](int& mref) { mref = 8; invoked = "f08"; }; auto f08 = on<int>() >> [&](int& mref) { mref = 8; invoked = "f08"; };
CPPA_CHECK_INVOKED(f08, (f08_val)); CPPA_CHECK_INVOKED(f08, (f08_val));
CPPA_CHECK_EQUAL(f08_val, 8); CPPA_CHECK_EQUAL(f08_val, 8);
any_tuple f08_any_val = make_cow_tuple(666); message f08_any_val = make_cow_tuple(666);
CPPA_CHECK(f08(f08_any_val)); CPPA_CHECK(f08(f08_any_val));
CPPA_CHECK_EQUAL(f08_any_val.get_as<int>(0), 8); CPPA_CHECK_EQUAL(f08_any_val.get_as<int>(0), 8);
...@@ -221,11 +218,11 @@ void check_guards() { ...@@ -221,11 +218,11 @@ void check_guards() {
CPPA_CHECK_NOT_INVOKED(f09, ("hello lambda", f09_val)); CPPA_CHECK_NOT_INVOKED(f09, ("hello lambda", f09_val));
CPPA_CHECK_INVOKED(f09, ("0", f09_val)); CPPA_CHECK_INVOKED(f09, ("0", f09_val));
CPPA_CHECK_EQUAL(f09_val, 9); CPPA_CHECK_EQUAL(f09_val, 9);
any_tuple f09_any_val = make_cow_tuple("0", 666); message f09_any_val = make_cow_tuple("0", 666);
CPPA_CHECK(f09(f09_any_val)); CPPA_CHECK(f09(f09_any_val));
CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9); CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9);
f09_any_val.get_as_mutable<int>(1) = 666; f09_any_val.get_as_mutable<int>(1) = 666;
any_tuple f09_any_val_copy{f09_any_val}; message f09_any_val_copy{f09_any_val};
CPPA_CHECK(f09_any_val.at(0) == f09_any_val_copy.at(0)); CPPA_CHECK(f09_any_val.at(0) == f09_any_val_copy.at(0));
// detaches f09_any_val from f09_any_val_copy // detaches f09_any_val from f09_any_val_copy
CPPA_CHECK(f09(f09_any_val)); CPPA_CHECK(f09(f09_any_val));
...@@ -340,7 +337,7 @@ void check_wildcards() { ...@@ -340,7 +337,7 @@ void check_wildcards() {
CPPA_CHECK_EQUAL("1", t0_0); CPPA_CHECK_EQUAL("1", t0_0);
CPPA_CHECK_EQUAL(2, t0_1); CPPA_CHECK_EQUAL(2, t0_1);
// use tuple cast to get a subtuple // use tuple cast to get a subtuple
any_tuple at0(t0); message at0(t0);
auto v0opt = tuple_cast<std::string, anything>(at0); auto v0opt = tuple_cast<std::string, anything>(at0);
CPPA_CHECK((std::is_same<decltype(v0opt), optional<cow_tuple<std::string>>>::value)); CPPA_CHECK((std::is_same<decltype(v0opt), optional<cow_tuple<std::string>>>::value));
CPPA_CHECK((v0opt)); CPPA_CHECK((v0opt));
...@@ -366,7 +363,7 @@ void check_wildcards() { ...@@ -366,7 +363,7 @@ void check_wildcards() {
CPPA_CHECK(lhs == rhs); CPPA_CHECK(lhs == rhs);
CPPA_CHECK(rhs == lhs); CPPA_CHECK(rhs == lhs);
} }
any_tuple at1 = make_cow_tuple("one", 2, 3.f, 4.0); { message at1 = make_cow_tuple("one", 2, 3.f, 4.0); {
// perfect match // perfect match
auto opt0 = tuple_cast<std::string, int, float, double>(at1); auto opt0 = tuple_cast<std::string, int, float, double>(at1);
CPPA_CHECK(opt0); CPPA_CHECK(opt0);
...@@ -404,7 +401,7 @@ void check_wildcards() { ...@@ -404,7 +401,7 @@ void check_wildcards() {
auto opt4 = tuple_cast<anything, double>(at1); auto opt4 = tuple_cast<anything, double>(at1);
CPPA_CHECK(opt4); CPPA_CHECK(opt4);
if (opt4) { if (opt4) {
CPPA_CHECK((*opt4 == make_any_tuple(4.0))); CPPA_CHECK((*opt4 == make_message(4.0)));
CPPA_CHECK_EQUAL(get<0>(*opt4), 4.0); CPPA_CHECK_EQUAL(get<0>(*opt4), 4.0);
CPPA_CHECK(&get<0>(*opt4) == at1.at(3)); CPPA_CHECK(&get<0>(*opt4) == at1.at(3));
} }
...@@ -441,17 +438,17 @@ void check_move_ops() { ...@@ -441,17 +438,17 @@ void check_move_ops() {
void check_drop() { void check_drop() {
CPPA_PRINT(__func__); CPPA_PRINT(__func__);
auto t0 = make_any_tuple(0, 1, 2, 3); auto t0 = make_message(0, 1, 2, 3);
auto t1 = t0.drop(2); auto t1 = t0.drop(2);
CPPA_CHECK_EQUAL(t1.size(), 2); CPPA_CHECK_EQUAL(t1.size(), 2);
CPPA_CHECK_EQUAL(t1.get_as<int>(0), 2); CPPA_CHECK_EQUAL(t1.get_as<int>(0), 2);
CPPA_CHECK_EQUAL(t1.get_as<int>(1), 3); CPPA_CHECK_EQUAL(t1.get_as<int>(1), 3);
CPPA_CHECK(t1 == make_any_tuple(2, 3)); CPPA_CHECK(t1 == make_message(2, 3));
auto t2 = t0.drop_right(2); auto t2 = t0.drop_right(2);
CPPA_CHECK_EQUAL(t2.size(), 2); CPPA_CHECK_EQUAL(t2.size(), 2);
CPPA_CHECK_EQUAL(t2.get_as<int>(0), 0); CPPA_CHECK_EQUAL(t2.get_as<int>(0), 0);
CPPA_CHECK_EQUAL(t2.get_as<int>(1), 1); CPPA_CHECK_EQUAL(t2.get_as<int>(1), 1);
CPPA_CHECK(t2 == make_any_tuple(0, 1)); CPPA_CHECK(t2 == make_message(0, 1));
CPPA_CHECK(t0.take(3) == t0.drop_right(1)); CPPA_CHECK(t0.take(3) == t0.drop_right(1));
CPPA_CHECK(t0.take_right(3) == t0.drop(1)); CPPA_CHECK(t0.take_right(3) == t0.drop(1));
CPPA_CHECK(t0 == t0.take(4)); CPPA_CHECK(t0 == t0.take(4));
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/message.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
...@@ -76,7 +76,7 @@ int main() { ...@@ -76,7 +76,7 @@ int main() {
"@cn_hdl", // io::connection_handle "@cn_hdl", // io::connection_handle
"@atom", // atom_value "@atom", // atom_value
"@addr", // actor address "@addr", // actor address
"@tuple", // any_tuple "@msg", // message
"@header", // message_header "@header", // message_header
"@actor", // actor_ptr "@actor", // actor_ptr
"@group", // group "@group", // group
...@@ -147,7 +147,7 @@ int main() { ...@@ -147,7 +147,7 @@ int main() {
std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t, std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t,
std::string, std::u16string, std::u32string, std::string, std::u16string, std::u32string,
float, double, float, double,
atom_value, any_tuple, message_header, atom_value, message, message_header,
actor, group, actor, group,
channel, node_id_ptr channel, node_id_ptr
>::arr; >::arr;
...@@ -169,7 +169,7 @@ int main() { ...@@ -169,7 +169,7 @@ int main() {
uniform_typeid<float>(), uniform_typeid<float>(),
uniform_typeid<double>(), uniform_typeid<double>(),
uniform_typeid<atom_value>(), uniform_typeid<atom_value>(),
uniform_typeid<any_tuple>(), uniform_typeid<message>(),
uniform_typeid<message_header>(), uniform_typeid<message_header>(),
uniform_typeid<actor>(), uniform_typeid<actor>(),
uniform_typeid<group>(), uniform_typeid<group>(),
......
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