// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_SLOTS_ATOMIC_INL_H_
#define V8_OBJECTS_SLOTS_ATOMIC_INL_H_

#include "src/base/atomic-utils.h"
#include "src/objects/compressed-slots.h"
#include "src/objects/slots.h"

namespace v8 {
namespace internal {

// This class is intended to be used as a wrapper for elements of an array
// that is passed in to STL functions such as std::sort. It ensures that
// elements accesses are atomic.
// Usage example:
//   FixedArray array;
//   AtomicSlot start(array->GetFirstElementAddress());
//   std::sort(start, start + given_length,
//             [](Tagged_t a, Tagged_t b) {
//               // Decompress a and b if necessary.
//               return my_comparison(a, b);
//             });
// Note how the comparator operates on Tagged_t values, representing the raw
// data found at the given heap location, so you probably want to construct
// an Object from it.
class AtomicSlot : public SlotBase<AtomicSlot, Tagged_t> {
 public:
  // This class is a stand-in for "Address&" that uses custom atomic
  // read/write operations for the actual memory accesses.
  class Reference {
   public:
    explicit Reference(Tagged_t* address) : address_(address) {}
    Reference(const Reference&) V8_NOEXCEPT = default;

    Reference& operator=(const Reference& other) V8_NOEXCEPT {
      AsAtomicTagged::Relaxed_Store(
          address_, AsAtomicTagged::Relaxed_Load(other.address_));
      return *this;
    }
    Reference& operator=(Tagged_t value) {
      AsAtomicTagged::Relaxed_Store(address_, value);
      return *this;
    }

    // Values of type AtomicSlot::reference must be implicitly convertible
    // to AtomicSlot::value_type.
    operator Tagged_t() const { return AsAtomicTagged::Relaxed_Load(address_); }

    void swap(Reference& other) {
      Tagged_t tmp = value();
      AsAtomicTagged::Relaxed_Store(address_, other.value());
      AsAtomicTagged::Relaxed_Store(other.address_, tmp);
    }

    bool operator<(const Reference& other) const {
      return value() < other.value();
    }

    bool operator==(const Reference& other) const {
      return value() == other.value();
    }

   private:
    Tagged_t value() const { return AsAtomicTagged::Relaxed_Load(address_); }

    Tagged_t* address_;
  };

  // The rest of this class follows C++'s "RandomAccessIterator" requirements.
  // Most of the heavy lifting is inherited from SlotBase.
  using difference_type = int;
  using value_type = Tagged_t;
  using reference = Reference;
  using pointer = void*;  // Must be present, but should not be used.
  using iterator_category = std::random_access_iterator_tag;

  AtomicSlot() : SlotBase(kNullAddress) {}
  explicit AtomicSlot(Address address) : SlotBase(address) {}
  explicit AtomicSlot(ObjectSlot slot) : SlotBase(slot.address()) {}
  explicit AtomicSlot(MaybeObjectSlot slot) : SlotBase(slot.address()) {}

  Reference operator*() const {
    return Reference(reinterpret_cast<Tagged_t*>(address()));
  }
  Reference operator[](difference_type i) const {
    return Reference(reinterpret_cast<Tagged_t*>(address() + i * kTaggedSize));
  }

  friend void swap(Reference lhs, Reference rhs) { lhs.swap(rhs); }

  friend difference_type operator-(AtomicSlot a, AtomicSlot b) {
    return static_cast<int>(a.address() - b.address()) / kTaggedSize;
  }
};

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_SLOTS_ATOMIC_INL_H_
