92 lines
2.6 KiB
C++
92 lines
2.6 KiB
C++
#pragma once
|
|
#include <atomic>
|
|
#include <concepts>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <ranges>
|
|
#include <thread>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include "proxy/v4/detail/facade_creation.h"
|
|
namespace aethera {
|
|
using pro::facade_builder;
|
|
using pro::proxy;
|
|
struct Non_Copyable {
|
|
protected:
|
|
Non_Copyable() = default;
|
|
~Non_Copyable() = default;
|
|
Non_Copyable(const Non_Copyable&) = delete;
|
|
Non_Copyable& operator=(const Non_Copyable&) = delete;
|
|
Non_Copyable(Non_Copyable&&) = default;
|
|
Non_Copyable& operator=(Non_Copyable&&) = default;
|
|
};
|
|
struct Immovable {
|
|
protected:
|
|
Immovable() = default;
|
|
~Immovable() = default;
|
|
Immovable(const Immovable&) = delete;
|
|
Immovable& operator=(const Immovable&) = delete;
|
|
Immovable(Immovable&&) = delete;
|
|
Immovable& operator=(Immovable&&) = delete;
|
|
};
|
|
template <class T>
|
|
concept Basic_Lockable = requires(T& lock) {
|
|
{ lock.lock() } -> std::same_as<void>;
|
|
{ lock.unlock() } -> std::same_as<void>;
|
|
};
|
|
template <class T>
|
|
concept Lockable = Basic_Lockable<T> && requires(T& lock) {
|
|
{ lock.try_lock() } -> std::convertible_to<bool>;
|
|
};
|
|
template <class T>
|
|
concept Exchange_Value =
|
|
std::default_initializable<T> &&
|
|
std::copy_constructible<T> &&
|
|
std::assignable_from<T&, const T&>;
|
|
template <class T>
|
|
concept Member_Value = std::is_object_v<T>;
|
|
template <class T>
|
|
concept Copyable_Member =
|
|
Member_Value<T> &&
|
|
std::copy_constructible<std::remove_cv_t<T>>;
|
|
template <class From, class To>
|
|
concept Assignable_To = std::assignable_from<To, From&&>;
|
|
template <class Fn, class Arg>
|
|
concept Invocable_With = std::invocable<Fn, Arg>;
|
|
template <class Fn, class Val>
|
|
concept Value_Reader =
|
|
Invocable_With<Fn, const Val&> &&
|
|
(!std::is_member_object_pointer_v<std::remove_cvref_t<Fn>>);
|
|
template <class Fn, class Val>
|
|
concept Value_Writer =
|
|
Invocable_With<Fn, Val&> &&
|
|
(!std::is_member_object_pointer_v<std::remove_cvref_t<Fn>>);
|
|
template <class T>
|
|
concept Clearable = requires(T& value) {
|
|
{ value.clear() } -> std::same_as<void>;
|
|
};
|
|
template <class T>
|
|
concept List_Value =
|
|
std::default_initializable<T> &&
|
|
std::ranges::range<T> &&
|
|
Clearable<T>;
|
|
struct Spin_Lock : Immovable {
|
|
Spin_Lock() noexcept = default;
|
|
void lock() noexcept {
|
|
while (flag_.test_and_set(std::memory_order_acquire)) {
|
|
while (flag_.test(std::memory_order_relaxed)) {
|
|
std::this_thread::yield();
|
|
}
|
|
}
|
|
}
|
|
bool try_lock() noexcept {
|
|
return !flag_.test_and_set(std::memory_order_acquire);
|
|
}
|
|
void unlock() noexcept {
|
|
flag_.clear(std::memory_order_release);
|
|
}
|
|
std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
|
|
};
|
|
static_assert(Lockable<Spin_Lock>);
|
|
}
|