Bug 953296 - Implement mozilla::IsRvalueReference and mozilla::IsReference. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Mon, 30 Dec 2013 01:07:25 -0600
changeset 162293 3d519786b8584b3c926d2fa3a8d3e0b480804781
parent 162292 8c5e82bc3241bb2ab210909c28a3843127362ae3
child 162294 a6330cc7cc46ab4190a7d1265f9dc6f0d6db930b
push idunknown
push userunknown
push dateunknown
reviewersfroydnj
bugs953296
milestone29.0a1
Bug 953296 - Implement mozilla::IsRvalueReference and mozilla::IsReference. r=froydnj
mfbt/TypeTraits.h
mfbt/tests/TestTypeTraits.cpp
--- a/mfbt/TypeTraits.h
+++ b/mfbt/TypeTraits.h
@@ -142,16 +142,33 @@ struct IsPointer<T*> : TrueType {};
  * mozilla::IsLvalueReference<struct S&&>::value is false.
  */
 template<typename T>
 struct IsLvalueReference : FalseType {};
 
 template<typename T>
 struct IsLvalueReference<T&> : TrueType {};
 
+/**
+ * IsRvalueReference determines whether a type is an rvalue reference.
+ *
+ * mozilla::IsRvalueReference<struct S*>::value is false;
+ * mozilla::IsRvalueReference<int**>::value is false;
+ * mozilla::IsRvalueReference<void (*)(void)>::value is false;
+ * mozilla::IsRvalueReference<int>::value is false;
+ * mozilla::IsRvalueReference<struct S>::value is false;
+ * mozilla::IsRvalueReference<struct S*&>::value is false;
+ * mozilla::IsRvalueReference<struct S&&>::value is true.
+ */
+template<typename T>
+struct IsRvalueReference : FalseType {};
+
+template<typename T>
+struct IsRvalueReference<T&&> : TrueType {};
+
 namespace detail {
 
 // __is_enum is a supported extension across all of our supported compilers.
 template<typename T>
 struct IsEnumHelper
   : IntegralConstant<bool, __is_enum(T)>
 {};
 
@@ -194,16 +211,36 @@ struct IsClassHelper
 template<typename T>
 struct IsClass
   : detail::IsClassHelper<typename RemoveCV<T>::Type>
 {};
 
 /* 20.9.4.2 Composite type traits [meta.unary.comp] */
 
 /**
+ * IsReference determines whether a type is an lvalue or rvalue reference.
+ *
+ * mozilla::IsReference<struct S*>::value is false;
+ * mozilla::IsReference<int**>::value is false;
+ * mozilla::IsReference<int&>::value is true;
+ * mozilla::IsReference<void (*)(void)>::value is false;
+ * mozilla::IsReference<const int&>::value is true;
+ * mozilla::IsReference<int>::value is false;
+ * mozilla::IsReference<struct S>::value is false;
+ * mozilla::IsReference<struct S&>::value is true;
+ * mozilla::IsReference<struct S*&>::value is true;
+ * mozilla::IsReference<struct S&&>::value is true.
+ */
+template<typename T>
+struct IsReference
+  : IntegralConstant<bool,
+                     IsLvalueReference<T>::value || IsRvalueReference<T>::value>
+{};
+
+/**
  * IsArithmetic determines whether a type is arithmetic.  A type is arithmetic
  * iff it is an integral type or a floating point type.
  *
  * mozilla::IsArithmetic<int>::value is true;
  * mozilla::IsArithmetic<double>::value is true;
  * mozilla::IsArithmetic<long double*>::value is false.
  */
 template<typename T>
--- a/mfbt/tests/TestTypeTraits.cpp
+++ b/mfbt/tests/TestTypeTraits.cpp
@@ -5,22 +5,64 @@
 
 #include "mozilla/Assertions.h"
 #include "mozilla/TypeTraits.h"
 
 using mozilla::IsBaseOf;
 using mozilla::IsClass;
 using mozilla::IsConvertible;
 using mozilla::IsEmpty;
+using mozilla::IsLvalueReference;
+using mozilla::IsReference;
+using mozilla::IsRvalueReference;
 using mozilla::IsSame;
 using mozilla::IsSigned;
 using mozilla::IsUnsigned;
 using mozilla::MakeSigned;
 using mozilla::MakeUnsigned;
 
+static_assert(!IsLvalueReference<bool>::value, "bool not an lvalue reference");
+static_assert(!IsLvalueReference<bool*>::value, "bool* not an lvalue reference");
+static_assert(IsLvalueReference<bool&>::value, "bool& is an lvalue reference");
+static_assert(!IsLvalueReference<bool&&>::value, "bool&& not an lvalue reference");
+
+static_assert(!IsLvalueReference<void>::value, "void not an lvalue reference");
+static_assert(!IsLvalueReference<void*>::value, "void* not an lvalue reference");
+
+static_assert(!IsLvalueReference<int>::value, "int not an lvalue reference");
+static_assert(!IsLvalueReference<int*>::value, "int* not an lvalue reference");
+static_assert(IsLvalueReference<int&>::value, "int& is an lvalue reference");
+static_assert(!IsLvalueReference<int&&>::value, "int&& not an lvalue reference");
+
+static_assert(!IsRvalueReference<bool>::value, "bool not an rvalue reference");
+static_assert(!IsRvalueReference<bool*>::value, "bool* not an rvalue reference");
+static_assert(!IsRvalueReference<bool&>::value, "bool& not an rvalue reference");
+static_assert(IsRvalueReference<bool&&>::value, "bool&& is an rvalue reference");
+
+static_assert(!IsRvalueReference<void>::value, "void not an rvalue reference");
+static_assert(!IsRvalueReference<void*>::value, "void* not an rvalue reference");
+
+static_assert(!IsRvalueReference<int>::value, "int not an rvalue reference");
+static_assert(!IsRvalueReference<int*>::value, "int* not an rvalue reference");
+static_assert(!IsRvalueReference<int&>::value, "int& not an rvalue reference");
+static_assert(IsRvalueReference<int&&>::value, "int&& is an rvalue reference");
+
+static_assert(!IsReference<bool>::value, "bool not a reference");
+static_assert(!IsReference<bool*>::value, "bool* not a reference");
+static_assert(IsReference<bool&>::value, "bool& is a reference");
+static_assert(IsReference<bool&&>::value, "bool&& is a reference");
+
+static_assert(!IsReference<void>::value, "void not a reference");
+static_assert(!IsReference<void*>::value, "void* not a reference");
+
+static_assert(!IsReference<int>::value, "int not a reference");
+static_assert(!IsReference<int*>::value, "int* not a reference");
+static_assert(IsReference<int&>::value, "int& is a reference");
+static_assert(IsReference<int&&>::value, "int&& is a reference");
+
 struct S1 {};
 union U1 { int x; };
 
 static_assert(!IsClass<int>::value, "int isn't a class");
 static_assert(IsClass<const S1>::value, "S is a class");
 static_assert(!IsClass<U1>::value, "U isn't a class");
 
 static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty");