Files
ligo/include/ligo/detail/state.hpp
T
khodowany 67429eacd1
publish / publish (push) Successful in 31m41s
Initial public khodo snapshot
2026-09-04 19:30:11 -05:00

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);
}