Rearrange atomic operator internals

This commit is contained in:
Nekotekina 2018-08-24 02:30:38 +03:00
parent 5afd12e8a4
commit 56a165ecdc
3 changed files with 28 additions and 66 deletions

View file

@ -3,7 +3,7 @@
#include "types.h" #include "types.h"
// Helper class, provides access to compiler-specific atomic intrinsics // Helper class, provides access to compiler-specific atomic intrinsics
template<typename T, std::size_t Size> template<typename T, std::size_t Size = sizeof(T)>
struct atomic_storage struct atomic_storage
{ {
static_assert(sizeof(T) <= 16 && sizeof(T) == alignof(T), "atomic_storage<> error: invalid type"); static_assert(sizeof(T) <= 16 && sizeof(T) == alignof(T), "atomic_storage<> error: invalid type");
@ -562,7 +562,7 @@ struct atomic_storage<T, 16> : atomic_storage<T, 0>
// TODO // TODO
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_add struct atomic_add
{ {
auto operator()(T1& lhs, const T2& rhs) const auto operator()(T1& lhs, const T2& rhs) const
@ -579,7 +579,7 @@ struct atomic_add<T1, T2, std::enable_if_t<std::is_integral<T1>::value && std::i
static constexpr auto atomic_op = &atomic_storage<T1>::add_fetch; static constexpr auto atomic_op = &atomic_storage<T1>::add_fetch;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_sub struct atomic_sub
{ {
auto operator()(T1& lhs, const T2& rhs) const auto operator()(T1& lhs, const T2& rhs) const
@ -596,7 +596,7 @@ struct atomic_sub<T1, T2, std::enable_if_t<std::is_integral<T1>::value && std::i
static constexpr auto atomic_op = &atomic_storage<T1>::sub_fetch; static constexpr auto atomic_op = &atomic_storage<T1>::sub_fetch;
}; };
template<typename T, typename> template<typename T, typename = void>
struct atomic_pre_inc struct atomic_pre_inc
{ {
auto operator()(T& v) const auto operator()(T& v) const
@ -611,7 +611,7 @@ struct atomic_pre_inc<T, std::enable_if_t<std::is_integral<T>::value>>
static constexpr auto atomic_op = &atomic_storage<T>::inc_fetch; static constexpr auto atomic_op = &atomic_storage<T>::inc_fetch;
}; };
template<typename T, typename> template<typename T, typename = void>
struct atomic_post_inc struct atomic_post_inc
{ {
auto operator()(T& v) const auto operator()(T& v) const
@ -626,7 +626,7 @@ struct atomic_post_inc<T, std::enable_if_t<std::is_integral<T>::value>>
static constexpr auto atomic_op = &atomic_storage<T>::fetch_inc; static constexpr auto atomic_op = &atomic_storage<T>::fetch_inc;
}; };
template<typename T, typename> template<typename T, typename = void>
struct atomic_pre_dec struct atomic_pre_dec
{ {
auto operator()(T& v) const auto operator()(T& v) const
@ -641,7 +641,7 @@ struct atomic_pre_dec<T, std::enable_if_t<std::is_integral<T>::value>>
static constexpr auto atomic_op = &atomic_storage<T>::dec_fetch; static constexpr auto atomic_op = &atomic_storage<T>::dec_fetch;
}; };
template<typename T, typename> template<typename T, typename = void>
struct atomic_post_dec struct atomic_post_dec
{ {
auto operator()(T& v) const auto operator()(T& v) const
@ -656,7 +656,7 @@ struct atomic_post_dec<T, std::enable_if_t<std::is_integral<T>::value>>
static constexpr auto atomic_op = &atomic_storage<T>::fetch_dec; static constexpr auto atomic_op = &atomic_storage<T>::fetch_dec;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_and struct atomic_and
{ {
auto operator()(T1& lhs, const T2& rhs) const auto operator()(T1& lhs, const T2& rhs) const
@ -673,7 +673,7 @@ struct atomic_and<T1, T2, std::enable_if_t<std::is_integral<T1>::value && std::i
static constexpr auto atomic_op = &atomic_storage<T1>::and_fetch; static constexpr auto atomic_op = &atomic_storage<T1>::and_fetch;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_or struct atomic_or
{ {
auto operator()(T1& lhs, const T2& rhs) const auto operator()(T1& lhs, const T2& rhs) const
@ -690,7 +690,7 @@ struct atomic_or<T1, T2, std::enable_if_t<std::is_integral<T1>::value && std::is
static constexpr auto atomic_op = &atomic_storage<T1>::or_fetch; static constexpr auto atomic_op = &atomic_storage<T1>::or_fetch;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_xor struct atomic_xor
{ {
auto operator()(T1& lhs, const T2& rhs) const auto operator()(T1& lhs, const T2& rhs) const
@ -707,7 +707,7 @@ struct atomic_xor<T1, T2, std::enable_if_t<std::is_integral<T1>::value && std::i
static constexpr auto atomic_op = &atomic_storage<T1>::xor_fetch; static constexpr auto atomic_op = &atomic_storage<T1>::xor_fetch;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_test_and_set struct atomic_test_and_set
{ {
bool operator()(T1& lhs, const T2& rhs) const bool operator()(T1& lhs, const T2& rhs) const
@ -724,7 +724,7 @@ struct atomic_test_and_set<T1, T2, std::enable_if_t<std::is_integral<T1>::value
static constexpr auto atomic_op = &atomic_storage<T1>::test_and_set; static constexpr auto atomic_op = &atomic_storage<T1>::test_and_set;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_test_and_reset struct atomic_test_and_reset
{ {
bool operator()(T1& lhs, const T2& rhs) const bool operator()(T1& lhs, const T2& rhs) const
@ -741,7 +741,7 @@ struct atomic_test_and_reset<T1, T2, std::enable_if_t<std::is_integral<T1>::valu
static constexpr auto atomic_op = &atomic_storage<T1>::test_and_reset; static constexpr auto atomic_op = &atomic_storage<T1>::test_and_reset;
}; };
template<typename T1, typename T2, typename> template<typename T1, typename T2, typename = void>
struct atomic_test_and_complement struct atomic_test_and_complement
{ {
bool operator()(T1& lhs, const T2& rhs) const bool operator()(T1& lhs, const T2& rhs) const
@ -916,7 +916,7 @@ public:
{ {
return fetch_op(atomic_add<type, T2>{}, rhs); return fetch_op(atomic_add<type, T2>{}, rhs);
} }
template<typename T2> template<typename T2>
type add_fetch(const T2& rhs) type add_fetch(const T2& rhs)
{ {

View file

@ -43,6 +43,7 @@ Intersection (&) and symmetric difference (^) is also available.
*/ */
#include "types.h" #include "types.h"
#include "Atomic.h"
// Helper template // Helper template
template<typename T> template<typename T>
@ -368,7 +369,7 @@ struct atomic_xor<BS, T, std::void_t<decltype(T::__bitset_enum_max), std::enable
}; };
template<typename T> template<typename T>
struct atomic_add<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_add<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -389,7 +390,7 @@ struct atomic_add<T, T, std::void_t<decltype(T::__bitset_set_type)>>
}; };
template<typename T> template<typename T>
struct atomic_sub<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_sub<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -410,7 +411,7 @@ struct atomic_sub<T, T, std::void_t<decltype(T::__bitset_set_type)>>
}; };
template<typename T> template<typename T>
struct atomic_and<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_and<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -431,7 +432,7 @@ struct atomic_and<T, T, std::void_t<decltype(T::__bitset_set_type)>>
}; };
template<typename T> template<typename T>
struct atomic_xor<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_xor<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -497,7 +498,7 @@ struct atomic_test_and_complement<BS, T, std::void_t<decltype(T::__bitset_enum_m
}; };
template<typename T> template<typename T>
struct atomic_test_and_set<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_test_and_set<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -512,7 +513,7 @@ struct atomic_test_and_set<T, T, std::void_t<decltype(T::__bitset_set_type)>>
}; };
template<typename T> template<typename T>
struct atomic_test_and_reset<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_test_and_reset<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -527,7 +528,7 @@ struct atomic_test_and_reset<T, T, std::void_t<decltype(T::__bitset_set_type)>>
}; };
template<typename T> template<typename T>
struct atomic_test_and_complement<T, T, std::void_t<decltype(T::__bitset_set_type)>> struct atomic_test_and_complement<T, T, std::enable_if_t<sizeof(T::__bitset_set_type) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -624,7 +625,7 @@ inline bool test_and_complement(T& lhs, T rhs)
} }
template<typename T> template<typename T>
struct atomic_or<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_or<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -645,7 +646,7 @@ struct atomic_or<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<
}; };
template<typename T> template<typename T>
struct atomic_and<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_and<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -666,7 +667,7 @@ struct atomic_and<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t
}; };
template<typename T> template<typename T>
struct atomic_xor<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_xor<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -687,7 +688,7 @@ struct atomic_xor<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t
}; };
template<typename T> template<typename T>
struct atomic_test_and_set<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_test_and_set<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -702,7 +703,7 @@ struct atomic_test_and_set<T, T, std::void_t<decltype(T::__bitwise_ops), std::en
}; };
template<typename T> template<typename T>
struct atomic_test_and_reset<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_test_and_reset<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;
@ -717,7 +718,7 @@ struct atomic_test_and_reset<T, T, std::void_t<decltype(T::__bitwise_ops), std::
}; };
template<typename T> template<typename T>
struct atomic_test_and_complement<T, T, std::void_t<decltype(T::__bitwise_ops), std::enable_if_t<std::is_enum<T>::value>>> struct atomic_test_and_complement<T, T, std::enable_if_t<sizeof(T::__bitwise_ops) != 0 && std::is_enum<T>::value>>
{ {
using under = std::underlying_type_t<T>; using under = std::underlying_type_t<T>;

View file

@ -114,45 +114,6 @@ struct se_storage;
template <typename T, bool Se = true, std::size_t Align = alignof(T)> template <typename T, bool Se = true, std::size_t Align = alignof(T)>
class se_t; class se_t;
template <typename T, std::size_t Size = sizeof(T)>
struct atomic_storage;
template <typename T1, typename T2, typename = void>
struct atomic_add;
template <typename T1, typename T2, typename = void>
struct atomic_sub;
template <typename T1, typename T2, typename = void>
struct atomic_and;
template <typename T1, typename T2, typename = void>
struct atomic_or;
template <typename T1, typename T2, typename = void>
struct atomic_xor;
template <typename T, typename = void>
struct atomic_pre_inc;
template <typename T, typename = void>
struct atomic_post_inc;
template <typename T, typename = void>
struct atomic_pre_dec;
template <typename T, typename = void>
struct atomic_post_dec;
template <typename T1, typename T2, typename = void>
struct atomic_test_and_set;
template <typename T1, typename T2, typename = void>
struct atomic_test_and_reset;
template <typename T1, typename T2, typename = void>
struct atomic_test_and_complement;
template <typename T> template <typename T>
class atomic_t; class atomic_t;