summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2012-12-17 19:02:05 +0000
committerNick Kledzik <kledzik@apple.com>2012-12-17 19:02:05 +0000
commitfbc8a73e0c9f4e9da49faa4782c9bfb0acb50a24 (patch)
tree3b87932c79e5841d838a857f20de9e24a15491fc /include
parentb0de1e31d11056037c4db3e2ecfe1547e85c3e1c (diff)
downloadllvm-fbc8a73e0c9f4e9da49faa4782c9bfb0acb50a24.tar.gz
llvm-fbc8a73e0c9f4e9da49faa4782c9bfb0acb50a24.tar.bz2
llvm-fbc8a73e0c9f4e9da49faa4782c9bfb0acb50a24.tar.xz
Use different trait techniques to be compatible with g++
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170355 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Support/YAMLTraits.h67
1 files changed, 41 insertions, 26 deletions
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 80580620ea..4487eae248 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -227,10 +227,9 @@ public:
};
-// Test if SequenceTraits<T> is defined on type T
-// and SequenceTraits<T>::flow is *not* defined.
+// Test if SequenceTraits<T> is defined on type T.
template <class T>
-struct has_SequenceTraits
+struct has_SequenceMethodTraits
{
typedef size_t (*Signature_size)(class IO&, T&);
@@ -240,43 +239,59 @@ struct has_SequenceTraits
template <typename U>
static double test(...);
- template <typename U> static
- char flowtest( char[sizeof(&U::flow)] ) ;
+public:
+ static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1);
+};
- template <typename U>
- static double flowtest(...);
+// has_FlowTraits<int> will cause an error with some compilers because
+// it subclasses int. Using this wrapper only instantiates the
+// real has_FlowTraits only if the template type is a class.
+template <typename T, bool Enabled = llvm::is_class<T>::value>
+class has_FlowTraits
+{
public:
- static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1)
- && (sizeof(flowtest<T>(0)) != 1);
+ static const bool value = false;
};
-
-// Test if SequenceTraits<T> is defined on type T
-// and SequenceTraits<T>::flow is defined.
+// Some older gcc compilers don't support straight forward tests
+// for members, so test for ambiguity cause by the base and derived
+// classes both defining the member.
template <class T>
-struct has_FlowSequenceTraits
+struct has_FlowTraits<T, true>
{
- typedef size_t (*Signature_size)(class IO&, T&);
+ struct Fallback { bool flow; };
+ struct Derived : T, Fallback { };
- template <typename U>
- static char test(SameType<Signature_size, &U::size>*);
-
- template <typename U>
- static double test(...);
+ template<typename C>
+ static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
- template <typename U> static
- char flowtest( char[sizeof(&U::flow)] ) ;
-
- template <typename U>
- static double flowtest(...);
+ template<typename C>
+ static char (&f(...))[2];
public:
- static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1)
- && (sizeof(flowtest<T>(0)) == 1);
+ static bool const value = sizeof(f<Derived>(0)) == 2;
};
+
+// Test if SequenceTraits<T> is defined on type T
+// and SequenceTraits<T>::flow is *not* defined.
+template<typename T>
+struct has_SequenceTraits : public llvm::integral_constant<bool,
+ has_SequenceMethodTraits<T>::value
+ && !has_FlowTraits<T>::value > { };
+
+
+// Test if SequenceTraits<T> is defined on type T
+// and SequenceTraits<T>::flow is defined.
+template<typename T>
+struct has_FlowSequenceTraits : public llvm::integral_constant<bool,
+ has_SequenceMethodTraits<T>::value
+ && has_FlowTraits<T>::value > { };
+
+
+
// Test if DocumentListTraits<T> is defined on type T
template <class T>
struct has_DocumentListTraits