Program Listing for File multithread.hpp

Return to documentation for file (rcppsw/al/multithread.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#if defined(RCPPSW_AL_MT_SAFE_TYPES)
#include <atomic>
#endif

#include "rcppsw/rcppsw.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::al {

/*******************************************************************************
 * Type Definitions
 ******************************************************************************/
#if defined(RCPPSW_AL_MT_SAFE_TYPES)

using mt_size_t = std::atomic_size_t;

using mt_double_t = std::atomic<double>;

template<typename LHS, typename RHS>
void mt_init(LHS* lhs, RHS rhs) { return std::atomic_init(lhs, rhs); }

template<typename T>
typename T::value_type mt_load(const T& value) { return value.load(); }

template<typename U, typename V,
         RCPPSW_SFINAE_DECLDEF(std::is_same<U, std::atomic<double>>::value)>
void mt_set(U& lhs, const V& rhs) {
  auto tmp = lhs.load();
  lhs.compare_exchange_strong(tmp, rhs);
}

template<typename U, typename V,
         RCPPSW_SFINAE_DECLDEF(std::is_same<U, std::atomic<size_t>>::value &&
                               !std::is_same<V, std::atomic<size_t>>::value)>
void mt_set(U& lhs, const V& rhs) { lhs = rhs; }

template<typename U, typename V,
         RCPPSW_SFINAE_DECLDEF(std::is_same<U, std::atomic<size_t>>::value &&
                               std::is_same<V, std::atomic<size_t>>::value)>
void mt_set(U& lhs, const V& rhs) { lhs = rhs.load(); }

template<typename U, typename V,
         RCPPSW_SFINAE_DECLDEF(std::is_same<U, std::atomic<double>>::value)>
void mt_accum(U& lhs, const V& rhs) {
  auto tmp = lhs.load();
  lhs.compare_exchange_strong(tmp, tmp + rhs);
}

template<typename U, typename V,
         RCPPSW_SFINAE_DECLDEF(std::is_same<U, std::atomic<size_t>>::value)>
void mt_accum(U& lhs, const V& rhs) {
  lhs += rhs;
}

#else

using mt_size_t = std::size_t;
using mt_double_t = double;
template<typename LHS, typename RHS>
void mt_init(LHS* lhs, RHS rhs) { *lhs = rhs; }

template<typename T>
T mt_load(const T& value) { return value; }

template<typename U, typename V>
void mt_accum(U& lhs, const V& rhs) {
  lhs += rhs;
}

template<typename U, typename V>
void mt_set(U& lhs, const V& rhs) { lhs = rhs; }

#endif

} /* namespace rcppsw::al */