carb/container/RHUnorderedMap.h
File members: carb/container/RHUnorderedMap.h
// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include "RobinHoodImpl.h"
namespace carb
{
namespace container
{
template <class Key, class Value, class Hasher = std::hash<Key>, class Equals = std::equal_to<Key>, size_t LoadFactorMax100 = 80>
class RHUnorderedMap
: public detail::
RobinHood<LoadFactorMax100, Key, std::pair<const Key, Value>, detail::Select1st<Key, std::pair<const Key, Value>>, Hasher, Equals>
{
using Base = detail::
RobinHood<LoadFactorMax100, Key, std::pair<const Key, Value>, detail::Select1st<Key, std::pair<const Key, Value>>, Hasher, Equals>;
public:
using key_type = typename Base::key_type;
using mapped_type = Value;
using value_type = typename Base::value_type;
using size_type = typename Base::size_type;
using difference_type = typename Base::difference_type;
using hasher = typename Base::hasher;
using key_equal = typename Base::key_equal;
using reference = typename Base::reference;
using const_reference = typename Base::const_reference;
using pointer = typename Base::pointer;
using const_pointer = typename Base::const_pointer;
using iterator = typename Base::iterator;
using const_iterator = typename Base::const_iterator;
using find_iterator = typename Base::find_iterator;
using const_find_iterator = typename Base::const_find_iterator;
constexpr RHUnorderedMap() noexcept = default;
RHUnorderedMap(const RHUnorderedMap& other) : Base(other)
{
}
RHUnorderedMap(RHUnorderedMap&& other) : Base(std::move(other))
{
}
~RHUnorderedMap() = default;
RHUnorderedMap& operator=(const RHUnorderedMap& other)
{
Base::operator=(other);
return *this;
}
RHUnorderedMap& operator=(RHUnorderedMap&& other)
{
Base::operator=(std::move(other));
return *this;
}
std::pair<iterator, bool> insert(const value_type& value)
{
return this->insert_unique(value);
}
std::pair<iterator, bool> insert(value_type&& value)
{
return this->insert_unique(std::move(value));
}
template <class P>
std::pair<iterator, bool> insert(std::enable_if_t<std::is_constructible<value_type, P&&>::value, P&&> value)
{
return insert(value_type{ std::forward<P>(value) });
}
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
// We need the key, so just construct the item here
return insert(value_type{ std::forward<Args>(args)... });
}
template <class... Args>
std::pair<iterator, bool> try_emplace(const key_type& key, Args&&... args)
{
auto result = this->internal_insert(key);
if (result.second)
new (result.first) value_type(std::piecewise_construct, std::forward_as_tuple(key),
std::forward_as_tuple(std::forward<Args>(args)...));
return std::make_pair(this->make_iter(result.first), result.second);
}
template <class... Args>
std::pair<iterator, bool> try_emplace(key_type&& key, Args&&... args)
{
auto result = this->internal_insert(key);
if (result.second)
new (result.first) value_type(std::piecewise_construct, std::forward_as_tuple(std::move(key)),
std::forward_as_tuple(std::forward<Args>(args)...));
return std::make_pair(this->make_iter(result.first), result.second);
}
size_type erase(const key_type& key)
{
auto vt = this->internal_find(key);
if (vt)
{
this->internal_erase(vt);
return 1;
}
return 0;
}
#if CARB_EXCEPTIONS_ENABLED || defined(DOXYGEN_BUILD)
mapped_type& at(const key_type& key)
{
auto vt = this->internal_find(key);
if (vt)
return vt->second;
throw std::out_of_range("key not found");
}
const mapped_type& at(const key_type& key) const
{
auto vt = this->internal_find(key);
if (vt)
return vt->second;
throw std::out_of_range("key not found");
}
#endif
mapped_type& operator[](const key_type& key)
{
auto result = this->internal_insert(key);
if (result.second)
new (result.first) value_type(std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>());
return result.first->second;
}
mapped_type& operator[](key_type&& key)
{
auto result = this->internal_insert(key);
if (result.second)
new (result.first) value_type(std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>());
return result.first->second;
}
size_t count(const key_type& key) const
{
return !!this->internal_find(key);
}
#ifndef DOXYGEN_BUILD
using Base::begin;
using Base::cbegin;
using Base::cend;
using Base::end;
using Base::capacity;
using Base::empty;
using Base::max_size;
using Base::size;
using Base::clear;
using Base::erase;
using Base::swap;
using Base::contains;
using Base::equal_range;
using Base::find;
using Base::rehash;
using Base::reserve;
#endif
};
} // namespace container
} // namespace carb