diff options
author | Lei Zhang <thestig@chromium.org> | 2015-12-24 19:00:05 -0800 |
---|---|---|
committer | Lei Zhang <thestig@chromium.org> | 2015-12-24 19:00:05 -0800 |
commit | d20dfba2ae10e8aeb328328f09da79ff904110a8 (patch) | |
tree | 560bc512ddec373595a9f719996e1d13338f72da /third_party | |
parent | bab9a98b71f351cf9f4eb39138bca55e3be4ef15 (diff) | |
download | pdfium-d20dfba2ae10e8aeb328328f09da79ff904110a8.tar.xz |
Switch from nonstd::unique_ptr to std::unique_ptr.
R=thakis@chromium.org
Review URL: https://codereview.chromium.org/1547833002 .
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/BUILD.gn | 2 | ||||
-rw-r--r-- | third_party/base/nonstd_unique_ptr.h | 398 | ||||
-rw-r--r-- | third_party/base/nonstd_unique_ptr_unittest.cpp | 391 | ||||
-rw-r--r-- | third_party/base/numerics/safe_conversions_impl.h | 1 | ||||
-rw-r--r-- | third_party/base/numerics/safe_math.h | 6 | ||||
-rw-r--r-- | third_party/base/numerics/safe_math_impl.h | 111 | ||||
-rw-r--r-- | third_party/base/template_util.h | 79 | ||||
-rw-r--r-- | third_party/third_party.gyp | 2 |
8 files changed, 60 insertions, 930 deletions
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn index 214614c8b6..a688ba3a5e 100644 --- a/third_party/BUILD.gn +++ b/third_party/BUILD.gn @@ -303,12 +303,10 @@ source_set("pdfium_base") { sources = [ "base/logging.h", "base/macros.h", - "base/nonstd_unique_ptr.h", "base/numerics/safe_conversions.h", "base/numerics/safe_conversions_impl.h", "base/numerics/safe_math.h", "base/numerics/safe_math_impl.h", "base/stl_util.h", - "base/template_util.h", ] } diff --git a/third_party/base/nonstd_unique_ptr.h b/third_party/base/nonstd_unique_ptr.h deleted file mode 100644 index f056e50397..0000000000 --- a/third_party/base/nonstd_unique_ptr.h +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright 2013 Google Inc. All Rights Reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// This is a copy of breakpad's standalone scoped_ptr, which has been -// renamed to nonstd::unique_ptr, and from which more complicated classes -// have been removed. The reset() method has also been tweaked to more -// closely match c++11, and an implicit conversion to bool has been added. - -// Scopers help you manage ownership of a pointer, helping you easily manage the -// a pointer within a scope, and automatically destroying the pointer at the -// end of a scope. -// -// A unique_ptr<T> is like a T*, except that the destructor of unique_ptr<T> -// automatically deletes the pointer it holds (if any). -// That is, unique_ptr<T> owns the T object that it points to. -// Like a T*, a unique_ptr<T> may hold either NULL or a pointer to a T object. -// Also like T*, unique_ptr<T> is thread-compatible, and once you -// dereference it, you get the thread safety guarantees of T. -// -// Example usage (unique_ptr): -// { -// unique_ptr<Foo> foo(new Foo("wee")); -// } // foo goes out of scope, releasing the pointer with it. -// -// { -// unique_ptr<Foo> foo; // No pointer managed. -// foo.reset(new Foo("wee")); // Now a pointer is managed. -// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed. -// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed. -// foo->Method(); // Foo::Method() called. -// foo.get()->Method(); // Foo::Method() called. -// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer -// // manages a pointer. -// foo.reset(new Foo("wee4")); // foo manages a pointer again. -// foo.reset(); // Foo("wee4") destroyed, foo no longer -// // manages a pointer. -// } // foo wasn't managing a pointer, so nothing was destroyed. -// -// The size of a unique_ptr is small: sizeof(unique_ptr<C>) == sizeof(C*) - -#ifndef NONSTD_UNIQUE_PTR_H_ -#define NONSTD_UNIQUE_PTR_H_ - -// This is an implementation designed to match the anticipated future C++11 -// implementation of the unique_ptr class. - -#include <assert.h> -#include <stddef.h> -#include <stdlib.h> - -#include <ostream> -#include <utility> - -#include "template_util.h" - -namespace nonstd { - -// Function object which deletes its parameter, which must be a pointer. -// If C is an array type, invokes 'delete[]' on the parameter; otherwise, -// invokes 'delete'. The default deleter for unique_ptr<T>. -template <class T> -struct DefaultDeleter { - DefaultDeleter() {} - template <typename U> - DefaultDeleter(const DefaultDeleter<U>& other) { - // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor - // if U* is implicitly convertible to T* and U is not an array type. - // - // Correct implementation should use SFINAE to disable this - // constructor. However, since there are no other 1-argument constructors, - // using a static_assert() based on is_convertible<> and requiring - // complete types is simpler and will cause compile failures for equivalent - // misuses. - // - // Note, the is_convertible<U*, T*> check also ensures that U is not an - // array. T is guaranteed to be a non-array, so any U* where U is an array - // cannot convert to T*. - enum { T_must_be_complete = sizeof(T) }; - enum { U_must_be_complete = sizeof(U) }; - static_assert((pdfium::base::is_convertible<U*, T*>::value), - "U_ptr_must_implicitly_convert_to_T_ptr"); - } - inline void operator()(T* ptr) const { - enum { type_must_be_complete = sizeof(T) }; - delete ptr; - } -}; - -// Specialization of DefaultDeleter for array types. -template <class T> -struct DefaultDeleter<T[]> { - inline void operator()(T* ptr) const { - enum { type_must_be_complete = sizeof(T) }; - delete[] ptr; - } - - private: - // Disable this operator for any U != T because it is undefined to execute - // an array delete when the static type of the array mismatches the dynamic - // type. - // - // References: - // C++98 [expr.delete]p3 - // http://cplusplus.github.com/LWG/lwg-defects.html#938 - template <typename U> - void operator()(U* array) const; -}; - -template <class T, int n> -struct DefaultDeleter<T[n]> { - // Never allow someone to declare something like unique_ptr<int[10]>. - static_assert(sizeof(T) == -1, "do_not_use_array_with_size_as_type"); -}; - -namespace internal { - -// Common implementation for both pointers to elements and pointers to -// arrays. These are differentiated below based on the need to invoke -// delete vs. delete[] as appropriate. -template <class C, class D> -class unique_ptr_base { - public: - // The element type - typedef C element_type; - - explicit unique_ptr_base(C* p) : data_(p) {} - - // Initializer for deleters that have data parameters. - unique_ptr_base(C* p, const D& d) : data_(p, d) {} - - // Move constructor. - unique_ptr_base(unique_ptr_base<C, D>&& that) - : data_(that.release(), that.get_deleter()) {} - - ~unique_ptr_base() { - enum { type_must_be_complete = sizeof(C) }; - if (data_.ptr != nullptr) { - // Not using get_deleter() saves one function call in non-optimized - // builds. - static_cast<D&>(data_)(data_.ptr); - } - } - - void reset(C* p = nullptr) { - C* old = data_.ptr; - data_.ptr = p; - if (old != nullptr) - static_cast<D&>(data_)(old); - } - - C* get() const { return data_.ptr; } - D& get_deleter() { return data_; } - const D& get_deleter() const { return data_; } - - // Comparison operators. - // These return whether two unique_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* p) const { return data_.ptr == p; } - bool operator!=(C* p) const { return data_.ptr != p; } - - // Swap two unique pointers. - void swap(unique_ptr_base& p2) { - Data tmp = data_; - data_ = p2.data_; - p2.data_ = tmp; - } - - // Release a pointer. - // The return value is the current pointer held by this object. - // If this object holds a NULL pointer, the return value is NULL. - // After this operation, this object will hold a NULL pointer, - // and will not own the object any more. - C* release() { - C* ptr = data_.ptr; - data_.ptr = nullptr; - return ptr; - } - - // Allow promotion to bool for conditional statements. - explicit operator bool() const { return data_.ptr != nullptr; } - - protected: - // Use the empty base class optimization to allow us to have a D - // member, while avoiding any space overhead for it when D is an - // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good - // discussion of this technique. - struct Data : public D { - explicit Data(C* ptr_in) : ptr(ptr_in) {} - Data(C* ptr_in, const D& other) : D(other), ptr(ptr_in) {} - C* ptr; - }; - - Data data_; -}; - -} // namespace internal - -// Implementation for ordinary pointers using delete. -template <class C, class D = DefaultDeleter<C>> -class unique_ptr : public internal::unique_ptr_base<C, D> { - public: - // Constructor. Defaults to initializing with nullptr. - unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} - - // Constructor. Takes ownership of p. - explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} - - // Constructor. Allows initialization of a stateful deleter. - unique_ptr(C* p, const D& d) : internal::unique_ptr_base<C, D>(p, d) {} - - // Constructor. Allows construction from a nullptr. - unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} - - // Move constructor. - unique_ptr(unique_ptr&& that) - : internal::unique_ptr_base<C, D>(std::move(that)) {} - - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // object, if any. - unique_ptr& operator=(decltype(nullptr)) { - this->reset(); - return *this; - } - - // Move assignment. - unique_ptr<C>& operator=(unique_ptr<C>&& that) { - this->reset(that.release()); - return *this; - } - - // Accessors to get the owned object. - // operator* and operator-> will assert() if there is no current object. - C& operator*() const { - assert(this->data_.ptr != nullptr); - return *this->data_.ptr; - } - C* operator->() const { - assert(this->data_.ptr != nullptr); - return this->data_.ptr; - } - - // Comparison operators. - // These return whether two unique_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(const C* p) const { return this->get() == p; } - bool operator!=(const C* p) const { return this->get() != p; } - - private: - // Disallow evil constructors. It doesn't make sense to make a copy of - // something that's allegedly unique. - unique_ptr(const unique_ptr&) = delete; - void operator=(const unique_ptr&) = delete; - - // Forbid comparison of unique_ptr types. If U != C, it totally - // doesn't make sense, and if U == C, it still doesn't make sense - // because you should never have the same object owned by two different - // unique_ptrs. - template <class U> - bool operator==(unique_ptr<U> const& p2) const; - template <class U> - bool operator!=(unique_ptr<U> const& p2) const; -}; - -// Specialization for arrays using delete[]. -template <class C, class D> -class unique_ptr<C[], D> : public internal::unique_ptr_base<C, D> { - public: - // Constructor. Defaults to initializing with nullptr. - unique_ptr() : internal::unique_ptr_base<C, D>(nullptr) {} - - // Constructor. Stores the given array. Note that the argument's type - // must exactly match T*. In particular: - // - it cannot be a pointer to a type derived from T, because it is - // inherently unsafe in the general case to access an array through a - // pointer whose dynamic type does not match its static type (eg., if - // T and the derived types had different sizes access would be - // incorrectly calculated). Deletion is also always undefined - // (C++98 [expr.delete]p3). If you're doing this, fix your code. - // - it cannot be const-qualified differently from T per unique_ptr spec - // (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting - // to work around this may use const_cast<const T*>(). - explicit unique_ptr(C* p) : internal::unique_ptr_base<C, D>(p) {} - - // Constructor. Allows construction from a nullptr. - unique_ptr(decltype(nullptr)) : internal::unique_ptr_base<C, D>(nullptr) {} - - // Move constructor. - unique_ptr(unique_ptr&& that) - : internal::unique_ptr_base<C, D>(std::move(that)) {} - - // operator=. Allows assignment from a nullptr. Deletes the currently owned - // array, if any. - unique_ptr& operator=(decltype(nullptr)) { - this->reset(); - return *this; - } - - // Move assignment. - unique_ptr<C>& operator=(unique_ptr<C>&& that) { - this->reset(that.release()); - return *this; - } - - // Reset. Deletes the currently owned array, if any. - // Then takes ownership of a new object, if given. - void reset(C* array = nullptr) { - static_cast<internal::unique_ptr_base<C, D>*>(this)->reset(array); - } - - // Support indexing since it is holding array. - C& operator[](size_t i) { return this->data_.ptr[i]; } - - // Comparison operators. - // These return whether two unique_ptr refer to the same object, not just to - // two different but equal objects. - bool operator==(C* array) const { return this->get() == array; } - bool operator!=(C* array) const { return this->get() != array; } - - private: - // Disable initialization from any type other than element_type*, by - // providing a constructor that matches such an initialization, but is - // private and has no definition. This is disabled because it is not safe to - // call delete[] on an array whose static type does not match its dynamic - // type. - template <typename U> - explicit unique_ptr(U* array); - explicit unique_ptr(int disallow_construction_from_null); - - // Disable reset() from any type other than element_type*, for the same - // reasons as the constructor above. - template <typename U> - void reset(U* array); - void reset(int disallow_reset_from_null); - - // Disallow evil constructors. It doesn't make sense to make a copy of - // something that's allegedly unique. - unique_ptr(const unique_ptr&) = delete; - void operator=(const unique_ptr&) = delete; - - // Forbid comparison of unique_ptr types. If U != C, it totally - // doesn't make sense, and if U == C, it still doesn't make sense - // because you should never have the same object owned by two different - // unique_ptrs. - template <class U> - bool operator==(unique_ptr<U> const& p2) const; - template <class U> - bool operator!=(unique_ptr<U> const& p2) const; -}; - -// Free functions -template <class C> -void swap(unique_ptr<C>& p1, unique_ptr<C>& p2) { - p1.swap(p2); -} - -template <class C> -bool operator==(C* p1, const unique_ptr<C>& p2) { - return p1 == p2.get(); -} - -template <class C> -bool operator!=(C* p1, const unique_ptr<C>& p2) { - return p1 != p2.get(); -} - -template <typename T> -std::ostream& operator<<(std::ostream& out, const unique_ptr<T>& p) { - return out << p.get(); -} - -} // namespace nonstd - -#endif // NONSTD_UNIQUE_PTR_H_ diff --git a/third_party/base/nonstd_unique_ptr_unittest.cpp b/third_party/base/nonstd_unique_ptr_unittest.cpp deleted file mode 100644 index 1dcfe48b02..0000000000 --- a/third_party/base/nonstd_unique_ptr_unittest.cpp +++ /dev/null @@ -1,391 +0,0 @@ -// 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 <sstream> -#include <utility> - -#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<CtorDtorLogger> TestReturnOfType(int* constructed) { - return unique_ptr<CtorDtorLogger>(new CtorDtorLogger(constructed)); -} - -} // namespace - -TEST(UniquePtrTest, MoveTest) { - int constructed = 0; - int constructed4 = 0; - { - unique_ptr<CtorDtorLogger> ptr1(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(ptr1); - - unique_ptr<CtorDtorLogger> ptr2(std::move(ptr1)); - EXPECT_EQ(1, constructed); - EXPECT_FALSE(ptr1); - EXPECT_TRUE(ptr2); - - unique_ptr<CtorDtorLogger> ptr3; - ptr3 = std::move(ptr2); - EXPECT_EQ(1, constructed); - EXPECT_FALSE(ptr2); - EXPECT_TRUE(ptr3); - - unique_ptr<CtorDtorLogger> ptr4(new CtorDtorLogger(&constructed4)); - EXPECT_EQ(1, constructed4); - ptr4 = std::move(ptr3); - EXPECT_EQ(0, constructed4); - EXPECT_FALSE(ptr3); - EXPECT_TRUE(ptr4); - } - EXPECT_EQ(0, constructed); -} - -TEST(UniquePtrTest, UniquePtr) { - int constructed = 0; - - // Ensure size of unique_ptr<> doesn't increase unexpectedly. - static_assert(sizeof(int*) >= sizeof(unique_ptr<int>), - "unique_ptr_larger_than_raw_ptr"); - - { - unique_ptr<CtorDtorLogger> scoper(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(scoper.get()); - - EXPECT_EQ(10, scoper->SomeMeth(10)); - EXPECT_EQ(10, scoper.get()->SomeMeth(10)); - EXPECT_EQ(10, (*scoper).SomeMeth(10)); - } - EXPECT_EQ(0, constructed); - - // Test reset() and release() - { - unique_ptr<CtorDtorLogger> scoper(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(scoper.get()); - - scoper.reset(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(scoper.get()); - - scoper.reset(); - EXPECT_EQ(0, constructed); - EXPECT_FALSE(scoper.get()); - - scoper.reset(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(scoper.get()); - - CtorDtorLogger* take = scoper.release(); - EXPECT_EQ(1, constructed); - EXPECT_FALSE(scoper.get()); - delete take; - EXPECT_EQ(0, constructed); - - scoper.reset(new CtorDtorLogger(&constructed)); - EXPECT_EQ(1, constructed); - EXPECT_TRUE(scoper.get()); - } - EXPECT_EQ(0, constructed); - - // Test swap(), == and != - { - unique_ptr<CtorDtorLogger> scoper1; - unique_ptr<CtorDtorLogger> scoper2; - EXPECT_TRUE(scoper1 == scoper2.get()); - EXPECT_FALSE(scoper1 != scoper2.get()); - - CtorDtorLogger* logger = new CtorDtorLogger(&constructed); - scoper1.reset(logger); - EXPECT_EQ(logger, scoper1.get()); - EXPECT_FALSE(scoper2.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - - scoper2.swap(scoper1); - EXPECT_EQ(logger, scoper2.get()); - EXPECT_FALSE(scoper1.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - } - EXPECT_EQ(0, constructed); -} - -TEST(UniquePtrTest, UniquePtrWithArray) { - static const int kNumLoggers = 12; - - int constructed = 0; - - { - unique_ptr<CtorDtorLogger[]> scoper(new CtorDtorLogger[kNumLoggers]); - EXPECT_TRUE(scoper); - EXPECT_EQ(&scoper[0], scoper.get()); - for (int i = 0; i < kNumLoggers; ++i) { - scoper[i].SetPtr(&constructed); - } - EXPECT_EQ(12, constructed); - - EXPECT_EQ(10, scoper.get()->SomeMeth(10)); - EXPECT_EQ(10, scoper[2].SomeMeth(10)); - } - EXPECT_EQ(0, constructed); - - // Test reset() and release() - { - unique_ptr<CtorDtorLogger[]> scoper; - EXPECT_FALSE(scoper.get()); - EXPECT_FALSE(scoper.release()); - EXPECT_FALSE(scoper.get()); - scoper.reset(); - EXPECT_FALSE(scoper.get()); - - scoper.reset(new CtorDtorLogger[kNumLoggers]); - for (int i = 0; i < kNumLoggers; ++i) { - scoper[i].SetPtr(&constructed); - } - EXPECT_EQ(12, constructed); - scoper.reset(); - EXPECT_EQ(0, constructed); - - scoper.reset(new CtorDtorLogger[kNumLoggers]); - for (int i = 0; i < kNumLoggers; ++i) { - scoper[i].SetPtr(&constructed); - } - EXPECT_EQ(12, constructed); - CtorDtorLogger* ptr = scoper.release(); - EXPECT_EQ(12, constructed); - delete[] ptr; - EXPECT_EQ(0, constructed); - } - EXPECT_EQ(0, constructed); - - // Test swap(), ==, !=, and type-safe Boolean. - { - unique_ptr<CtorDtorLogger[]> scoper1; - unique_ptr<CtorDtorLogger[]> scoper2; - EXPECT_TRUE(scoper1 == scoper2.get()); - EXPECT_FALSE(scoper1 != scoper2.get()); - - CtorDtorLogger* loggers = new CtorDtorLogger[kNumLoggers]; - for (int i = 0; i < kNumLoggers; ++i) { - loggers[i].SetPtr(&constructed); - } - scoper1.reset(loggers); - EXPECT_TRUE(scoper1); - EXPECT_EQ(loggers, scoper1.get()); - EXPECT_FALSE(scoper2); - EXPECT_FALSE(scoper2.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - - scoper2.swap(scoper1); - EXPECT_EQ(loggers, scoper2.get()); - EXPECT_FALSE(scoper1.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - } - EXPECT_EQ(0, constructed); -} - -TEST(UniquePtrTest, ReturnTypeBehavior) { - int constructed = 0; - - // Test that we can return a unique_ptr. - { - CtorDtorLogger* logger = new CtorDtorLogger(&constructed); - unique_ptr<CtorDtorLogger> scoper(logger); - EXPECT_EQ(1, constructed); - } - EXPECT_EQ(0, constructed); - - // Test uncaught return type not leak. - { - CtorDtorLogger* logger = new CtorDtorLogger(&constructed); - unique_ptr<CtorDtorLogger> scoper(logger); - EXPECT_EQ(1, constructed); - } - EXPECT_EQ(0, constructed); - - // Call TestReturnOfType() so the compiler doesn't warn for an unused - // function. - { TestReturnOfType(&constructed); } - EXPECT_EQ(0, constructed); -} - -TEST(UniquePtrTest, CustomDeleter) { - double dummy_value; // Custom deleter never touches this value. - int deletes = 0; - int alternate_deletes = 0; - - // Normal delete support. - { - deletes = 0; - unique_ptr<double, CountingDeleter> scoper(&dummy_value, - CountingDeleter(&deletes)); - EXPECT_EQ(0, deletes); - EXPECT_TRUE(scoper.get()); - } - EXPECT_EQ(1, deletes); - - // Test reset() and release(). - deletes = 0; - { - unique_ptr<double, CountingDeleter> scoper(nullptr, - CountingDeleter(&deletes)); - EXPECT_FALSE(scoper.get()); - EXPECT_FALSE(scoper.release()); - EXPECT_FALSE(scoper.get()); - scoper.reset(); - EXPECT_FALSE(scoper.get()); - EXPECT_EQ(0, deletes); - - scoper.reset(&dummy_value); - scoper.reset(); - EXPECT_EQ(1, deletes); - - scoper.reset(&dummy_value); - EXPECT_EQ(&dummy_value, scoper.release()); - } - EXPECT_EQ(1, deletes); - - // Test get_deleter(). - deletes = 0; - alternate_deletes = 0; - { - unique_ptr<double, CountingDeleter> scoper(&dummy_value, - CountingDeleter(&deletes)); - // Call deleter manually. - EXPECT_EQ(0, deletes); - scoper.get_deleter()(&dummy_value); - EXPECT_EQ(1, deletes); - - // Deleter is still there after reset. - scoper.reset(); - EXPECT_EQ(2, deletes); - scoper.get_deleter()(&dummy_value); - EXPECT_EQ(3, deletes); - - // Deleter can be assigned into (matches C++11 unique_ptr<> spec). - scoper.get_deleter() = CountingDeleter(&alternate_deletes); - scoper.reset(&dummy_value); - EXPECT_EQ(0, alternate_deletes); - } - EXPECT_EQ(3, deletes); - EXPECT_EQ(1, alternate_deletes); - - // Test swap(), ==, !=, and type-safe Boolean. - { - unique_ptr<double, CountingDeleter> scoper1(nullptr, - CountingDeleter(&deletes)); - unique_ptr<double, CountingDeleter> scoper2(nullptr, - CountingDeleter(&deletes)); - EXPECT_TRUE(scoper1 == scoper2.get()); - EXPECT_FALSE(scoper1 != scoper2.get()); - - scoper1.reset(&dummy_value); - EXPECT_TRUE(scoper1); - EXPECT_EQ(&dummy_value, scoper1.get()); - EXPECT_FALSE(scoper2); - EXPECT_FALSE(scoper2.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - - scoper2.swap(scoper1); - EXPECT_EQ(&dummy_value, scoper2.get()); - EXPECT_FALSE(scoper1.get()); - EXPECT_FALSE(scoper1 == scoper2.get()); - EXPECT_TRUE(scoper1 != scoper2.get()); - } -} - -unique_ptr<int> NullIntReturn() { - return nullptr; -} - -TEST(UniquePtrTest, Nullptr) { - unique_ptr<int> scoper1(nullptr); - unique_ptr<int> scoper2(new int); - scoper2 = nullptr; - unique_ptr<int> scoper3(NullIntReturn()); - unique_ptr<int> scoper4 = NullIntReturn(); - EXPECT_EQ(nullptr, scoper1.get()); - EXPECT_EQ(nullptr, scoper2.get()); - EXPECT_EQ(nullptr, scoper3.get()); - EXPECT_EQ(nullptr, scoper4.get()); -} - -unique_ptr<int[]> NullIntArrayReturn() { - return nullptr; -} - -TEST(UniquePtrTest, NullptrArray) { - unique_ptr<int[]> scoper1(nullptr); - unique_ptr<int[]> scoper2(new int[3]); - scoper2 = nullptr; - unique_ptr<int[]> scoper3(NullIntArrayReturn()); - unique_ptr<int[]> scoper4 = NullIntArrayReturn(); - EXPECT_EQ(nullptr, scoper1.get()); - EXPECT_EQ(nullptr, scoper2.get()); - EXPECT_EQ(nullptr, scoper3.get()); - EXPECT_EQ(nullptr, scoper4.get()); -} - -// Logging a unique_ptr<T> to an ostream shouldn't convert it to a boolean -// value first. -TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) { - unique_ptr<int> x(new int); - std::stringstream s1; - s1 << x; - - std::stringstream s2; - s2 << x.get(); - - EXPECT_EQ(s2.str(), s1.str()); -} diff --git a/third_party/base/numerics/safe_conversions_impl.h b/third_party/base/numerics/safe_conversions_impl.h index c974ee0590..e1c4c3b756 100644 --- a/third_party/base/numerics/safe_conversions_impl.h +++ b/third_party/base/numerics/safe_conversions_impl.h @@ -9,7 +9,6 @@ #include <limits> #include "third_party/base/macros.h" -#include "third_party/base/template_util.h" namespace pdfium { namespace base { diff --git a/third_party/base/numerics/safe_math.h b/third_party/base/numerics/safe_math.h index 9540e83321..013af1eb60 100644 --- a/third_party/base/numerics/safe_math.h +++ b/third_party/base/numerics/safe_math.h @@ -166,15 +166,15 @@ class CheckedNumeric { template <typename Src> static CheckedNumeric<T> cast( Src u, - typename enable_if<std::numeric_limits<Src>::is_specialized, int>::type = - 0) { + typename std::enable_if<std::numeric_limits<Src>::is_specialized, + int>::type = 0) { return u; } template <typename Src> static CheckedNumeric<T> cast( const CheckedNumeric<Src>& u, - typename enable_if<!is_same<Src, T>::value, int>::type = 0) { + typename std::enable_if<!std::is_same<Src, T>::value, int>::type = 0) { return u; } diff --git a/third_party/base/numerics/safe_math_impl.h b/third_party/base/numerics/safe_math_impl.h index 4209446694..f219cf52bb 100644 --- a/third_party/base/numerics/safe_math_impl.h +++ b/third_party/base/numerics/safe_math_impl.h @@ -10,10 +10,10 @@ #include <cmath> #include <cstdlib> #include <limits> +#include <type_traits> #include "safe_conversions.h" #include "third_party/base/macros.h" -#include "third_party/base/template_util.h" namespace pdfium { namespace base { @@ -65,21 +65,21 @@ struct IntegerForSizeAndSign<8, false> { template <typename Integer> struct UnsignedIntegerForSize { - typedef typename enable_if< + typedef typename std::enable_if< std::numeric_limits<Integer>::is_integer, typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type type; }; template <typename Integer> struct SignedIntegerForSize { - typedef typename enable_if< + typedef typename std::enable_if< std::numeric_limits<Integer>::is_integer, typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type type; }; template <typename Integer> struct TwiceWiderInteger { - typedef typename enable_if< + typedef typename std::enable_if< std::numeric_limits<Integer>::is_integer, typename IntegerForSizeAndSign< sizeof(Integer) * 2, @@ -88,8 +88,9 @@ struct TwiceWiderInteger { template <typename Integer> struct PositionOfSignBit { - static const typename enable_if<std::numeric_limits<Integer>::is_integer, - size_t>::type value = 8 * sizeof(Integer) - 1; + static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, + size_t>::type value = + 8 * sizeof(Integer) - 1; }; // Helper templates for integer manipulations. @@ -112,7 +113,7 @@ T BinaryComplement(T x) { // way to coalesce things into the CheckedNumericState specializations below. template <typename T> -typename enable_if<std::numeric_limits<T>::is_integer, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type CheckedAdd(T x, T y, RangeConstraint* validity) { // Since the value of x+y is undefined if we have a signed type, we compute // it using the unsigned type of the same size. @@ -135,7 +136,7 @@ CheckedAdd(T x, T y, RangeConstraint* validity) { } template <typename T> -typename enable_if<std::numeric_limits<T>::is_integer, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type CheckedSub(T x, T y, RangeConstraint* validity) { // Since the value of x+y is undefined if we have a signed type, we compute // it using the unsigned type of the same size. @@ -162,9 +163,9 @@ CheckedSub(T x, T y, RangeConstraint* validity) { // slow case we need to manually check that the result won't be truncated by // checking with division against the appropriate bound. template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer && sizeof(T) * 2 <= sizeof(uintmax_t), - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + sizeof(T) * 2 <= sizeof(uintmax_t), + T>::type CheckedMul(T x, T y, RangeConstraint* validity) { typedef typename TwiceWiderInteger<T>::type IntermediateType; IntermediateType tmp = @@ -174,9 +175,10 @@ CheckedMul(T x, T y, RangeConstraint* validity) { } template <typename T> -typename enable_if<std::numeric_limits<T>::is_integer&& std::numeric_limits< - T>::is_signed&&(sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed && + (sizeof(T) * 2 > sizeof(uintmax_t)), + T>::type CheckedMul(T x, T y, RangeConstraint* validity) { // If either side is zero then the result will be zero. if (!x || !y) { @@ -203,10 +205,10 @@ CheckedMul(T x, T y, RangeConstraint* validity) { } template <typename T> -typename enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed && + (sizeof(T) * 2 > sizeof(uintmax_t)), + T>::type CheckedMul(T x, T y, RangeConstraint* validity) { *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) ? RANGE_VALID @@ -216,11 +218,11 @@ CheckedMul(T x, T y, RangeConstraint* validity) { // Division just requires a check for an invalid negation on signed min/-1. template <typename T> -T CheckedDiv( - T x, - T y, - RangeConstraint* validity, - typename enable_if<std::numeric_limits<T>::is_integer, int>::type = 0) { +T CheckedDiv(T x, + T y, + RangeConstraint* validity, + typename std::enable_if<std::numeric_limits<T>::is_integer, + int>::type = 0) { if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() && y == static_cast<T>(-1)) { *validity = RANGE_OVERFLOW; @@ -232,27 +234,27 @@ T CheckedDiv( } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, + T>::type CheckedMod(T x, T y, RangeConstraint* validity) { *validity = y > 0 ? RANGE_VALID : RANGE_INVALID; return x % y; } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, + T>::type CheckedMod(T x, T y, RangeConstraint* validity) { *validity = RANGE_VALID; return x % y; } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, + T>::type CheckedNeg(T value, RangeConstraint* validity) { *validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; @@ -261,9 +263,9 @@ CheckedNeg(T value, RangeConstraint* validity) { } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, + T>::type CheckedNeg(T value, RangeConstraint* validity) { // The only legal unsigned negation is zero. *validity = value ? RANGE_UNDERFLOW : RANGE_VALID; @@ -272,9 +274,9 @@ CheckedNeg(T value, RangeConstraint* validity) { } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer&& std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, + T>::type CheckedAbs(T value, RangeConstraint* validity) { *validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; @@ -282,9 +284,9 @@ CheckedAbs(T value, RangeConstraint* validity) { } template <typename T> -typename enable_if< - std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, - T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, + T>::type CheckedAbs(T value, RangeConstraint* validity) { // Absolute value of a positive is just its identiy. *validity = RANGE_VALID; @@ -293,12 +295,12 @@ CheckedAbs(T value, RangeConstraint* validity) { // These are the floating point stubs that the compiler needs to see. Only the // negation operation is ever called. -#define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ - template <typename T> \ - typename enable_if<std::numeric_limits<T>::is_iec559, T>::type \ - Checked##NAME(T, T, RangeConstraint*) { \ - NOTREACHED(); \ - return 0; \ +#define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ + template <typename T> \ + typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type \ + Checked##NAME(T, T, RangeConstraint*) { \ + NOTREACHED(); \ + return 0; \ } BASE_FLOAT_ARITHMETIC_STUBS(Add) @@ -310,14 +312,14 @@ BASE_FLOAT_ARITHMETIC_STUBS(Mod) #undef BASE_FLOAT_ARITHMETIC_STUBS template <typename T> -typename enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg( +typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg( T value, RangeConstraint*) { return -value; } template <typename T> -typename enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs( +typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs( T value, RangeConstraint*) { return std::abs(value); @@ -377,8 +379,8 @@ class CheckedNumericState<T, NUMERIC_INTEGER> { template <typename Src> explicit CheckedNumericState( Src value, - typename enable_if<std::numeric_limits<Src>::is_specialized, int>::type = - 0) + typename std::enable_if<std::numeric_limits<Src>::is_specialized, + int>::type = 0) : value_(static_cast<T>(value)), validity_(DstRangeRelationToSrcRange<T>(value)) {} @@ -402,7 +404,8 @@ class CheckedNumericState<T, NUMERIC_FLOATING> { CheckedNumericState( Src value, RangeConstraint validity, - typename enable_if<std::numeric_limits<Src>::is_integer, int>::type = 0) { + typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = + 0) { switch (DstRangeRelationToSrcRange<T>(value)) { case RANGE_VALID: value_ = static_cast<T>(value); @@ -428,8 +431,8 @@ class CheckedNumericState<T, NUMERIC_FLOATING> { template <typename Src> explicit CheckedNumericState( Src value, - typename enable_if<std::numeric_limits<Src>::is_specialized, int>::type = - 0) + typename std::enable_if<std::numeric_limits<Src>::is_specialized, + int>::type = 0) : value_(static_cast<T>(value)) {} // Copy constructor. diff --git a/third_party/base/template_util.h b/third_party/base/template_util.h deleted file mode 100644 index 719f3f1c3a..0000000000 --- a/third_party/base/template_util.h +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PDFIUM_THIRD_PARTY_BASE_TEMPLATE_UTIL_H_ -#define PDFIUM_THIRD_PARTY_BASE_TEMPLATE_UTIL_H_ - -#include <cstddef> // For size_t. - -namespace pdfium { -namespace base { - -template<class T, T v> -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant<T, v> type; -}; - -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; - -template <class T, class U> struct is_same : public false_type {}; -template <class T> -struct is_same<T, T> : true_type {}; - -template<bool B, class T = void> -struct enable_if {}; - -template<class T> -struct enable_if<true, T> { typedef T type; }; - -namespace internal { - -// Types YesType and NoType are guaranteed such that sizeof(YesType) < -// sizeof(NoType). -typedef char YesType; - -struct NoType { - YesType dummy[2]; -}; - -// This class is an implementation detail for is_convertible, and you -// don't need to know how it works to use is_convertible. For those -// who care: we declare two different functions, one whose argument is -// of type To and one with a variadic argument list. We give them -// return types of different size, so we can use sizeof to trick the -// compiler into telling us which function it would have chosen if we -// had called it with an argument of type From. See Alexandrescu's -// _Modern C++ Design_ for more details on this sort of trick. - -struct ConvertHelper { - template <typename To> - static YesType Test(To); - - template <typename To> - static NoType Test(...); - - template <typename From> - static From& Create(); -}; - -} // namespace internal - -// Inherits from true_type if From is convertible to To, false_type otherwise. -// -// Note that if the type is convertible, this will be a true_type REGARDLESS -// of whether or not the conversion would emit a warning. -template <typename From, typename To> -struct is_convertible - : integral_constant<bool, - sizeof(internal::ConvertHelper::Test<To>( - internal::ConvertHelper::Create<From>())) == - sizeof(internal::YesType)> {}; - -} // namespace base -} // namespace pdfium - -#endif // PDFIUM_THIRD_PARTY_BASE_TEMPLATE_UTIL_H_ diff --git a/third_party/third_party.gyp b/third_party/third_party.gyp index a8360e3c26..9bc9e04411 100644 --- a/third_party/third_party.gyp +++ b/third_party/third_party.gyp @@ -286,13 +286,11 @@ 'sources': [ 'base/logging.h', 'base/macros.h', - 'base/nonstd_unique_ptr.h', 'base/numerics/safe_conversions.h', 'base/numerics/safe_conversions_impl.h', 'base/numerics/safe_math.h', 'base/numerics/safe_math_impl.h', 'base/stl_util.h', - 'base/template_util.h', ], }, ], |