Move constructors should be noexcept
authorNicholas Ormrod <njormrod@fb.com>
Thu, 30 Oct 2014 17:18:27 +0000 (10:18 -0700)
committerPavlo Kushnir <pavlo@fb.com>
Sat, 8 Nov 2014 02:09:45 +0000 (18:09 -0800)
Summary:
The compiler is able to make some nice optimizations when it
knows that move constructors are noexcept. (In particular, it helps a
lot inside of std::vector if you don't need to worry about the
possibility of exception during reallocation.) Some move constructors in
folly are obviously moveable: change them.

Test Plan: unit tests

Reviewed By: delong.j@fb.com

Subscribers: trunkagent, sdwilsh, njormrod, folly-diffs@

FB internal diff: D1644296

Tasks: 5486739

Signature: t1:1644296:1414618605:d9a0db5193c82650b96e9c62b019d5da218b15c5

12 files changed:
folly/Benchmark.h
folly/File.cpp
folly/File.h
folly/MemoryMapping.cpp
folly/MemoryMapping.h
folly/ScopeGuard.h
folly/ThreadLocal.h
folly/io/IOBufQueue.cpp
folly/io/IOBufQueue.h
folly/test/ApplyTupleTest.cpp
folly/test/LazyTest.cpp
folly/test/small_vector_test.cpp

index 4fd28b4862ef365c5006d177970cf64623654182..3460a79d3f656a00ca4811e24cfc028fc49fc2ca 100644 (file)
@@ -116,7 +116,7 @@ struct BenchmarkSuspender {
   }
 
   BenchmarkSuspender(const BenchmarkSuspender &) = delete;
-  BenchmarkSuspender(BenchmarkSuspender && rhs) {
+  BenchmarkSuspender(BenchmarkSuspender && rhs) noexcept {
     start = rhs.start;
     rhs.start.tv_nsec = rhs.start.tv_sec = 0;
   }
index 12c4902f05cb553587d285b7118ca43f80f49aa9..2f239c2ace035c7a1c8f8845b1f68debbcb7a211 100644 (file)
@@ -52,7 +52,7 @@ File::File(const char* name, int flags, mode_t mode)
   ownsFd_ = true;
 }
 
