mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #42047 from rjmccall/extended-existential-type-metadata
Add type metadata for extended existential types
This commit is contained in:
@@ -70,6 +70,17 @@ struct ExternalUnionMembers {
|
||||
// (private to the implementation)
|
||||
using Info = ExternalUnionImpl::MembersHelper<Members...>;
|
||||
|
||||
enum : bool {
|
||||
is_copy_constructible = Info::is_copy_constructible,
|
||||
is_nothrow_copy_constructible = Info::is_nothrow_copy_constructible,
|
||||
is_move_constructible = Info::is_move_constructible,
|
||||
is_nothrow_move_constructible = Info::is_nothrow_move_constructible,
|
||||
is_copy_assignable = Info::is_copy_assignable,
|
||||
is_nothrow_copy_assignable = Info::is_nothrow_copy_assignable,
|
||||
is_move_assignable = Info::is_move_assignable,
|
||||
is_nothrow_move_assignable = Info::is_nothrow_move_assignable,
|
||||
};
|
||||
|
||||
/// The type of indices into the union member type list.
|
||||
enum Index : unsigned {};
|
||||
|
||||
@@ -429,7 +440,15 @@ namespace ExternalUnionImpl {
|
||||
template <>
|
||||
struct MembersHelper<> {
|
||||
enum : bool {
|
||||
is_trivially_copyable = true
|
||||
is_trivially_copyable = true,
|
||||
is_copy_constructible = true,
|
||||
is_nothrow_copy_constructible = true,
|
||||
is_move_constructible = true,
|
||||
is_nothrow_move_constructible = true,
|
||||
is_copy_assignable = true,
|
||||
is_nothrow_copy_assignable = true,
|
||||
is_move_assignable = true,
|
||||
is_nothrow_move_assignable = true,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
@@ -476,7 +495,32 @@ private:
|
||||
public:
|
||||
enum : bool {
|
||||
is_trivially_copyable =
|
||||
Member::is_trivially_copyable && Others::is_trivially_copyable
|
||||
Member::is_trivially_copyable &&
|
||||
Others::is_trivially_copyable,
|
||||
is_copy_constructible =
|
||||
Member::is_copy_constructible &&
|
||||
Others::is_copy_constructible,
|
||||
is_nothrow_copy_constructible =
|
||||
Member::is_nothrow_copy_constructible &&
|
||||
Others::is_nothrow_copy_constructible,
|
||||
is_move_constructible =
|
||||
Member::is_move_constructible &&
|
||||
Others::is_move_constructible,
|
||||
is_nothrow_move_constructible =
|
||||
Member::is_nothrow_move_constructible &&
|
||||
Others::is_nothrow_move_constructible,
|
||||
is_copy_assignable =
|
||||
Member::is_copy_assignable &&
|
||||
Others::is_copy_assignable,
|
||||
is_nothrow_copy_assignable =
|
||||
Member::is_nothrow_copy_assignable &&
|
||||
Others::is_nothrow_copy_assignable,
|
||||
is_move_assignable =
|
||||
Member::is_move_assignable &&
|
||||
Others::is_move_assignable,
|
||||
is_nothrow_move_assignable =
|
||||
Member::is_nothrow_move_assignable &&
|
||||
Others::is_nothrow_move_assignable,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
@@ -536,7 +580,19 @@ public:
|
||||
template <class T>
|
||||
struct UnionMemberInfo {
|
||||
enum : bool {
|
||||
is_trivially_copyable = IsTriviallyCopyable<T>::value
|
||||
is_trivially_copyable = IsTriviallyCopyable<T>::value,
|
||||
is_copy_constructible = std::is_copy_constructible<T>::value,
|
||||
is_nothrow_copy_constructible =
|
||||
std::is_nothrow_copy_constructible<T>::value,
|
||||
is_move_constructible = std::is_move_constructible<T>::value,
|
||||
is_nothrow_move_constructible =
|
||||
std::is_nothrow_move_constructible<T>::value,
|
||||
is_copy_assignable = std::is_copy_assignable<T>::value,
|
||||
is_nothrow_copy_assignable =
|
||||
std::is_nothrow_copy_assignable<T>::value,
|
||||
is_move_assignable = std::is_move_assignable<T>::value,
|
||||
is_nothrow_move_assignable =
|
||||
std::is_nothrow_move_assignable<T>::value,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
@@ -575,7 +631,15 @@ struct UnionMemberInfo {
|
||||
template <>
|
||||
struct UnionMemberInfo<void> {
|
||||
enum : bool {
|
||||
is_trivially_copyable = true
|
||||
is_trivially_copyable = true,
|
||||
is_copy_constructible = true,
|
||||
is_nothrow_copy_constructible = true,
|
||||
is_move_constructible = true,
|
||||
is_nothrow_move_constructible = true,
|
||||
is_copy_assignable = true,
|
||||
is_nothrow_copy_assignable = true,
|
||||
is_move_assignable = true,
|
||||
is_nothrow_move_assignable = true,
|
||||
};
|
||||
|
||||
enum : size_t {
|
||||
|
||||
@@ -769,6 +769,20 @@ erase_if(std::unordered_set<Key, Hash, KeyEqual, Alloc> &c, Pred pred) {
|
||||
return startingSize - c.size();
|
||||
}
|
||||
|
||||
/// Call \c vector.emplace_back with each of the other arguments
|
||||
/// to this function, in order. Constructing an intermediate
|
||||
/// \c std::initializer_list can be inefficient; more problematically,
|
||||
/// types such as \c std::vector copy out of the \c initializer_list
|
||||
/// instead of move.
|
||||
template <class VectorType, class ValueType, class... ValueTypes>
|
||||
void emplace_back_all(VectorType &vector, ValueType &&value,
|
||||
ValueTypes &&...values) {
|
||||
vector.emplace_back(std::forward<ValueType>(value));
|
||||
emplace_back_all(vector, std::forward<ValueTypes>(values)...);
|
||||
}
|
||||
template <class VectorType>
|
||||
void emplace_back_all(VectorType &vector) {}
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
#endif // SWIFT_BASIC_INTERLEAVE_H
|
||||
|
||||
@@ -163,26 +163,60 @@ public:
|
||||
TaggedUnionImpl::Empty>::type = {})
|
||||
: super(std::forward<T>(value)) {}
|
||||
|
||||
TaggedUnionBase(const TaggedUnionBase &other) : super(other.TheKind) {
|
||||
// We want to either define or delete all the special members.
|
||||
// C++ does not provide a direct way to conditionally delete a
|
||||
// function. enable_if doesn't work, for several reasons: you can't
|
||||
// make an enable_if condition depend only on a property of the
|
||||
// enclosing class template (because all member function signatures
|
||||
// must successfully instantiate as part of instantiating the class
|
||||
// template; this is not covered by SFINAE), and you can't make the
|
||||
// special member itself a template (because then it's not a special
|
||||
// member anymore). static_assert within the member also doesn't work.
|
||||
// But we *can* make template substitution decide whether something
|
||||
// turns into a special member, then declare it both ways.
|
||||
template <bool condition>
|
||||
using self_if = typename std::conditional<condition,
|
||||
TaggedUnionBase,
|
||||
TaggedUnionImpl::Empty>::type;
|
||||
|
||||
TaggedUnionBase(const self_if<Members::is_copy_constructible> &other)
|
||||
noexcept(Members::is_nothrow_copy_constructible)
|
||||
: super(other.TheKind) {
|
||||
Storage.copyConstruct(other.TheKind, other.Storage);
|
||||
}
|
||||
|
||||
TaggedUnionBase(TaggedUnionBase &&other) : super(other.TheKind) {
|
||||
TaggedUnionBase(const self_if<!Members::is_copy_constructible> &other)
|
||||
= delete;
|
||||
|
||||
TaggedUnionBase(self_if<Members::is_move_constructible> &&other)
|
||||
noexcept(Members::is_nothrow_move_constructible)
|
||||
: super(other.TheKind) {
|
||||
Storage.moveConstruct(other.TheKind, std::move(other.Storage));
|
||||
}
|
||||
|
||||
TaggedUnionBase &operator=(const TaggedUnionBase &other) {
|
||||
TaggedUnionBase(self_if<!Members::is_move_constructible> &&other)
|
||||
= delete;
|
||||
|
||||
TaggedUnionBase &operator=(const self_if<Members::is_copy_assignable> &other)
|
||||
noexcept(Members::is_nothrow_copy_assignable) {
|
||||
Storage.copyAssign(TheKind, other.TheKind, other.Storage);
|
||||
TheKind = other.TheKind;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TaggedUnionBase &operator=(TaggedUnionBase &&other) {
|
||||
TaggedUnionBase &operator=(const self_if<!Members::is_copy_assignable> &other)
|
||||
= delete;
|
||||
|
||||
TaggedUnionBase &operator=(self_if<Members::is_move_assignable> &&other)
|
||||
noexcept(Members::is_nothrow_move_assignable) {
|
||||
Storage.moveAssign(TheKind, other.TheKind, std::move(other.Storage));
|
||||
TheKind = other.TheKind;
|
||||
return *this;
|
||||
}
|
||||
|
||||
TaggedUnionBase &operator=(self_if<!Members::is_move_assignable> &&other)
|
||||
= delete;
|
||||
|
||||
~TaggedUnionBase() {
|
||||
Storage.destruct(TheKind);
|
||||
}
|
||||
@@ -250,10 +284,16 @@ public:
|
||||
/// empty state and provides a default constructor as well as `empty()`
|
||||
/// and `reset()` methods.
|
||||
template <class... Members>
|
||||
using TaggedUnion =
|
||||
TaggedUnionBase<ExternalUnionImpl::OptimalKindTypeHelper<sizeof...(Members)>,
|
||||
ExternalUnionMembers<Members...>>;
|
||||
class TaggedUnion :
|
||||
public TaggedUnionBase<ExternalUnionImpl::OptimalKindTypeHelper<sizeof...(Members)>,
|
||||
ExternalUnionMembers<Members...>> {
|
||||
using super =
|
||||
TaggedUnionBase<ExternalUnionImpl::OptimalKindTypeHelper<sizeof...(Members)>,
|
||||
ExternalUnionMembers<Members...>>;
|
||||
public:
|
||||
using super::super;
|
||||
};
|
||||
|
||||
}
|
||||
} // end namespace swift
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user