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