You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2018/08/07 03:06:10 UTC

[mesos] branch master updated (fad7d7a -> 8132c64)

This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git.


    from fad7d7a  Added MESOS-9127 to 1.4.2 CHANGELOG.
     new 5cde1e2  Added move support for `Resources`.
     new 23cb8da  Added tests for `Resources` move semantics.
     new 8132c64  Added ref-qualified addition operations to `Resources`.

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 include/mesos/resources.hpp    |  35 +++++++++-
 include/mesos/v1/resources.hpp |  35 +++++++++-
 src/common/resources.cpp       | 137 ++++++++++++++++++++++++++++++++++++-
 src/tests/resources_tests.cpp  | 149 +++++++++++++++++++++++++++++++++++++----
 src/v1/resources.cpp           | 137 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 469 insertions(+), 24 deletions(-)


[mesos] 02/03: Added tests for `Resources` move semantics.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 23cb8da5f267963232c2985c82de721dbf0ef72d
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Mon Aug 6 19:17:21 2018 -0700

    Added tests for `Resources` move semantics.
    
    Review: https://reviews.apache.org/r/68242/
---
 src/tests/resources_tests.cpp | 149 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 135 insertions(+), 14 deletions(-)

diff --git a/src/tests/resources_tests.cpp b/src/tests/resources_tests.cpp
index 9475b6e..002338a 100644
--- a/src/tests/resources_tests.cpp
+++ b/src/tests/resources_tests.cpp
@@ -797,6 +797,47 @@ TEST(ResourcesTest, Resources)
 }
 
 
+TEST(ResourcesTest, MoveConstruction)
+{
+  const Resources r = CHECK_NOTERROR(Resources::parse(
+      "cpus:45.55;mem:1024;ports:[10000-20000, 30000-50000];disk:512"));
+
+  // Move constructor for `Resources`.
+  Resources r1 = r;
+  Resources rr1{std::move(r)};
+  EXPECT_EQ(r, rr1);
+
+  // Move constructor for `vector<Resource>`.
+  vector<Resource> r2;
+  foreach (const Resource& resource, r) {
+    r2.push_back(resource);
+  }
+  Resources rr2{std::move(r2)};
+  EXPECT_EQ(r, rr2);
+
+  // Move constructor for `google::protobuf::RepeatedPtrField<Resource>`.
+  google::protobuf::RepeatedPtrField<Resource> r3;
+  foreach (const Resource& resource, r) {
+    *r3.Add() = resource;
+  }
+  Resources rr3{std::move(r3)};
+  EXPECT_EQ(r, rr3);
+
+  // Move assignment for `Resources`.
+  Resources r4 = r;
+  Resources rr4;
+  rr4 = std::move(r4);
+  EXPECT_EQ(r, rr4);
+
+  // Move constructor for `Resource`.
+  const Resource resource = CHECK_NOTERROR(Resources::parse("cpu", "1.0", "*"));
+
+  Resource r5 = resource;
+  Resources rr5{std::move(r5)};
+  EXPECT_EQ(Resources(resource), rr5);
+}
+
+
 TEST(ResourcesTest, Printing)
 {
   Resources r = Resources::parse(
@@ -1078,9 +1119,10 @@ TEST(ResourcesTest, ScalarAddition)
   r1 += cpus1;
   r1 += mem1;
 
+  // Test +=(Resource&&).
   Resources r2;
-  r2 += cpus2;
-  r2 += mem2;
+  r2 += Resource(cpus2);
+  r2 += Resource(mem2);
 
   Resources sum = r1 + r2;
 
@@ -1089,6 +1131,15 @@ TEST(ResourcesTest, ScalarAddition)
   EXPECT_EQ(3, sum.get<Value::Scalar>("cpus")->value());
   EXPECT_EQ(15, sum.get<Value::Scalar>("mem")->value());
 
+  // Verify operator+ with rvalue references.
+  Resources sum1 = Resources(r1) + r2;
+  Resources sum2 = r1 + Resources(r2);
+  Resources sum3 = Resources(r1) + Resources(r2);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
+
   Resources r = r1;
   r += r2;
 
@@ -1107,7 +1158,7 @@ TEST(ResourcesTest, ScalarAddition2)
 
   Resources r1;
   r1 += cpus1;
-  r1 += cpus2;
+  r1 += Resource(cpus2); // Test +=(Resource&&).
 
   Resources r2;
   r2 += cpus3;
@@ -1118,6 +1169,15 @@ TEST(ResourcesTest, ScalarAddition2)
   EXPECT_EQ(2u, sum.size());
   EXPECT_EQ(9, sum.cpus().get());
   EXPECT_EQ(sum, Resources::parse("cpus(role1):6;cpus(role2):3").get());
+
+  // Verify operator+ with rvalue references.
+  Resources sum1 = Resources(r1) + r2;
+  Resources sum2 = r1 + Resources(r2);
+  Resources sum3 = Resources(r1) + Resources(r2);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
 }
 
 
@@ -1248,7 +1308,7 @@ TEST(ResourcesTest, RangesAddition)
 
   Resources r;
   r += ports1;
-  r += ports2;
+  r += Resource(ports2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r.empty());
 
@@ -1265,7 +1325,7 @@ TEST(ResourcesTest, RangesAddition2)
 
   Resources r;
   r += ports1;
-  r += ports2;
+  r += Resource(ports2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r.empty());
 
@@ -1284,7 +1344,7 @@ TEST(ResourcesTest, RangesAddition3)
 
   Resources r1;
   r1 += ports1;
-  r1 += ports2;
+  r1 += Resource(ports2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r1.empty());
 
@@ -1294,7 +1354,7 @@ TEST(ResourcesTest, RangesAddition3)
 
   Resources r2;
   r2 += ports3;
-  r2 += ports4;
+  r2 += Resource(ports4); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r2.empty());
 
