/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2017-2020 Telegram Systems LLP */ #pragma once #include "td/actor/common.h" namespace td { namespace actor { template class ActorId; template class ActorOwn; template class ActorShared; namespace core { template ActorId actor_id(SelfT *self); } // Essentially ActorInfoWeakPtr with Type template class ActorId { public: using ActorT = ActorType; ActorId() = default; ActorId(const ActorId &) = default; ActorId &operator=(const ActorId &) = default; ActorId(ActorId &&other) = default; ActorId &operator=(ActorId &&other) = default; // allow only conversion from child to parent template ::value>> operator ActorId() const { return ActorId(ptr_); } template friend ActorId actor_dynamic_cast(ActorId from); ActorType &get_actor_unsafe() const { return static_cast(actor_info().actor()); } bool empty() const { return !ptr_; } bool is_alive() const { return !empty() && actor_info().is_alive(); } template static ActorId create(ActorOptions &options, ArgsT &&... args) { return ActorId(detail::create_actor(options, std::forward(args)...)); } template bool operator==(const ActorId &other) const { return ptr_ == other.ptr_; } detail::ActorRef as_actor_ref() const { CHECK(!empty()); return detail::ActorRef(*actor_info_ptr()); } const core::ActorInfoPtr &actor_info_ptr() const { return ptr_; } core::ActorInfo &actor_info() const { CHECK(ptr_); return *ptr_; } private: core::ActorInfoPtr ptr_; template friend class ActorId; template friend class ActorOwn; template friend class ActorShared; explicit ActorId(core::ActorInfoPtr ptr) : ptr_(std::move(ptr)) { } template friend ActorId core::actor_id(SelfT *self); }; template ActorId actor_dynamic_cast(ActorId from) { static_assert( std::is_base_of::value || std::is_base_of::value, "Invalid actor dynamic conversion"); auto res = ActorId(std::move(from.ptr_)); CHECK(dynamic_cast(&res.actor_info().actor()) == &res.get_actor_unsafe()); return res; } namespace core { // for ADL template ActorId actor_id(SelfT *self) { CHECK(self); CHECK(static_cast(self) == &core::ActorExecuteContext::get()->actor()); return ActorId(core::ActorExecuteContext::get()->actor().get_actor_info_ptr()); } inline ActorId<> actor_id() { return actor_id(&core::ActorExecuteContext::get()->actor()); } } // namespace core using core::actor_id; } // namespace actor } // namespace td