Commit 1028e5b6 authored by Dominik Charousset's avatar Dominik Charousset

Fix doxygen, harmonize actor handles, use noexcept

parent e6cb9172
...@@ -38,7 +38,9 @@ namespace caf { ...@@ -38,7 +38,9 @@ namespace caf {
class scoped_actor; class scoped_actor;
struct invalid_actor_t { struct invalid_actor_t {
constexpr invalid_actor_t() {} constexpr invalid_actor_t() {
// nop
}
}; };
/// Identifies an invalid {@link actor}. /// Identifies an invalid {@link actor}.
...@@ -59,36 +61,40 @@ class actor : detail::comparable<actor>, ...@@ -59,36 +61,40 @@ class actor : detail::comparable<actor>,
detail::comparable<actor, actor_addr>, detail::comparable<actor, actor_addr>,
detail::comparable<actor, invalid_actor_t>, detail::comparable<actor, invalid_actor_t>,
detail::comparable<actor, invalid_actor_addr_t> { detail::comparable<actor, invalid_actor_addr_t> {
public:
// grant access to private ctor
friend class local_actor; friend class local_actor;
// allow conversion via actor_cast
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
public:
actor() = default; actor() = default;
actor(actor&&) = default; actor(actor&&) = default;
actor(const actor&) = default; actor(const actor&) = default;
actor& operator=(actor&&) = default;
actor& operator=(const actor&) = default;
template <class T> template <class T,
actor(intrusive_ptr<T> ptr, class Enable =
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0) typename std::enable_if<
: ptr_(std::move(ptr)) {} is_convertible_to_actor<T>::value
>::type>
actor(intrusive_ptr<T> ptr) : ptr_(std::move(ptr)) {
// nop
}
template <class T> template <class T,
actor(T* ptr, class Enable =
typename std::enable_if<is_convertible_to_actor<T>::value>::type* = 0) typename std::enable_if<
: ptr_(ptr) {} is_convertible_to_actor<T>::value
>::type>
actor(T* ptr) : ptr_(ptr) {
// nop
}
actor(const invalid_actor_t&); actor(const invalid_actor_t&);
actor& operator=(actor&&) = default;
actor& operator=(const actor&) = default;
template <class T> template <class T>
typename std::enable_if<is_convertible_to_actor<T>::value, actor&>::type typename std::enable_if<is_convertible_to_actor<T>::value, actor&>::type
operator=(intrusive_ptr<T> ptr) { operator=(intrusive_ptr<T> ptr) {
...@@ -107,55 +113,56 @@ public: ...@@ -107,55 +113,56 @@ public:
actor& operator=(const invalid_actor_t&); actor& operator=(const invalid_actor_t&);
inline operator bool() const { /// Returns the address of the stored actor.
actor_addr address() const noexcept;
/// Returns `*this != invalid_actor`.
inline operator bool() const noexcept {
return static_cast<bool>(ptr_); return static_cast<bool>(ptr_);
} }
inline bool operator!() const { /// Returns `*this == invalid_actor`.
inline bool operator!() const noexcept {
return ! ptr_; return ! ptr_;
} }
/// Returns a handle that grants access to actor operations such as enqueue. /// Returns whether this is an handle to a remote actor.
inline abstract_actor* operator->() const { bool is_remote() const noexcept;
return ptr_.get();
} /// Returns the ID of this actor.
actor_id id() const noexcept;
/// Exchange content of `*this` and `other`.
void swap(actor& other) noexcept;
/// @cond PRIVATE
inline abstract_actor& operator*() const { inline abstract_actor* operator->() const noexcept {
return *ptr_; return ptr_.get();
} }
intptr_t compare(const actor& other) const; intptr_t compare(const actor&) const noexcept;
intptr_t compare(const actor_addr&) const; intptr_t compare(const actor_addr&) const noexcept;
inline intptr_t compare(const invalid_actor_t&) const { inline intptr_t compare(const invalid_actor_t&) const noexcept {
return ptr_ ? 1 : 0; return ptr_ ? 1 : 0;
} }
inline intptr_t compare(const invalid_actor_addr_t&) const { inline intptr_t compare(const invalid_actor_addr_t&) const noexcept {
return compare(invalid_actor); return compare(invalid_actor);
} }
/// Returns the address of the stored actor. /// @endcond
actor_addr address() const;
/// Returns whether this is an handle to a remote actor.
bool is_remote() const;
actor_id id() const;
void swap(actor& other);
private: private:
inline abstract_actor* get() const noexcept {
inline abstract_actor* get() const {
return ptr_.get(); return ptr_.get();
} }
actor(abstract_actor*); actor(abstract_actor*);
abstract_actor_ptr ptr_; abstract_actor_ptr ptr_;
}; };
} // namespace caf } // namespace caf
......
...@@ -45,62 +45,73 @@ constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{}; ...@@ -45,62 +45,73 @@ constexpr invalid_actor_addr_t invalid_actor_addr = invalid_actor_addr_t{};
/// Stores the address of typed as well as untyped actors. /// Stores the address of typed as well as untyped actors.
class actor_addr : detail::comparable<actor_addr>, class actor_addr : detail::comparable<actor_addr>,
detail::comparable<actor_addr, abstract_actor*>, detail::comparable<actor_addr, abstract_actor*>,
detail::comparable<actor_addr, abstract_actor_ptr> { detail::comparable<actor_addr, abstract_actor_ptr> {
public:
// grant access to private ctor
friend class actor; friend class actor;
friend class abstract_actor; friend class abstract_actor;
template <class T, typename U> template <class T, typename U>
friend T actor_cast(const U&); friend T actor_cast(const U&);
public:
actor_addr() = default; actor_addr() = default;
actor_addr(actor_addr&&) = default; actor_addr(actor_addr&&) = default;
actor_addr(const actor_addr&) = default; actor_addr(const actor_addr&) = default;
actor_addr& operator=(actor_addr&&) = default; actor_addr& operator=(actor_addr&&) = default;
actor_addr& operator=(const actor_addr&) = default; actor_addr& operator=(const actor_addr&) = default;
actor_addr(const invalid_actor_addr_t&); actor_addr(const invalid_actor_addr_t&);
actor_addr operator=(const invalid_actor_addr_t&); actor_addr operator=(const invalid_actor_addr_t&);
inline explicit operator bool() const { return static_cast<bool>(ptr_); } /// Returns `*this != invalid_actor_addr`.
inline explicit operator bool() const noexcept {
return static_cast<bool>(ptr_);
}
/// Returns `*this == invalid_actor_addr`.
inline bool operator!() const noexcept {
return !ptr_;
}
inline bool operator!() const { return ! ptr_; } /// Returns whether this is an handle to a remote actor.
bool is_remote() const noexcept;
intptr_t compare(const actor_addr& other) const; /// Returns the ID of this actor.
actor_id id() const noexcept;
intptr_t compare(const abstract_actor* other) const; /// Returns the origin node of this actor.
node_id node() const noexcept;
inline intptr_t compare(const abstract_actor_ptr& other) const { /// Exchange content of `*this` and `other`.
return compare(other.get()); void swap(actor_addr& other) noexcept;
/// @cond PRIVATE
inline abstract_actor* operator->() const noexcept {
return ptr_.get();
} }
actor_id id() const; intptr_t compare(const actor_addr& other) const noexcept;
node_id node() const; intptr_t compare(const abstract_actor* other) const noexcept;
/// Returns whether this is an address of a remote actor. inline intptr_t compare(const abstract_actor_ptr& other) const noexcept {
bool is_remote() const; return compare(other.get());
}
/// Returns the set of accepted messages types as strings or /// @endcond
/// an empty set if this actor is untyped.
std::set<std::string> message_types() const;
private: private:
inline abstract_actor* get() const noexcept {
inline abstract_actor* get() const { return ptr_.get(); } return ptr_.get();
}
explicit actor_addr(abstract_actor*); explicit actor_addr(abstract_actor*);
abstract_actor_ptr ptr_; abstract_actor_ptr ptr_;
}; };
} // namespace caf } // namespace caf
......
...@@ -51,7 +51,7 @@ public: ...@@ -51,7 +51,7 @@ public:
~blocking_actor(); ~blocking_actor();
/************************************************************************** /**************************************************************************
* utility stuff and receive() member function family * * utility stuff and receive() member function family *
**************************************************************************/ **************************************************************************/
using timeout_type = std::chrono::high_resolution_clock::time_point; using timeout_type = std::chrono::high_resolution_clock::time_point;
......
...@@ -38,17 +38,12 @@ ...@@ -38,17 +38,12 @@
#define CAF_VERSION 1400 #define CAF_VERSION 1400
/// Defined to the major version number of CAF. /// Defined to the major version number of CAF.
///*/
#define CAF_MAJOR_VERSION (CAF_VERSION / 10000) #define CAF_MAJOR_VERSION (CAF_VERSION / 10000)
/**
/// Defined to the minor version number of CAF. /// Defined to the minor version number of CAF.
///*/
#define CAF_MINOR_VERSION ((CAF_VERSION / 100) % 100) #define CAF_MINOR_VERSION ((CAF_VERSION / 100) % 100)
/**
/// Defined to the patch version number of CAF. /// Defined to the patch version number of CAF.
///*/
#define CAF_PATCH_VERSION (CAF_VERSION % 100) #define CAF_PATCH_VERSION (CAF_VERSION % 100)
// This compiler-specific block defines: // This compiler-specific block defines:
......
...@@ -31,84 +31,80 @@ namespace detail { ...@@ -31,84 +31,80 @@ namespace detail {
/// - `x == 0` if `*this == other` /// - `x == 0` if `*this == other`
template <class Subclass, class T = Subclass> template <class Subclass, class T = Subclass>
class comparable { class comparable {
friend bool operator==(const Subclass& lhs, const T& rhs) noexcept {
friend bool operator==(const Subclass& lhs, const T& rhs) {
return lhs.compare(rhs) == 0; return lhs.compare(rhs) == 0;
} }
friend bool operator==(const T& lhs, const Subclass& rhs) { friend bool operator==(const T& lhs, const Subclass& rhs) noexcept {
return rhs.compare(lhs) == 0; return rhs.compare(lhs) == 0;
} }
friend bool operator!=(const Subclass& lhs, const T& rhs) { friend bool operator!=(const Subclass& lhs, const T& rhs) noexcept {
return lhs.compare(rhs) != 0; return lhs.compare(rhs) != 0;
} }
friend bool operator!=(const T& lhs, const Subclass& rhs) { friend bool operator!=(const T& lhs, const Subclass& rhs) noexcept {
return rhs.compare(lhs) != 0; return rhs.compare(lhs) != 0;
} }
friend bool operator<(const Subclass& lhs, const T& rhs) { friend bool operator<(const Subclass& lhs, const T& rhs) noexcept {
return lhs.compare(rhs) < 0; return lhs.compare(rhs) < 0;
} }
friend bool operator>(const Subclass& lhs, const T& rhs) { friend bool operator>(const Subclass& lhs, const T& rhs) noexcept {
return lhs.compare(rhs) > 0; return lhs.compare(rhs) > 0;
} }
friend bool operator<(const T& lhs, const Subclass& rhs) { friend bool operator<(const T& lhs, const Subclass& rhs) noexcept {
return rhs > lhs; return rhs > lhs;
} }
friend bool operator>(const T& lhs, const Subclass& rhs) { friend bool operator>(const T& lhs, const Subclass& rhs) noexcept {
return rhs < lhs; return rhs < lhs;
} }
friend bool operator<=(const Subclass& lhs, const T& rhs) { friend bool operator<=(const Subclass& lhs, const T& rhs) noexcept {
return lhs.compare(rhs) <= 0; return lhs.compare(rhs) <= 0;
} }
friend bool operator>=(const Subclass& lhs, const T& rhs) { friend bool operator>=(const Subclass& lhs, const T& rhs) noexcept {
return lhs.compare(rhs) >= 0; return lhs.compare(rhs) >= 0;
} }
friend bool operator<=(const T& lhs, const Subclass& rhs) { friend bool operator<=(const T& lhs, const Subclass& rhs) noexcept {
return rhs >= lhs; return rhs >= lhs;
} }
friend bool operator>=(const T& lhs, const Subclass& rhs) { friend bool operator>=(const T& lhs, const Subclass& rhs) noexcept {
return rhs <= lhs; return rhs <= lhs;
} }
}; };
template <class Subclass> template <class Subclass>
class comparable<Subclass, Subclass> { class comparable<Subclass, Subclass> {
friend bool operator==(const Subclass& lhs, const Subclass& rhs) noexcept {
friend bool operator==(const Subclass& lhs, const Subclass& rhs) {
return lhs.compare(rhs) == 0; return lhs.compare(rhs) == 0;
} }
friend bool operator!=(const Subclass& lhs, const Subclass& rhs) { friend bool operator!=(const Subclass& lhs, const Subclass& rhs) noexcept {
return lhs.compare(rhs) != 0; return lhs.compare(rhs) != 0;
} }
friend bool operator<(const Subclass& lhs, const Subclass& rhs) { friend bool operator<(const Subclass& lhs, const Subclass& rhs) noexcept {
return lhs.compare(rhs) < 0; return lhs.compare(rhs) < 0;
} }
friend bool operator<=(const Subclass& lhs, const Subclass& rhs) { friend bool operator<=(const Subclass& lhs, const Subclass& rhs) noexcept {
return lhs.compare(rhs) <= 0; return lhs.compare(rhs) <= 0;
} }
friend bool operator>(const Subclass& lhs, const Subclass& rhs) { friend bool operator>(const Subclass& lhs, const Subclass& rhs) noexcept {
return lhs.compare(rhs) > 0; return lhs.compare(rhs) > 0;
} }
friend bool operator>=(const Subclass& lhs, const Subclass& rhs) { friend bool operator>=(const Subclass& lhs, const Subclass& rhs) noexcept {
return lhs.compare(rhs) >= 0; return lhs.compare(rhs) >= 0;
} }
}; };
} // namespace details } // namespace details
......
...@@ -71,13 +71,13 @@ public: ...@@ -71,13 +71,13 @@ public:
} }
} }
void swap(intrusive_ptr& other) { void swap(intrusive_ptr& other) noexcept {
std::swap(ptr_, other.ptr_); std::swap(ptr_, other.ptr_);
} }
/// Returns the raw pointer without modifying reference /// Returns the raw pointer without modifying reference
/// count and sets this to `nullptr`. /// count and sets this to `nullptr`.
pointer release() { pointer release() noexcept {
auto result = ptr_; auto result = ptr_;
ptr_ = nullptr; ptr_ = nullptr;
return result; return result;
......
...@@ -54,9 +54,11 @@ class typed_broker; ...@@ -54,9 +54,11 @@ class typed_broker;
template <class... Sigs> template <class... Sigs>
class typed_actor : detail::comparable<typed_actor<Sigs...>>, class typed_actor : detail::comparable<typed_actor<Sigs...>>,
detail::comparable<typed_actor<Sigs...>, actor_addr>, detail::comparable<typed_actor<Sigs...>, actor_addr>,
detail::comparable<typed_actor<Sigs...>, invalid_actor_t>,
detail::comparable<typed_actor<Sigs...>, detail::comparable<typed_actor<Sigs...>,
invalid_actor_addr_t> { invalid_actor_addr_t> {
public: public:
// grant access to private ctor
friend class local_actor; friend class local_actor;
// friend with all possible instantiations // friend with all possible instantiations
...@@ -97,55 +99,85 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>, ...@@ -97,55 +99,85 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>,
typed_actor& operator=(const typed_actor&) = default; typed_actor& operator=(const typed_actor&) = default;
template <class TypedActor, template <class TypedActor,
class Enable = typename std::enable_if< class Enable =
detail::tlf_is_subset(signatures{}, typename std::enable_if<
typename TypedActor::signatures{}) detail::tlf_is_subset(signatures(),
>::type> typename TypedActor::signatures())
>::type>
typed_actor(const TypedActor& other) : ptr_(other.ptr_) { typed_actor(const TypedActor& other) : ptr_(other.ptr_) {
// nop // nop
} }
template <class TypedActor, template <class TypedActor,
class Enable = typename std::enable_if< class Enable =
detail::tlf_is_subset(signatures{}, typename std::enable_if<
typename TypedActor::signatures{}) detail::tlf_is_subset(signatures(),
>::type> typename TypedActor::signatures())
>::type>
typed_actor& operator=(const TypedActor& other) { typed_actor& operator=(const TypedActor& other) {
ptr_ = other.ptr_; ptr_ = other.ptr_;
return *this; return *this;
} }
template <class Impl, template <class Impl,
class Enable = typename std::enable_if< class Enable =
detail::tlf_is_subset(signatures{}, typename std::enable_if<
typename Impl::signatures{}) detail::tlf_is_subset(signatures(),
>::type> typename Impl::signatures())
>::type>
typed_actor(intrusive_ptr<Impl> other) : ptr_(std::move(other)) { typed_actor(intrusive_ptr<Impl> other) : ptr_(std::move(other)) {
// nop // nop
} }
abstract_actor* operator->() const { /// Queries the address of the stored actor.
return ptr_.get(); actor_addr address() const noexcept {
return ptr_ ? ptr_->address() : actor_addr();
} }
abstract_actor& operator*() const { /// Returns `*this != invalid_actor`.
return *ptr_.get(); explicit operator bool() const noexcept {
return static_cast<bool>(ptr_);
} }
/// Queries the address of the stored actor. /// Returns `*this == invalid_actor`.
actor_addr address() const { bool operator!() const noexcept {
return ptr_ ? ptr_->address() : actor_addr{}; return !ptr_;
}
/// Returns whether this is an handle to a remote actor.
bool is_remote() const noexcept {
return ptr_ ? ptr_->is_remote() : false;
}
/// Returns the ID of this actor.
actor_id id() const noexcept {
return ptr_ ? ptr_->id() : invalid_actor_id;
}
/// Exchange content of `*this` and `other`.
void swap(actor& other) noexcept {
ptr_.swap(other.ptr_);
} }
intptr_t compare(const actor_addr& rhs) const { /// @cond PRIVATE
abstract_actor* operator->() const noexcept {
return ptr_.get();
}
abstract_actor& operator*() const noexcept {
return *ptr_.get();
}
intptr_t compare(const actor_addr& rhs) const noexcept {
return address().compare(rhs); return address().compare(rhs);
} }
intptr_t compare(const typed_actor& other) const { intptr_t compare(const typed_actor& other) const noexcept {
return compare(other.address()); return compare(other.address());
} }
intptr_t compare(const invalid_actor_addr_t&) const { intptr_t compare(const invalid_actor_addr_t&) const noexcept {
return ptr_ ? 1 : 0; return ptr_ ? 1 : 0;
} }
...@@ -153,13 +185,7 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>, ...@@ -153,13 +185,7 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>,
return {Sigs::static_type_name()...}; return {Sigs::static_type_name()...};
} }
explicit operator bool() const { /// @endcond
return static_cast<bool>(ptr_);
}
bool operator!() const {
return !ptr_;
}
private: private:
abstract_actor* get() const { abstract_actor* get() const {
......
...@@ -84,85 +84,62 @@ uniform_value make_uniform_value(const uniform_type_info* uti, Ts&&... xs) { ...@@ -84,85 +84,62 @@ uniform_value make_uniform_value(const uniform_type_info* uti, Ts&&... xs) {
/// Unfortunately, this is not possible using the C++ RTTI system. /// Unfortunately, this is not possible using the C++ RTTI system.
/// ///
/// Since it is not possible to extend `std::type_info, `libcaf` /// Since it is not possible to extend `std::type_info, `libcaf`
/// uses its own type abstraction: /// uses its own type abstraction: `uniform_type_info`.
/// {@link caf::uniform_type_info uniform_type_info}.
/// ///
/// Unlike `std::type_info::name(), /// Unlike `std::type_info::name()`, `uniform_type_info::name()`
/// {@link caf::uniform_type_info::name() uniform_type_info::name()}
/// is guaranteed to return the same name on all supported platforms. /// is guaranteed to return the same name on all supported platforms.
/// Furthermore, it allows to create an instance of a type by name: /// Furthermore, it allows to create an instance of a type by name:
/// ///
/// @code /// @code
/// // creates a signed, 32 bit integer /// // creates a signed, 32 bit integer
/// caf::object i = caf::uniform_type_info::by_name("@i32")->create(); /// uniform_value i = caf::uniform_type_info::by_name("@i32")->create();
/// @endcode /// @endcode
/// ///
/// However, you should rarely if ever need to use {@link caf::object object} /// However, you should rarely if ever need to use `uniform_value`
/// or {@link caf::uniform_type_info uniform_type_info}. /// or `uniform_type_info`.
/// ///
/// There is one exception, though, where you need to care about /// There is one exception, though, where you need to care about
/// the type system: using custom data types in messages. /// the type system: using custom data types in messages.
/// The source code below compiles fine, but crashes with an exception during /// The source code below compiles fine, but crashes with an exception during
/// runtime. /// runtime.
/// ///
/// @code /// ~~~
/// #include "caf/all.hpp" /// #include "caf/all.hpp"
/// using namespace caf; /// using namespace caf;
/// ///
/// struct foo { int a; int b; }; /// struct foo { int a; int b; };
/// ///
/// int main() /// int main() {
/// {
/// send(self, foo{1, 2}); /// send(self, foo{1, 2});
/// return 0; /// return 0;
/// } /// }
/// @endcode /// ~~~
///
/// Depending on your platform, the error message looks somewhat like this:
///
/// <tt>
/// terminate called after throwing an instance of std::runtime_error
/// <br>
/// what(): uniform_type_info::by_type_info(): foo is an unknown typeid name
/// </tt>
/// ///
/// The user-defined struct `foo` is not known by the type system. /// The user-defined struct `foo` is not known by the type system.
/// Thus, `foo` cannot be serialized and is rejected. /// Thus, `foo` cannot be serialized and the code above code above will
/// /// throw a `std::runtime_error`.
/// Fortunately, there is an easy way to add `foo` the type system,
/// without needing to implement serialize/deserialize by yourself:
///
/// @code
/// caf::announce<foo>(&foo::a, &foo::b);
/// @endcode
/// ///
/// {@link caf::announce announce()} takes the class as template /// Fortunately, there is an easy way to add simple data structures like
/// parameter and pointers to all members (or getter/setter pairs) /// `foo` the type system without implementing serialize/deserialize yourself:
/// as arguments. This works for all primitive data types and STL compliant /// `caf::announce<foo>("foo", &foo::a, &foo::b)`.
/// containers. See the announce {@link announce_example_1.cpp example 1},
/// {@link announce_example_2.cpp example 2},
/// {@link announce_example_3.cpp example 3} and
/// {@link announce_example_4.cpp example 4} for more details.
/// ///
/// Obviously, there are limitations. If your class does implement /// The function `announce()` takes the class as template
/// an unsupported data structure, you have to implement serialize/deserialize /// parameter. The name of the announced type is the first argument, followed
/// by yourself. {@link announce_example_5.cpp Example 5} shows, how to /// by pointers to all members (or getter/setter pairs). This works for all
/// announce a tree data structure to the type system. /// primitive data types and STL compliant containers. See the announce example
/// for more details. Complex data structures usually require a custom
/// serializer class.
/// @ingroup TypeSystem /// @ingroup TypeSystem
/// Provides a platform independent type name and a (very primitive) /// Provides a platform independent type name and a (very primitive)
/// kind of reflection in combination with {@link caf::object object}. /// kind of reflection in combination with `uniform_value`.
/// The platform independent name is equal to the "in-sourcecode-name" /// CAF uses abbvreviate type names for brevity:
/// with a few exceptions:
/// - std::string is named \@str /// - std::string is named \@str
/// - std::u16string is named \@u16str /// - std::u16string is named \@u16str
/// - std::u32string is named \@u32str /// - std::u32string is named \@u32str
/// - integers are named `\@(i|u)$size\n /// - integers are named `\@(i|u)$size\n
/// e.g.: \@i32 is a 32 bit signed integer; \@u16 /// e.g.: \@i32 is a 32 bit signed integer; \@u16
/// is a 16 bit unsigned integer /// is a 16 bit unsigned integer
/// - the <em>anonymous namespace</em> is named \@_ \n
/// e.g.: `namespace { class foo { }; } is mapped to
/// \@_::foo
class uniform_type_info { class uniform_type_info {
public: public:
friend bool operator==(const uniform_type_info& lhs, friend bool operator==(const uniform_type_info& lhs,
...@@ -190,8 +167,7 @@ public: ...@@ -190,8 +167,7 @@ public:
/// @throws std::runtime_error if `tinfo` is not an announced type. /// @throws std::runtime_error if `tinfo` is not an announced type.
static const uniform_type_info* from(const std::type_info& tinfo); static const uniform_type_info* from(const std::type_info& tinfo);
/// Get all instances. /// Returns a vector with all known (announced) types.
/// @returns A vector with all known (announced) instances.
static std::vector<const uniform_type_info*> instances(); static std::vector<const uniform_type_info*> instances();
/// Creates a copy of `other`. /// Creates a copy of `other`.
......
...@@ -42,28 +42,28 @@ actor& actor::operator=(const invalid_actor_t&) { ...@@ -42,28 +42,28 @@ actor& actor::operator=(const invalid_actor_t&) {
return *this; return *this;
} }
intptr_t actor::compare(const actor& other) const { intptr_t actor::compare(const actor& other) const noexcept {
return channel::compare(ptr_.get(), other.ptr_.get()); return channel::compare(ptr_.get(), other.ptr_.get());
} }
intptr_t actor::compare(const actor_addr& other) const { intptr_t actor::compare(const actor_addr& other) const noexcept {
return static_cast<ptrdiff_t>(ptr_.get() - other.ptr_.get()); return static_cast<ptrdiff_t>(ptr_.get() - other.ptr_.get());
} }
void actor::swap(actor& other) { void actor::swap(actor& other) noexcept {
ptr_.swap(other.ptr_); ptr_.swap(other.ptr_);
} }
actor_addr actor::address() const { actor_addr actor::address() const noexcept {
return ptr_ ? ptr_->address() : actor_addr{}; return ptr_ ? ptr_->address() : actor_addr{};
} }
bool actor::is_remote() const { bool actor::is_remote() const noexcept {
return ptr_ ? ptr_->is_remote() : false; return ptr_ ? ptr_->is_remote() : false;
} }
actor_id actor::id() const { actor_id actor::id() const noexcept {
return (ptr_) ? ptr_->id() : 0; return ptr_ ? ptr_->id() : invalid_actor_id;
} }
} // namespace caf } // namespace caf
...@@ -41,33 +41,33 @@ actor_addr::actor_addr(abstract_actor* ptr) : ptr_(ptr) { ...@@ -41,33 +41,33 @@ actor_addr::actor_addr(abstract_actor* ptr) : ptr_(ptr) {
// nop // nop
} }
intptr_t actor_addr::compare(const actor_addr& other) const { actor_addr actor_addr::operator=(const invalid_actor_addr_t&) {
ptr_.reset();
return *this;
}
intptr_t actor_addr::compare(const actor_addr& other) const noexcept {
return compare_impl(ptr_.get(), other.ptr_.get()); return compare_impl(ptr_.get(), other.ptr_.get());
} }
intptr_t actor_addr::compare(const abstract_actor* other) const { intptr_t actor_addr::compare(const abstract_actor* other) const noexcept {
return compare_impl(ptr_.get(), other); return compare_impl(ptr_.get(), other);
} }
actor_addr actor_addr::operator=(const invalid_actor_addr_t&) {
ptr_.reset();
return *this;
}
actor_id actor_addr::id() const { actor_id actor_addr::id() const noexcept {
return (ptr_) ? ptr_->id() : 0; return (ptr_) ? ptr_->id() : 0;
} }
node_id actor_addr::node() const { node_id actor_addr::node() const noexcept {
return ptr_ ? ptr_->node() : detail::singletons::get_node_id(); return ptr_ ? ptr_->node() : detail::singletons::get_node_id();
} }
bool actor_addr::is_remote() const { bool actor_addr::is_remote() const noexcept {
return ptr_ ? ptr_->is_remote() : false; return ptr_ ? ptr_->is_remote() : false;
} }
std::set<std::string> actor_addr::message_types() const { void actor_addr::swap(actor_addr& other) noexcept {
return ! ptr_ ? std::set<std::string>{} : ptr_->message_types(); ptr_.swap(other.ptr_);
} }
} // namespace caf } // namespace caf
...@@ -779,7 +779,9 @@ void basp_broker::init_handshake_as_server(connection_context& ctx, ...@@ -779,7 +779,9 @@ void basp_broker::init_handshake_as_server(connection_context& ctx,
if (addr != invalid_actor_addr) { if (addr != invalid_actor_addr) {
auto writer = make_payload_writer([&](binary_serializer& sink) { auto writer = make_payload_writer([&](binary_serializer& sink) {
sink << addr.id(); sink << addr.id();
auto sigs = addr.message_types(); // TODO: this always exposes the "real" type of an actor,
// which prohibits users from announcing sub-types
auto sigs = addr->message_types();
sink << static_cast<uint32_t>(sigs.size()); sink << static_cast<uint32_t>(sigs.size());
for (auto& sig : sigs) { for (auto& sig : sigs) {
sink << sig; sink << sig;
......
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