@@ -1322,7 +1382,7 @@ TEST(ResourcesTest, RangesAddition4)
 
   Resources r;
   r += ports1;
-  r += ports2;
+  r += Resource(ports2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r.empty());
 
@@ -1498,7 +1558,7 @@ TEST(ResourcesTest, SetAddition)
 
   Resources r;
   r += disks1;
-  r += disks2;
+  r += Resource(disks2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r.empty());
 
@@ -1612,7 +1672,7 @@ TEST(ResourceProviderIDTest, Addition)
 
   Resources r1;
   r1 += cpus;
-  r1 += disk2;
+  r1 += Resource(disk2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r1.empty());
   EXPECT_EQ(2u, r1.size());
@@ -1624,7 +1684,7 @@ TEST(ResourceProviderIDTest, Addition)
 
   Resources r2;
   r2 += disk2;
-  r2 += disk2;
+  r2 += Resource(disk2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r2.empty());
   EXPECT_EQ(1u, r2.size());
@@ -1635,7 +1695,7 @@ TEST(ResourceProviderIDTest, Addition)
 
   Resources r3;
   r3 += disk1;
-  r3 += disk2;
+  r3 += Resources(disk2); // Test operator+=(Resource&&).
 
   EXPECT_FALSE(r3.empty());
   EXPECT_EQ(2u, r3.size());
@@ -2052,6 +2112,11 @@ TEST(ReservedResourcesTest, AdditionStaticallyReserved)
     createReservedResource("cpus", "12", createStaticReservationInfo("role"));
 
   EXPECT_EQ(expected, left + right);
+
+  // Test operator+ with rvalue references.
+  EXPECT_EQ(expected, Resources(left) + right);
+  EXPECT_EQ(expected, left + Resources(right));
+  EXPECT_EQ(expected, Resources(left) + Resources(right));
 }
 
 
@@ -2065,6 +2130,11 @@ TEST(ReservedResourcesTest, AdditionDynamicallyReservedWithoutLabels)
   Resources expected = createReservedResource("cpus", "12", reservation);
 
   EXPECT_EQ(expected, left + right);
+
+  // Test operator+ with rvalue references.
+  EXPECT_EQ(expected, left + Resources(right));
+  EXPECT_EQ(expected, Resources(left) + right);
+  EXPECT_EQ(expected, Resources(left) + Resources(right));
 }
 
 
@@ -2081,6 +2151,11 @@ TEST(ReservedResourcesTest, AdditionDynamicallyReservedWithSameLabels)
   Resources expected = createReservedResource("cpus", "12", reservation);
 
   EXPECT_EQ(expected, left + right);
