#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 {
class AtomicSlot : public SlotBase<AtomicSlot, Tagged_t> {
public:
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;
}
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_;
};
using difference_type = int;
using value_type = Tagged_t;
using reference = Reference;
using pointer = void*;
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;
}
};
}
}
#endif