Skip to content

Commit

Permalink
Add deduction guides for polymorphic
Browse files Browse the repository at this point in the history
  • Loading branch information
jbcoe committed Feb 16, 2025
1 parent 93ddae5 commit 4bf1917
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
55 changes: 55 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,60 @@
".venv": true,
"bazel-*": true,
"build": true,
},
"files.associations": {
"__bit_reference": "cpp",
"__hash_table": "cpp",
"__locale": "cpp",
"__node_handle": "cpp",
"__split_buffer": "cpp",
"__threading_support": "cpp",
"__tree": "cpp",
"__verbose_abort": "cpp",
"array": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"complex": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"execution": "cpp",
"memory": "cpp",
"initializer_list": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"locale": "cpp",
"map": "cpp",
"mutex": "cpp",
"new": "cpp",
"optional": "cpp",
"ostream": "cpp",
"print": "cpp",
"queue": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stack": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"tuple": "cpp",
"typeinfo": "cpp",
"unordered_map": "cpp",
"variant": "cpp",
"vector": "cpp",
"algorithm": "cpp"
}
}
26 changes: 24 additions & 2 deletions polymorphic.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ class direct_control_block final : public control_block<T, A> {

} // namespace detail

template <class T, class A>
class polymorphic;

template <class>
inline constexpr bool is_polymorphic_v = false;

template <class T, class A>
inline constexpr bool is_polymorphic_v<polymorphic<T, A>> = true;

template <class T, class A = std::allocator<T>>
class polymorphic {
using cblock_t = detail::control_block<T, A>;
Expand Down Expand Up @@ -241,7 +250,8 @@ class polymorphic {
cb_ = create_control_block<U>(ilist, std::forward<Ts>(ts)...);
}

constexpr polymorphic(std::allocator_arg_t, const A& alloc,
constexpr polymorphic(std::allocator_arg_t,
const std::type_identity_t<A>& alloc,
const polymorphic& other)
: alloc_(alloc) {
if (!other.valueless_after_move()) {
Expand All @@ -252,7 +262,7 @@ class polymorphic {
}

constexpr polymorphic(
std::allocator_arg_t, const A& alloc,
std::allocator_arg_t, const std::type_identity_t<A>& alloc,
polymorphic&& other) noexcept(allocator_traits::is_always_equal::value)
: alloc_(alloc) {
if constexpr (allocator_traits::is_always_equal::value) {
Expand Down Expand Up @@ -405,6 +415,18 @@ class polymorphic {
}
};

template <typename Value>
polymorphic(Value) -> polymorphic<Value>;

template <typename Alloc, typename Value,
typename std::enable_if_t<!is_polymorphic_v<Value>, int> = 0>
polymorphic(std::allocator_arg_t, Alloc, Value) -> polymorphic<
Value, typename std::allocator_traits<Alloc>::template rebind_alloc<Value>>;

template <typename Alloc, typename Value>
polymorphic(std::allocator_arg_t, std::type_identity_t<Alloc>,
polymorphic<Value, Alloc>) -> polymorphic<Value, Alloc>;

} // namespace xyz

#endif // XYZ_POLYMORPHIC_H_
40 changes: 40 additions & 0 deletions polymorphic_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -845,4 +845,44 @@ TEST(PolymorphicTest, TaggedAllocatorsNotEqualMoveConstructFromValueless) {
EXPECT_TRUE(iii.valueless_after_move());
}

TEST(PolymorphicTest, TemplateArgumentDeduction) {
xyz::polymorphic p(Derived(4));

EXPECT_EQ(p->value(), 4);
}

TEST(PolymorphicTest, TemplateArgumentDeductionCopy) {
xyz::polymorphic p(Derived(4));
xyz::polymorphic pp(p);

static_assert(std::is_same_v<decltype(p), decltype(pp)>);

EXPECT_EQ(pp->value(), 4);
}

TEST(PolymorphicTest, TemplateArgumentDeductionWithAllocator) {
xyz::TaggedAllocator<int> a(1);
xyz::polymorphic p(std::allocator_arg, a, Derived(4));

EXPECT_EQ(p->value(), 4);
EXPECT_EQ(p.get_allocator().tag, 1);
}

TEST(PolymorphicTest, TemplateArgumentDeductionWithDeducedAllocatorAndCopy) {
xyz::TaggedAllocator<int> a(1);
xyz::polymorphic p(std::allocator_arg, a, Derived(4));
xyz::polymorphic pp(std::allocator_arg, 2, p);

EXPECT_EQ(pp->value(), 4);
EXPECT_EQ(pp.get_allocator().tag, 2);
}

TEST(PolymorphicTest, TemplateArgumentDeductionWithDeducedAllocatorAndMove) {
xyz::TaggedAllocator<int> a(1);
xyz::polymorphic p(std::allocator_arg, a, Derived(4));
xyz::polymorphic pp(std::allocator_arg, 2, std::move(p));

EXPECT_EQ(pp->value(), 4);
EXPECT_EQ(pp.get_allocator().tag, 2);
}
} // namespace

0 comments on commit 4bf1917

Please sign in to comment.