Skip to content

Commit

Permalink
Improve sequential initialization of HAMTs
Browse files Browse the repository at this point in the history
With this implementation, it uses transients also when using a tracing
garbage collector -- before it would be optimized only when using
reference counting.
  • Loading branch information
arximboldi committed Jun 2, 2022
1 parent 72a565e commit 160ba64
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 27 deletions.
22 changes: 22 additions & 0 deletions immer/detail/hamts/champ.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ struct champ
node_t::delete_deep(root, 0);
}

template <typename U>
static auto from_initializer_list(std::initializer_list<U> values)
{
auto e = owner_t{};
auto result = champ{empty()};
for (auto&& v : values)
result.add_mut(e, v);
return result;
}

template <typename Iter,
typename Sent,
std::enable_if_t<compatible_sentinel_v<Iter, Sent>, bool> = true>
static auto from_range(Iter first, Sent last)
{
auto e = owner_t{};
auto result = champ{empty()};
for (; first != last; ++first)
result.add_mut(e, *first);
return result;
}

template <typename Fn>
void for_each_chunk(Fn&& fn) const
{
Expand Down
12 changes: 4 additions & 8 deletions immer/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,8 @@ class map
* Constructs a map containing the elements in `values`.
*/
map(std::initializer_list<value_type> values)
{
for (auto&& v : values)
*this = std::move(*this).insert(v);
}
: impl_{impl_t::from_initializer_list(values)}
{}

/*!
* Constructs a map containing the elements in the range
Expand All @@ -184,10 +182,8 @@ class map
std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>,
bool> = true>
map(Iter first, Sent last)
{
for (; first != last; ++first)
*this = std::move(*this).insert(*first);
}
: impl_{impl_t::from_range(first, last)}
{}

/*!
* Default constructor. It creates a map of `size() == 0`. It
Expand Down
12 changes: 4 additions & 8 deletions immer/set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,8 @@ class set
* Constructs a set containing the elements in `values`.
*/
set(std::initializer_list<value_type> values)
{
for (auto&& v : values)
*this = std::move(*this).insert(v);
}
: impl_{impl_t::from_initializer_list(values)}
{}

/*!
* Constructs a set containing the elements in the range
Expand All @@ -109,10 +107,8 @@ class set
std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>,
bool> = true>
set(Iter first, Sent last)
{
for (; first != last; ++first)
*this = std::move(*this).insert(*first);
}
: impl_{impl_t::from_range(first, last)}
{}

/*!
* Returns an iterator pointing at the first element of the
Expand Down
18 changes: 7 additions & 11 deletions immer/table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,8 @@ class table
* Constructs a table containing the elements in `values`.
*/
table(std::initializer_list<value_type> values)
{
for (auto&& v : values)
*this = std::move(*this).insert(v);
}
: impl_{impl_t::from_initializer_list(values)}
{}

/*!
* Constructs a table containing the elements in the range
Expand All @@ -200,10 +198,8 @@ class table
std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>,
bool> = true>
table(Iter first, Sent last)
{
for (; first != last; ++first)
*this = std::move(*this).insert(*first);
}
: impl_{impl_t::from_range(first, last)}
{}

/*!
* Default constructor. It creates a table of `size() == 0`. It
Expand Down Expand Up @@ -467,16 +463,16 @@ class table
table&& update_move(std::true_type, key_type k, Fn&& fn)
{
impl_.template update_mut<project_value, default_value, combine_value>(
std::move(k), std::forward<Fn>(fn));
{}, std::move(k), std::forward<Fn>(fn));
return std::move(*this);
}

template <typename Fn>
table update_move(std::false_type, key_type k, Fn&& fn)
{
return impl_
.template update_mut<project_value, default_value, combine_value>(
{}, std::move(k), std::forward<Fn>(fn));
.template update<project_value, default_value, combine_value>(
std::move(k), std::forward<Fn>(fn));
}

table&& erase_move(std::true_type, const key_type& value)
Expand Down

0 comments on commit 160ba64

Please sign in to comment.