File indexing completed on 2025-02-23 09:22:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 #ifndef G4atomic_hh_
0068 #define G4atomic_hh_
0069
0070
0071
0072 #ifdef G4MULTITHREADED
0073
0074 # include "G4atomic_defines.hh"
0075
0076
0077
0078 template<typename _Tp>
0079 class G4atomic
0080 {
0081 public:
0082 typedef typename std::atomic<_Tp> base_type;
0083 typedef _Tp value_type;
0084
0085 private:
0086 using mem_ord = std::memory_order;
0087
0088 public:
0089
0090 explicit G4atomic(mem_ord mo = std::memory_order_acq_rel) : fMemOrder(mo)
0091 {
0092 atomics::set(&fvalue, value_type());
0093 }
0094
0095 explicit G4atomic(const value_type& _init, mem_ord mo = std::memory_order_acq_rel)
0096 : fMemOrder(mo)
0097 {
0098 atomics::set(&fvalue, _init);
0099 }
0100
0101
0102 explicit G4atomic(const base_type& rhs, mem_ord mo = std::memory_order_acq_rel) : fMemOrder(mo)
0103 {
0104 atomics::set(&fvalue, rhs);
0105 }
0106
0107
0108 explicit G4atomic(const G4atomic& rhs) : fMemOrder(rhs.fMemOrder)
0109 {
0110 atomics::set(&fvalue, rhs.base());
0111 }
0112
0113
0114 G4atomic& operator=(const G4atomic& rhs)
0115 {
0116 if (this != &rhs) atomics::set(&fvalue, rhs.fvalue);
0117 return *this;
0118 }
0119
0120 G4atomic& operator=(const value_type& rhs)
0121 {
0122 atomics::set(&fvalue, rhs);
0123 return *this;
0124 }
0125
0126 G4atomic& operator=(const base_type& rhs)
0127 {
0128 atomics::set(&fvalue, rhs);
0129 return *this;
0130 }
0131
0132
0133 ~G4atomic() { fvalue.~base_type(); }
0134
0135
0136 base_type& base() { return fvalue; }
0137 const base_type& base() const { return fvalue; }
0138 base_type& base() volatile { return fvalue; }
0139 const base_type& base() const volatile { return fvalue; }
0140
0141
0142 bool is_lock_free() const { return fvalue.is_lock_free(); }
0143 bool is_lock_free() const volatile { return fvalue.is_lock_free(); }
0144
0145
0146 void store(_Tp _desired, mem_ord mo = std::memory_order_seq_cst)
0147 {
0148 atomics::set(fvalue, _desired, mo);
0149 }
0150 void store(_Tp _desired, mem_ord mo = std::memory_order_seq_cst) volatile
0151 {
0152 atomics::set(fvalue, _desired, mo);
0153 }
0154
0155
0156 _Tp load(mem_ord mo = std::memory_order_seq_cst) const { return atomics::get(fvalue, mo); }
0157 _Tp load(mem_ord mo = std::memory_order_seq_cst) const volatile
0158 {
0159 return atomics::get(fvalue, mo);
0160 }
0161
0162
0163 operator _Tp() const { return this->load(); }
0164 operator _Tp() const volatile { return this->load(); }
0165
0166 operator base_type&() const { return fvalue; }
0167
0168
0169 bool compare_exchange_weak(_Tp& _expected, _Tp _desired, mem_ord _success, mem_ord _failure)
0170 {
0171 return fvalue.compare_exchange_weak(_expected, _desired, _success, _failure);
0172 }
0173 bool compare_exchange_weak(_Tp& _expected, _Tp _desired, mem_ord _success,
0174 mem_ord _failure) volatile
0175 {
0176 return fvalue.compare_exchange_weak(_expected, _desired, _success, _failure);
0177 }
0178
0179 bool compare_exchange_weak(_Tp& _expected, _Tp _desired, mem_ord _order)
0180 {
0181 return fvalue.compare_exchange_weak(_expected, _desired, _order);
0182 }
0183 bool compare_exchange_weak(_Tp& _expected, _Tp _desired, mem_ord _order) volatile
0184 {
0185 return fvalue.compare_exchange_weak(_expected, _desired, _order);
0186 }
0187
0188 bool compare_exchange_strong(_Tp& _expected, _Tp _desired, mem_ord _success, mem_ord _failure)
0189 {
0190 return fvalue.compare_exchange_weak(_expected, _desired, _success, _failure);
0191 }
0192 bool compare_exchange_strong(_Tp& _expected, _Tp _desired, mem_ord _success,
0193 mem_ord _failure) volatile
0194 {
0195 return fvalue.compare_exchange_weak(_expected, _desired, _success, _failure);
0196 }
0197
0198 bool compare_exchange_strong(_Tp& _expected, _Tp _desired, mem_ord _order)
0199 {
0200 return fvalue.compare_exchange_weak(_expected, _desired, _order);
0201 }
0202 bool compare_exchange_strong(_Tp& _expected, _Tp _desired, mem_ord _order) volatile
0203 {
0204 return fvalue.compare_exchange_weak(_expected, _desired, _order);
0205 }
0206
0207
0208 G4atomic& operator+=(const value_type& rhs)
0209 {
0210 atomics::increment(&fvalue, rhs, fMemOrder);
0211 return *this;
0212 }
0213 G4atomic& operator-=(const value_type& rhs)
0214 {
0215 atomics::decrement(&fvalue, rhs, fMemOrder);
0216 return *this;
0217 }
0218 G4atomic& operator*=(const value_type& rhs)
0219 {
0220 atomics::multiply(&fvalue, rhs, fMemOrder);
0221 return *this;
0222 }
0223 G4atomic& operator/=(const value_type& rhs)
0224 {
0225 atomics::divide(&fvalue, rhs, fMemOrder);
0226 return *this;
0227 }
0228
0229
0230 G4atomic& operator+=(const G4atomic& rhs)
0231 {
0232 atomics::increment(&fvalue, rhs.fvalue);
0233 return *this;
0234 }
0235 G4atomic& operator-=(const G4atomic& rhs)
0236 {
0237 atomics::decrement(&fvalue, rhs.fvalue);
0238 return *this;
0239 }
0240 G4atomic& operator*=(const G4atomic& rhs)
0241 {
0242 atomics::multiply(&fvalue, rhs.fvalue);
0243 return *this;
0244 }
0245 G4atomic& operator/=(const G4atomic& rhs)
0246 {
0247 atomics::divide(&fvalue, rhs.fvalue);
0248 return *this;
0249 }
0250
0251 G4atomic& operator+=(const G4atomic& rhs) volatile
0252 {
0253 atomics::increment(&fvalue, rhs.fvalue);
0254 return *this;
0255 }
0256 G4atomic& operator-=(const G4atomic& rhs) volatile
0257 {
0258 atomics::decrement(&fvalue, rhs.fvalue);
0259 return *this;
0260 }
0261 G4atomic& operator*=(const G4atomic& rhs) volatile
0262 {
0263 atomics::multiply(&fvalue, rhs.fvalue);
0264 return *this;
0265 }
0266 G4atomic& operator/=(const G4atomic& rhs) volatile
0267 {
0268 atomics::divide(&fvalue, rhs.fvalue);
0269 return *this;
0270 }
0271
0272
0273 G4atomic& operator+=(const std::atomic<_Tp>& rhs)
0274 {
0275 atomics::increment(&fvalue, rhs, fMemOrder);
0276 return *this;
0277 }
0278 G4atomic& operator-=(const std::atomic<_Tp>& rhs)
0279 {
0280 atomics::decrement(&fvalue, rhs, fMemOrder);
0281 return *this;
0282 }
0283 G4atomic& operator*=(const std::atomic<_Tp>& rhs)
0284 {
0285 atomics::multiply(&fvalue, rhs, fMemOrder);
0286 return *this;
0287 }
0288 G4atomic& operator/=(const std::atomic<_Tp>& rhs)
0289 {
0290 atomics::divide(&fvalue, rhs, fMemOrder);
0291 return *this;
0292 }
0293
0294 G4atomic& operator+=(const std::atomic<_Tp>& rhs) volatile
0295 {
0296 atomics::increment(&fvalue, rhs, fMemOrder);
0297 return *this;
0298 }
0299 G4atomic& operator-=(const std::atomic<_Tp>& rhs) volatile
0300 {
0301 atomics::decrement(&fvalue, rhs, fMemOrder);
0302 return *this;
0303 }
0304 G4atomic& operator*=(const std::atomic<_Tp>& rhs) volatile
0305 {
0306 atomics::multiply(&fvalue, rhs, fMemOrder);
0307 return *this;
0308 }
0309 G4atomic& operator/=(const std::atomic<_Tp>& rhs) volatile
0310 {
0311 atomics::divide(&fvalue, rhs, fMemOrder);
0312 return *this;
0313 }
0314
0315
0316 value_type operator++()
0317 {
0318 value_type _tmp = ++fvalue;
0319 return _tmp;
0320 }
0321 value_type operator++(int)
0322 {
0323 value_type _tmp = fvalue++;
0324 return _tmp;
0325 }
0326
0327 value_type operator--()
0328 {
0329 value_type _tmp = --fvalue;
0330 return _tmp;
0331 }
0332 value_type operator--(int)
0333 {
0334 value_type _tmp = fvalue--;
0335 return _tmp;
0336 }
0337
0338 protected:
0339 base_type fvalue;
0340 mem_ord fMemOrder;
0341 };
0342
0343
0344
0345 #else
0346
0347 template<typename _Tp>
0348 using G4atomic = _Tp;
0349
0350 #endif
0351
0352
0353
0354 #endif