Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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(const A& a, Us&&... us) -> indirect<T, A> {
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(const 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