Nugget
atomic_casts.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
5 
6 #ifndef EASTL_ATOMIC_INTERNAL_CASTS_H
7 #define EASTL_ATOMIC_INTERNAL_CASTS_H
8 
9 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
10  #pragma once
11 #endif
12 
13 
14 #include <EASTL/internal/type_transformations.h>
15 
16 
17 namespace eastl
18 {
19 
20 
21 namespace internal
22 {
23 
24 
25 template <typename T>
26 EASTL_FORCE_INLINE volatile T* AtomicVolatileCast(T* ptr) EA_NOEXCEPT
27 {
28  static_assert(!eastl::is_volatile<volatile T*>::value, "eastl::atomic<T> : pointer must not be volatile, the pointed to type must be volatile!");
29  static_assert(eastl::is_volatile<volatile T>::value, "eastl::atomic<T> : the pointed to type must be volatile!");
30 
31  return reinterpret_cast<volatile T*>(ptr);
32 }
33 
34 
54 template <typename Integral, typename T>
55 EASTL_FORCE_INLINE volatile Integral* AtomicVolatileIntegralCast(T* ptr) EA_NOEXCEPT
56 {
57  static_assert(!eastl::is_volatile<volatile Integral*>::value, "eastl::atomic<T> : pointer must not be volatile, the pointed to type must be volatile!");
58  static_assert(eastl::is_volatile<volatile Integral>::value, "eastl::atomic<T> : the pointed to type must be volatile!");
59  static_assert(eastl::is_integral<Integral>::value, "eastl::atomic<T> : Integral cast must cast to an Integral type!");
60  static_assert(sizeof(Integral) == sizeof(T), "eastl::atomic<T> : Integral and T must be same size for casting!");
61 
62  return reinterpret_cast<volatile Integral*>(ptr);
63 }
64 
65 template <typename Integral, typename T>
66 EASTL_FORCE_INLINE Integral* AtomicIntegralCast(T* ptr) EA_NOEXCEPT
67 {
68  static_assert(eastl::is_integral<Integral>::value, "eastl::atomic<T> : Integral cast must cast to an Integral type!");
69  static_assert(sizeof(Integral) == sizeof(T), "eastl::atomic<T> : Integral and T must be same size for casting!");
70 
71  return reinterpret_cast<Integral*>(ptr);
72 }
73 
74 
84 template <typename ToType, typename FromType>
85 EASTL_FORCE_INLINE volatile ToType* AtomicVolatileTypeCast(FromType* ptr) EA_NOEXCEPT
86 {
87  static_assert(!eastl::is_volatile<volatile ToType*>::value, "eastl::atomic<T> : pointer must not be volatile, the pointed to type must be volatile!");
88  static_assert(eastl::is_volatile<volatile ToType>::value, "eastl::atomic<T> : the pointed to type must be volatile!");
89 
90  return reinterpret_cast<volatile ToType*>(ptr);
91 }
92 
93 template <typename ToType, typename FromType>
94 EASTL_FORCE_INLINE ToType* AtomicTypeCast(FromType* ptr) EA_NOEXCEPT
95 {
96  return reinterpret_cast<ToType*>(ptr);
97 }
98 
99 
117 template <typename Pun, typename T, eastl::enable_if_t<!eastl::is_same_v<Pun, T>, int> = 0>
118 EASTL_FORCE_INLINE Pun AtomicTypePunCast(const T& fromType) EA_NOEXCEPT
119 {
120  static_assert(sizeof(Pun) == sizeof(T), "eastl::atomic<T> : Pun and T must be the same size for type punning!");
121 
126  typename eastl::aligned_storage<sizeof(Pun), alignof(Pun)>::type ret;
127  __builtin_memcpy(eastl::addressof(ret), eastl::addressof(fromType), sizeof(Pun));
128  return reinterpret_cast<Pun&>(ret);
129 }
130 
131 template <typename Pun, typename T, eastl::enable_if_t<eastl::is_same_v<Pun, T>, int> = 0>
132 EASTL_FORCE_INLINE Pun AtomicTypePunCast(const T& fromType) EA_NOEXCEPT
133 {
134  return fromType;
135 }
136 
137 
138 template <typename T>
139 EASTL_FORCE_INLINE T AtomicNegateOperand(T val) EA_NOEXCEPT
140 {
141  static_assert(eastl::is_integral<T>::value, "eastl::atomic<T> : Integral Negation must be an Integral type!");
142  static_assert(!eastl::is_volatile<T>::value, "eastl::atomic<T> : T must not be volatile!");
143 
144  return static_cast<T>(0U - static_cast<eastl::make_unsigned_t<T>>(val));
145 }
146 
147 EASTL_FORCE_INLINE ptrdiff_t AtomicNegateOperand(ptrdiff_t val) EA_NOEXCEPT
148 {
149  return -val;
150 }
151 
152 
153 } // namespace internal
154 
155 
156 } // namespace eastl
157 
158 
165 #define EASTL_ATOMIC_VOLATILE_CAST(ptr) \
166  eastl::internal::AtomicVolatileCast((ptr))
167 
168 #define EASTL_ATOMIC_VOLATILE_INTEGRAL_CAST(IntegralType, ptr) \
169  eastl::internal::AtomicVolatileIntegralCast<IntegralType>((ptr))
170 
171 #define EASTL_ATOMIC_INTEGRAL_CAST(IntegralType, ptr) \
172  eastl::internal::AtomicIntegralCast<IntegralType>((ptr))
173 
174 #define EASTL_ATOMIC_VOLATILE_TYPE_CAST(ToType, ptr) \
175  eastl::internal::AtomicVolatileTypeCast<ToType>((ptr))
176 
177 #define EASTL_ATOMIC_TYPE_CAST(ToType, ptr) \
178  eastl::internal::AtomicTypeCast<ToType>((ptr))
179 
180 #define EASTL_ATOMIC_TYPE_PUN_CAST(PunType, fromType) \
181  eastl::internal::AtomicTypePunCast<PunType>((fromType))
182 
183 #define EASTL_ATOMIC_NEGATE_OPERAND(val) \
184  eastl::internal::AtomicNegateOperand((val))
185 
186 
187 #endif /* EASTL_ATOMIC_INTERNAL_CASTS_H */
EA Standard Template Library.
Definition: algorithm.h:288
T * addressof(T &value) EA_NOEXCEPT
Definition: memory_base.h:29
Definition: type_transformations.h:615
Definition: type_fundamental.h:148
Definition: type_traits.h:650