[530] | 1 | // Copyright (C) 2015-2017 ChaosForge Ltd
|
---|
[432] | 2 | // http://chaosforge.org/
|
---|
| 3 | //
|
---|
| 4 | // This file is part of Nova libraries.
|
---|
| 5 | // For conditions of distribution and use, see copying.txt file in root folder.
|
---|
| 6 |
|
---|
| 7 | /**
|
---|
| 8 | * @file hash_store.hh
|
---|
| 9 | * @author Kornel Kisielewicz
|
---|
| 10 | * @brief hash_store class
|
---|
| 11 | */
|
---|
| 12 |
|
---|
| 13 | #ifndef NV_STL_HASH_STORE_HH
|
---|
| 14 | #define NV_STL_HASH_STORE_HH
|
---|
| 15 |
|
---|
| 16 | #include <nv/common.hh>
|
---|
| 17 | #include <nv/stl/container/hash_table.hh>
|
---|
| 18 | #include <nv/stl/container/hash_table_policy.hh>
|
---|
| 19 |
|
---|
| 20 | namespace nv
|
---|
| 21 | {
|
---|
| 22 |
|
---|
| 23 | template <
|
---|
| 24 | typename Mapped,
|
---|
| 25 | typename Hash
|
---|
| 26 | >
|
---|
| 27 | struct hash_store_entry_policy
|
---|
| 28 | {
|
---|
| 29 | typedef Hash key_type;
|
---|
| 30 | typedef Hash query_type;
|
---|
| 31 | typedef Mapped mapped_type;
|
---|
| 32 | typedef Hash hash_type;
|
---|
| 33 | typedef pair< hash_type, mapped_type > value_type;
|
---|
| 34 |
|
---|
| 35 | struct entry_type
|
---|
| 36 | {
|
---|
| 37 | value_type value;
|
---|
| 38 | };
|
---|
| 39 |
|
---|
| 40 | static constexpr hash_type get_hash( const key_type& t ) { return t; }
|
---|
| 41 | static constexpr hash_type get_hash( const value_type& t ) { return t.first; }
|
---|
| 42 | static constexpr hash_type get_entry_hash( const entry_type* entry ) { return entry->value.first; }
|
---|
| 43 | static constexpr hash_type get_value_hash( const value_type& value ) { return value.first; }
|
---|
| 44 |
|
---|
| 45 | static constexpr bool entry_compare( const entry_type* entry, hash_type h, const key_type& )
|
---|
| 46 | {
|
---|
| 47 | return entry->value.first == h;
|
---|
| 48 | }
|
---|
| 49 | static constexpr bool entry_compare( const entry_type* entry, hash_type h, const value_type& )
|
---|
| 50 | {
|
---|
| 51 | return entry->value.first == h;
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | template < typename... Args >
|
---|
| 55 | static void entry_construct( entry_type* entry, hash_type hash_code, Args&&... params )
|
---|
| 56 | {
|
---|
| 57 | construct_object( &( entry->value ), ::nv::forward<Args>( params )... );
|
---|
| 58 | entry->value.first = hash_code;
|
---|
| 59 | }
|
---|
| 60 |
|
---|
| 61 | static void entry_destroy( entry_type* entry )
|
---|
| 62 | {
|
---|
| 63 | destroy_object( &( entry->value ) );
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | };
|
---|
| 67 |
|
---|
| 68 | template < typename H, typename T >
|
---|
| 69 | class hash_store
|
---|
| 70 | : public hash_table_base<
|
---|
| 71 | hash_store_entry_policy< T, H >
|
---|
| 72 | >
|
---|
| 73 | {
|
---|
| 74 | public:
|
---|
| 75 | typedef hash_table_base< hash_store_entry_policy< T, H > > base_type;
|
---|
[487] | 76 | typedef typename base_type::iterator iterator;
|
---|
| 77 | typedef typename base_type::const_iterator const_iterator;
|
---|
| 78 | typedef typename base_type::insert_return_type insert_return_type;
|
---|
[432] | 79 | typedef H key_type;
|
---|
| 80 | typedef H query_type;
|
---|
| 81 | typedef T mapped_type;
|
---|
| 82 | typedef H hash_type;
|
---|
| 83 |
|
---|
| 84 | using base_type::base_type;
|
---|
| 85 |
|
---|
| 86 | mapped_type& operator[]( const key_type& key )
|
---|
| 87 | {
|
---|
| 88 | return ( *base_type::insert_key( key ).first ).second;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | mapped_type& at( const query_type& key )
|
---|
| 92 | {
|
---|
| 93 | iterator it = base_type::find( key );
|
---|
| 94 | NV_ASSERT_ALWAYS( it != base_type::end(), "Key not found in map!" );
|
---|
| 95 | return it->second;
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | const mapped_type& at( const query_type& key ) const
|
---|
| 99 | {
|
---|
| 100 | const_iterator it = base_type::find( key );
|
---|
| 101 | NV_ASSERT_ALWAYS( it != base_type::cend(), "Key not found in map!" );
|
---|
| 102 | return it->second;
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | template < typename M >
|
---|
| 106 | insert_return_type assign( hash_type& k, M&& obj )
|
---|
| 107 | {
|
---|
| 108 | insert_return_type result = base_type::try_insert( k, nv::forward<M>( obj ) );
|
---|
[486] | 109 | if ( !result.second ) result.first->second = nv::move(obj);
|
---|
[432] | 110 | return result;
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 | };
|
---|
| 114 |
|
---|
| 115 | }
|
---|
| 116 |
|
---|
[433] | 117 | #endif // NV_STL_HASH_STORE_HH
|
---|