42 #ifndef G4atomic_defines_hh_ 
   43 #define G4atomic_defines_hh_ 
   47 #ifdef G4MULTITHREADED 
   62         template <
typename _Tp>
 
   63         using OpFunction = std::function<_Tp(const _Tp&, const _Tp&)>;
 
   65         template <
typename _Tp>
 
   66         inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
 
   68                                        std::memory_order mem_odr)
 
   70             _atomic->store(_value, mem_odr);
 
   73         template <
typename _Tp>
 
   74         inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
 
   75                                        const std::atomic<_Tp>& _value,
 
   76                                        std::memory_order mem_odr)
 
   78             _atomic->store(_value.load(), mem_odr);
 
   81         template <
typename _Tp>
 
   82         inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
 
   84                           const OpFunction<_Tp>& _operator,
 
   85                           std::memory_order mem_odr)
 
   87             _Tp _expected = _Tp();
 
   89                 _expected = _atomic->load();
 
   90             } 
while (!(_atomic->compare_exchange_weak(_expected,
 
   96         template <
typename _Tp>
 
   97         inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
 
   98                                         const std::atomic<_Tp>&
 
  100                                         const OpFunction<_Tp>& _operator,
 
  101                         std::memory_order mem_odr)
 
  103             _Tp _expected = _Tp();
 
  105                 _expected = _atomic->load();
 
  106             } 
while (!(_atomic->compare_exchange_weak(_expected,
 
  108                                                           _atomic_value.load()),
 
  116     template <
typename T>
 
  117     inline void set(std::atomic<T>* _atomic,
 
  119                     std::memory_order mem_odr
 
  120                     = std::memory_order_seq_cst)
 
  122         details::do_compare_and_swap(_atomic,
 
  124                                      details::OpFunction<T>
 
  125                                      ([](
const T&, 
const T& y){
return y;}),
 
  129     template <
typename T>
 
  130     inline void set(std::atomic<T>& _atomic,
 
  132                     std::memory_order mem_odr
 
  133                     = std::memory_order_seq_cst)
 
  135         set(&_atomic, _desired, mem_odr);
 
  138     template <
typename T>
 
  139     inline void increment(std::atomic<T>* _atomic,
 
  141                           std::memory_order mem_odr)
 
  143         details::do_compare_and_swap(_atomic, _increment,
 
  144                                      details::OpFunction<T>
 
  145                                      ([](
const T& 
x, 
const T& y){
return x+y;}),
 
  149     template <
typename T>
 
  150     inline void decrement(std::atomic<T>* _atomic, 
const T& _decrement,
 
  151                           std::memory_order mem_odr)
 
  153         details::do_compare_and_swap(_atomic, _decrement,
 
  154                                      details::OpFunction<T>
 
  155                                      ([](
const T& 
x, 
const T& y){
return x-y;}),
 
  159     template <
typename T>
 
  160     inline void multiply(std::atomic<T>* _atomic, 
const T& _factor,
 
  161                          std::memory_order mem_odr)
 
  163         details::do_compare_and_swap(_atomic, _factor,
 
  164                                      details::OpFunction<T>
 
  165                                      ([](
const T& 
x, 
const T& y){
return x*y;}),
 
  169     template <
typename T>
 
  170     inline void divide(std::atomic<T>* _atomic, 
const T& _factor,
 
  171                        std::memory_order mem_odr)
 
  173         details::do_compare_and_swap(_atomic, _factor,
 
  174                                      details::OpFunction<T>
 
  175                                      ([](
const T& 
x, 
const T& y){
return x/y;}),
 
  181     template <
typename T>
 
  182     inline void set(std::atomic<T>* _atomic,
 
  183                     const std::atomic<T>& _atomic_desired,
 
  184                     std::memory_order mem_odr
 
  185                     = std::memory_order_seq_cst)
 
  188         details::do_compare_and_swap(_atomic, _atomic_desired,
 
  189                                      details::OpFunction<T>
 
  190                                      ([](
const T&, 
const T& y){
return y;}),
 
  194     template <
typename T>
 
  195     inline void set(std::atomic<T>& _atomic,
 
  196                     const std::atomic<T>& _atomic_desired,
 
  197                     std::memory_order mem_odr)
 
  199         set(&_atomic, _atomic_desired, mem_odr);
 
  202     template <
typename T>
 
  203     inline void increment(std::atomic<T>* _atomic,
 
  204                           const std::atomic<T>& _atomic_increment,
 
  205                           std::memory_order mem_odr)
 
  207         details::do_compare_and_swap(_atomic, _atomic_increment,
 
  208                                      details::OpFunction<T>
 
  209                                      ([](
const T& 
x, 
const T& y){
return x+y;}),
 
  213     template <
typename T>
 
  214     inline void decrement(std::atomic<T>* _atomic,
 
  215                           const std::atomic<T>& _atomic_decrement,
 
  216                           std::memory_order mem_odr)
 
  218         details::do_compare_and_swap(_atomic, _atomic_decrement,
 
  219                                      details::OpFunction<T>
 
  220                                      ([](
const T& 
x, 
const T& y){
return x-y;}),
 
  224     template <
typename T>
 
  225     inline void multiply(std::atomic<T>* _atomic,
 
  226                          const std::atomic<T>& _atomic_factor,
 
  227                          std::memory_order mem_odr)
 
  229         details::do_compare_and_swap(_atomic, _atomic_factor,
 
  230                                      details::OpFunction<T>
 
  231                                      ([](
const T& 
x, 
const T& y){
return x*y;}),
 
  235     template <
typename T>
 
  236     inline void divide(std::atomic<T>* _atomic,
 
  237                        const std::atomic<T>& _atomic_factor,
 
  238                        std::memory_order mem_odr)
 
  240         details::do_compare_and_swap(_atomic, _atomic_factor,
 
  241                                      details::OpFunction<T>
 
  242                                      ([](
const T& 
x, 
const T& y){
return x/y;}),
 
  249     template <
typename T>
 
  250     inline void set(T* _non_atomic, 
const T& _desired)
 
  252       *_non_atomic = _desired;
 
  255     template <
typename T>
 
  256     inline void set(T& _non_atomic, 
const T& _desired)
 
  258       set(&_non_atomic, _desired);
 
  267     template <
typename T, 
typename U>
 
  268     inline void set(std::pair<std::atomic<T>,
 
  269                               std::atomic<U> >* _atomic,
 
  270                     const std::pair<T, U>& _desired)
 
  272         set(&_atomic->first, _desired.first);
 
  273         set(&_atomic->second, _desired.second);
 
  276     template <
typename T, 
typename U>
 
  277     inline void set(std::pair<std::atomic<T>,
 
  278                               std::atomic<U> >& _atomic,
 
  279                     const std::pair<T, U>& _desired)
 
  281         set(&_atomic, _desired);
 
  284     template <
typename T, 
typename U>
 
  285     inline void increment(std::pair<std::atomic<T>,
 
  286                                     std::atomic<U> >* _atomic,
 
  287                           const std::pair<T, U>& _increment)
 
  289         increment(&_atomic->first, _increment.first);
 
  290         increment(&_atomic->second, _increment.second);
 
  293     template <
typename T, 
typename U>
 
  294     inline void decrement(std::pair<std::atomic<T>,
 
  295                                     std::atomic<U> >* _atomic,
 
  296                           const std::pair<T, U>& _decrement)
 
  298         decrement(&_atomic->first, _decrement.first);
 
  299         decrement(&_atomic->second, _decrement.second);
 
  302     template <
typename T, 
typename U>
 
  303     inline void multiply(std::pair<std::atomic<T>,
 
  304                                    std::atomic<U> >* _atomic,
 
  305                          const std::pair<T, U>& _factor)
 
  307         multiply(&_atomic->first, _factor.first);
 
  308         multiply(&_atomic->second, _factor.second);
 
  311     template <
typename T, 
typename U>
 
  312     inline void divide(std::pair<std::atomic<T>,
 
  313                                  std::atomic<U> >* _atomic,
 
  314                        const std::pair<T, U>& _factor)
 
  316         divide(&_atomic->first, _factor.first);
 
  317         divide(&_atomic->second, _factor.second);
 
  322     template <
typename T, 
typename U>
 
  323     inline void set(std::pair<std::atomic<T>,
 
  324                               std::atomic<U> >* _atomic,
 
  325                     const std::pair<std::atomic<T>,
 
  326                                     std::atomic<U> >& _desired)
 
  328         set(&_atomic->first, _desired.first);
 
  329         set(&_atomic->second, _desired.second);
 
  332     template <
typename T, 
typename U>
 
  333     inline void set(std::pair<std::atomic<T>,
 
  334                               std::atomic<U> >& _atomic,
 
  335                     const std::pair<std::atomic<T>,
 
  336                                     std::atomic<U> >& _desired)
 
  338         set(&_atomic, _desired);
 
  341     template <
typename T, 
typename U>
 
  342     inline void increment(std::pair<std::atomic<T>,
 
  343                                     std::atomic<U> >* _atomic,
 
  344                           const std::pair<std::atomic<T>,
 
  345                                           std::atomic<U> >& _increment)
 
  347         increment(&_atomic->first, _increment.first);
 
  348         increment(&_atomic->second, _increment.second);
 
  351     template <
typename T, 
typename U>
 
  352     inline void decrement(std::pair<std::atomic<T>,
 
  353                                     std::atomic<U> >* _atomic,
 
  354                           const std::pair<std::atomic<T>,
 
  355                                           std::atomic<U> >& _decrement)
 
  357         decrement(&_atomic->first, _decrement.first);
 
  358         decrement(&_atomic->second, _decrement.second);
 
  361     template <
typename T, 
typename U>
 
  362     inline void multiply(std::pair<std::atomic<T>,
 
  363                                    std::atomic<U> >* _atomic,
 
  364                          const std::pair<std::atomic<T>,
 
  365                                          std::atomic<U> >& _factor)
 
  367         multiply(&_atomic->first, _factor.first);
 
  368         multiply(&_atomic->second, _factor.second);
 
  371     template <
typename T, 
typename U>
 
  372     inline void divide(std::pair<std::atomic<T>,
 
  373                                  std::atomic<U> >* _atomic,
 
  374                        const std::pair<std::atomic<T>,
 
  375                                        std::atomic<U> >& _factor)
 
  377         divide(&_atomic->first, _factor.first);
 
  378         divide(&_atomic->second, _factor.second);
 
  384     template <
typename T>
 
  385     inline T 
get(
const T& _non_atomic)
 
  390     template <
typename T>
 
  391     inline T 
get(
const T& _non_atomic, std::memory_order)
 
  396     template <
typename T>
 
  397     inline T 
get(
const std::atomic<T>& _atomic)
 
  399         return _atomic.load();
 
  402     template <
typename T>
 
  403     inline T 
get(
const std::atomic<T>& _atomic,
 
  404                  std::memory_order mem_odr)
 
  406         return _atomic.load(mem_odr);
 
  409     template <
typename T, 
typename U>
 
  410     inline std::pair<T, U> 
get(
const std::pair<std::atomic<T>,
 
  411                                std::atomic<U> >& _atomic)
 
  413         return std::pair<T, U>(
get(_atomic.first), 
get(_atomic.second));
 
  416     template <
typename T, 
typename U>
 
  417     inline std::pair<T, U> 
get(
const std::pair<std::atomic<T>,
 
  418                                std::atomic<U> >& _atomic,
 
  419                                std::memory_order mem_odr)
 
  421         return std::pair<T, U>(
get(_atomic.first, mem_odr),
 
  422                                get(_atomic.second, mem_odr));
 
  430     template <
typename _Tp_base, 
typename _Tp_atom>
 
  431     inline _Tp_base base(
const _Tp_atom& _atomic)
 
  441 #endif // G4MULTITHREADED 
  443 #endif  // atomic_typedefs_hh_ 
const G4double x[NPOINTSGL]