Commit a334ca5b authored by Dominik Charousset's avatar Dominik Charousset

Make actor_cast move-aware

parent 7836c7b3
......@@ -68,8 +68,8 @@ public:
friend class local_actor;
// allow conversion via actor_cast
template <class T, typename U>
friend T actor_cast(const U&);
template <class>
friend struct actor_cast_access;
actor() = default;
actor(actor&&) = default;
......@@ -170,8 +170,14 @@ private:
return ptr_.get();
}
inline abstract_actor* release() noexcept {
return ptr_.release();
}
actor(abstract_actor*);
actor(abstract_actor*, bool);
abstract_actor_ptr ptr_;
};
......
......@@ -52,9 +52,8 @@ public:
friend class actor;
friend class abstract_actor;
template <class T, typename U>
friend T actor_cast(const U&);
template <class>
friend struct actor_cast_access;
actor_addr() = default;
actor_addr(actor_addr&&) = default;
......@@ -112,8 +111,14 @@ private:
return ptr_.get();
}
inline abstract_actor* release() noexcept {
return ptr_.release();
}
actor_addr(abstract_actor*);
actor_addr(abstract_actor*, bool);
abstract_actor_ptr ptr_;
};
......
......@@ -20,12 +20,46 @@
#ifndef CAF_ACTOR_CAST_HPP
#define CAF_ACTOR_CAST_HPP
#include <type_traits>
namespace caf {
/// Converts actor handle `what` to a different actor handle of type `T`.
template <class T, typename U>
T actor_cast(const U& what) {
return what.get();
template <class T>
struct actor_cast_access {
constexpr actor_cast_access() {
// nop
}
template<class U>
T operator()(U& y) const {
return {y.get(), true};
}
template<class U>
typename std::enable_if<std::is_rvalue_reference<U&&>::value, T>::type
operator()(U&& y) const {
return {y.release(), false};
}
};
template <class T>
struct actor_cast_access<T*> {
constexpr actor_cast_access() {
// nop
}
template<class U>
T* operator()(const U& y) const {
return y.get();
}
};
/// Converts actor handle `what` to a different actor
/// handle or raw pointer of type `T`.
template <class T, class U>
T actor_cast(U&& what) {
actor_cast_access<T> f;
return f(std::forward<U>(what));
}
} // namespace caf
......
......@@ -48,8 +48,8 @@ class channel : detail::comparable<channel>,
detail::comparable<channel, actor>,
detail::comparable<channel, abstract_channel*> {
public:
template <class T, typename U>
friend T actor_cast(const U&);
template <class>
friend struct actor_cast_access;
channel() = default;
channel(channel&&) = default;
......@@ -106,7 +106,9 @@ public:
friend void serialize(deserializer& source, channel& x, const unsigned int);
private:
channel(abstract_channel* ptr);
channel(abstract_channel*);
channel(abstract_channel*, bool);
inline abstract_channel* get() const noexcept {
return ptr_.get();
......
......@@ -31,6 +31,9 @@ class maybe;
template <class>
class intrusive_ptr;
template <class>
struct actor_cast_access;
// classes
class actor;
class group;
......@@ -86,10 +89,6 @@ enum class atom_value : uint64_t;
// aliases
using actor_id = uint32_t;
// functions
template <class T, typename U>
T actor_cast(const U&);
namespace io {
class broker;
......
......@@ -45,8 +45,8 @@ constexpr invalid_group_t invalid_group = invalid_group_t{};
class group : detail::comparable<group>,
detail::comparable<group, invalid_group_t> {
public:
template <class T, typename U>
friend T actor_cast(const U&);
template <class>
friend struct actor_cast_access;
group() = default;
......@@ -100,6 +100,12 @@ private:
return ptr_.get();
}
inline abstract_group* release() noexcept {
return ptr_.release();
}
group(abstract_group*, bool);
abstract_group_ptr ptr_;
};
......
......@@ -68,8 +68,8 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>,
friend class typed_actor;
// allow conversion via actor_cast
template <class T, typename U>
friend T actor_cast(const U&);
template <class>
friend struct actor_cast_access;
/// Creates a new `typed_actor` type by extending this one with `Es...`.
template <class... Es>
......@@ -248,10 +248,14 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>,
/// @endcond
private:
abstract_actor* get() const {
abstract_actor* get() const noexcept {
return ptr_.get();
}
abstract_actor* release() noexcept {
return ptr_.release();
}
typed_actor(abstract_actor* ptr) : ptr_(ptr) {
// nop
}
......
......@@ -42,6 +42,10 @@ actor::actor(abstract_actor* ptr) : ptr_(ptr) {
// nop
}
actor::actor(abstract_actor* ptr, bool add_ref) : ptr_(ptr, add_ref) {
// nop
}
actor& actor::operator=(const invalid_actor_t&) {
ptr_.reset();
return *this;
......
......@@ -36,6 +36,10 @@ actor_addr::actor_addr(abstract_actor* ptr) : ptr_(ptr) {
// nop
}
actor_addr::actor_addr(abstract_actor* ptr, bool add_ref) : ptr_(ptr, add_ref) {
// nop
}
actor_addr actor_addr::operator=(const invalid_actor_addr_t&) {
ptr_.reset();
return *this;
......
......@@ -19,6 +19,7 @@
#include "caf/bound_actor.hpp"
#include "caf/actor_cast.hpp"
#include "caf/mailbox_element.hpp"
#include "caf/system_messages.hpp"
......
......@@ -48,6 +48,11 @@ channel::channel(abstract_channel* ptr) : ptr_(ptr) {
// nop
}
channel::channel(abstract_channel* ptr, bool add_ref) : ptr_(ptr, add_ref) {
// nop
}
channel::channel(local_actor* ptr) : ptr_(ptr) {
// nop
}
......
......@@ -30,6 +30,10 @@ group::group(abstract_group* ptr) : ptr_(ptr) {
// nop
}
group::group(abstract_group* ptr, bool add_ref) : ptr_(ptr, add_ref) {
// nop
}
group::group(const invalid_group_t&) : ptr_(nullptr) {
// nop
}
......
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