#pragma once
#include <concepts>
#include <cstdint>
#include <type_traits>
template <class That>
concept Observation_Struct = std::is_class_v<That>;
template <class That>
concept Observer_Enable_Flag = requires {
    { That::enabled } -> std::convertible_to<bool>;
    typename std::bool_constant<static_cast<bool>(That::enabled)>;
};
template <class That, class Observation>
concept Struct_Observer = Observation_Struct<Observation> && Observer_Enable_Flag<That> && requires(That& observer, const Observation& observation) {
    { observer.observe(observation) } noexcept -> std::same_as<void>;
};
template <class That, class Observation>
concept Timed_Struct_Observer = Struct_Observer<That, Observation> && requires(That& observer, const That& const_observer, const Observation& observation) {
    { const_observer.now_ns() } noexcept -> std::convertible_to<std::uint64_t>;
    { observer.observe(observation) } noexcept -> std::same_as<void>;
};
