Files
Cpp-in-Embedded-Systems/Chapter18/cib/libs/conc/concepts.hpp
Amar Mahmutbegovic 8634accda5 add Chapter18
2025-02-06 00:19:59 +01:00

57 lines
1.9 KiB
C++

#pragma once
#if __cplusplus >= 202002L
#include <atomic>
#include <concepts>
namespace conc {
template <typename T>
concept policy = requires(auto (*f)()->int &&, auto (*pred)()->bool) {
{ T::call_in_critical_section(f) } -> std::same_as<int &&>;
{ T::call_in_critical_section(f, pred) } -> std::same_as<int &&>;
};
} // namespace conc
namespace atomic {
template <typename T>
concept load_store_policy = requires(int &a, int value, std::memory_order mo) {
{ T::load(a) } -> std::same_as<int>;
{ T::load(a, mo) } -> std::same_as<int>;
{ T::store(a, value) } -> std::same_as<void>;
{ T::store(a, value, mo) } -> std::same_as<void>;
};
template <typename T>
concept exchange_policy =
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
{ T::exchange(a, value) } -> std::same_as<int>;
{ T::exchange(a, value, mo) } -> std::same_as<int>;
};
template <typename T>
concept add_sub_policy =
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
{ T::fetch_add(a, value) } -> std::same_as<int>;
{ T::fetch_add(a, value, mo) } -> std::same_as<int>;
{ T::fetch_sub(a, value) } -> std::same_as<int>;
{ T::fetch_sub(a, value, mo) } -> std::same_as<int>;
};
template <typename T>
concept bitwise_policy =
load_store_policy<T> and requires(int &a, int value, std::memory_order mo) {
{ T::fetch_and(a, value) } -> std::same_as<int>;
{ T::fetch_and(a, value, mo) } -> std::same_as<int>;
{ T::fetch_or(a, value) } -> std::same_as<int>;
{ T::fetch_or(a, value, mo) } -> std::same_as<int>;
{ T::fetch_xor(a, value) } -> std::same_as<int>;
{ T::fetch_xor(a, value, mo) } -> std::same_as<int>;
};
template <typename T>
concept policy = exchange_policy<T> and add_sub_policy<T> and bitwise_policy<T>;
} // namespace atomic
#endif