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