97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
/**
|
|
This file is a part of rexy's general purpose library
|
|
Copyright (C) 2020-2022 rexy712
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef REXY_CX_HASHMAP_HPP
|
|
#define REXY_CX_HASHMAP_HPP
|
|
|
|
#include "vector.hpp"
|
|
#include "array.hpp"
|
|
#include "../algorithm.hpp"
|
|
#include "../hash.hpp"
|
|
|
|
#include <climits> //CHAR_BIT
|
|
#include <cstddef> //std::size_t, ptrdiff_t
|
|
#include <type_traits> //decay
|
|
#include <initializer_list>
|
|
|
|
namespace rexy::cx{
|
|
|
|
template<class Key, class Value>
|
|
struct element{
|
|
using key_type = Key;
|
|
using value_type = Value;
|
|
|
|
Key key;
|
|
Value value;
|
|
};
|
|
template<class Key, class Value>
|
|
element(Key,Value) -> element<Key,Value>;
|
|
|
|
template<class Key, class Value, std::size_t N, class Hash = hash<Key>>
|
|
class hashmap
|
|
{
|
|
public:
|
|
using key_type = Key;
|
|
using mapped_type = Value;
|
|
using value_type = element<Key,Value>;
|
|
using size_type = std::size_t;
|
|
using difference_type = ptrdiff_t;
|
|
using hasher = Hash;
|
|
using reference = mapped_type&;
|
|
using const_reference = const mapped_type&;
|
|
using pointer = mapped_type*;
|
|
using const_pointer = const mapped_type*;
|
|
|
|
static constexpr size_type single_bucket_bit = size_type{1} << ((sizeof(size_type)*CHAR_BIT) - 1);
|
|
static constexpr size_type max_size = N;
|
|
|
|
static_assert((max_size & single_bucket_bit) == 0);
|
|
|
|
|
|
private:
|
|
array<value_type,N> m_elements; //perfect hash table
|
|
array<size_type,N> m_g; //'salt' values for indexing into the perfect hash table
|
|
|
|
public:
|
|
constexpr hashmap(const value_type(&elements)[N])
|
|
noexcept(std::is_nothrow_default_constructible<value_type>::value &&
|
|
std::is_nothrow_copy_constructible<value_type>::value &&
|
|
std::is_nothrow_move_assignable<mapped_type>::value &&
|
|
std::is_nothrow_invocable<Hash,Key,std::size_t>::value);
|
|
|
|
//no key checks. give a correct key or get a random answer :)
|
|
template<class U, class UHash = hash<std::decay_t<U>>>
|
|
constexpr reference operator[](U&& u)noexcept;
|
|
template<class U, class UHash = hash<std::decay_t<U>>>
|
|
constexpr const_reference operator[](U&& u)const noexcept;
|
|
|
|
template<class U, class UHash = hash<std::decay_t<U>>>
|
|
constexpr bool contains(U&& u)const noexcept;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#include "hashmap.tpp"
|
|
|
|
#ifdef REXY_STRING_BASE_HPP
|
|
#include "../string_hash.hpp"
|
|
#endif
|
|
|
|
#endif
|