summaryrefslogtreecommitdiff
path: root/include/llvm/ADT/FoldingSet.h
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-01-19 03:58:00 +0000
committerTed Kremenek <kremenek@apple.com>2008-01-19 03:58:00 +0000
commita753f703d1e532dbec5f89c6af834ccd72581ca9 (patch)
treeb346330f811dbdacdf38fbf40031c00ed41d1e44 /include/llvm/ADT/FoldingSet.h
parentb4eae999f6064291ef1069a5d5e219189cc902a4 (diff)
downloadllvm-a753f703d1e532dbec5f89c6af834ccd72581ca9.tar.gz
llvm-a753f703d1e532dbec5f89c6af834ccd72581ca9.tar.bz2
llvm-a753f703d1e532dbec5f89c6af834ccd72581ca9.tar.xz
Made 'profiling' of objects in a FoldingSet trait-based using FoldingSetTrait
instead of always assuming that the stored objects had a method called 'Profile'. The default behavior is to dispatch to a 'Profile' method (as before), but via template specialization this behavior can now be overridden by clients. Added templated class 'FoldingSetNodeWrapper', a generic wrapper class that allows one to insert objects into a FoldingSet that do not directly inherit from FoldingSetNode. This is useful for inserting objects that do not always need to pay the overhead of inheriting from FoldingSetNode, or were designed with that behavior in mind. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46186 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT/FoldingSet.h')
-rw-r--r--include/llvm/ADT/FoldingSet.h54
1 files changed, 53 insertions, 1 deletions
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 9f4fb05d7f..da1f16c60b 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -226,6 +226,19 @@ typedef FoldingSetImpl::NodeID FoldingSetNodeID;
template<class T> class FoldingSetIterator;
//===----------------------------------------------------------------------===//
+/// FoldingSetTrait - This trait class is used to define behavior of how
+/// to "profile" (in the FoldingSet parlance) an object of a given type.
+/// The default behavior is to invoke a 'Profile' method on an object, but
+/// through template specialization the behavior can be tailored for specific
+/// types. Combined with the FoldingSetNodeWrapper classs, one can add objects
+/// to FoldingSets that were not originally designed to have that behavior.
+///
+template<typename T> struct FoldingSetTrait {
+ static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);}
+ static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
+};
+
+//===----------------------------------------------------------------------===//
/// FoldingSet - This template class is used to instantiate a specialized
/// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function.
@@ -236,7 +249,7 @@ private:
/// way to convert nodes into a unique specifier.
virtual void GetNodeProfile(NodeID &ID, Node *N) const {
T *TN = static_cast<T *>(N);
- TN->Profile(ID);
+ FoldingSetTrait<T>::Profile(*TN,ID);
}
public:
@@ -307,6 +320,45 @@ public:
FoldingSetIterator tmp = *this; ++*this; return tmp;
}
};
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
+/// types in an enclosing object so that they can be inserted into FoldingSets.
+template <typename T>
+class FoldingSetNodeWrapper : public FoldingSetNode {
+ T data;
+public:
+ FoldingSetNodeWrapper(const T& x) : data(x) {}
+ virtual ~FoldingSetNodeWrapper();
+
+ template<typename A1>
+ explicit FoldingSetNodeWrapper(const A1& a1)
+ : data(a1) {}
+
+ template <typename A1, typename A2>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2)
+ : data(a1,a2) {}
+
+ template <typename A1, typename A2, typename A3>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3)
+ : data(a1,a2,a3) {}
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4)
+ : data(a1,a2,a3,a4) {}
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4, const A5& a5)
+ : data(a1,a2,a3,a4,a5) {}
+
+
+ void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); }
+
+ operator T&() { return data; }
+ operator const T&() const { return data; }
+};
} // End of namespace llvm.