Skip to content

Commit

Permalink
make any_unique movable and swappable; fix under-constrained any_uniq…
Browse files Browse the repository at this point in the history
…ue ctor
  • Loading branch information
ericniebler committed Apr 27, 2021
1 parent 4646ecf commit b6b53bd
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
35 changes: 32 additions & 3 deletions include/unifex/any_unique.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@ class _byval<CPOs...>::type
, vtable_(vtable_holder_t::template create<Concrete>()) {}

template(typename Concrete)
(requires (!instance_of_v<std::in_place_type_t, Concrete>))
(requires (!same_as<type, remove_cvref_t<Concrete>>) AND
(!instance_of_v<std::in_place_type_t, Concrete>))
type(Concrete&& concrete)
: type(
std::in_place_type<remove_cvref_t<Concrete>>,
Expand All @@ -395,6 +396,24 @@ class _byval<CPOs...>::type
, vtable_(other.vtable_) {}

UNIFEX_ALWAYS_INLINE ~type() {
unsafe_deallocate();
}

void swap(type& other) noexcept {
std::swap(vtable_, other.vtable_);
std::swap(impl_, other.impl_);
}

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

private:
using vtable_holder_t = vtable_holder<_deallocate_cpo, CPOs...>;

UNIFEX_ALWAYS_INLINE void unsafe_deallocate() noexcept {
// This leaves the any_unique in an invalid state.
if (nullptr != impl_) {
static_assert(noexcept(vtable_->template get<_deallocate_cpo>()));
auto* deallocateFn = vtable_->template get<_deallocate_cpo>();
Expand All @@ -403,8 +422,9 @@ class _byval<CPOs...>::type
}
}

private:
using vtable_holder_t = vtable_holder<_deallocate_cpo, CPOs...>;
friend void swap(type& left, type& right) noexcept {
left.swap(right);
}

friend const vtable_holder_t& get_vtable(const type& self) noexcept {
return self.vtable_;
Expand Down Expand Up @@ -433,9 +453,18 @@ class _byref<CPOs...>::type
: vtable_(vtable_holder_t::template create<Concrete>())
, impl_(std::addressof(impl)) {}

void swap(type& other) noexcept {
std::swap(vtable_, other.vtable_);
std::swap(impl_, other.impl_);
}

private:
using vtable_holder_t = vtable_holder<CPOs...>;

friend void swap(type& left, type& right) noexcept {
left.swap(right);
}

friend const vtable_holder_t& get_vtable(const type& self) noexcept {
return self.vtable_;
}
Expand Down
2 changes: 2 additions & 0 deletions test/any_unique_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class counting_memory_resource : public memory_resource {
using A = unifex::any_unique_t<get_typeid>;
using B = unifex::any_unique_t<>;

static_assert(unifex::movable<A>);

TEST(AnyUniqueTest, WithTypeid) {
const ::A a = std::string{"hello"};
auto id = get_typeid(a);
Expand Down

0 comments on commit b6b53bd

Please sign in to comment.