Skip to content

Commit d37fa5a

Browse files
authored
Revert "[ADT] Remove CRTP from FoldingSet and ContextualFoldingSet (NFC)" (#216957)
Reverts #216830 due to breakage on msvc builds
1 parent 6bba49a commit d37fa5a

1 file changed

Lines changed: 104 additions & 59 deletions

File tree

llvm/include/llvm/ADT/FoldingSet.h

Lines changed: 104 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ class StringRef;
113113
/// This class provides default implementations for FoldingSetTrait
114114
/// implementations.
115115
template <typename T> struct DefaultFoldingSetTrait {
116-
struct ContextStorage {};
117-
118116
static void Profile(const T &X, FoldingSetNodeID &ID) { X.Profile(ID); }
119117
static void Profile(T &X, FoldingSetNodeID &ID) { X.Profile(ID); }
120118

@@ -144,12 +142,6 @@ struct FoldingSetTrait : public DefaultFoldingSetTrait<T> {};
144142

145143
/// Like DefaultFoldingSetTrait, but for ContextualFoldingSets.
146144
template <typename T, typename Ctx> struct DefaultContextualFoldingSetTrait {
147-
struct ContextStorage {
148-
Ctx Context;
149-
explicit ContextStorage(Ctx Context) : Context(Context) {}
150-
Ctx getContext() const { return Context; }
151-
};
152-
153145
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
154146
X.Profile(ID, Context);
155147
}
@@ -441,50 +433,11 @@ inline unsigned DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(
441433
//===----------------------------------------------------------------------===//
442434
/// An implementation detail that lets us share code between FoldingSet and
443435
/// ContextualFoldingSet.
444-
template <class T, class Trait = FoldingSetTrait<T>>
445-
class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
446-
static constexpr FoldingSetBase::FoldingSetInfo Info = {
447-
// GetNodeProfile
448-
[](const FoldingSetBase *Base, FoldingSetNode *N, FoldingSetNodeID &ID) {
449-
if constexpr (std::is_empty_v<typename Trait::ContextStorage>)
450-
Trait::Profile(*static_cast<T *>(N), ID);
451-
else
452-
Trait::Profile(
453-
*static_cast<T *>(N), ID,
454-
static_cast<const FoldingSetImpl *>(Base)->getContext());
455-
},
456-
// NodeEquals
457-
[](const FoldingSetBase *Base, FoldingSetNode *N,
458-
const FoldingSetNodeID &ID, unsigned IDHash,
459-
FoldingSetNodeID &TempID) {
460-
if constexpr (std::is_empty_v<typename Trait::ContextStorage>)
461-
return Trait::Equals(*static_cast<T *>(N), ID, IDHash, TempID);
462-
else
463-
return Trait::Equals(
464-
*static_cast<T *>(N), ID, IDHash, TempID,
465-
static_cast<const FoldingSetImpl *>(Base)->getContext());
466-
},
467-
// ComputeNodeHash
468-
[](const FoldingSetBase *Base, FoldingSetNode *N,
469-
FoldingSetNodeID &TempID) {
470-
if constexpr (std::is_empty_v<typename Trait::ContextStorage>)
471-
return Trait::ComputeHash(*static_cast<T *>(N), TempID);
472-
else
473-
return Trait::ComputeHash(
474-
*static_cast<T *>(N), TempID,
475-
static_cast<const FoldingSetImpl *>(Base)->getContext());
476-
}};
477-
478-
public:
479-
explicit FoldingSetImpl(unsigned Log2InitSize = 6)
436+
template <class Derived, class T> class FoldingSetImpl : public FoldingSetBase {
437+
protected:
438+
explicit FoldingSetImpl(unsigned Log2InitSize)
480439
: FoldingSetBase(Log2InitSize) {}
481440

482-
template <typename C, typename = std::enable_if_t<std::is_constructible_v<
483-
typename Trait::ContextStorage, C>>>
484-
explicit FoldingSetImpl(C &&Context, unsigned Log2InitSize = 6)
485-
: FoldingSetBase(Log2InitSize),
486-
Trait::ContextStorage(std::forward<C>(Context)) {}
487-
488441
FoldingSetImpl(FoldingSetImpl &&Arg) = default;
489442
FoldingSetImpl &operator=(FoldingSetImpl &&RHS) = default;
490443
~FoldingSetImpl() = default;
@@ -503,7 +456,9 @@ class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
503456
/// Increase the number of buckets such that adding the \p EltCount th node
504457
/// won't cause a rebucket operation. reserve is permitted to allocate more
505458
/// space than requested by EltCount.
506-
void reserve(unsigned EltCount) { FoldingSetBase::reserve(EltCount, Info); }
459+
void reserve(unsigned EltCount) {
460+
FoldingSetBase::reserve(EltCount, Derived::getFoldingSetInfo());
461+
}
507462

508463
/// Remove a node from the folding set, returning true if one
509464
/// was removed or false if the node was not in the folding set.
@@ -512,21 +467,22 @@ class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
512467
/// If there is an existing simple Node exactly equal to the specified node,
513468
/// return it. Otherwise, insert 'N' and return it instead.
514469
T *GetOrInsertNode(T *N) {
515-
return static_cast<T *>(FoldingSetBase::GetOrInsertNode(N, Info));
470+
return static_cast<T *>(
471+
FoldingSetBase::GetOrInsertNode(N, Derived::getFoldingSetInfo()));
516472
}
517473

518474
/// Look up the node specified by ID. If it exists, return it. If not,
519475
/// return the insertion token that will make insertion faster.
520476
T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
521-
return static_cast<T *>(
522-
FoldingSetBase::FindNodeOrInsertPos(ID, InsertPos, Info));
477+
return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(
478+
ID, InsertPos, Derived::getFoldingSetInfo()));
523479
}
524480

525481
/// Insert the specified node into the folding set, knowing that
526482
/// it is not already in the folding set. InsertPos must be obtained from
527483
/// FindNodeOrInsertPos.
528484
void InsertNode(T *N, void *InsertPos) {
529-
FoldingSetBase::InsertNode(N, InsertPos, Info);
485+
FoldingSetBase::InsertNode(N, InsertPos, Derived::getFoldingSetInfo());
530486
}
531487

532488
/// Insert the specified node into the folding set, knowing that it is not
@@ -547,8 +503,47 @@ class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
547503
/// moved-from state is not a valid state for anything other than
548504
/// move-assigning and destroying. This is primarily to enable movable APIs
549505
/// that incorporate these objects.
550-
template <class T, class Trait = FoldingSetTrait<T>>
551-
using FoldingSet = FoldingSetImpl<T, Trait>;
506+
template <class T> class FoldingSet : public FoldingSetImpl<FoldingSet<T>, T> {
507+
using Super = FoldingSetImpl<FoldingSet, T>;
508+
using Node = typename Super::Node;
509+
510+
/// Each instantiation of the FoldingSet needs to provide a
511+
/// way to convert nodes into a unique specifier.
512+
static void GetNodeProfile(const FoldingSetBase *, Node *N,
513+
FoldingSetNodeID &ID) {
514+
T *TN = static_cast<T *>(N);
515+
FoldingSetTrait<T>::Profile(*TN, ID);
516+
}
517+
518+
/// Instantiations may optionally provide a way to compare a
519+
/// node with a specified ID.
520+
static bool NodeEquals(const FoldingSetBase *, Node *N,
521+
const FoldingSetNodeID &ID, unsigned IDHash,
522+
FoldingSetNodeID &TempID) {
523+
T *TN = static_cast<T *>(N);
524+
return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
525+
}
526+
527+
/// Instantiations may optionally provide a way to compute a
528+
/// hash value directly from a node.
529+
static unsigned ComputeNodeHash(const FoldingSetBase *, Node *N,
530+
FoldingSetNodeID &TempID) {
531+
T *TN = static_cast<T *>(N);
532+
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
533+
}
534+
535+
static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
536+
static constexpr FoldingSetBase::FoldingSetInfo Info = {
537+
GetNodeProfile, NodeEquals, ComputeNodeHash};
538+
return Info;
539+
}
540+
friend Super;
541+
542+
public:
543+
explicit FoldingSet(unsigned Log2InitSize = 6) : Super(Log2InitSize) {}
544+
FoldingSet(FoldingSet &&Arg) = default;
545+
FoldingSet &operator=(FoldingSet &&RHS) = default;
546+
};
552547

553548
//===----------------------------------------------------------------------===//
554549
/// This template class is a further refinement of FoldingSet which provides a
@@ -559,8 +554,58 @@ using FoldingSet = FoldingSetImpl<T, Trait>;
559554
/// function with signature
560555
/// void Profile(FoldingSetNodeID &, Ctx);
561556
template <class T, class Ctx>
562-
using ContextualFoldingSet =
563-
FoldingSetImpl<T, ContextualFoldingSetTrait<T, Ctx>>;
557+
class ContextualFoldingSet
558+
: public FoldingSetImpl<ContextualFoldingSet<T, Ctx>, T> {
559+
// Unfortunately, this can't derive from FoldingSet<T> because the
560+
// construction of the vtable for FoldingSet<T> requires
561+
// FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
562+
// requires a single-argument T::Profile().
563+
564+
using Super = FoldingSetImpl<ContextualFoldingSet, T>;
565+
using Node = typename Super::Node;
566+
567+
Ctx Context;
568+
569+
static const Ctx &getContext(const FoldingSetBase *Base) {
570+
return static_cast<const ContextualFoldingSet *>(Base)->Context;
571+
}
572+
573+
/// Each instantiatation of the FoldingSet needs to provide a way to convert
574+
/// nodes into a unique specifier.
575+
static void GetNodeProfile(const FoldingSetBase *Base, Node *N,
576+
FoldingSetNodeID &ID) {
577+
T *TN = static_cast<T *>(N);
578+
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, getContext(Base));
579+
}
580+
581+
static bool NodeEquals(const FoldingSetBase *Base, Node *N,
582+
const FoldingSetNodeID &ID, unsigned IDHash,
583+
FoldingSetNodeID &TempID) {
584+
T *TN = static_cast<T *>(N);
585+
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
586+
getContext(Base));
587+
}
588+
589+
static unsigned ComputeNodeHash(const FoldingSetBase *Base, Node *N,
590+
FoldingSetNodeID &TempID) {
591+
T *TN = static_cast<T *>(N);
592+
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID,
593+
getContext(Base));
594+
}
595+
596+
static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
597+
static constexpr FoldingSetBase::FoldingSetInfo Info = {
598+
GetNodeProfile, NodeEquals, ComputeNodeHash};
599+
return Info;
600+
}
601+
friend Super;
602+
603+
public:
604+
explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
605+
: Super(Log2InitSize), Context(Context) {}
606+
607+
Ctx getContext() const { return Context; }
608+
};
564609

565610
//===----------------------------------------------------------------------===//
566611
/// This template class combines a FoldingSet and a vector to provide the

0 commit comments

Comments
 (0)