#ifndef V8_BASE_SMALL_MAP_H_
#define V8_BASE_SMALL_MAP_H_
#include "src/base/macros.h"
namespace v8::base {
namespace internal {
template <typename NormalMap>
class SmallMapDefaultInit { … };
template <typename M>
struct has_key_equal { … };
template <typename M>
const bool has_key_equal<M>::value;
template <typename M, bool has_key_equal_value>
struct select_equal_key { … };
select_equal_key<M, true>;
}
template <typename NormalMap, size_t kArraySize = 4,
typename EqualKey = typename internal::select_equal_key<
NormalMap, internal::has_key_equal<NormalMap>::value>::equal_key,
typename MapInit = internal::SmallMapDefaultInit<NormalMap>>
class SmallMap {
static constexpr size_t kUsingFullMapSentinel =
std::numeric_limits<size_t>::max();
static_assert(kArraySize > 0, "Initial size must be greater than 0");
static_assert(kArraySize != kUsingFullMapSentinel,
"Initial size out of range");
public:
typedef typename NormalMap::key_type key_type;
typedef typename NormalMap::mapped_type data_type;
typedef typename NormalMap::mapped_type mapped_type;
typedef typename NormalMap::value_type value_type;
typedef EqualKey key_equal;
SmallMap() : … { … }
explicit SmallMap(const MapInit& functor) : … { … }
SmallMap(const SmallMap& src) V8_NOEXCEPT { … }
void operator=(const SmallMap& src) V8_NOEXCEPT { … }
~SmallMap() { … }
class const_iterator;
class iterator {
public:
typedef typename NormalMap::iterator::iterator_category iterator_category;
typedef typename NormalMap::iterator::value_type value_type;
typedef typename NormalMap::iterator::difference_type difference_type;
typedef typename NormalMap::iterator::pointer pointer;
typedef typename NormalMap::iterator::reference reference;
V8_INLINE iterator() : array_iter_(nullptr) {}
V8_INLINE iterator& operator++() {
if (array_iter_ != nullptr) {
++array_iter_;
} else {
++map_iter_;
}
return *this;
}
V8_INLINE iterator operator++(int ) {
iterator result(*this);
++(*this);
return result;
}
V8_INLINE iterator& operator--() {
if (array_iter_ != nullptr) {
--array_iter_;
} else {
--map_iter_;
}
return *this;
}
V8_INLINE iterator operator--(int ) {
iterator result(*this);
--(*this);
return result;
}
V8_INLINE value_type* operator->() const {
return array_iter_ ? array_iter_ : map_iter_.operator->();
}
V8_INLINE value_type& operator*() const {
return array_iter_ ? *array_iter_ : *map_iter_;
}
V8_INLINE bool operator==(const iterator& other) const {
if (array_iter_ != nullptr) {
return array_iter_ == other.array_iter_;
} else {
return other.array_iter_ == nullptr && map_iter_ == other.map_iter_;
}
}
V8_INLINE bool operator!=(const iterator& other) const {
return !(*this == other);
}
private:
friend class SmallMap;
friend class const_iterator;
V8_INLINE explicit iterator(value_type* init) : array_iter_(init) {}
V8_INLINE explicit iterator(const typename NormalMap::iterator& init)
: array_iter_(nullptr), map_iter_(init) {}
value_type* array_iter_;
typename NormalMap::iterator map_iter_;
};
class const_iterator {
public:
typedef
typename NormalMap::const_iterator::iterator_category iterator_category;
typedef typename NormalMap::const_iterator::value_type value_type;
typedef typename NormalMap::const_iterator::difference_type difference_type;
typedef typename NormalMap::const_iterator::pointer pointer;
typedef typename NormalMap::const_iterator::reference reference;
V8_INLINE const_iterator() : array_iter_(nullptr) {}
V8_INLINE const_iterator(const iterator& other)
: array_iter_(other.array_iter_), map_iter_(other.map_iter_) {}
V8_INLINE const_iterator& operator++() {
if (array_iter_ != nullptr) {
++array_iter_;
} else {
++map_iter_;
}
return *this;
}
V8_INLINE const_iterator operator++(int ) {
const_iterator result(*this);
++(*this);
return result;
}
V8_INLINE const_iterator& operator--() {
if (array_iter_ != nullptr) {
--array_iter_;
} else {
--map_iter_;
}
return *this;
}
V8_INLINE const_iterator operator--(int ) {
const_iterator result(*this);
--(*this);
return result;
}
V8_INLINE const value_type* operator->() const {
return array_iter_ ? array_iter_ : map_iter_.operator->();
}
V8_INLINE const value_type& operator*() const {
return array_iter_ ? *array_iter_ : *map_iter_;
}
V8_INLINE bool operator==(const const_iterator& other) const {
if (array_iter_ != nullptr) {
return array_iter_ == other.array_iter_;
}
return other.array_iter_ == nullptr && map_iter_ == other.map_iter_;
}
V8_INLINE bool operator!=(const const_iterator& other) const {
return !(*this == other);
}
private:
friend class SmallMap;
V8_INLINE explicit const_iterator(const value_type* init)
: array_iter_(init) {}
V8_INLINE explicit const_iterator(
const typename NormalMap::const_iterator& init)
: array_iter_(nullptr), map_iter_(init) {}
const value_type* array_iter_;
typename NormalMap::const_iterator map_iter_;
};
iterator find(const key_type& key) { … }
const_iterator find(const key_type& key) const { … }
data_type& operator[](const key_type& key) { … }
std::pair<iterator, bool> insert(const value_type& x) { … }
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { … }
template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) { … }
template <typename... Args>
std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args) { … }
iterator begin() { … }
const_iterator begin() const { … }
iterator end() { … }
const_iterator end() const { … }
void clear() { … }
iterator erase(const iterator& position) { … }
size_t erase(const key_type& key) { … }
size_t count(const key_type& key) const { … }
size_t size() const { … }
bool empty() const { … }
bool UsingFullMap() const { … }
V8_INLINE NormalMap* map() { … }
V8_INLINE const NormalMap* map() const { … }
private:
size_t size_;
MapInit functor_;
union {
value_type array_[kArraySize];
NormalMap map_;
};
V8_NOINLINE V8_PRESERVE_MOST void ConvertToRealMap() { … }
void InitFrom(const SmallMap& src) { … }
void Destroy() { … }
};
}
#endif