-File::File(File&& other)
+File::File(File&& other) noexcept
   : fd_(other.fd_)
   , ownsFd_(other.ownsFd_) {
   other.release();
@@ -80,7 +80,7 @@ File::~File() {
   return File(fd, true);
 }
 
-int File::release() {
+int File::release() noexcept {
   int released = fd_;
   fd_ = -1;
   ownsFd_ = false;
index 2183609b97ac7b67831762de7aaeb0197e7b3de6..4a25e1c6938f82ad6dba340450116a4ed8e71550 100644 (file)
@@ -87,7 +87,7 @@ class File {
    * Returns and releases the file descriptor; no longer owned by this File.
    * Returns -1 if the File object didn't wrap a file.
    */
-  int release();
+  int release() noexcept;
 
   /**
    * Swap this File with another.
@@ -95,7 +95,7 @@ class File {
   void swap(File& other);
 
   // movable
-  File(File&&);
+  File(File&&) noexcept;
   File& operator=(File&&);
 
   // FLOCK (INTERPROCESS) LOCKS
index 4e78b560d9228d1c3f9eb608b86ffec9863d9b11..855d4af6708bb3952c6fdb4aab2a25bc3f815795 100644 (file)
@@ -38,7 +38,7 @@ DEFINE_int64(mlock_chunk_size, 1 << 20,  // 1MB
 
 namespace folly {
 
-MemoryMapping::MemoryMapping(MemoryMapping&& other) {
+MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept {
   swap(other);
 }
 
@@ -298,7 +298,7 @@ MemoryMapping& MemoryMapping::operator=(MemoryMapping other) {
   return *this;
 }
 
-void MemoryMapping::swap(MemoryMapping& other) {
+void MemoryMapping::swap(MemoryMapping& other) noexcept {
   using std::swap;
   swap(this->file_, other.file_);
   swap(this->mapStart_, other.mapStart_);
@@ -308,7 +308,7 @@ void MemoryMapping::swap(MemoryMapping& other) {
   swap(this->data_, other.data_);
 }
 
-void swap(MemoryMapping& a, MemoryMapping& b) { a.swap(b); }
+void swap(MemoryMapping& a, MemoryMapping& b) noexcept { a.swap(b); }
 
 void alignedForwardMemcpy(void* dst, const void* src, size_t size) {
   assert(reinterpret_cast<uintptr_t>(src) % alignof(unsigned long) == 0);
index 19ca243ed9452c5583b5461b230a0d2742cd7cd4..d404a7853c04cd51fe0af49633bbc170ac592de5 100644 (file)
@@ -127,13 +127,13 @@ class MemoryMapping : boost::noncopyable {
                          off_t length=-1,
                          Options options=Options());
 
-  MemoryMapping(MemoryMapping&&);
+  MemoryMapping(MemoryMapping&&) noexcept;
 
   ~MemoryMapping();
 
   MemoryMapping& operator=(MemoryMapping);
 
-  void swap(MemoryMapping& other);
+  void swap(MemoryMapping& other) noexcept;
 
   /**
    * Lock the pages in memory
@@ -229,7 +229,7 @@ class MemoryMapping : boost::noncopyable {
   MutableByteRange data_;
 };
 
-void swap(MemoryMapping&, MemoryMapping&);
+void swap(MemoryMapping&, MemoryMapping&) noexcept;
 
 /**
  * A special case of memcpy() that always copies memory forwards.
index 9a65811d9001f146f6478d17fcce4d354da2d92a..348a5933ddf4a0495cc74a74868bdad5d07f6bbb 100644 (file)
@@ -77,7 +77,7 @@ class ScopeGuardImplBase {
   ScopeGuardImplBase()
     : dismissed_(false) {}
 
-  ScopeGuardImplBase(ScopeGuardImplBase&& other)
+  ScopeGuardImplBase(ScopeGuardImplBase&& other) noexcept
     : dismissed_(other.dismissed_) {
     other.dismissed_ = true;
   }
index ad111168ee55df75ff8e19e30fafe7fd267467fd..78a26979412bb8ec92d6a2c83f8ca757299ddc18 100644 (file)
@@ -137,7 +137,7 @@ class ThreadLocalPtr {
  public:
   ThreadLocalPtr() : id_(threadlocal_detail::StaticMeta<Tag>::create()) { }
 
-  ThreadLocalPtr(ThreadLocalPtr&& other) : id_(other.id_) {
+  ThreadLocalPtr(ThreadLocalPtr&& other) noexcept : id_(other.id_) {
     other.id_ = 0;
   }
 
index 8f40d07919b96cf22b1829e73ebef7b14fedbb49..23e721fa7f99d0f77745d5ff58481936e610955e 100644 (file)
@@ -71,7 +71,7 @@ IOBufQueue::IOBufQueue(const Options& options)
     chainLength_(0) {
 }
 
-IOBufQueue::IOBufQueue(IOBufQueue&& other)
+IOBufQueue::IOBufQueue(IOBufQueue&& other) noexcept
   : options_(other.options_),
     chainLength_(other.chainLength_),
     head_(std::move(other.head_)) {
index 59fdc940057626f483e94df7146ff23f043b9412..cbc11376a993e731533c7c13e969963141079dbc 100644 (file)
@@ -262,7 +262,7 @@ class IOBufQueue {
   void clear();
 
   /** Movable */
-  IOBufQueue(IOBufQueue&&);
+  IOBufQueue(IOBufQueue&&) noexcept;
   IOBufQueue& operator=(IOBufQueue&&);
 
  private:
index bf82a9cd1fff09db1bfaba33996eacacc395882c..be48939f24463f6b6dda35b4f767faa54a64803e 100644 (file)
@@ -73,7 +73,7 @@ std::function<void (int, int, double)> makeFunc() {
 }
 
 struct GuardObjBase {
-  GuardObjBase(GuardObjBase&&) {}
+  GuardObjBase(GuardObjBase&&) noexcept {}
   GuardObjBase() {}
   GuardObjBase(GuardObjBase const&) = delete;
   GuardObjBase& operator=(GuardObjBase const&) = delete;
@@ -115,7 +115,7 @@ guard(F&& f, Args&&... args) {
 
 struct Mover {
   Mover() {}
-  Mover(Mover&&) {}
+  Mover(Mover&&) noexcept {}
   Mover(const Mover&) = delete;
   Mover& operator=(const Mover&) = delete;
 };
index d2947de2a412e3de3e1c4391616ac21ffa5125f0..6d3eed06b48fd3a3376cedec7172ffdf7d82ed47 100644 (file)
@@ -72,7 +72,7 @@ TEST(Lazy, Map) {
 struct CopyCount {
   CopyCount() {}
   CopyCount(const CopyCount&) { ++count; }
-  CopyCount(CopyCount&&)      {}
+  CopyCount(CopyCount&&) noexcept {}
 
   static int count;
 
index 89362d38cffcba09a34b935f359c8b72148c75e5..f80a4605dfc67b4156d3fdb9485314b4fe78a8bd 100644 (file)
@@ -136,7 +136,7 @@ struct NoncopyableCounter {
   ~NoncopyableCounter() {
     --alive;
   }
-  NoncopyableCounter(NoncopyableCounter&&) { ++alive; }
+  NoncopyableCounter(NoncopyableCounter&&) noexcept { ++alive; }
   NoncopyableCounter(NoncopyableCounter const&) = delete;
   NoncopyableCounter& operator=(NoncopyableCounter const&) const = delete;
   NoncopyableCounter& operator=(NoncopyableCounter&&) { return *this; }