carb/container/RHUnorderedSet.h

File members: carb/container/RHUnorderedSet.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 Hasher = std::hash<Key>, class Equals = std::equal_to<Key>, size_t LoadFactorMax100 = 80>
class RHUnorderedSet
    : public detail::RobinHood<LoadFactorMax100, Key, const Key, detail::Identity<Key, const Key>, Hasher, Equals>
{
    using Base = detail::RobinHood<LoadFactorMax100, Key, const Key, detail::Identity<Key, const Key>, Hasher, Equals>;

public:
    using key_type = typename Base::key_type;
    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 RHUnorderedSet() noexcept = default;

    RHUnorderedSet(const RHUnorderedSet& other) : Base(other)
    {
    }

    RHUnorderedSet(RHUnorderedSet&& other) : Base(std::move(other))
    {
    }

    ~RHUnorderedSet() = default;

    RHUnorderedSet& operator=(const RHUnorderedSet& other)
    {
        Base::operator=(other);
        return *this;
    }

    RHUnorderedSet& operator=(RHUnorderedSet&& 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)
    {
        // The value is the key, so just construct the item here
        return insert(value_type{ std::forward<Args>(args)... });
    }

    size_type erase(const key_type& key)
    {
        auto vt = this->internal_find(key);
        if (vt)
        {
            this->internal_erase(vt);
            return 1;
        }
        return 0;
    }

    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