#ifndef WPIUTIL_SUPPORT_ATOMIC_STATIC_H_
#define WPIUTIL_SUPPORT_ATOMIC_STATIC_H_
#if !defined(_MSC_VER) || (_MSC_VER >= 1900)
#define ATOMIC_STATIC(cls, inst) static cls inst
#define ATOMIC_STATIC_DECL(cls)
#define ATOMIC_STATIC_INIT(cls)
#else
#include <atomic>
#include <mutex>
#define ATOMIC_STATIC(cls, inst) \
cls* inst##tmp = m_instance.load(std::memory_order_acquire); \
if (inst##tmp == nullptr) { \
std::lock_guard<std::mutex> lock(m_instance_mutex); \
inst##tmp = m_instance.load(std::memory_order_relaxed); \
if (inst##tmp == nullptr) { \
inst##tmp = new cls; \
m_instance.store(inst##tmp, std::memory_order_release); \
} \
} \
cls& inst = *inst##tmp
#define ATOMIC_STATIC_DECL(cls) \
static std::atomic<cls*> m_instance; \
static std::mutex m_instance_mutex;
#define ATOMIC_STATIC_INIT(cls) \
std::atomic<cls*> cls::m_instance; \
std::mutex cls::m_instance_mutex;
#endif
#endif