+
+ protected:
+ //@cond
+ /// Calculates hash value of \p key
+ template <typename Q>
+ size_t hash_value( Q const& key ) const
+ {
+ return m_HashFunctor( key ) & m_nHashBitmask;
+ }
+
+ /// Returns the bucket (ordered list) for \p key
+ template <typename Q>
+ internal_bucket_type& bucket( Q const& key )
+ {
+ return m_Buckets[ hash_value( key ) ];
+ }
+ template <typename Q>
+ internal_bucket_type const& bucket( Q const& key ) const
+ {
+ return m_Buckets[hash_value( key )];
+ }
+ //@endcond
+
+ private:
+ //@cond
+ internal_bucket_type* bucket_begin() const
+ {
+ return m_Buckets;
+ }
+
+ internal_bucket_type* bucket_end() const
+ {
+ return m_Buckets + bucket_count();
+ }
+
+ const_iterator get_const_begin() const
+ {
+ return const_iterator( bucket_begin()->cbegin(), bucket_begin(), bucket_end() );
+ }
+ const_iterator get_const_end() const
+ {
+ return const_iterator(( bucket_end() -1 )->cend(), bucket_end() - 1, bucket_end() );
+ }
+
+ template <typename Stat>
+ typename std::enable_if< Stat::empty >::type construct_bucket( internal_bucket_type* bucket )
+ {
+ new (bucket) internal_bucket_type;
+ }
+
+ template <typename Stat>
+ typename std::enable_if< !Stat::empty >::type construct_bucket( internal_bucket_type* bucket )
+ {
+ new (bucket) internal_bucket_type( m_Stat );
+ }
+
+ template <typename List, typename... Args>
+ typename std::enable_if< !is_iterable_list<List>::value, bool>::type
+ bucket_emplace( Args&&... args )
+ {
+ class list_accessor: public List
+ {
+ public:
+ using List::alloc_node;
+ using List::node_to_value;
+ using List::insert_node;
+ };
+
+ auto pNode = list_accessor::alloc_node( std::forward<Args>( args )... );
+ assert( pNode != nullptr );
+ return static_cast<list_accessor&>( bucket( list_accessor::node_to_value( *pNode ))).insert_node( pNode );
+ }
+
+ template <typename List, typename... Args>
+ typename std::enable_if< is_iterable_list<List>::value, bool>::type
+ bucket_emplace( Args&&... args )
+ {
+ class list_accessor: public List
+ {
+ public:
+ using List::alloc_data;
+ using List::insert_node;
+ };
+
+ auto pData = list_accessor::alloc_data( std::forward<Args>( args )... );
+ assert( pData != nullptr );
+ return static_cast<list_accessor&>( bucket( *pData )).insert_node( pData );
+ }
+ //@endcond