Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cc_library(
srcs = ["indirect.cc"],
hdrs = ["indirect.h"],
copts = ["-Iexternal/value_types/"],
defines = ["XYZ_HAS_EXTENSION_MAKE_INDIRECT"],
visibility = ["//visibility:public"],
deps = ["feature_check"],
)
Expand Down Expand Up @@ -91,6 +92,7 @@ cc_library(
srcs = ["polymorphic.cc"],
hdrs = ["polymorphic.h"],
copts = ["-Iexternal/value_types/"],
defines = ["XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC"],
visibility = ["//visibility:public"],
)

Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ target_sources(xyz_value_types
xyz_add_library(
NAME indirect
ALIAS xyz_value_types::indirect
DEFINITIONS XYZ_HAS_EXTENSION_MAKE_INDIRECT
)
target_sources(indirect
INTERFACE
Expand Down Expand Up @@ -75,6 +76,7 @@ target_sources(indirect_cxx17
xyz_add_library(
NAME polymorphic
ALIAS xyz_value_types::polymorphic
DEFINITIONS XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC
)
target_sources(polymorphic
INTERFACE
Expand Down
12 changes: 12 additions & 0 deletions indirect.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,18 @@ template <typename Alloc, typename Value>
indirect(std::allocator_arg_t, Alloc, Value) -> indirect<
Value, typename std::allocator_traits<Alloc>::template rebind_alloc<Value>>;

#ifdef XYZ_HAS_EXTENSION_MAKE_INDIRECT
template <typename T, typename... Us>
auto make_indirect(Us&&... us) -> indirect<T> {
return indirect<T>(std::in_place, std::forward<Us>(us)...);
}

template <typename T, typename A, typename... Us>
auto allocate_indirect(A a, Us&&... us) -> indirect<T, A> {
Comment thread
jbcoe marked this conversation as resolved.
Outdated
return indirect<T, A>(std::allocator_arg, a, std::in_place,
std::forward<Us>(us)...);
}
#endif // XYZ_HAS_EXTENSION_MAKE_INDIRECT
} // namespace xyz

template <class T, class Alloc>
Expand Down
29 changes: 27 additions & 2 deletions indirect_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1015,8 +1015,6 @@ TEST(IndirectTest, SupportNonCopyableType) {
EXPECT_TRUE(a.valueless_after_move());
}

} // namespace

struct NonThreeWayComparable {
int x_;

Expand Down Expand Up @@ -1052,3 +1050,30 @@ TEST(IndirectTest, NonThreeWayComparable) {
EXPECT_TRUE(i != ii);
}
#endif // XYZ_HAS_STD_THREE_WAY_COMPARISON

#ifdef XYZ_HAS_EXTENSION_MAKE_INDIRECT
TEST(IndirectTest, MakeIndirectNoArgs) {
auto i = xyz::make_indirect<int>();
EXPECT_EQ(*i, 0);
}

TEST(IndirectTest, MakeIndirect) {
auto i = xyz::make_indirect<int>(42);
EXPECT_EQ(*i, 42);
}

TEST(IndirectTest, AllocateIndirectNoArgs) {
auto a = xyz::TaggedAllocator<int>(1);
auto i = xyz::allocate_indirect<int>(a);
EXPECT_EQ(*i, 0);
EXPECT_EQ(i.get_allocator().tag, 1);
}

TEST(IndirectTest, AllocateIndirect) {
auto a = xyz::TaggedAllocator<int>(1);
auto i = xyz::allocate_indirect<int>(a, 42);
EXPECT_EQ(*i, 42);
EXPECT_EQ(i.get_allocator().tag, 1);
}
#endif // XYZ_HAS_EXTENSION_MAKE_INDIRECT
} // namespace
14 changes: 13 additions & 1 deletion polymorphic.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,20 @@ class polymorphic {
cb_ = nullptr;
}
}
}; // namespace xyz
};

#ifdef XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC
template <typename T, typename U = T, typename... Us>
auto make_polymorphic(Us&&... us) -> polymorphic<T> {
return polymorphic<T>(std::in_place_type<U>, std::forward<Us>(us)...);
}

template <typename T, typename U = T, typename A, typename... Us>
auto allocate_polymorphic(A a, Us&&... us) -> polymorphic<T, A> {
return polymorphic<T, A>(std::allocator_arg, a, std::in_place_type<U>,
std::forward<Us>(us)...);
}
#endif // XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC
} // namespace xyz

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

#ifdef XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC
TEST(PolymorphicTest, MakePolymorphicDerivedNoArgs) {
auto p = xyz::make_polymorphic<Derived>();
EXPECT_EQ(p->value(), 0);
}

TEST(PolymorphicTest, MakePolymorphicBaseDerivedNoArgs) {
auto p = xyz::make_polymorphic<Base, Derived>();
static_assert(std::is_same_v<decltype(p), xyz::polymorphic<Base>>);
EXPECT_EQ(p->value(), 0);
}

TEST(PolymorphicTest, MakePolymorphicDerived) {
auto p = xyz::make_polymorphic<Derived>(42);
EXPECT_EQ(p->value(), 42);
}

TEST(PolymorphicTest, MakePolymorphicBaseDerived) {
auto p = xyz::make_polymorphic<Base, Derived>(42);
static_assert(std::is_same_v<decltype(p), xyz::polymorphic<Base>>);
EXPECT_EQ(p->value(), 42);
}

TEST(PolymorphicTest, AllocatePolymorphicDerivedNoArgs) {
xyz::TaggedAllocator<Derived> a(1);
auto p = xyz::allocate_polymorphic<Derived>(a);
EXPECT_EQ(p->value(), 0);
EXPECT_EQ(p.get_allocator().tag, 1);
}

TEST(PolymorphicTest, AllocatePolymorphicBaseDerivedNoArgs) {
xyz::TaggedAllocator<Base> a(1);
auto p = xyz::allocate_polymorphic<Base, Derived>(a);
static_assert(
std::is_same_v<decltype(p),
xyz::polymorphic<Base, xyz::TaggedAllocator<Base>>>);
EXPECT_EQ(p->value(), 0);
EXPECT_EQ(p.get_allocator().tag, 1);
}

TEST(PolymorphicTest, AllocatePolymorphicDerived) {
xyz::TaggedAllocator<Derived> a(1);
auto p = xyz::allocate_polymorphic<Derived>(a, 42);
EXPECT_EQ(p->value(), 42);
EXPECT_EQ(p.get_allocator().tag, 1);
}

TEST(PolymorphicTest, AllocatePolymorphicBaseDerived) {
xyz::TaggedAllocator<Derived> a(1);
auto p = xyz::allocate_polymorphic<Base, Derived>(a, 42);
static_assert(
std::is_same_v<decltype(p),
xyz::polymorphic<Base, xyz::TaggedAllocator<Derived>>>);
EXPECT_EQ(p->value(), 42);
EXPECT_EQ(p.get_allocator().tag, 1);
}
#endif // XYZ_HAS_EXTENSION_MAKE_POLYMORPHIC
} // namespace