Commit a334ca5b authored by Dominik Charousset's avatar Dominik Charousset

Make actor_cast move-aware

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