Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix const reference return by iterator #68

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions include/tsl/robin_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ class bucket_entry : public bucket_entry_hash<StoreHash> {
* Behaviour is undefined if the destructor of `ValueType` throws.
*/
template <class ValueType, class KeySelect, class ValueSelect, class Hash,
class KeyEqual, class Allocator, bool StoreHash, class GrowthPolicy>
class KeyEqual, class Allocator, bool StoreHash, class GrowthPolicy,
class ValueTypeIt>
class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
private:
template <typename U>
Expand Down Expand Up @@ -387,6 +388,12 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
using iterator = robin_iterator<false>;
using const_iterator = robin_iterator<true>;

using value_type_it = ValueTypeIt;
using reference_it = value_type_it&;
using const_reference_it = const value_type_it&;
using pointer_it = value_type_it*;
using const_pointer_it = const value_type_it*;

private:
/**
* Either store the hash because we are asked by the `StoreHash` template
Expand Down Expand Up @@ -463,10 +470,16 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {

public:
using iterator_category = std::forward_iterator_tag;
using value_type = const typename robin_hash::value_type;
using value_type = typename robin_hash::value_type_it;
using difference_type = std::ptrdiff_t;
using reference = value_type&;
using pointer = value_type*;
using reference =
typename std::conditional<IsConst,
typename robin_hash::const_reference_it,
typename robin_hash::reference_it>::type;
using pointer =
typename std::conditional<IsConst,
typename robin_hash::const_pointer_it,
typename robin_hash::pointer_it>::type;

robin_iterator() noexcept {}

Expand Down Expand Up @@ -499,9 +512,13 @@ class robin_hash : private Hash, private KeyEqual, private GrowthPolicy {
return U()(m_bucket->value());
}

reference operator*() const { return m_bucket->value(); }
reference operator*() const {
return reinterpret_cast<reference>(m_bucket->value());
}

pointer operator->() const { return std::addressof(m_bucket->value()); }
pointer operator->() const {
return reinterpret_cast<pointer>(std::addressof(m_bucket->value()));
}

robin_iterator& operator++() {
while (true) {
Expand Down
16 changes: 13 additions & 3 deletions include/tsl/robin_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ class robin_map {
key_type& operator()(std::pair<Key, T>& key_value) noexcept {
return key_value.first;
}

const key_type& operator()(
const std::pair<const Key, T>& key_value) const noexcept {
return key_value.first;
}

const key_type& operator()(std::pair<const Key, T>& key_value) noexcept {
return key_value.first;
}
};

class ValueSelect {
Expand All @@ -121,9 +130,10 @@ class robin_map {
}
};

using ht = detail_robin_hash::robin_hash<std::pair<Key, T>, KeySelect,
ValueSelect, Hash, KeyEqual,
Allocator, StoreHash, GrowthPolicy>;
using ht =
detail_robin_hash::robin_hash<std::pair<Key, T>, KeySelect, ValueSelect,
Hash, KeyEqual, Allocator, StoreHash,
GrowthPolicy, std::pair<const Key, T>>;

public:
using key_type = typename ht::key_type;
Expand Down
5 changes: 3 additions & 2 deletions include/tsl/robin_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ class robin_set {
key_type& operator()(Key& key) noexcept { return key; }
};

using ht = detail_robin_hash::robin_hash<Key, KeySelect, void, Hash, KeyEqual,
Allocator, StoreHash, GrowthPolicy>;
using ht =
detail_robin_hash::robin_hash<Key, KeySelect, void, Hash, KeyEqual,
Allocator, StoreHash, GrowthPolicy, Key>;

public:
using key_type = typename ht::key_type;
Expand Down