Bug 1142366 - Add an equivalent of std::make_pair for mozilla::Pair. r=waldo
authorSeth Fowler <seth@mozilla.com>
Thu, 12 Mar 2015 17:44:28 -0700
changeset 262306 70bccab35a0286eae6522cb973e70fff71362fb2
parent 262305 76e28af52416814caece9ac0b8b08dbee2b9cfb2
child 262307 d3f34e3bffcea6d2189fb69128c6dfef96af986b
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1142366
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1142366 - Add an equivalent of std::make_pair for mozilla::Pair. r=waldo
mfbt/Pair.h
mfbt/tests/TestPair.cpp
--- a/mfbt/Pair.h
+++ b/mfbt/Pair.h
@@ -155,16 +155,20 @@ struct Pair
   typedef typename detail::PairHelper<A, B> Base;
 
 public:
   template<typename AArg, typename BArg>
   Pair(AArg&& aA, BArg&& aB)
     : Base(Forward<AArg>(aA), Forward<BArg>(aB))
   {}
 
+  Pair(Pair&& aOther)
+    : Base(Move(aOther.first()), Move(aOther.second()))
+  { }
+
   /** The A instance. */
   using Base::first;
   /** The B instance. */
   using Base::second;
 
   /** Swap this pair with another pair. */
   void swap(Pair& aOther) { Base::swap(aOther); }
 
@@ -174,11 +178,31 @@ private:
 
 template<typename A, class B>
 void
 Swap(Pair<A, B>& aX, Pair<A, B>& aY)
 {
   aX.swap(aY);
 }
 
+/**
+ * MakePair allows you to construct a Pair instance using type inference. A call
+ * like this:
+ *
+ *   MakePair(Foo(), Bar())
+ *
+ * will return a Pair<Foo, Bar>.
+ */
+template<typename A, typename B>
+Pair<typename RemoveCV<typename RemoveReference<A>::Type>::Type,
+     typename RemoveCV<typename RemoveReference<B>::Type>::Type>
+MakePair(A&& aA, B&& aB)
+{
+  return
+    Pair<typename RemoveCV<typename RemoveReference<A>::Type>::Type,
+         typename RemoveCV<typename RemoveReference<B>::Type>::Type>(
+             Forward<A>(aA),
+             Forward<B>(aB));
+}
+
 } // namespace mozilla
 
 #endif /* mozilla_Pair_h */
--- a/mfbt/tests/TestPair.cpp
+++ b/mfbt/tests/TestPair.cpp
@@ -1,16 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Pair.h"
+#include "mozilla/TypeTraits.h"
 
+using mozilla::IsSame;
+using mozilla::MakePair;
 using mozilla::Pair;
 
 // Sizes aren't part of the guaranteed Pair interface, but we want to verify our
 // attempts at compactness through EBO are moderately functional, *somewhere*.
 #define INSTANTIATE(T1, T2, name, size) \
   Pair<T1, T2> name##_1(T1(0), T2(0)); \
   static_assert(sizeof(name##_1.first()) > 0, \
                 "first method should work on Pair<" #T1 ", " #T2 ">"); \
@@ -54,10 +57,23 @@ struct OtherEmpty : EmptyClass { explici
 // potentially assert something about size for this case, but whatever we could
 // assert would be very finicky.  Plus it's two empty classes -- hardly likely.
 // So don't bother trying to assert anything about this case.
 //INSTANTIATE(EmptyClass, OtherEmpty, class4, ...something finicky...);
 
 int
 main()
 {
+  A a(0);
+  B b(0);
+  const A constA(0);
+  const B constB(0);
+
+  // Check that MakePair generates Pair objects of the correct types.
+  static_assert(IsSame<decltype(MakePair(A(0), B(0))), Pair<A, B>>::value,
+                "MakePair should strip rvalue references");
+  static_assert(IsSame<decltype(MakePair(a, b)), Pair<A, B>>::value,
+                "MakePair should strip lvalue references");
+  static_assert(IsSame<decltype(MakePair(constA, constB)), Pair<A, B>>::value,
+                "MakePair should strip CV-qualifiers");
+
   return 0;
 }