Skip to content

Commit

Permalink
Merge pull request #285 from jj683/make-set-map-nothrow-move
Browse files Browse the repository at this point in the history
set/map nothrow move constructible/assignable
  • Loading branch information
arximboldi authored Jul 25, 2024
2 parents bd9f318 + 577b3e4 commit 18b42d2
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
18 changes: 11 additions & 7 deletions immer/detail/hamts/champ.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,26 @@ struct champ

static node_t* empty()
{
static const auto node = node_t::make_inner_n(0);
return node->inc();
static const auto empty_ = []{
constexpr auto size = node_t::sizeof_inner_n(0);
static std::aligned_storage_t<size, alignof(std::max_align_t)> storage;
return node_t::make_inner_n_into(&storage, size, 0u);
}();
return empty_->inc();
}

champ(node_t* r, size_t sz = 0)
champ(node_t* r, size_t sz = 0) noexcept
: root{r}
, size{sz}
{}

champ(const champ& other)
champ(const champ& other) noexcept
: champ{other.root, other.size}
{
inc();
}

champ(champ&& other)
champ(champ&& other) noexcept
: champ{empty()}
{
swap(*this, other);
Expand All @@ -167,13 +171,13 @@ struct champ
return *this;
}

champ& operator=(champ&& other)
champ& operator=(champ&& other) noexcept
{
swap(*this, other);
return *this;
}

friend void swap(champ& x, champ& y)
friend void swap(champ& x, champ& y) noexcept
{
using std::swap;
swap(x.root, y.root);
Expand Down
14 changes: 10 additions & 4 deletions immer/detail/hamts/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,11 @@ struct node
return can_mutate(impl.d.data.inner.values, e);
}

static node_t* make_inner_n(count_t n)
static node_t* make_inner_n_into(void* buffer, std::size_t size, count_t n)
{
assert(n <= branches<B>);
auto m = heap::allocate(sizeof_inner_n(n));
auto p = new (m) node_t;
assert(p == (node_t*) m);
assert(size >= sizeof_inner_n(n));
auto p = new (buffer) node_t;
#if IMMER_TAGGED_NODE
p->impl.d.kind = node_t::kind_t::inner;
#endif
Expand All @@ -237,6 +236,13 @@ struct node
return p;
}

static node_t* make_inner_n(count_t n)
{
assert(n <= branches<B>);
auto m = heap::allocate(sizeof_inner_n(n));
return make_inner_n_into(m, sizeof_inner_n(n), n);
}

static node_t* make_inner_n(count_t n, values_t* values)
{
auto p = make_inner_n(n);
Expand Down
5 changes: 5 additions & 0 deletions immer/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,4 +547,9 @@ class map
impl_t impl_ = impl_t::empty();
};

static_assert(std::is_nothrow_move_constructible<map<int, int>>::value,
"map is not nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<map<int, int>>::value,
"map is not nothrow move assignable");

} // namespace immer
6 changes: 6 additions & 0 deletions immer/set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,10 @@ class set
impl_t impl_ = impl_t::empty();
};

static_assert(std::is_nothrow_move_constructible<set<int>>::value,
"set is not nothrow move constructible");
static_assert(std::is_nothrow_move_assignable<set<int>>::value,
"set is not nothrow move assignable");


} // namespace immer

0 comments on commit 18b42d2

Please sign in to comment.