tdlight/tdactor/td/actor/impl/ActorId-decl.h
levlam 5cbda834bd Update copyright year.
GitOrigin-RevId: 1369d3af1195221f6ddb9462d5f8b74fb5fef20f
2018-01-02 16:45:09 +03:00

170 lines
4.2 KiB
C++

//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/utils/ObjectPool.h"
#include "td/utils/Slice.h"
#include <type_traits>
namespace td {
class ActorInfo;
class Actor;
template <class ActorType = Actor>
class ActorId {
public:
using ActorT = ActorType;
explicit ActorId(ObjectPool<ActorInfo>::WeakPtr ptr) : ptr_(ptr) {
}
ActorId() = default;
ActorId(const ActorId &) = default;
ActorId &operator=(const ActorId &) = default;
ActorId(ActorId &&other) : ptr_(other.ptr_) {
other.ptr_.clear();
}
ActorId &operator=(ActorId &&other) {
if (&other == this) {
return *this;
}
ptr_ = other.ptr_;
other.clear();
return *this;
}
~ActorId() = default;
bool empty() const {
return ptr_.empty();
}
void clear() {
ptr_.clear();
}
bool is_alive() const {
return ptr_.is_alive_unsafe();
}
ActorInfo *get_actor_info() const;
ActorType *get_actor_unsafe() const;
// returns pointer to actor if it is on current thread. nullptr otherwise
ActorType *try_get_actor() const;
Slice get_name() const;
template <class ToActorType, class = std::enable_if_t<std::is_base_of<ToActorType, ActorType>::value>>
explicit operator ActorId<ToActorType>() const {
return ActorId<ToActorType>(ptr_);
}
template <class AsActorType>
ActorId<AsActorType> as() const {
return ActorId<AsActorType>(ptr_);
}
private:
ObjectPool<ActorInfo>::WeakPtr ptr_;
};
// threat ActorId as pointer and ActorOwn as
// unique_ptr<ActorId>
template <class ActorType = Actor>
class ActorOwn {
public:
using ActorT = ActorType;
ActorOwn() = default;
explicit ActorOwn(ActorId<ActorType>);
template <class OtherActorType>
explicit ActorOwn(ActorId<OtherActorType> id);
template <class OtherActorType>
explicit ActorOwn(ActorOwn<OtherActorType> &&);
template <class OtherActorType>
ActorOwn &operator=(ActorOwn<OtherActorType> &&);
ActorOwn(ActorOwn &&);
ActorOwn &operator=(ActorOwn &&);
ActorOwn(const ActorOwn &) = delete;
ActorOwn &operator=(const ActorOwn &) = delete;
~ActorOwn();
bool empty() const;
bool is_alive() const {
return id_.is_alive();
}
ActorId<ActorType> get() const;
ActorId<ActorType> release();
void reset(ActorId<ActorType> other = ActorId<ActorType>());
void hangup() const;
const ActorId<ActorType> *operator->() const;
using ActorIdConstRef = const ActorId<ActorType> &;
// operator ActorIdConstRef();
private:
ActorId<ActorType> id_;
};
template <class ActorType = Actor>
class ActorShared {
public:
using ActorT = ActorType;
ActorShared() = default;
template <class OtherActorType>
ActorShared(ActorId<OtherActorType>, uint64 token);
template <class OtherActorType>
ActorShared(ActorShared<OtherActorType> &&);
template <class OtherActorType>
ActorShared(ActorOwn<OtherActorType> &&);
template <class OtherActorType>
ActorShared &operator=(ActorShared<OtherActorType> &&);
ActorShared(ActorShared &&);
ActorShared &operator=(ActorShared &&);
ActorShared(const ActorShared &) = delete;
ActorShared &operator=(const ActorShared &) = delete;
~ActorShared();
uint64 token() const;
bool empty() const;
bool is_alive() const {
return id_.is_alive();
}
ActorId<ActorType> get() const;
ActorId<ActorType> release();
void reset(ActorId<ActorType> other = ActorId<ActorType>());
template <class OtherActorType>
void reset(ActorId<OtherActorType> other);
const ActorId<ActorType> *operator->() const;
private:
ActorId<ActorType> id_;
uint64 token_;
};
class ActorRef {
public:
ActorRef() = default;
template <class T>
ActorRef(const ActorId<T> &actor_id);
template <class T>
ActorRef(const ActorShared<T> &actor_id);
template <class T>
ActorRef(ActorShared<T> &&actor_id);
template <class T>
ActorRef(const ActorOwn<T> &actor_id);
template <class T>
ActorRef(ActorOwn<T> &&actor_id);
ActorId<> get() const {
return actor_id_;
}
uint64 token() const {
return token_;
}
private:
ActorId<> actor_id_;
uint64 token_ = 0;
};
} // namespace td