// Copyright (C) 2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. /** * @file hash_store.hh * @author Kornel Kisielewicz * @brief hash_store class */ #ifndef NV_STL_HASH_STORE_HH #define NV_STL_HASH_STORE_HH #include #include #include namespace nv { template < typename Mapped, typename Hash > struct hash_store_entry_policy { typedef Hash key_type; typedef Hash query_type; typedef Mapped mapped_type; typedef Hash hash_type; typedef pair< hash_type, mapped_type > value_type; struct entry_type { value_type value; }; static constexpr hash_type get_hash( const key_type& t ) { return t; } static constexpr hash_type get_hash( const value_type& t ) { return t.first; } static constexpr hash_type get_entry_hash( const entry_type* entry ) { return entry->value.first; } static constexpr hash_type get_value_hash( const value_type& value ) { return value.first; } static constexpr bool entry_compare( const entry_type* entry, hash_type h, const key_type& ) { return entry->value.first == h; } static constexpr bool entry_compare( const entry_type* entry, hash_type h, const value_type& ) { return entry->value.first == h; } template < typename... Args > static void entry_construct( entry_type* entry, hash_type hash_code, Args&&... params ) { construct_object( &( entry->value ), ::nv::forward( params )... ); entry->value.first = hash_code; } static void entry_destroy( entry_type* entry ) { destroy_object( &( entry->value ) ); } }; template < typename H, typename T > class hash_store : public hash_table_base< hash_store_entry_policy< T, H > > { public: typedef hash_table_base< hash_store_entry_policy< T, H > > base_type; typedef H key_type; typedef H query_type; typedef T mapped_type; typedef H hash_type; using base_type::base_type; mapped_type& operator[]( const key_type& key ) { return ( *base_type::insert_key( key ).first ).second; } mapped_type& at( const query_type& key ) { iterator it = base_type::find( key ); NV_ASSERT_ALWAYS( it != base_type::end(), "Key not found in map!" ); return it->second; } const mapped_type& at( const query_type& key ) const { const_iterator it = base_type::find( key ); NV_ASSERT_ALWAYS( it != base_type::cend(), "Key not found in map!" ); return it->second; } template < typename M > insert_return_type assign( hash_type& k, M&& obj ) { insert_return_type result = base_type::try_insert( k, nv::forward( obj ) ); if ( !result.second ) result.first->second = obj; return result; } }; } #endif // NV_STL_HASH_STORE_HH