+
+  // Test operator+ with rvalue references.
+  EXPECT_EQ(expected, left + Resources(right));
+  EXPECT_EQ(expected, Resources(left) + right);
+  EXPECT_EQ(expected, Resources(left) + Resources(right));
 }
 
 
@@ -2104,6 +2179,15 @@ TEST(ReservedResourcesTest, AdditionDynamicallyReservedWithDistinctLabels)
   EXPECT_EQ(2u, sum.size());
   EXPECT_FALSE(sum == r1 + r1);
   EXPECT_FALSE(sum == r2 + r2);
+
+  // Test operator+ with rvalue references.
+  Resources sum1 = Resources(r1) + r2;
+  Resources sum2 = r1 + Resources(r2);
+  Resources sum3 = Resources(r1) + Resources(r2);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
 }
 
 
@@ -2402,6 +2486,15 @@ TEST(DiskResourcesTest, Addition)
   EXPECT_TRUE(sum.contains(r5));
   EXPECT_FALSE(sum.contains(r3));
   EXPECT_FALSE(sum.contains(r6));
+
+  // Test operator+ with rvalue references.
+  Resources sum1 = Resources(r4) + r5;
+  Resources sum2 = r4 + Resources(r5);
+  Resources sum3 = Resources(r4) + Resources(r5);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
 }
 
 
@@ -2435,7 +2528,17 @@ TEST(DiskResourcesTest, DiskSourceAddition)
   EXPECT_FALSE(r8.contains(r5));
   EXPECT_TRUE(r8.contains(r8));
 
-  EXPECT_NE(r4, r1 + r5);
+  Resources sum = r1 + r5;
+  EXPECT_NE(r4, sum);
+
+  // Test operator+ with rvalue references.
+  Resources sum1 = Resources(r1) + r5;
+  Resources sum2 = r1 + Resources(r5);
+  Resources sum3 = Resources(r1) + Resources(r5);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
 }
 
 
@@ -2869,6 +2972,15 @@ TEST(RevocableResourceTest, Addition)
   EXPECT_TRUE(sum.contains(r5));
   EXPECT_FALSE(sum.contains(r3));
   EXPECT_FALSE(sum.contains(r6));
+
+  // Test operator+ with rvalue references.
+  Resources sum1 = Resources(r4) + r5;
+  Resources sum2 = r4 + Resources(r5);
+  Resources sum3 = Resources(r4) + Resources(r5);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
 }
 
 
@@ -3339,6 +3451,15 @@ TEST(SharedResourcesTest, ScalarAdditionShared)
   EXPECT_EQ(50, sum.get<Value::Scalar>("disk")->value());
   EXPECT_EQ(2u, sum.count(disk));
 
+  // Test operator+ with rvalue references.
+  Resources sum1 = Resources(r1) + r2;
+  Resources sum2 = r1 + Resources(r2);
+  Resources sum3 = Resources(r1) + Resources(r2);
+
+  EXPECT_EQ(sum, sum1);
+  EXPECT_EQ(sum, sum2);
+  EXPECT_EQ(sum, sum3);
+
   // Verify operator+= on Resources is the same as operator+.
   Resources r = r1;
   r += r2;
@@ -3535,7 +3656,7 @@ TEST(AllocatedResourcesTest, Addition)
   cpus2.allocate("role2");
 
   EXPECT_EQ(2u, (cpus1 + cpus2).size());
-  EXPECT_SOME_EQ(2.0, (cpus1 + cpus2).cpus());
+  EXPECT_SOME_EQ(2.0, (cpus1 + Resources(cpus2)).cpus());
 }
 
 


[mesos] 03/03: Added ref-qualified addition operations to `Resources`.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 8132c64502717e10277297f4958f5f78a7b96093
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Mon Aug 6 19:30:55 2018 -0700

    Added ref-qualified addition operations to `Resources`.
    
    This patch futher adds move support for `Resources`
    addition operations when the lhs is an rvalue reference.
    
    Review: https://reviews.apache.org/r/68248/
---
 include/mesos/resources.hpp    | 17 ++++++++++-------
 include/mesos/v1/resources.hpp | 17 ++++++++++-------
 src/common/resources.cpp       | 40 ++++++++++++++++++++++++++++++++++++----
 src/v1/resources.cpp           | 40 ++++++++++++++++++++++++++++++++++++----
 4 files changed, 92 insertions(+), 22 deletions(-)

diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index dc0a562..6d81d0e 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -618,17 +618,20 @@ public:
   // doing subtraction), the semantics is as though the second operand
   // was actually just an empty resource (as though you didn't do the
   // operation at all).
-  //
-  // TODO(mzhu): Add overloading for addition operations where lhs is (also)
-  // an rvalue reference.
-  Resources operator+(const Resource& that) const;
-  Resources operator+(Resource&& that) const;
+  Resources operator+(const Resource& that) const &;
+  Resources operator+(const Resource& that) &&;
+
+  Resources operator+(Resource&& that) const &;
+  Resources operator+(Resource&& that) &&;
 
   Resources& operator+=(const Resource& that);
   Resources& operator+=(Resource&& that);
 
-  Resources operator+(const Resources& that) const;
-  Resources operator+(Resources&& that) const;
+  Resources operator+(const Resources& that) const &;
+  Resources operator+(const Resources& that) &&;
+
+  Resources operator+(Resources&& that) const &;
+  Resources operator+(Resources&& that) &&;
 
   Resources& operator+=(const Resources& that);
   Resources& operator+=(Resources&& that);
diff --git a/include/mesos/v1/resources.hpp b/include/mesos/v1/resources.hpp
index 2d50123..f34f38f 100644
--- a/include/mesos/v1/resources.hpp
+++ b/include/mesos/v1/resources.hpp
@@ -612,17 +612,20 @@ public:
   // doing subtraction), the semantics is as though the second operand
   // was actually just an empty resource (as though you didn't do the
   // operation at all).
-  //
-  // TODO(mzhu): Add overloading for addition operations where lhs is (also)
-  // an rvalue reference.
-  Resources operator+(const Resource& that) const;
-  Resources operator+(Resource&& that) const;
+  Resources operator+(const Resource& that) const &;
+  Resources operator+(const Resource& that) &&;
+
+  Resources operator+(Resource&& that) const &;
+  Resources operator+(Resource&& that) &&;
 
   Resources& operator+=(const Resource& that);
   Resources& operator+=(Resource&& that);
 
-  Resources operator+(const Resources& that) const;
-  Resources operator+(Resources&& that) const;
+  Resources operator+(const Resources& that) const &;
+  Resources operator+(const Resources& that) &&;
+
+  Resources operator+(Resources&& that) const &;
+  Resources operator+(Resources&& that) &&;
 
   Resources& operator+=(const Resources& that);
   Resources& operator+=(Resources&& that);
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index 599bda2..cef2acd 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -2019,7 +2019,7 @@ Resources Resources::operator+(Resource_&& that) const
 }
 
 
-Resources Resources::operator+(const Resource& that) const
+Resources Resources::operator+(const Resource& that) const &
 {
   Resources result = *this;
   result += that;
@@ -2027,7 +2027,15 @@ Resources Resources::operator+(const Resource& that) const
 }
 
 
-Resources Resources::operator+(Resource&& that) const
+Resources Resources::operator+(const Resource& that) &&
+{
+  Resources result = std::move(*this);
+  result += that;
+  return result;
+}
+
+
+Resources Resources::operator+(Resource&& that) const &
 {
   Resources result = *this;
   result += std::move(that);
@@ -2035,7 +2043,15 @@ Resources Resources::operator+(Resource&& that) const
 }
 
 
-Resources Resources::operator+(const Resources& that) const
+Resources Resources::operator+(Resource&& that) &&
+{
+  Resources result = std::move(*this);
+  result += std::move(that);
+  return result;
+}
+
+
+Resources Resources::operator+(const Resources& that) const &
 {
   Resources result = *this;
   result += that;
@@ -2043,7 +2059,15 @@ Resources Resources::operator+(const Resources& that) const
 }
 
 
-Resources Resources::operator+(Resources&& that) const
+Resources Resources::operator+(const Resources& that) &&
+{
+  Resources result = std::move(*this);
+  result += that;
+  return result;
+}
+
+
+Resources Resources::operator+(Resources&& that) const &
 {
   Resources result = std::move(that);
   result += *this;
@@ -2051,6 +2075,14 @@ Resources Resources::operator+(Resources&& that) const
 }
 
 
