From dd7a7f012424ec8505830710ac0dd0183203c189 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Tue, 22 Sep 2015 15:06:59 -0700 Subject: Add nonstd::unique_ptr move assigment operator. std::unique_ptr supports move assignment as in: ptr2 = std::move(ptr1); R=jyasskin@chromium.org Review URL: https://codereview.chromium.org/1358163002 . --- pdfium.gyp | 1 + third_party/base/nonstd_unique_ptr.h | 14 ++++ third_party/base/nonstd_unique_ptr_unittest.cpp | 87 +++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 third_party/base/nonstd_unique_ptr_unittest.cpp diff --git a/pdfium.gyp b/pdfium.gyp index 12314d7e93..d62cd56e2f 100644 --- a/pdfium.gyp +++ b/pdfium.gyp @@ -723,6 +723,7 @@ 'core/src/fxcrt/fx_system_unittest.cpp', 'testing/fx_string_testhelpers.h', 'testing/fx_string_testhelpers.cpp', + 'third_party/base/nonstd_unique_ptr_unittest.cpp', ], }, { diff --git a/third_party/base/nonstd_unique_ptr.h b/third_party/base/nonstd_unique_ptr.h index 1d1c43f42f..d666e1eeb2 100644 --- a/third_party/base/nonstd_unique_ptr.h +++ b/third_party/base/nonstd_unique_ptr.h @@ -176,6 +176,13 @@ class unique_ptr : public unique_ptr_base { } } + // Move assignment. + unique_ptr& operator=(unique_ptr&& that) { + if (that.ptr_ != ptr_) + reset(that.release()); + return *this; + } + private: // Forbid comparison of unique_ptr types. If C2 != C, it totally doesn't // make sense, and if C2 == C, it still doesn't make sense because you should @@ -222,6 +229,13 @@ class unique_ptr : public unique_ptr_base { } } + // Move assignment. + unique_ptr& operator=(unique_ptr&& that) { + if (that.ptr_ != ptr_) + reset(that.release()); + return *this; + } + // Support indexing since it is holding array. C& operator[] (size_t i) { return ptr_[i]; } diff --git a/third_party/base/nonstd_unique_ptr_unittest.cpp b/third_party/base/nonstd_unique_ptr_unittest.cpp new file mode 100644 index 0000000000..49cc901fe2 --- /dev/null +++ b/third_party/base/nonstd_unique_ptr_unittest.cpp @@ -0,0 +1,87 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include "testing/gtest/include/gtest/gtest.h" +#include "macros.h" +#include "nonstd_unique_ptr.h" + +using nonstd::unique_ptr; + +namespace { + +// Used to test depth subtyping. +class CtorDtorLoggerParent { + public: + virtual ~CtorDtorLoggerParent() {} + + virtual void SetPtr(int* ptr) = 0; + + virtual int SomeMeth(int x) const = 0; +}; + +class CtorDtorLogger : public CtorDtorLoggerParent { + public: + CtorDtorLogger() : ptr_(nullptr) {} + explicit CtorDtorLogger(int* ptr) { SetPtr(ptr); } + ~CtorDtorLogger() override { --*ptr_; } + + void SetPtr(int* ptr) override { + ptr_ = ptr; + ++*ptr_; + } + + int SomeMeth(int x) const override { return x; } + + private: + int* ptr_; + + // Disallow evil constructors. + CtorDtorLogger(const CtorDtorLogger&) = delete; + void operator=(const CtorDtorLogger&) = delete; +}; + +struct CountingDeleter { + explicit CountingDeleter(int* count) : count_(count) {} + inline void operator()(double* ptr) const { (*count_)++; } + int* count_; +}; + +// Do not delete this function! It's existence is to test that you can +// return a temporarily constructed version of the scoper. +unique_ptr TestReturnOfType(int* constructed) { + return unique_ptr(new CtorDtorLogger(constructed)); +} + +} // namespace + +TEST(UniquePtrTest, MoveTest) { + int constructed = 0; + int constructed4 = 0; + { + unique_ptr ptr1(new CtorDtorLogger(&constructed)); + EXPECT_EQ(1, constructed); + EXPECT_TRUE(ptr1); + + unique_ptr ptr2(nonstd::move(ptr1)); + EXPECT_EQ(1, constructed); + EXPECT_FALSE(ptr1); + EXPECT_TRUE(ptr2); + + unique_ptr ptr3; + ptr3 = nonstd::move(ptr2); + EXPECT_EQ(1, constructed); + EXPECT_FALSE(ptr2); + EXPECT_TRUE(ptr3); + + unique_ptr ptr4(new CtorDtorLogger(&constructed4)); + EXPECT_EQ(1, constructed4); + ptr4 = nonstd::move(ptr3); + EXPECT_EQ(0, constructed4); + EXPECT_FALSE(ptr3); + EXPECT_TRUE(ptr4); + } + EXPECT_EQ(0, constructed); +} -- cgit v1.2.3