#pragma once #include #include namespace mln { class TaggedScheduler; template class OptionalActor { public: template OptionalActor(bool syncObject, Scheduler& scheduler, Args&&... args) { if (syncObject) { object = std::make_unique(std::forward(args)...); selfRef = OptionalActorRef(object->self()); } else { actor = std::make_unique>(scheduler, std::forward(args)...); selfRef = OptionalActorRef(actor->self()); } } template OptionalActor(bool syncObject, const TaggedScheduler& scheduler, Args&&... args) { if (syncObject) { object = std::make_unique(std::forward(args)...); selfRef = OptionalActorRef(object->self()); } else { actor = std::make_unique>(scheduler, std::forward(args)...); selfRef = OptionalActorRef(actor->self()); } } template OptionalActor(bool syncObject, std::shared_ptr scheduler, Args&&... args) { if (syncObject) { object = std::make_unique(std::forward(args)...); selfRef = OptionalActorRef(object->self()); } else { actor = std::make_unique>(scheduler, std::forward(args)...); selfRef = OptionalActorRef(actor->self()); } } OptionalActor(const OptionalActor&) = delete; const OptionalActorRef& self() { return selfRef; } private: class SyncObject { public: template SyncObject(Args&&... args) requires(std::is_constructible_v, Args...>) { new (&objectStorage) Object(OptionalActorRef(self()), std::forward(args)...); } template SyncObject(Args&&... args) requires(std::is_constructible_v) { new (&objectStorage) Object(std::forward(args)...); } SyncObject(const SyncObject&) = delete; ~SyncObject() { self().~Object(); } Object& self() { return reinterpret_cast(objectStorage); } private: std::aligned_storage_t objectStorage; }; std::unique_ptr object; std::unique_ptr> actor; OptionalActorRef selfRef; }; } // namespace mln