+Resources Resources::operator+(Resources&& that) &&
+{
+  Resources result = std::move(*this);
+  result += std::move(that);
+  return result;
+}
+
+
 void Resources::add(const Resource_& that)
 {
   if (that.isEmpty()) {
diff --git a/src/v1/resources.cpp b/src/v1/resources.cpp
index be4a0cc..aa775bd 100644
--- a/src/v1/resources.cpp
+++ b/src/v1/resources.cpp
@@ -2026,7 +2026,7 @@ Resources Resources::operator+(Resource_&& that) const
 }
 
 
-Resources Resources::operator+(const Resource& that) const
+Resources Resources::operator+(const Resource& that) const &
 {
   Resources result = *this;
   result += that;
@@ -2034,7 +2034,15 @@ Resources Resources::operator+(const Resource& that) const
 }
 
 
-Resources Resources::operator+(Resource&& that) const
+Resources Resources::operator+(const Resource& that) &&
+{
+  Resources result = std::move(*this);
+  result += that;
+  return result;
+}
+
+
+Resources Resources::operator+(Resource&& that) const &
 {
   Resources result = *this;
   result += std::move(that);
@@ -2042,7 +2050,15 @@ Resources Resources::operator+(Resource&& that) const
 }
 
 
-Resources Resources::operator+(const Resources& that) const
+Resources Resources::operator+(Resource&& that) &&
+{
+  Resources result = std::move(*this);
+  result += std::move(that);
+  return result;
+}
+
+
+Resources Resources::operator+(const Resources& that) const &
 {
   Resources result = *this;
   result += that;
@@ -2050,7 +2066,15 @@ Resources Resources::operator+(const Resources& that) const
 }
 
 
-Resources Resources::operator+(Resources&& that) const
+Resources Resources::operator+(const Resources& that) &&
+{
+  Resources result = std::move(*this);
+  result += that;
+  return result;
+}
+
+
+Resources Resources::operator+(Resources&& that) const &
 {
   Resources result = std::move(that);
   result += *this;
@@ -2058,6 +2082,14 @@ Resources Resources::operator+(Resources&& that) const
 }
 
 
+Resources Resources::operator+(Resources&& that) &&
+{
+  Resources result = std::move(*this);
+  result += std::move(that);
+  return result;
+}
+
+
 void Resources::add(const Resource_& that)
 {
   if (that.isEmpty()) {


[mesos] 01/03: Added move support for `Resources`.

Posted by bm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 5cde1e24e655d107d92fde2eda487883972c2466
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Mon Aug 6 19:04:05 2018 -0700

    Added move support for `Resources`.
    
    Review: https://reviews.apache.org/r/68197/
---
 include/mesos/resources.hpp    |  30 +++++++++++-
 include/mesos/v1/resources.hpp |  30 +++++++++++-
 src/common/resources.cpp       | 101 +++++++++++++++++++++++++++++++++++++++++
 src/v1/resources.cpp           | 101 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 258 insertions(+), 4 deletions(-)

diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index 21aaf0d..dc0a562 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -389,14 +389,18 @@ public:
 
   // TODO(jieyu): Consider using C++11 initializer list.
   /*implicit*/ Resources(const Resource& resource);
+  /*implicit*/ Resources(Resource&& resource);
 
   /*implicit*/
   Resources(const std::vector<Resource>& _resources);
+  Resources(std::vector<Resource>&& _resources);
 
   /*implicit*/
   Resources(const google::protobuf::RepeatedPtrField<Resource>& _resources);
+  Resources(google::protobuf::RepeatedPtrField<Resource>&& _resources);
 
-  Resources(const Resources& that) : resources(that.resources) {}
+  Resources(const Resources& that) = default;
+  Resources(Resources&& that) = default;
 
   Resources& operator=(const Resources& that)
   {
@@ -406,6 +410,14 @@ public:
     return *this;
   }
 
+  Resources& operator=(Resources&& that)
+  {
+    if (this != &that) {
+      resources = std::move(that.resources);
+    }
+    return *this;
+  }
+
   bool empty() const { return resources.size() == 0; }
 
   size_t size() const { return resources.size(); }
@@ -606,10 +618,20 @@ public:
   // doing subtraction), the semantics is as though the second operand
   // was actually just an empty resource (as though you didn't do the
   // operation at all).
+  //
+  // TODO(mzhu): Add overloading for addition operations where lhs is (also)
+  // an rvalue reference.
   Resources operator+(const Resource& that) const;
-  Resources operator+(const Resources& that) const;
+  Resources operator+(Resource&& that) const;
+
   Resources& operator+=(const Resource& that);
+  Resources& operator+=(Resource&& that);
+
+  Resources operator+(const Resources& that) const;
+  Resources operator+(Resources&& that) const;
+
   Resources& operator+=(const Resources& that);
+  Resources& operator+=(Resources&& that);
 
   Resources operator-(const Resource& that) const;
   Resources operator-(const Resources& that) const;
@@ -640,11 +662,15 @@ private:
   // NOTE: `Resource` objects are implicitly converted to `Resource_`
   // objects, so here the API can also accept a `Resource` object.
   void add(const Resource_& r);
+  void add(Resource_&& r);
   void subtract(const Resource_& r);
 
   Resources operator+(const Resource_& that) const;
   Resources& operator+=(const Resource_& that);
 
+  Resources operator+(Resource_&& that) const;
+  Resources& operator+=(Resource_&& that);
+
   Resources operator-(const Resource_& that) const;
   Resources& operator-=(const Resource_& that);
 
diff --git a/include/mesos/v1/resources.hpp b/include/mesos/v1/resources.hpp
index 2f9c704..2d50123 100644
--- a/include/mesos/v1/resources.hpp
+++ b/include/mesos/v1/resources.hpp
@@ -388,14 +388,18 @@ public:
 
   // TODO(jieyu): Consider using C++11 initializer list.
   /*implicit*/ Resources(const Resource& resource);
+  /*implicit*/ Resources(Resource&& resource);
 
   /*implicit*/
   Resources(const std::vector<Resource>& _resources);
+  Resources(std::vector<Resource>&& _resources);
 
   /*implicit*/
   Resources(const google::protobuf::RepeatedPtrField<Resource>& _resources);
+  Resources(google::protobuf::RepeatedPtrField<Resource>&& _resources);
 
-  Resources(const Resources& that) : resources(that.resources) {}
+  Resources(const Resources& that) = default;
+  Resources(Resources&& that) = default;
 
   Resources& operator=(const Resources& that)
   {
@@ -405,6 +409,14 @@ public:
     return *this;
   }
 
+  Resources& operator=(Resources&& that)
+  {
+    if (this != &that) {
+      resources = std::move(that.resources);
+    }
+    return *this;
+  }
+
   bool empty() const { return resources.size() == 0; }
 
   size_t size() const { return resources.size(); }
@@ -600,10 +612,20 @@ public:
   // doing subtraction), the semantics is as though the second operand
   // was actually just an empty resource (as though you didn't do the
   // operation at all).
+  //
+  // TODO(mzhu): Add overloading for addition operations where lhs is (also)
+  // an rvalue reference.
   Resources operator+(const Resource& that) const;
-  Resources operator+(const Resources& that) const;
+  Resources operator+(Resource&& that) const;
+
   Resources& operator+=(const Resource& that);
+  Resources& operator+=(Resource&& that);
+
+  Resources operator+(const Resources& that) const;
+  Resources operator+(Resources&& that) const;
+
   Resources& operator+=(const Resources& that);
+  Resources& operator+=(Resources&& that);
 
   Resources operator-(const Resource& that) const;
   Resources operator-(const Resources& that) const;
@@ -634,11 +656,15 @@ private:
   // NOTE: `Resource` objects are implicitly converted to `Resource_`
   // objects, so here the API can also accept a `Resource` object.
   void add(const Resource_& r);
+  void add(Resource_&& r);
   void subtract(const Resource_& r);
 
   Resources operator+(const Resource_& that) const;
   Resources& operator+=(const Resource_& that);
 
+  Resources operator+(Resource_&& that) const;
+  Resources& operator+=(Resource_&& that);
+
   Resources operator-(const Resource_& that) const;
   Resources& operator-=(const Resource_& that);
 
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index 253b8bc..599bda2 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -1417,6 +1417,13 @@ Resources::Resources(const Resource& resource)
 }
 
 
+Resources::Resources(Resource&& resource)
+{
+  // NOTE: Invalid and zero Resource object will be ignored.
+  *this += std::move(resource);
+}
+
+
 Resources::Resources(const vector<Resource>& _resources)
 {
   resources.reserve(_resources.size());
@@ -1427,6 +1434,16 @@ Resources::Resources(const vector<Resource>& _resources)
 }
 
 
+Resources::Resources(vector<Resource>&& _resources)
+{
+  resources.reserve(_resources.size());
+  foreach (Resource& resource, _resources) {
+    // NOTE: Invalid and zero Resource objects will be ignored.
+    *this += std::move(resource);
+  }
+}
+
+
 Resources::Resources(const RepeatedPtrField<Resource>& _resources)
 {
   resources.reserve(_resources.size());
@@ -1437,6 +1454,16 @@ Resources::Resources(const RepeatedPtrField<Resource>& _resources)
 }
 
 
+Resources::Resources(RepeatedPtrField<Resource>&& _resources)
+{
+  resources.reserve(_resources.size());
+  foreach (Resource& resource, _resources) {
+    // NOTE: Invalid and zero Resource objects will be ignored.
+    *this += std::move(resource);
+  }
+}
+
+
 bool Resources::contains(const Resources& that) const
 {
   Resources remaining = *this;
@@ -1984,6 +2011,14 @@ Resources Resources::operator+(const Resource_& that) const
 }
 
 
+Resources Resources::operator+(Resource_&& that) const
+{
+  Resources result = *this;
+  result += std::move(that);
+  return result;
+}
+
+
 Resources Resources::operator+(const Resource& that) const
 {
   Resources result = *this;
@@ -1992,6 +2027,14 @@ Resources Resources::operator+(const Resource& that) const
 }
 
 
+Resources Resources::operator+(Resource&& that) const
+{
+  Resources result = *this;
+  result += std::move(that);
+  return result;
+}
+
+
 Resources Resources::operator+(const Resources& that) const
 {
   Resources result = *this;
@@ -2000,6 +2043,14 @@ Resources Resources::operator+(const Resources& that) const
 }
 
 
+Resources Resources::operator+(Resources&& that) const
+{
+  Resources result = std::move(that);
+  result += *this;
+  return result;
+}
+
+
 void Resources::add(const Resource_& that)
 {
   if (that.isEmpty()) {
@@ -2022,6 +2073,28 @@ void Resources::add(const Resource_& that)
 }
 
 
+void Resources::add(Resource_&& that)
+{
+  if (that.isEmpty()) {
+    return;
+  }
+
+  bool found = false;
+  foreach (Resource_& resource_, resources) {
+    if (internal::addable(resource_.resource, that)) {
+      resource_ += that;
+      found = true;
+      break;
+    }
+  }
+
+  // Cannot be combined with any existing Resource object.
+  if (!found) {
+    resources.push_back(std::move(that));
+  }
+}
+
+
 Resources& Resources::operator+=(const Resource_& that)
 {
   if (that.validate().isNone()) {
@@ -2032,6 +2105,16 @@ Resources& Resources::operator+=(const Resource_& that)
 }
 
 
+Resources& Resources::operator+=(Resource_&& that)
+{
+  if (that.validate().isNone()) {
+    add(std::move(that));
+  }
+
+  return *this;
+}
+
+
 Resources& Resources::operator+=(const Resource& that)
 {
   *this += Resource_(that);
@@ -2040,6 +2123,14 @@ Resources& Resources::operator+=(const Resource& that)
 }
 
 
+Resources& Resources::operator+=(Resource&& that)
+{
+  *this += Resource_(std::move(that));
+
+  return *this;
+}
+
+
 Resources& Resources::operator+=(const Resources& that)
 {
   foreach (const Resource_& resource_, that) {
@@ -2050,6 +2141,16 @@ Resources& Resources::operator+=(const Resources& that)
 }
 
 
+Resources& Resources::operator+=(Resources&& that)
+{
+  foreach (Resource_& resource_, that.resources) {
+    add(std::move(resource_));
+  }
+
+  return *this;
+}
+
+
 Resources Resources::operator-(const Resource_& that) const
 {
   Resources result = *this;
diff --git a/src/v1/resources.cpp b/src/v1/resources.cpp
index ab8fc3e..be4a0cc 100644
--- a/src/v1/resources.cpp
+++ b/src/v1/resources.cpp
@@ -1437,6 +1437,13 @@ Resources::Resources(const Resource& resource)
 }
 
 
+Resources::Resources(Resource&& resource)
+{
+  // NOTE: Invalid and zero Resource object will be ignored.
+  *this += std::move(resource);
+}
+
+
 Resources::Resources(const vector<Resource>& _resources)
 {
   foreach (const Resource& resource, _resources) {
@@ -1446,6 +1453,16 @@ Resources::Resources(const vector<Resource>& _resources)
 }
 
 
+Resources::Resources(vector<Resource>&& _resources)
+{
+  resources.reserve(_resources.size());
+  foreach (Resource& resource, _resources) {
+    // NOTE: Invalid and zero Resource objects will be ignored.
+    *this += std::move(resource);
+  }
+}
+
+
 Resources::Resources(const RepeatedPtrField<Resource>& _resources)
 {
   foreach (const Resource& resource, _resources) {
@@ -1455,6 +1472,16 @@ Resources::Resources(const RepeatedPtrField<Resource>& _resources)
 }
 
 
+Resources::Resources(RepeatedPtrField<Resource>&& _resources)
+{
+  resources.reserve(_resources.size());
+  foreach (Resource& resource, _resources) {
+    // NOTE: Invalid and zero Resource objects will be ignored.
+    *this += std::move(resource);
+  }
+}
+
+
 bool Resources::contains(const Resources& that) const
 {
   Resources remaining = *this;
@@ -1991,6 +2018,14 @@ Resources Resources::operator+(const Resource_& that) const
 }
 
 
+Resources Resources::operator+(Resource_&& that) const
+{
+  Resources result = *this;
+  result += std::move(that);
+  return result;
+}
+
+
 Resources Resources::operator+(const Resource& that) const
 {
   Resources result = *this;
@@ -1999,6 +2034,14 @@ Resources Resources::operator+(const Resource& that) const
 }
 
 
+Resources Resources::operator+(Resource&& that) const
+{
+  Resources result = *this;
+  result += std::move(that);
+  return result;
+}
+
+
 Resources Resources::operator+(const Resources& that) const
 {
   Resources result = *this;
@@ -2007,6 +2050,14 @@ Resources Resources::operator+(const Resources& that) const
 }
 
 
+Resources Resources::operator+(Resources&& that) const
+{
+  Resources result = std::move(that);
+  result += *this;
+  return result;
+}
+
+
 void Resources::add(const Resource_& that)
 {
   if (that.isEmpty()) {
@@ -2029,6 +2080,28 @@ void Resources::add(const Resource_& that)
 }
 
 
+void Resources::add(Resource_&& that)
+{
+  if (that.isEmpty()) {
+    return;
+  }
+
+  bool found = false;
+  foreach (Resource_& resource_, resources) {
+    if (internal::addable(resource_.resource, that)) {
+      resource_ += that;
+      found = true;
+      break;
+    }
+  }
+
+  // Cannot be combined with any existing Resource object.
+  if (!found) {
+    resources.push_back(std::move(that));
+  }
+}
+
+
 Resources& Resources::operator+=(const Resource_& that)
 {
   if (that.validate().isNone()) {
@@ -2039,6 +2112,16 @@ Resources& Resources::operator+=(const Resource_& that)
 }
 
 
+Resources& Resources::operator+=(Resource_&& that)
+{
+  if (that.validate().isNone()) {
+    add(std::move(that));
+  }
+
+  return *this;
+}
+
+
 Resources& Resources::operator+=(const Resource& that)
 {
   *this += Resource_(that);
@@ -2047,6 +2130,14 @@ Resources& Resources::operator+=(const Resource& that)
 }
 
 
+Resources& Resources::operator+=(Resource&& that)
+{
+  *this += Resource_(std::move(that));
+
+  return *this;
+}
+
+
 Resources& Resources::operator+=(const Resources& that)
 {
   foreach (const Resource_& resource_, that) {
@@ -2057,6 +2148,16 @@ Resources& Resources::operator+=(const Resources& that)
 }
 
 
+Resources& Resources::operator+=(Resources&& that)
+{
+  foreach (Resource_& resource_, that.resources) {
+    add(std::move(resource_));
+  }
+
+  return *this;
+}
+
+
 Resources Resources::operator-(const Resource_& that) const
 {
   Resources result = *this;