#ifndef BOOST_DETAIL_ATOMIC_FALLBACK_HPP
#define BOOST_DETAIL_ATOMIC_FALLBACK_HPP

//  Copyright (c) 2009 Helge Bahmann
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

#include <string.h>
#include <boost/smart_ptr/detail/spinlock_pool.hpp>

namespace boost {
namespace detail {
namespace atomic {

template<typename T>
class fallback_atomic {
public:
    fallback_atomic(void) {}
    explicit fallback_atomic(const T &t) {memcpy(&i, &t, sizeof(T));}
    
    void store(const T &t, memory_order order=memory_order_seq_cst) volatile
    {
        detail::spinlock_pool<0>::scoped_lock guard(const_cast<T*>(&i));
        memcpy((void*)&i, &t, sizeof(T));
    }
    T load(memory_order /*order*/=memory_order_seq_cst) volatile const
    {
        detail::spinlock_pool<0>::scoped_lock guard(const_cast<T*>(&i));
        T tmp;
        memcpy(&tmp, (T*)&i, sizeof(T));
        return tmp;
    }
    bool compare_exchange_strong(
        T &expected,
        T desired,
        memory_order /*success_order*/,
        memory_order /*failure_order*/) volatile
    {
        detail::spinlock_pool<0>::scoped_lock guard(const_cast<T*>(&i));
        if (memcmp((void*)&i, &expected, sizeof(T))==0) {
            memcpy((void*)&i, &desired, sizeof(T));
            return true;
        } else {
            memcpy(&expected, (void*)&i, sizeof(T));
            return false;
        }
    }
    bool compare_exchange_weak(
        T &expected,
        T desired,
        memory_order success_order,
        memory_order failure_order) volatile
    {
        return compare_exchange_strong(expected, desired, success_order, failure_order);
    }
    T exchange(T replacement, memory_order /*order*/=memory_order_seq_cst) volatile
    {
        detail::spinlock_pool<0>::scoped_lock guard(const_cast<T*>(&i));
        T tmp;
        memcpy(&tmp, (void*)&i, sizeof(T));
        memcpy((void*)&i, &replacement, sizeof(T));
        return tmp;
    }
    bool is_lock_free(void) const volatile {return false;}
protected:
    T i;
    typedef T integral_type;
};

}
}
}

#endif
