71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include <modulus.hpp>
|
|
|
|
namespace ligo::detail {
|
|
|
|
class state_handle {
|
|
public:
|
|
state_handle() = default;
|
|
state_handle(ligo::detail::state_handle const&) = delete;
|
|
state_handle(ligo::detail::state_handle&& other) noexcept;
|
|
~state_handle() = default;
|
|
auto operator=(ligo::detail::state_handle const&) -> ligo::detail::state_handle& = delete;
|
|
auto operator=(ligo::detail::state_handle&& other) noexcept -> ligo::detail::state_handle&;
|
|
explicit operator std::bool_t() const noexcept;
|
|
template <typename S>
|
|
explicit state_handle(std::shared_ptr<S> state);
|
|
template <typename S>
|
|
auto as() const -> std::shared_ptr<S>;
|
|
private:
|
|
std::atomic<std::shared_ptr<void>> state_{};
|
|
};
|
|
|
|
class unique_state {
|
|
public:
|
|
unique_state() noexcept = default;
|
|
unique_state(ligo::detail::unique_state const&) = delete;
|
|
unique_state(ligo::detail::unique_state&&) noexcept = default;
|
|
~unique_state() = default;
|
|
auto operator=(ligo::detail::unique_state const&) -> ligo::detail::unique_state& = delete;
|
|
auto operator=(ligo::detail::unique_state&&) noexcept -> ligo::detail::unique_state& = default;
|
|
explicit operator std::bool_t() const noexcept;
|
|
template <typename STATE>
|
|
explicit unique_state(std::unique_ptr<STATE> state);
|
|
template <typename STATE>
|
|
auto as() const noexcept -> STATE*;
|
|
private:
|
|
static auto ignore_state(void* state) -> void;
|
|
template <typename STATE>
|
|
static auto delete_state(void* state) -> void;
|
|
std::unique_ptr<void, std::function<void(void*)>> state_{nullptr, ignore_state};
|
|
};
|
|
|
|
}
|
|
|
|
template <typename STATE>
|
|
ligo::detail::state_handle::state_handle(std::shared_ptr<STATE> state) : state_{std::shared_ptr<void>{std::move(state)}} {}
|
|
|
|
template <typename STATE>
|
|
auto ligo::detail::state_handle::as() const -> std::shared_ptr<STATE> {
|
|
return std::static_pointer_cast<STATE>(state_.load());
|
|
}
|
|
|
|
template <typename STATE>
|
|
ligo::detail::unique_state::unique_state(std::unique_ptr<STATE> state) : state_{state.release(), delete_state<STATE>} {}
|
|
|
|
template <typename STATE>
|
|
auto ligo::detail::unique_state::as() const noexcept -> STATE* {
|
|
return static_cast<STATE*>(state_.get());
|
|
}
|
|
|
|
template <typename STATE>
|
|
auto ligo::detail::unique_state::delete_state(void* state) -> void {
|
|
delete static_cast<STATE*>(state);
|
|
}
|