// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_PLATFORM_ATOMIC_H_
#define RUNTIME_PLATFORM_ATOMIC_H_

#include <atomic>

namespace dart {

// Like std::atomic, but operations default to relaxed ordering instead of
// sequential consistency.
template <typename T>
class RelaxedAtomic {
 public:
  constexpr RelaxedAtomic() : value_() {}
  constexpr RelaxedAtomic(T arg) : value_(arg) {}           // NOLINT
  RelaxedAtomic(const RelaxedAtomic& arg) : value_(arg) {}  // NOLINT

  T load(std::memory_order order = std::memory_order_relaxed) const {
    return value_.load(order);
  }
  T load(std::memory_order order = std::memory_order_relaxed) const volatile {
    return value_.load(order);
  }
  void store(T arg, std::memory_order order = std::memory_order_relaxed) {
    value_.store(arg, order);
  }
  void store(T arg,
             std::memory_order order = std::memory_order_relaxed) volatile {
    value_.store(arg, order);
  }

  T fetch_add(T arg, std::memory_order order = std::memory_order_relaxed) {
    return value_.fetch_add(arg, order);
  }
  T fetch_sub(T arg, std::memory_order order = std::memory_order_relaxed) {
    return value_.fetch_sub(arg, order);
  }
  T fetch_or(T arg, std::memory_order order = std::memory_order_relaxed) {
    return value_.fetch_or(arg, order);
  }
  T fetch_and(T arg, std::memory_order order = std::memory_order_relaxed) {
    return value_.fetch_and(arg, order);
  }

  T exchange(T arg, std::memory_order order = std::memory_order_relaxed) {
    return value_.exchange(arg, order);
  }

  bool compare_exchange_weak(
      T& expected,  // NOLINT
      T desired,
      std::memory_order order = std::memory_order_relaxed) {
    return value_.compare_exchange_weak(expected, desired, order, order);
  }
  bool compare_exchange_weak(
      T& expected,  // NOLINT
      T desired,
      std::memory_order order = std::memory_order_relaxed) volatile {
    return value_.compare_exchange_weak(expected, desired, order, order);
  }
  bool compare_exchange_strong(
      T& expected,  // NOLINT
      T desired,
      std::memory_order order = std::memory_order_relaxed) {
    return value_.compare_exchange_strong(expected, desired, order, order);
  }

  operator T() const { return load(); }
  T operator=(T arg) {
    store(arg);
    return arg;
  }
  T operator=(const RelaxedAtomic& arg) {
    T loaded_once = arg;
    store(loaded_once);
    return loaded_once;
  }
  T operator+=(T arg) { return fetch_add(arg) + arg; }
  T operator-=(T arg) { return fetch_sub(arg) - arg; }
  T& operator++() { return fetch_add(1) + 1; }
  T& operator--() { return fetch_sub(1) - 1; }
  T operator++(int) { return fetch_add(1); }
  T operator--(int) { return fetch_sub(1); }

 private:
  std::atomic<T> value_;
};

// Like std::atomic, but operations default to acquire for load, release for
// stores, and acquire-release for read-and-updates.
template <typename T>
class AcqRelAtomic {
 public:
  constexpr AcqRelAtomic() : value_() {}
  constexpr AcqRelAtomic(T arg) : value_(arg) {}  // NOLINT
  AcqRelAtomic(const AcqRelAtomic& arg) = delete;

  T load(std::memory_order order = std::memory_order_acquire) const {
    return value_.load(order);
  }
  void store(T arg, std::memory_order order = std::memory_order_release) {
    value_.store(arg, order);
  }

  T fetch_add(T arg, std::memory_order order = std::memory_order_acq_rel) {
    return value_.fetch_add(arg, order);
  }
  T fetch_sub(T arg, std::memory_order order = std::memory_order_acq_rel) {
    return value_.fetch_sub(arg, order);
  }
  T fetch_or(T arg, std::memory_order order = std::memory_order_acq_rel) {
    return value_.fetch_or(arg, order);
  }
  T fetch_and(T arg, std::memory_order order = std::memory_order_acq_rel) {
    return value_.fetch_and(arg, order);
  }

  bool compare_exchange_weak(
      T& expected,  // NOLINT
      T desired,
      std::memory_order success_order = std::memory_order_acq_rel,
      std::memory_order failure_order = std::memory_order_seq_cst) {
    return value_.compare_exchange_weak(expected, desired, success_order,
                                        failure_order);
  }
  bool compare_exchange_strong(
      T& expected,  // NOLINT
      T desired,
      std::memory_order success_order = std::memory_order_acq_rel,
      std::memory_order failure_order = std::memory_order_seq_cst) {
    return value_.compare_exchange_strong(expected, desired, success_order,
                                          failure_order);
  }

  // Require explicit loads and stores.
  operator T() const = delete;
  T operator=(T arg) = delete;
  T operator=(const AcqRelAtomic& arg) = delete;
  T operator+=(T arg) = delete;
  T operator-=(T arg) = delete;

 private:
  std::atomic<T> value_;
};

}  // namespace dart

#endif  // RUNTIME_PLATFORM_ATOMIC_H_
