aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/provider/curl_http_client.cc1
-rw-r--r--file_lists.mk1
-rw-r--r--src/backoff_entry.cc4
-rw-r--r--src/backoff_entry.h4
-rw-r--r--src/config.cc7
-rw-r--r--third_party/chromium/base/basictypes.h45
-rw-r--r--third_party/chromium/base/bind.h49
-rw-r--r--third_party/chromium/base/bind_helpers.h229
-rw-r--r--third_party/chromium/base/bind_internal.h81
-rw-r--r--third_party/chromium/base/bind_unittest.cc175
-rw-r--r--third_party/chromium/base/callback.h44
-rw-r--r--third_party/chromium/base/callback_forward.h4
-rw-r--r--third_party/chromium/base/callback_internal.h91
-rw-r--r--third_party/chromium/base/callback_list.h8
-rw-r--r--third_party/chromium/base/callback_list_unittest.cc54
-rw-r--r--third_party/chromium/base/callback_unittest.cc37
-rw-r--r--third_party/chromium/base/compiler_specific.h35
-rw-r--r--third_party/chromium/base/guid.h5
-rw-r--r--third_party/chromium/base/guid_posix.cc6
-rw-r--r--third_party/chromium/base/guid_unittest.cc7
-rw-r--r--third_party/chromium/base/json/json_parser.cc53
-rw-r--r--third_party/chromium/base/json/json_parser.h20
-rw-r--r--third_party/chromium/base/json/json_parser_unittest.cc63
-rw-r--r--third_party/chromium/base/json/json_reader.cc36
-rw-r--r--third_party/chromium/base/json/json_reader.h21
-rw-r--r--third_party/chromium/base/json/json_reader_unittest.cc119
-rw-r--r--third_party/chromium/base/json/json_writer.cc10
-rw-r--r--third_party/chromium/base/json/json_writer.h4
-rw-r--r--third_party/chromium/base/json/json_writer_unittest.cc7
-rw-r--r--third_party/chromium/base/json/string_escape.cc29
-rw-r--r--third_party/chromium/base/json/string_escape_unittest.cc4
-rw-r--r--third_party/chromium/base/location.h3
-rw-r--r--third_party/chromium/base/logging.cc21
-rw-r--r--third_party/chromium/base/logging.h115
-rw-r--r--third_party/chromium/base/logging_unittest.cc46
-rw-r--r--third_party/chromium/base/macros.h123
-rw-r--r--third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h64
-rw-r--r--third_party/chromium/base/memory/ref_counted.h16
-rw-r--r--third_party/chromium/base/memory/ref_counted_unittest.cc36
-rw-r--r--third_party/chromium/base/memory/scoped_ptr.h371
-rw-r--r--third_party/chromium/base/memory/scoped_ptr_unittest.cc329
-rw-r--r--third_party/chromium/base/memory/weak_ptr.h16
-rw-r--r--third_party/chromium/base/move.h257
-rw-r--r--third_party/chromium/base/move_unittest.cc49
-rw-r--r--third_party/chromium/base/numerics/safe_conversions.h48
-rw-r--r--third_party/chromium/base/numerics/safe_conversions_impl.h67
-rw-r--r--third_party/chromium/base/numerics/safe_math.h28
-rw-r--r--third_party/chromium/base/numerics/safe_math_impl.h106
-rw-r--r--third_party/chromium/base/numerics/safe_numerics_unittest.cc202
-rw-r--r--third_party/chromium/base/observer_list.h8
-rw-r--r--third_party/chromium/base/rand_util.cc24
-rw-r--r--third_party/chromium/base/rand_util.h13
-rw-r--r--third_party/chromium/base/rand_util_posix.cc6
-rw-r--r--third_party/chromium/base/rand_util_unittest.cc32
-rw-r--r--third_party/chromium/base/scoped_clear_errno.h2
-rw-r--r--third_party/chromium/base/scoped_observer.h7
-rw-r--r--third_party/chromium/base/strings/string_number_conversions.cc191
-rw-r--r--third_party/chromium/base/strings/string_number_conversions.h29
-rw-r--r--third_party/chromium/base/strings/string_number_conversions_unittest.cc452
-rw-r--r--third_party/chromium/base/strings/string_piece.cc4
-rw-r--r--third_party/chromium/base/strings/string_piece.h16
-rw-r--r--third_party/chromium/base/strings/string_piece_unittest.cc2
-rw-r--r--third_party/chromium/base/strings/string_util.cc83
-rw-r--r--third_party/chromium/base/strings/string_util.h101
-rw-r--r--third_party/chromium/base/strings/string_util_posix.h2
-rw-r--r--third_party/chromium/base/strings/string_util_unittest.cc4
-rw-r--r--third_party/chromium/base/strings/stringprintf.cc3
-rw-r--r--third_party/chromium/base/strings/stringprintf.h1
-rw-r--r--third_party/chromium/base/strings/stringprintf_unittest.cc14
-rw-r--r--third_party/chromium/base/strings/utf_string_conversion_utils.cc12
-rw-r--r--third_party/chromium/base/strings/utf_string_conversion_utils.h24
-rw-r--r--third_party/chromium/base/template_util.h2
-rw-r--r--third_party/chromium/base/template_util_unittest.cc132
-rw-r--r--third_party/chromium/base/third_party/icu/icu_utf.cc18
-rw-r--r--third_party/chromium/base/third_party/icu/icu_utf.h76
-rw-r--r--third_party/chromium/base/time/time.cc58
-rw-r--r--third_party/chromium/base/time/time.h270
-rw-r--r--third_party/chromium/base/time/time_posix.cc69
-rw-r--r--third_party/chromium/base/time/time_unittest.cc151
-rw-r--r--third_party/chromium/base/tuple.h40
-rw-r--r--third_party/chromium/base/values.cc74
-rw-r--r--third_party/chromium/base/values.h20
-rw-r--r--third_party/chromium/base/values_unittest.cc75
-rw-r--r--third_party/chromium/crypto/p224.cc142
-rw-r--r--third_party/chromium/crypto/p224.h14
-rw-r--r--third_party/chromium/crypto/p224_spake.cc37
-rw-r--r--third_party/chromium/crypto/p224_spake.h28
-rw-r--r--third_party/chromium/crypto/p224_spake_unittest.cc5
-rw-r--r--third_party/chromium/crypto/p224_unittest.cc49
-rw-r--r--third_party/chromium/crypto/sha2_unittest.cc15
90 files changed, 2936 insertions, 2519 deletions
diff --git a/examples/provider/curl_http_client.cc b/examples/provider/curl_http_client.cc
index 2bf10f5..de8b3dd 100644
--- a/examples/provider/curl_http_client.cc
+++ b/examples/provider/curl_http_client.cc
@@ -4,6 +4,7 @@
#include "examples/provider/curl_http_client.h"
+#include <algorithm>
#include <future>
#include <thread>
diff --git a/file_lists.mk b/file_lists.mk
index 1e78935..a018178 100644
--- a/file_lists.mk
+++ b/file_lists.mk
@@ -129,7 +129,6 @@ THIRD_PARTY_CHROMIUM_BASE_UNITTEST_SRC_FILES := \
third_party/chromium/base/memory/ref_counted_unittest.cc \
third_party/chromium/base/memory/scoped_ptr_unittest.cc \
third_party/chromium/base/memory/weak_ptr_unittest.cc \
- third_party/chromium/base/move_unittest.cc \
third_party/chromium/base/numerics/safe_numerics_unittest.cc \
third_party/chromium/base/observer_list_unittest.cc \
third_party/chromium/base/rand_util_unittest.cc \
diff --git a/src/backoff_entry.cc b/src/backoff_entry.cc
index 6b99d79..7efc33b 100644
--- a/src/backoff_entry.cc
+++ b/src/backoff_entry.cc
@@ -74,7 +74,7 @@ bool BackoffEntry::CanDiscard() const {
base::TimeTicks now = ImplGetTimeNow();
- int64 unused_since_ms =
+ int64_t unused_since_ms =
(now - exponential_backoff_release_time_).InMilliseconds();
// Release time is further than now, we are managing it.
@@ -152,7 +152,7 @@ base::TimeTicks BackoffEntry::CalculateReleaseTime() const {
// Decide between maximum release time and calculated release time, accounting
// for overflow with both.
- int64 release_time_us =
+ int64_t release_time_us =
std::min(calculated_release_time_us.ValueOrDefault(kMaxTime),
maximum_release_time_us.ValueOrDefault(kMaxTime));
diff --git a/src/backoff_entry.h b/src/backoff_entry.h
index 002fb8d..422ffc7 100644
--- a/src/backoff_entry.h
+++ b/src/backoff_entry.h
@@ -38,11 +38,11 @@ class BackoffEntry {
// Maximum amount of time we are willing to delay our request, -1
// for no maximum.
- int64 maximum_backoff_ms;
+ int64_t maximum_backoff_ms;
// Time to keep an entry from being discarded even when it
// has no significant state, -1 to never discard.
- int64 entry_lifetime_ms;
+ int64_t entry_lifetime_ms;
// If true, we always use a delay of initial_delay_ms, even before
// we've seen num_errors_to_ignore errors. Otherwise, initial_delay_ms
diff --git a/src/config.cc b/src/config.cc
index 37e907c..76be205 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -121,10 +121,9 @@ void Config::Load() {
CHECK(!settings_.model_id.empty());
CHECK(!settings_.name.empty());
CHECK(!settings_.device_id.empty());
- CHECK_EQ(
- settings_.embedded_code.empty(),
- std::find(settings_.pairing_modes.begin(), settings_.pairing_modes.end(),
- PairingType::kEmbeddedCode) == settings_.pairing_modes.end());
+ CHECK_EQ(settings_.embedded_code.empty(),
+ (settings_.pairing_modes.find(PairingType::kEmbeddedCode) ==
+ settings_.pairing_modes.end()));
// Values below will be generated at runtime.
CHECK(settings_.cloud_id.empty());
diff --git a/third_party/chromium/base/basictypes.h b/third_party/chromium/base/basictypes.h
deleted file mode 100644
index d71abd9..0000000
--- a/third_party/chromium/base/basictypes.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 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.
-
-// This file contains definitions of our old basic integral types
-// ((u)int{8,16,32,64}) and further includes. I recommend that you use the C99
-// standard types instead, and include <stdint.h>/<stddef.h>/etc. as needed.
-// Note that the macros and macro-like constructs that were formerly defined in
-// this file are now available separately in base/macros.h.
-
-#ifndef BASE_BASICTYPES_H_
-#define BASE_BASICTYPES_H_
-
-#include <limits.h> // So we can set the bounds of our types.
-#include <stddef.h> // For size_t.
-#include <stdint.h> // For intptr_t.
-
-#include "base/macros.h"
-#include "build/build_config.h"
-
-// DEPRECATED: Please use (u)int{8,16,32,64}_t instead (and include <stdint.h>).
-typedef int8_t int8;
-typedef uint8_t uint8;
-typedef int16_t int16;
-typedef uint16_t uint16;
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
-
-// DEPRECATED: Please use std::numeric_limits (from <limits>) instead.
-const uint8 kuint8max = 0xFF;
-const uint16 kuint16max = 0xFFFF;
-const uint32 kuint32max = 0xFFFFFFFF;
-const uint64 kuint64max = 0xFFFFFFFFFFFFFFFFULL;
-const int8 kint8min = -0x7F - 1;
-const int8 kint8max = 0x7F;
-const int16 kint16min = -0x7FFF - 1;
-const int16 kint16max = 0x7FFF;
-const int32 kint32min = -0x7FFFFFFF - 1;
-const int32 kint32max = 0x7FFFFFFF;
-const int64 kint64min = -0x7FFFFFFFFFFFFFFFLL - 1;
-const int64 kint64max = 0x7FFFFFFFFFFFFFFFLL;
-
-#endif // BASE_BASICTYPES_H_
diff --git a/third_party/chromium/base/bind.h b/third_party/chromium/base/bind.h
index 51be10d..770e457 100644
--- a/third_party/chromium/base/bind.h
+++ b/third_party/chromium/base/bind.h
@@ -47,49 +47,34 @@
namespace base {
-template <typename Functor>
-base::Callback<
- typename internal::BindState<
- typename internal::FunctorTraits<Functor>::RunnableType,
- typename internal::FunctorTraits<Functor>::RunType,
- internal::TypeList<>>::UnboundRunType>
-Bind(Functor functor) {
- // Typedefs for how to store and run the functor.
- typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
- typedef typename internal::FunctorTraits<Functor>::RunType RunType;
-
- typedef internal::BindState<RunnableType, RunType,
- internal::TypeList<>> BindState;
-
- return Callback<typename BindState::UnboundRunType>(
- new BindState(internal::MakeRunnable(functor)));
-}
-
template <typename Functor, typename... Args>
base::Callback<
typename internal::BindState<
typename internal::FunctorTraits<Functor>::RunnableType,
typename internal::FunctorTraits<Functor>::RunType,
- internal::TypeList<
- typename internal::CallbackParamTraits<Args>::StorageType...>>
+ typename internal::CallbackParamTraits<Args>::StorageType...>
::UnboundRunType>
Bind(Functor functor, const Args&... args) {
- // Typedefs for how to store and run the functor.
- typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
- typedef typename internal::FunctorTraits<Functor>::RunType RunType;
+ // Type aliases for how to store and run the functor.
+ using RunnableType = typename internal::FunctorTraits<Functor>::RunnableType;
+ using RunType = typename internal::FunctorTraits<Functor>::RunType;
// Use RunnableType::RunType instead of RunType above because our
- // checks should below for bound references need to know what the actual
+ // checks below for bound references need to know what the actual
// functor is going to interpret the argument as.
- typedef typename RunnableType::RunType BoundRunType;
+ using BoundRunType = typename RunnableType::RunType;
+
+ using BoundArgs =
+ internal::TakeTypeListItem<sizeof...(Args),
+ internal::ExtractArgs<BoundRunType>>;
// Do not allow binding a non-const reference parameter. Non-const reference
// parameters are disallowed by the Google style guide. Also, binding a
// non-const reference parameter can make for subtle bugs because the
// invoked function will receive a reference to the stored copy of the
// argument and not the original.
- static_assert(!internal::HasNonConstReferenceParam<BoundRunType>::value,
- "do_not_bind_functions_with_nonconst_ref");
+ static_assert(!internal::HasNonConstReferenceItem<BoundArgs>::value,
+ "do not bind functions with nonconst ref");
const bool is_method = internal::HasIsMethodTag<RunnableType>::value;
@@ -98,16 +83,14 @@ Bind(Functor functor, const Args&... args) {
// methods. We also disallow binding of an array as the method's target
// object.
static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value,
- "first_bound_argument_to_method_cannot_be_array");
+ "first bound argument to method cannot be array");
static_assert(
!internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value,
- "a_parameter_is_refcounted_type_and_needs_scoped_refptr");
+ "a parameter is a refcounted type and needs scoped_refptr");
- typedef internal::BindState<
+ using BindState = internal::BindState<
RunnableType, RunType,
- internal::TypeList<
- typename internal::CallbackParamTraits<Args>::StorageType...>>
- BindState;
+ typename internal::CallbackParamTraits<Args>::StorageType...>;
return Callback<typename BindState::UnboundRunType>(
new BindState(internal::MakeRunnable(functor), args...));
diff --git a/third_party/chromium/base/bind_helpers.h b/third_party/chromium/base/bind_helpers.h
index 5044a1c..23e2cc9 100644
--- a/third_party/chromium/base/bind_helpers.h
+++ b/third_party/chromium/base/bind_helpers.h
@@ -111,7 +111,7 @@
// scoped_ptr<Foo> f(new Foo());
//
// // |cb| is given ownership of Foo(). |f| is now NULL.
-// // You can use f.Pass() in place of &f, but it's more verbose.
+// // You can use std::move(f) in place of &f, but it's more verbose.
// Closure cb = Bind(&TakesOwnership, Passed(&f));
//
// // Run was never called so |cb| still owns Foo() and deletes
@@ -143,14 +143,18 @@
#ifndef BASE_BIND_HELPERS_H_
#define BASE_BIND_HELPERS_H_
+#include <stddef.h>
+
#include <map>
#include <memory>
+#include <type_traits>
+#include <utility>
#include <vector>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/template_util.h"
+#include "build/build_config.h"
namespace base {
namespace internal {
@@ -189,7 +193,7 @@ namespace internal {
// want to probe for. Then we create a class Base that inherits from both T
// (the class we wish to probe) and BaseMixin. Note that the function
// signature in BaseMixin does not need to match the signature of the function
-// we are probing for; thus it's easiest to just use void(void).
+// we are probing for; thus it's easiest to just use void().
//
// Now, if TargetFunc exists somewhere in T, then &Base::TargetFunc has an
// ambiguous resolution between BaseMixin and T. This lets us write the
@@ -226,8 +230,8 @@ namespace internal {
// See http://crbug.com/82038.
template <typename T>
class SupportsAddRefAndRelease {
- typedef char Yes[1];
- typedef char No[2];
+ using Yes = char[1];
+ using No = char[2];
struct BaseMixin {
void AddRef();
@@ -246,7 +250,7 @@ class SupportsAddRefAndRelease {
#pragma warning(pop)
#endif
- template <void(BaseMixin::*)(void)> struct Helper {};
+ template <void(BaseMixin::*)()> struct Helper {};
template <typename C>
static No& Check(Helper<&C::AddRef>*);
@@ -280,8 +284,8 @@ struct UnsafeBindtoRefCountedArg<T*>
template <typename T>
class HasIsMethodTag {
- typedef char Yes[1];
- typedef char No[2];
+ using Yes = char[1];
+ using No = char[2];
template <typename U>
static Yes& Check(typename U::IsMethod*);
@@ -363,80 +367,21 @@ class OwnedWrapper {
// created when we are explicitly trying to do a destructive move.
//
// Two notes:
-// 1) PassedWrapper supports any type that has a "Pass()" function.
-// This is intentional. The whitelisting of which specific types we
-// support is maintained by CallbackParamTraits<>.
+// 1) PassedWrapper supports any type that has a move constructor, however
+// the type will need to be specifically whitelisted in order for it to be
+// bound to a Callback. We guard this explicitly at the call of Passed()
+// to make for clear errors. Things not given to Passed() will be forwarded
+// and stored by value which will not work for general move-only types.
// 2) is_valid_ is distinct from NULL because it is valid to bind a "NULL"
// scoper to a Callback and allow the Callback to execute once.
template <typename T>
class PassedWrapper {
public:
- explicit PassedWrapper(T scoper) : is_valid_(true), scoper_(scoper.Pass()) {}
- PassedWrapper(const PassedWrapper& other)
- : is_valid_(other.is_valid_), scoper_(other.scoper_.Pass()) {
- }
- T Pass() const {
- CHECK(is_valid_);
- is_valid_ = false;
- return scoper_.Pass();
- }
-
- private:
- mutable bool is_valid_;
- mutable T scoper_;
-};
-
-// Specialize PassedWrapper for std::unique_ptr used by base::Passed().
-// Use std::move() to transfer the data from one storage to another.
-template <typename T, typename D>
-class PassedWrapper<std::unique_ptr<T, D>> {
- public:
- explicit PassedWrapper(std::unique_ptr<T, D> scoper)
- : is_valid_(true), scoper_(std::move(scoper)) {}
- PassedWrapper(const PassedWrapper& other)
- : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
-
- std::unique_ptr<T, D> Pass() const {
- CHECK(is_valid_);
- is_valid_ = false;
- return std::move(scoper_);
- }
-
- private:
- mutable bool is_valid_;
- mutable std::unique_ptr<T, D> scoper_;
-};
-
-// Specialize PassedWrapper for std::vector<std::unique_ptr<T>>.
-template <typename T, typename D, typename A>
-class PassedWrapper<std::vector<std::unique_ptr<T, D>, A>> {
- public:
- explicit PassedWrapper(std::vector<std::unique_ptr<T, D>, A> scoper)
+ explicit PassedWrapper(T&& scoper)
: is_valid_(true), scoper_(std::move(scoper)) {}
PassedWrapper(const PassedWrapper& other)
: is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
-
- std::vector<std::unique_ptr<T, D>, A> Pass() const {
- CHECK(is_valid_);
- is_valid_ = false;
- return std::move(scoper_);
- }
-
- private:
- mutable bool is_valid_;
- mutable std::vector<std::unique_ptr<T, D>, A> scoper_;
-};
-
-// Specialize PassedWrapper for std::map<K, std::unique_ptr<T>>.
-template <typename K, typename T, typename D, typename C, typename A>
-class PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>> {
- public:
- explicit PassedWrapper(std::map<K, std::unique_ptr<T, D>, C, A> scoper)
- : is_valid_(true), scoper_(std::move(scoper)) {}
- PassedWrapper(const PassedWrapper& other)
- : is_valid_(other.is_valid_), scoper_(std::move(other.scoper_)) {}
-
- std::map<K, std::unique_ptr<T, D>, C, A> Pass() const {
+ T Pass() const {
CHECK(is_valid_);
is_valid_ = false;
return std::move(scoper_);
@@ -444,19 +389,19 @@ class PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>> {
private:
mutable bool is_valid_;
- mutable std::map<K, std::unique_ptr<T, D>, C, A> scoper_;
+ mutable T scoper_;
};
// Unwrap the stored parameters for the wrappers above.
template <typename T>
struct UnwrapTraits {
- typedef const T& ForwardType;
+ using ForwardType = const T&;
static ForwardType Unwrap(const T& o) { return o; }
};
template <typename T>
struct UnwrapTraits<UnretainedWrapper<T> > {
- typedef T* ForwardType;
+ using ForwardType = T*;
static ForwardType Unwrap(UnretainedWrapper<T> unretained) {
return unretained.get();
}
@@ -464,7 +409,7 @@ struct UnwrapTraits<UnretainedWrapper<T> > {
template <typename T>
struct UnwrapTraits<ConstRefWrapper<T> > {
- typedef const T& ForwardType;
+ using ForwardType = const T&;
static ForwardType Unwrap(ConstRefWrapper<T> const_ref) {
return const_ref.get();
}
@@ -472,19 +417,19 @@ struct UnwrapTraits<ConstRefWrapper<T> > {
template <typename T>
struct UnwrapTraits<scoped_refptr<T> > {
- typedef T* ForwardType;
+ using ForwardType = T*;
static ForwardType Unwrap(const scoped_refptr<T>& o) { return o.get(); }
};
template <typename T>
struct UnwrapTraits<WeakPtr<T> > {
- typedef const WeakPtr<T>& ForwardType;
+ using ForwardType = const WeakPtr<T>&;
static ForwardType Unwrap(const WeakPtr<T>& o) { return o; }
};
template <typename T>
struct UnwrapTraits<OwnedWrapper<T> > {
- typedef T* ForwardType;
+ using ForwardType = T*;
static ForwardType Unwrap(const OwnedWrapper<T>& o) {
return o.get();
}
@@ -492,7 +437,7 @@ struct UnwrapTraits<OwnedWrapper<T> > {
template <typename T>
struct UnwrapTraits<PassedWrapper<T> > {
- typedef T ForwardType;
+ using ForwardType = T;
static T Unwrap(PassedWrapper<T>& o) {
return o.Pass();
}
@@ -520,7 +465,7 @@ struct MaybeScopedRefPtr<false, T[n], Rest...> {
template <typename T, typename... Rest>
struct MaybeScopedRefPtr<true, T, Rest...> {
- MaybeScopedRefPtr(const T& o, const Rest&...) {}
+ MaybeScopedRefPtr(const T& /* o */, const Rest&...) {}
};
template <typename T, typename... Rest>
@@ -575,25 +520,50 @@ struct DropTypeListItemImpl<n, TypeList<T, List...>>
template <typename T, typename... List>
struct DropTypeListItemImpl<0, TypeList<T, List...>> {
- typedef TypeList<T, List...> Type;
+ using Type = TypeList<T, List...>;
};
template <>
struct DropTypeListItemImpl<0, TypeList<>> {
- typedef TypeList<> Type;
+ using Type = TypeList<>;
};
// A type-level function that drops |n| list item from given TypeList.
template <size_t n, typename List>
using DropTypeListItem = typename DropTypeListItemImpl<n, List>::Type;
+// Used for TakeTypeListItem implementation.
+template <size_t n, typename List, typename... Accum>
+struct TakeTypeListItemImpl;
+
+// Do not use enable_if and SFINAE here to avoid MSVC2013 compile failure.
+template <size_t n, typename T, typename... List, typename... Accum>
+struct TakeTypeListItemImpl<n, TypeList<T, List...>, Accum...>
+ : TakeTypeListItemImpl<n - 1, TypeList<List...>, Accum..., T> {};
+
+template <typename T, typename... List, typename... Accum>
+struct TakeTypeListItemImpl<0, TypeList<T, List...>, Accum...> {
+ using Type = TypeList<Accum...>;
+};
+
+template <typename... Accum>
+struct TakeTypeListItemImpl<0, TypeList<>, Accum...> {
+ using Type = TypeList<Accum...>;
+};
+
+// A type-level function that takes first |n| list item from given TypeList.
+// E.g. TakeTypeListItem<3, TypeList<A, B, C, D>> is evaluated to
+// TypeList<A, B, C>.
+template <size_t n, typename List>
+using TakeTypeListItem = typename TakeTypeListItemImpl<n, List>::Type;
+
// Used for ConcatTypeLists implementation.
template <typename List1, typename List2>
struct ConcatTypeListsImpl;
template <typename... Types1, typename... Types2>
struct ConcatTypeListsImpl<TypeList<Types1...>, TypeList<Types2...>> {
- typedef TypeList<Types1..., Types2...> Type;
+ using Type = TypeList<Types1..., Types2...>;
};
// A type-level function that concats two TypeLists.
@@ -606,7 +576,9 @@ struct MakeFunctionTypeImpl;
template <typename R, typename... Args>
struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
- typedef R(Type)(Args...);
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef R Type(Args...);
};
// A type-level function that constructs a function type that has |R| as its
@@ -614,6 +586,20 @@ struct MakeFunctionTypeImpl<R, TypeList<Args...>> {
template <typename R, typename ArgList>
using MakeFunctionType = typename MakeFunctionTypeImpl<R, ArgList>::Type;
+// Used for ExtractArgs.
+template <typename Signature>
+struct ExtractArgsImpl;
+
+template <typename R, typename... Args>
+struct ExtractArgsImpl<R(Args...)> {
+ using Type = TypeList<Args...>;
+};
+
+// A type-level function that extracts function arguments into a TypeList.
+// E.g. ExtractArgs<R(A, B, C)> is evaluated to TypeList<A, B, C>.
+template <typename Signature>
+using ExtractArgs = typename ExtractArgsImpl<Signature>::Type;
+
} // namespace internal
template <typename T>
@@ -631,60 +617,25 @@ static inline internal::OwnedWrapper<T> Owned(T* o) {
return internal::OwnedWrapper<T>(o);
}
-// We offer 2 syntaxes for calling Passed(). The first takes a temporary and
-// is best suited for use with the return value of a function. The second
-// takes a pointer to the scoper and is just syntactic sugar to avoid having
-// to write Passed(scoper.Pass()).
-template <typename T>
-static inline internal::PassedWrapper<T> Passed(T scoper) {
- return internal::PassedWrapper<T>(scoper.Pass());
+// We offer 2 syntaxes for calling Passed(). The first takes an rvalue and
+// is best suited for use with the return value of a function or other temporary
+// rvalues. The second takes a pointer to the scoper and is just syntactic sugar
+// to avoid having to write Passed(std::move(scoper)).
+//
+// Both versions of Passed() prevent T from being an lvalue reference. The first
+// via use of enable_if, and the second takes a T* which will not bind to T&.
+template <typename T,
+ typename std::enable_if<internal::IsMoveOnlyType<T>::value &&
+ !std::is_lvalue_reference<T>::value>::type* =
+ nullptr>
+static inline internal::PassedWrapper<T> Passed(T&& scoper) {
+ return internal::PassedWrapper<T>(std::move(scoper));
}
-template <typename T>
+template <typename T,
+ typename std::enable_if<internal::IsMoveOnlyType<T>::value>::type* =
+ nullptr>
static inline internal::PassedWrapper<T> Passed(T* scoper) {
- return internal::PassedWrapper<T>(scoper->Pass());
-}
-
-// Overload base::Passed() for std::unique_ptr<T>.
-template <typename T>
-static inline internal::PassedWrapper<std::unique_ptr<T>>
-Passed(std::unique_ptr<T>* scoper) {
- return internal::PassedWrapper<std::unique_ptr<T>>(std::move(*scoper));
-}
-
-template <typename T>
-static inline internal::PassedWrapper<std::unique_ptr<T>>
-Passed(std::unique_ptr<T> scoper) {
- return internal::PassedWrapper<std::unique_ptr<T>>(std::move(scoper));
-}
-
-// Overload base::Passed() for std::vector<std::unique_ptr<T>>.
-template <typename T, typename D, typename A>
-static inline internal::PassedWrapper<std::vector<std::unique_ptr<T, D>, A>>
-Passed(std::vector<std::unique_ptr<T, D>, A>* scoper) {
- return internal::PassedWrapper<std::vector<std::unique_ptr<T, D>, A>>(
- std::move(*scoper));
-}
-
-template <typename T, typename D, typename A>
-static inline internal::PassedWrapper<std::vector<std::unique_ptr<T, D>, A>>
-Passed(std::vector<std::unique_ptr<T, D>, A> scoper) {
- return internal::PassedWrapper<std::vector<std::unique_ptr<T, D>, A>>(
- std::move(scoper));
-}
-
-// Overload base::Passed() for std::map<K, std::unique_ptr<T>>.
-template <typename K, typename T, typename D, typename C, typename A>
-static inline internal::PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>>
-Passed(std::map<K, std::unique_ptr<T, D>, C, A>* scoper) {
- return internal::PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>>(
- std::move(*scoper));
-}
-
-template <typename K, typename T, typename D, typename C, typename A>
-static inline internal::PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>>
-Passed(std::map<K, std::unique_ptr<T, D>, C, A> scoper) {
- return internal::PassedWrapper<std::map<K, std::unique_ptr<T, D>, C, A>>(
- std::move(scoper));
+ return internal::PassedWrapper<T>(std::move(*scoper));
}
template <typename T>
diff --git a/third_party/chromium/base/bind_internal.h b/third_party/chromium/base/bind_internal.h
index 613f7a9..50c3e24 100644
--- a/third_party/chromium/base/bind_internal.h
+++ b/third_party/chromium/base/bind_internal.h
@@ -5,8 +5,13 @@
#ifndef BASE_BIND_INTERNAL_H_
#define BASE_BIND_INTERNAL_H_
+#include <stddef.h>
+
+#include <type_traits>
+
#include "base/bind_helpers.h"
#include "base/callback_internal.h"
+#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
#include "base/memory/weak_ptr.h"
#include "base/template_util.h"
#include "base/tuple.h"
@@ -36,12 +41,7 @@ namespace internal {
// even if the invocation syntax differs.
// RunType -- A function type (as opposed to function _pointer_ type) for
// a Run() function. Usually just a convenience typedef.
-// (Bound)ArgsType -- A function type that is being (ab)used to store the
-// types of set of arguments. The "return" type is always
-// void here. We use this hack so that we do not need
-// a new type name for each arity of type. (eg.,
-// BindState1, BindState2). This makes forward
-// declarations and friending much much easier.
+// (Bound)Args -- A set of types that stores the arguments.
//
// Types:
// RunnableAdapter<> -- Wraps the various "function" pointer types into an
@@ -53,7 +53,6 @@ namespace internal {
// signature adapters are applied.
// MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
// type class that represents the underlying Functor.
-// There are |O(1)| MakeRunnable types.
// InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
// Handle the differing syntaxes needed for WeakPtr<>
// support, and for ignoring return values. This is separate
@@ -68,17 +67,17 @@ namespace internal {
// |Sig| is a non-const reference.
// Implementation note: This non-specialized case handles zero-arity case only.
// Non-zero-arity cases should be handled by the specialization below.
-template <typename Sig>
-struct HasNonConstReferenceParam : std::false_type {};
+template <typename List>
+struct HasNonConstReferenceItem : std::false_type {};
// Implementation note: Select true_type if the first parameter is a non-const
// reference. Otherwise, skip the first parameter and check rest of parameters
// recursively.
-template <typename R, typename T, typename... Args>
-struct HasNonConstReferenceParam<R(T, Args...)>
- : SelectType<is_non_const_reference<T>::value,
- std::true_type,
- HasNonConstReferenceParam<R(Args...)>>::Type {};
+template <typename T, typename... Args>
+struct HasNonConstReferenceItem<TypeList<T, Args...>>
+ : std::conditional<is_non_const_reference<T>::value,
+ std::true_type,
+ HasNonConstReferenceItem<TypeList<Args...>>>::type {};
// HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
// pointer to a RefCounted type.
@@ -87,6 +86,15 @@ struct HasNonConstReferenceParam<R(T, Args...)>
template <typename... Args>
struct HasRefCountedTypeAsRawPtr : std::false_type {};
+// Implementation note: Select true_type if the first parameter is a raw pointer
+// to a RefCounted type. Otherwise, skip the first parameter and check rest of
+// parameters recursively.
+template <typename T, typename... Args>
+struct HasRefCountedTypeAsRawPtr<T, Args...>
+ : std::conditional<NeedsScopedRefptrButGetsRawPtr<T>::value,
+ std::true_type,
+ HasRefCountedTypeAsRawPtr<Args...>>::type {};
+
// BindsArrayToFirstArg selects true_type when |is_method| is true and the first
// item of |Args| is an array type.
// Implementation note: This non-specialized case handles !is_method case and
@@ -137,7 +145,9 @@ class RunnableAdapter;
template <typename R, typename... Args>
class RunnableAdapter<R(*)(Args...)> {
public:
- typedef R (RunType)(Args...);
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef R RunType(Args...);
explicit RunnableAdapter(R(*function)(Args...))
: function_(function) {
@@ -155,8 +165,10 @@ class RunnableAdapter<R(*)(Args...)> {
template <typename R, typename T, typename... Args>
class RunnableAdapter<R(T::*)(Args...)> {
public:
- typedef R (RunType)(T*, Args...);
- typedef std::true_type IsMethod;
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef R RunType(T*, Args...);
+ using IsMethod = std::true_type;
explicit RunnableAdapter(R(T::*method)(Args...))
: method_(method) {
@@ -174,8 +186,8 @@ class RunnableAdapter<R(T::*)(Args...)> {
template <typename R, typename T, typename... Args>
class RunnableAdapter<R(T::*)(Args...) const> {
public:
- typedef R (RunType)(const T*, Args...);
- typedef std::true_type IsMethod;
+ using RunType = R(const T*, Args...);
+ using IsMethod = std::true_type;
explicit RunnableAdapter(R(T::*method)(Args...) const)
: method_(method) {
@@ -199,7 +211,9 @@ struct ForceVoidReturn;
template <typename R, typename... Args>
struct ForceVoidReturn<R(Args...)> {
- typedef void(RunType)(Args...);
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef void RunType(Args...);
};
@@ -208,21 +222,21 @@ struct ForceVoidReturn<R(Args...)> {
// See description at top of file.
template <typename T>
struct FunctorTraits {
- typedef RunnableAdapter<T> RunnableType;
- typedef typename RunnableType::RunType RunType;
+ using RunnableType = RunnableAdapter<T>;
+ using RunType = typename RunnableType::RunType;
};
template <typename T>
struct FunctorTraits<IgnoreResultHelper<T>> {
- typedef typename FunctorTraits<T>::RunnableType RunnableType;
- typedef typename ForceVoidReturn<
- typename RunnableType::RunType>::RunType RunType;
+ using RunnableType = typename FunctorTraits<T>::RunnableType;
+ using RunType =
+ typename ForceVoidReturn<typename RunnableType::RunType>::RunType;
};
template <typename T>
struct FunctorTraits<Callback<T>> {
- typedef Callback<T> RunnableType;
- typedef typename Callback<T>::RunType RunType;
+ using RunnableType = Callback<T> ;
+ using RunType = typename Callback<T>::RunType;
};
@@ -301,8 +315,8 @@ struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
// WeakCalls are only supported for functions with a void return type.
// Otherwise, the function result would be undefined if the the WeakPtr<>
// is invalidated.
- COMPILE_ASSERT(std::is_void<ReturnType>::value,
- weak_ptrs_can_only_bind_to_methods_without_return_values);
+ static_assert(std::is_void<ReturnType>::value,
+ "weak_ptrs can only bind to methods without return values");
};
#endif
@@ -348,19 +362,18 @@ struct Invoker<IndexSequence<bound_indices...>,
// Normally, this is the same as the RunType of the Runnable, but it can
// be different if an adapter like IgnoreResult() has been used.
//
-// BoundArgsType contains the storage type for all the bound arguments by
-// (ab)using a function type.
-template <typename Runnable, typename RunType, typename BoundArgList>
+// BoundArgs contains the storage type for all the bound arguments.
+template <typename Runnable, typename RunType, typename... BoundArgs>
struct BindState;
template <typename Runnable,
typename R,
typename... Args,
typename... BoundArgs>
-struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> final
+struct BindState<Runnable, R(Args...), BoundArgs...> final
: public BindStateBase {
private:
- using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>;
+ using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
using RunnableType = Runnable;
// true_type if Runnable is a method invocation and the first bound argument
diff --git a/third_party/chromium/base/bind_unittest.cc b/third_party/chromium/base/bind_unittest.cc
index d3cc79a..f3a1211 100644
--- a/third_party/chromium/base/bind_unittest.cc
+++ b/third_party/chromium/base/bind_unittest.cc
@@ -4,13 +4,18 @@
#include "base/bind.h"
+#include <memory>
+#include <utility>
+
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "base/callback.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "build/build_config.h"
using ::testing::Mock;
using ::testing::Return;
@@ -25,11 +30,11 @@ class NoRef {
public:
NoRef() {}
- MOCK_METHOD0(VoidMethod0, void(void));
- MOCK_CONST_METHOD0(VoidConstMethod0, void(void));
+ MOCK_METHOD0(VoidMethod0, void());
+ MOCK_CONST_METHOD0(VoidConstMethod0, void());
- MOCK_METHOD0(IntMethod0, int(void));
- MOCK_CONST_METHOD0(IntConstMethod0, int(void));
+ MOCK_METHOD0(IntMethod0, int());
+ MOCK_CONST_METHOD0(IntConstMethod0, int());
private:
// Particularly important in this test to ensure no copies are made.
@@ -40,8 +45,8 @@ class HasRef : public NoRef {
public:
HasRef() {}
- MOCK_CONST_METHOD0(AddRef, void(void));
- MOCK_CONST_METHOD0(Release, bool(void));
+ MOCK_CONST_METHOD0(AddRef, void());
+ MOCK_CONST_METHOD0(Release, bool());
private:
// Particularly important in this test to ensure no copies are made.
@@ -58,8 +63,9 @@ static const int kChildValue = 2;
class Parent {
public:
- void AddRef(void) const {}
- void Release(void) const {}
+ virtual ~Parent() = default;
+ void AddRef() const {}
+ void Release() const {}
virtual void VirtualSet() { value = kParentValue; }
void NonVirtualSet() { value = kParentValue; }
int value;
@@ -67,18 +73,22 @@ class Parent {
class Child : public Parent {
public:
+ ~Child() override = default;
void VirtualSet() override { value = kChildValue; }
void NonVirtualSet() { value = kChildValue; }
};
class NoRefParent {
public:
+ virtual ~NoRefParent() = default;
virtual void VirtualSet() { value = kParentValue; }
void NonVirtualSet() { value = kParentValue; }
int value;
};
class NoRefChild : public NoRefParent {
+ public:
+ ~NoRefChild() override = default;
void VirtualSet() override { value = kChildValue; }
void NonVirtualSet() { value = kChildValue; }
};
@@ -151,7 +161,7 @@ class DeleteCounter {
template <typename T>
T PassThru(T scoper) {
- return scoper.Pass();
+ return scoper;
}
// Some test functions that we can Bind to.
@@ -160,9 +170,10 @@ T PolymorphicIdentity(T t) {
return t;
}
-template <typename T>
-void VoidPolymorphic1(T t) {
-}
+template <typename... Ts>
+struct VoidPolymorphic {
+ static void Run(Ts... t) {}
+};
int Identity(int n) {
return n;
@@ -227,11 +238,11 @@ class BindTest : public ::testing::Test {
virtual ~BindTest() {
}
- static void VoidFunc0(void) {
+ static void VoidFunc0() {
static_func_mock_ptr->VoidMethod0();
}
- static int IntFunc0(void) { return static_func_mock_ptr->IntMethod0(); }
+ static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
protected:
StrictMock<NoRef> no_ref_;
@@ -251,7 +262,7 @@ StrictMock<NoRef>* BindTest::static_func_mock_ptr;
// Sanity check that we can instantiate a callback for each arity.
TEST_F(BindTest, ArityTest) {
- Callback<int(void)> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1);
+ Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1);
EXPECT_EQ(63, c0.Run());
Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2);
@@ -293,7 +304,7 @@ TEST_F(BindTest, CurryingTest) {
Callback<int(int)> c1 = Bind(c2, 2);
EXPECT_EQ(75, c1.Run(13));
- Callback<int(void)> c0 = Bind(c1, 1);
+ Callback<int()> c0 = Bind(c1, 1);
EXPECT_EQ(63, c0.Run());
}
@@ -334,7 +345,7 @@ TEST_F(BindTest, FunctionTypeSupport) {
EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2);
Closure normal_cb = Bind(&VoidFunc0);
- Callback<NoRef*(void)> normal_non_refcounted_cb =
+ Callback<NoRef*()> normal_non_refcounted_cb =
Bind(&PolymorphicIdentity<NoRef*>, &no_ref_);
normal_cb.Run();
EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run());
@@ -376,11 +387,11 @@ TEST_F(BindTest, ReturnValues) {
.WillOnce(Return(41337))
.WillOnce(Return(51337));
- Callback<int(void)> normal_cb = Bind(&IntFunc0);
- Callback<int(void)> method_cb = Bind(&HasRef::IntMethod0, &has_ref_);
- Callback<int(void)> const_method_nonconst_obj_cb =
+ Callback<int()> normal_cb = Bind(&IntFunc0);
+ Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_);
+ Callback<int()> const_method_nonconst_obj_cb =
Bind(&HasRef::IntConstMethod0, &has_ref_);
- Callback<int(void)> const_method_const_obj_cb =
+ Callback<int()> const_method_const_obj_cb =
Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_);
EXPECT_EQ(1337, normal_cb.Run());
EXPECT_EQ(31337, method_cb.Run());
@@ -444,46 +455,46 @@ TEST_F(BindTest, IgnoreResult) {
TEST_F(BindTest, ArgumentBinding) {
int n = 2;
- Callback<int(void)> bind_primitive_cb = Bind(&Identity, n);
+ Callback<int()> bind_primitive_cb = Bind(&Identity, n);
EXPECT_EQ(n, bind_primitive_cb.Run());
- Callback<int*(void)> bind_primitive_pointer_cb =
+ Callback<int*()> bind_primitive_pointer_cb =
Bind(&PolymorphicIdentity<int*>, &n);
EXPECT_EQ(&n, bind_primitive_pointer_cb.Run());
- Callback<int(void)> bind_int_literal_cb = Bind(&Identity, 3);
+ Callback<int()> bind_int_literal_cb = Bind(&Identity, 3);
EXPECT_EQ(3, bind_int_literal_cb.Run());
- Callback<const char*(void)> bind_string_literal_cb =
+ Callback<const char*()> bind_string_literal_cb =
Bind(&CStringIdentity, "hi");
EXPECT_STREQ("hi", bind_string_literal_cb.Run());
- Callback<int(void)> bind_template_function_cb =
+ Callback<int()> bind_template_function_cb =
Bind(&PolymorphicIdentity<int>, 4);
EXPECT_EQ(4, bind_template_function_cb.Run());
NoRefParent p;
p.value = 5;
- Callback<int(void)> bind_object_cb = Bind(&UnwrapNoRefParent, p);
+ Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p);
EXPECT_EQ(5, bind_object_cb.Run());
IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
- Callback<IncompleteType*(void)> bind_incomplete_ptr_cb =
+ Callback<IncompleteType*()> bind_incomplete_ptr_cb =
Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr);
EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run());
NoRefChild c;
c.value = 6;
- Callback<int(void)> bind_promotes_cb = Bind(&UnwrapNoRefParent, c);
+ Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c);
EXPECT_EQ(6, bind_promotes_cb.Run());
c.value = 7;
- Callback<int(void)> bind_pointer_promotes_cb =
+ Callback<int()> bind_pointer_promotes_cb =
Bind(&UnwrapNoRefParentPtr, &c);
EXPECT_EQ(7, bind_pointer_promotes_cb.Run());
c.value = 8;
- Callback<int(void)> bind_const_reference_promotes_cb =
+ Callback<int()> bind_const_reference_promotes_cb =
Bind(&UnwrapNoRefParentConstRef, c);
EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
}
@@ -497,17 +508,20 @@ TEST_F(BindTest, ArgumentBinding) {
// - Unbound sized array.
// - Unbound array-of-arrays.
TEST_F(BindTest, UnboundArgumentTypeSupport) {
- Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic1<int>);
- Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic1<int*>);
- Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic1<int&>);
+ Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run);
+ Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run);
+ Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run);
Callback<void(const int&)> unbound_const_ref_cb =
- Bind(&VoidPolymorphic1<const int&>);
+ Bind(&VoidPolymorphic<const int&>::Run);
Callback<void(int[])> unbound_unsized_array_cb =
- Bind(&VoidPolymorphic1<int[]>);
+ Bind(&VoidPolymorphic<int[]>::Run);
Callback<void(int[2])> unbound_sized_array_cb =
- Bind(&VoidPolymorphic1<int[2]>);
+ Bind(&VoidPolymorphic<int[2]>::Run);
Callback<void(int[][2])> unbound_array_of_arrays_cb =
- Bind(&VoidPolymorphic1<int[][2]>);
+ Bind(&VoidPolymorphic<int[][2]>::Run);
+
+ Callback<void(int&)> unbound_ref_with_bound_arg =
+ Bind(&VoidPolymorphic<int, int&>::Run, 1);
}
// Function with unbound reference parameter.
@@ -527,12 +541,12 @@ TEST_F(BindTest, ReferenceArgumentBinding) {
int& ref_n = n;
const int& const_ref_n = n;
- Callback<int(void)> ref_copies_cb = Bind(&Identity, ref_n);
+ Callback<int()> ref_copies_cb = Bind(&Identity, ref_n);
EXPECT_EQ(n, ref_copies_cb.Run());
n++;
EXPECT_EQ(n - 1, ref_copies_cb.Run());
- Callback<int(void)> const_ref_copies_cb = Bind(&Identity, const_ref_n);
+ Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n);
EXPECT_EQ(n, const_ref_copies_cb.Run());
n++;
EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
@@ -545,10 +559,10 @@ TEST_F(BindTest, ArrayArgumentBinding) {
int array[4] = {1, 1, 1, 1};
const int (*const_array_ptr)[4] = &array;
- Callback<int(void)> array_cb = Bind(&ArrayGet, array, 1);
+ Callback<int()> array_cb = Bind(&ArrayGet, array, 1);
EXPECT_EQ(1, array_cb.Run());
- Callback<int(void)> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1);
+ Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1);
EXPECT_EQ(1, const_array_cb.Run());
array[1] = 3;
@@ -586,15 +600,15 @@ TEST_F(BindTest, Unretained) {
EXPECT_CALL(no_ref_, VoidMethod0());
EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
- Callback<void(void)> method_cb =
+ Callback<void()> method_cb =
Bind(&NoRef::VoidMethod0, Unretained(&no_ref_));
method_cb.Run();
- Callback<void(void)> const_method_cb =
+ Callback<void()> const_method_cb =
Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_));
const_method_cb.Run();
- Callback<void(void)> const_method_const_ptr_cb =
+ Callback<void()> const_method_const_ptr_cb =
Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_));
const_method_const_ptr_cb.Run();
}
@@ -646,8 +660,8 @@ TEST_F(BindTest, WeakPtr) {
TEST_F(BindTest, ConstRef) {
int n = 1;
- Callback<int(void)> copy_cb = Bind(&Identity, n);
- Callback<int(void)> const_ref_cb = Bind(&Identity, ConstRef(n));
+ Callback<int()> copy_cb = Bind(&Identity, n);
+ Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n));
EXPECT_EQ(n, copy_cb.Run());
EXPECT_EQ(n, const_ref_cb.Run());
n++;
@@ -657,7 +671,7 @@ TEST_F(BindTest, ConstRef) {
int copies = 0;
int assigns = 0;
CopyCounter counter(&copies, &assigns);
- Callback<int(void)> all_const_ref_cb =
+ Callback<int()> all_const_ref_cb =
Bind(&GetCopies, ConstRef(counter));
EXPECT_EQ(0, all_const_ref_cb.Run());
EXPECT_EQ(0, copies);
@@ -674,7 +688,7 @@ TEST_F(BindTest, ScopedRefptr) {
const scoped_refptr<StrictMock<HasRef> > refptr(&has_ref_);
- Callback<int(void)> scoped_refptr_const_ref_cb =
+ Callback<int()> scoped_refptr_const_ref_cb =
Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1);
EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run());
}
@@ -686,7 +700,7 @@ TEST_F(BindTest, Owned) {
// If we don't capture, delete happens on Callback destruction/reset.
// return the same value.
- Callback<DeleteCounter*(void)> no_capture_cb =
+ Callback<DeleteCounter*()> no_capture_cb =
Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
ASSERT_EQ(counter, no_capture_cb.Run());
ASSERT_EQ(counter, no_capture_cb.Run());
@@ -715,7 +729,7 @@ TEST_F(BindTest, ScopedPtr) {
// Tests the Passed() function's support for pointers.
scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes));
- Callback<scoped_ptr<DeleteCounter>(void)> unused_callback =
+ Callback<scoped_ptr<DeleteCounter>()> unused_callback =
Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr));
EXPECT_FALSE(ptr.get());
EXPECT_EQ(0, deletes);
@@ -727,7 +741,7 @@ TEST_F(BindTest, ScopedPtr) {
// Tests the Passed() function's support for rvalues.
deletes = 0;
DeleteCounter* counter = new DeleteCounter(&deletes);
- Callback<scoped_ptr<DeleteCounter>(void)> callback =
+ Callback<scoped_ptr<DeleteCounter>()> callback =
Bind(&PassThru<scoped_ptr<DeleteCounter> >,
Passed(scoped_ptr<DeleteCounter>(counter)));
EXPECT_FALSE(ptr.get());
@@ -750,7 +764,50 @@ TEST_F(BindTest, ScopedPtr) {
Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound =
Bind(&PassThru<scoped_ptr<DeleteCounter> >);
ptr.reset(new DeleteCounter(&deletes));
- cb_unbound.Run(ptr.Pass());
+ cb_unbound.Run(std::move(ptr));
+}
+
+TEST_F(BindTest, UniquePtr) {
+ int deletes = 0;
+
+ // Tests the Passed() function's support for pointers.
+ std::unique_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes));
+ Callback<std::unique_ptr<DeleteCounter>()> unused_callback =
+ Bind(&PassThru<std::unique_ptr<DeleteCounter>>, Passed(&ptr));
+ EXPECT_FALSE(ptr.get());
+ EXPECT_EQ(0, deletes);
+
+ // If we never invoke the Callback, it retains ownership and deletes.
+ unused_callback.Reset();
+ EXPECT_EQ(1, deletes);
+
+ // Tests the Passed() function's support for rvalues.
+ deletes = 0;
+ DeleteCounter* counter = new DeleteCounter(&deletes);
+ Callback<std::unique_ptr<DeleteCounter>()> callback =
+ Bind(&PassThru<std::unique_ptr<DeleteCounter>>,
+ Passed(std::unique_ptr<DeleteCounter>(counter)));
+ EXPECT_FALSE(ptr.get());
+ EXPECT_EQ(0, deletes);
+
+ // Check that ownership can be transferred back out.
+ std::unique_ptr<DeleteCounter> result = callback.Run();
+ ASSERT_EQ(counter, result.get());
+ EXPECT_EQ(0, deletes);
+
+ // Resetting does not delete since ownership was transferred.
+ callback.Reset();
+ EXPECT_EQ(0, deletes);
+
+ // Ensure that we actually did get ownership.
+ result.reset();
+ EXPECT_EQ(1, deletes);
+
+ // Test unbound argument forwarding.
+ Callback<std::unique_ptr<DeleteCounter>(std::unique_ptr<DeleteCounter>)>
+ cb_unbound = Bind(&PassThru<std::unique_ptr<DeleteCounter>>);
+ ptr.reset(new DeleteCounter(&deletes));
+ cb_unbound.Run(std::move(ptr));
}
// Argument Copy-constructor usage for non-reference parameters.
@@ -764,15 +821,15 @@ TEST_F(BindTest, ArgumentCopies) {
CopyCounter counter(&copies, &assigns);
- Callback<void(void)> copy_cb =
- Bind(&VoidPolymorphic1<CopyCounter>, counter);
+ Callback<void()> copy_cb =
+ Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
EXPECT_GE(1, copies);
EXPECT_EQ(0, assigns);
copies = 0;
assigns = 0;
Callback<void(CopyCounter)> forward_cb =
- Bind(&VoidPolymorphic1<CopyCounter>);
+ Bind(&VoidPolymorphic<CopyCounter>::Run);
forward_cb.Run(counter);
EXPECT_GE(1, copies);
EXPECT_EQ(0, assigns);
@@ -781,7 +838,7 @@ TEST_F(BindTest, ArgumentCopies) {
assigns = 0;
DerivedCopyCounter derived(&copies, &assigns);
Callback<void(CopyCounter)> coerce_cb =
- Bind(&VoidPolymorphic1<CopyCounter>);
+ Bind(&VoidPolymorphic<CopyCounter>::Run);
coerce_cb.Run(CopyCounter(derived));
EXPECT_GE(2, copies);
EXPECT_EQ(0, assigns);
@@ -806,10 +863,10 @@ int __stdcall StdCallFunc(int n) {
// - Can bind a __fastcall function.
// - Can bind a __stdcall function.
TEST_F(BindTest, WindowsCallingConventions) {
- Callback<int(void)> fastcall_cb = Bind(&FastCallFunc, 1);
+ Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1);
EXPECT_EQ(1, fastcall_cb.Run());
- Callback<int(void)> stdcall_cb = Bind(&StdCallFunc, 2);
+ Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2);
EXPECT_EQ(2, stdcall_cb.Run());
}
#endif
diff --git a/third_party/chromium/base/callback.h b/third_party/chromium/base/callback.h
index 00669dd..3bf0008 100644
--- a/third_party/chromium/base/callback.h
+++ b/third_party/chromium/base/callback.h
@@ -26,7 +26,7 @@
// much like lexical closures are used in other languages. For example, it
// is used in Chromium code to schedule tasks on different MessageLoops.
//
-// A callback with no unbound input parameters (base::Callback<void(void)>)
+// A callback with no unbound input parameters (base::Callback<void()>)
// is called a base::Closure. Note that this is NOT the same as what other
// languages refer to as a closure -- it does not retain a reference to its
// enclosing environment.
@@ -48,7 +48,7 @@
// BINDING A BARE FUNCTION
//
// int Return5() { return 5; }
-// base::Callback<int(void)> func_cb = base::Bind(&Return5);
+// base::Callback<int()> func_cb = base::Bind(&Return5);
// LOG(INFO) << func_cb.Run(); // Prints 5.
//
// BINDING A CLASS METHOD
@@ -62,7 +62,7 @@
// void PrintBye() { LOG(INFO) << "bye."; }
// };
// scoped_refptr<Ref> ref = new Ref();
-// base::Callback<void(void)> ref_cb = base::Bind(&Ref::Foo, ref);
+// base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref);
// LOG(INFO) << ref_cb.Run(); // Prints out 3.
//
// By default the object must support RefCounted or you will get a compiler
@@ -104,10 +104,10 @@
// calling.
//
// void MyFunc(int i, const std::string& str) {}
-// base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");
+// base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
// cb.Run();
//
-// A callback with no unbound input parameters (base::Callback<void(void)>)
+// A callback with no unbound input parameters (base::Callback<void()>)
// is called a base::Closure. So we could have also written:
//
// base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
@@ -165,7 +165,7 @@
// that doesn't expect a return value.
//
// int DoSomething(int arg) { cout << arg << endl; }
-// base::Callback<void<int>) cb =
+// base::Callback<void(int)> cb =
// base::Bind(base::IgnoreResult(&DoSomething));
//
//
@@ -175,7 +175,7 @@
//
// Bound parameters are specified as arguments to Bind() and are passed to the
// function. A callback with no parameters or no unbound parameters is called a
-// Closure (base::Callback<void(void)> and base::Closure are the same thing).
+// Closure (base::Callback<void()> and base::Closure are the same thing).
//
// PASSING PARAMETERS OWNED BY THE CALLBACK
//
@@ -354,32 +354,30 @@ namespace base {
//
// If you are thinking of forward declaring Callback in your own header file,
// please include "base/callback_forward.h" instead.
-template <typename Sig>
-class Callback;
namespace internal {
-template <typename Runnable, typename RunType, typename BoundArgsType>
+template <typename Runnable, typename RunType, typename... BoundArgsType>
struct BindState;
} // namespace internal
template <typename R, typename... Args>
class Callback<R(Args...)> : public internal::CallbackBase {
public:
- typedef R(RunType)(Args...);
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef R RunType(Args...);
- Callback() : CallbackBase(NULL) { }
+ Callback() : CallbackBase(nullptr) { }
- // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
- // return the exact Callback<> type. See base/bind.h for details.
- template <typename Runnable, typename BindRunType, typename BoundArgsType>
- Callback(internal::BindState<Runnable, BindRunType,
- BoundArgsType>* bind_state)
+ template <typename Runnable, typename BindRunType, typename... BoundArgsType>
+ explicit Callback(
+ internal::BindState<Runnable, BindRunType, BoundArgsType...>* bind_state)
: CallbackBase(bind_state) {
// Force the assignment to a local variable of PolymorphicInvoke
// so the compiler will typecheck that the passed in Run() method has
// the correct type.
PolymorphicInvoke invoke_func =
- &internal::BindState<Runnable, BindRunType, BoundArgsType>
+ &internal::BindState<Runnable, BindRunType, BoundArgsType...>
::InvokerType::Run;
polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
}
@@ -397,15 +395,11 @@ class Callback<R(Args...)> : public internal::CallbackBase {
}
private:
- typedef R(*PolymorphicInvoke)(
- internal::BindStateBase*,
- typename internal::CallbackParamTraits<Args>::ForwardType...);
+ using PolymorphicInvoke =
+ R(*)(internal::BindStateBase*,
+ typename internal::CallbackParamTraits<Args>::ForwardType...);
};
-// Syntactic sugar to make Callback<void(void)> easier to declare since it
-// will be used in a lot of APIs with delayed execution.
-typedef Callback<void(void)> Closure;
-
} // namespace base
#endif // BASE_CALLBACK_H_
diff --git a/third_party/chromium/base/callback_forward.h b/third_party/chromium/base/callback_forward.h
index 262c306..a9a263a 100644
--- a/third_party/chromium/base/callback_forward.h
+++ b/third_party/chromium/base/callback_forward.h
@@ -10,7 +10,9 @@ namespace base {
template <typename Sig>
class Callback;
-typedef Callback<void(void)> Closure;
+// Syntactic sugar to make Callback<void()> easier to declare since it
+// will be used in a lot of APIs with delayed execution.
+using Closure = Callback<void()>;
} // namespace base
diff --git a/third_party/chromium/base/callback_internal.h b/third_party/chromium/base/callback_internal.h
index 94e4f79..6339437 100644
--- a/third_party/chromium/base/callback_internal.h
+++ b/third_party/chromium/base/callback_internal.h
@@ -11,6 +11,7 @@
#include <stddef.h>
#include <map>
#include <memory>
+#include <type_traits>
#include <vector>
#include "base/base_export.h"
@@ -19,9 +20,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/template_util.h"
-template <typename T>
-class ScopedVector;
-
namespace base {
namespace internal {
class CallbackBase;
@@ -76,7 +74,7 @@ class BASE_EXPORT CallbackBase {
// another type. It is not okay to use void*. We create a InvokeFuncStorage
// that that can store our function pointer, and then cast it back to
// the original type on usage.
- typedef void(*InvokeFuncStorage)(void);
+ using InvokeFuncStorage = void(*)();
// Returns true if this callback equals |other|. |other| may be null.
bool Equals(const CallbackBase& other) const;
@@ -97,8 +95,14 @@ class BASE_EXPORT CallbackBase {
};
// A helper template to determine if given type is non-const move-only-type,
-// i.e. if a value of the given type should be passed via .Pass() in a
-// destructive way.
+// i.e. if a value of the given type should be passed via std::move() in a
+// destructive way. Types are considered to be move-only if they have a
+// sentinel MoveOnlyTypeForCPP03 member: a class typically gets this from using
+// the DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND macro.
+// It would be easy to generalize this trait to all move-only types... but this
+// confuses template deduction in VS2013 with certain types such as
+// std::unique_ptr.
+// TODO(dcheng): Revisit this when Windows switches to VS2015 by default.
template <typename T> struct IsMoveOnlyType {
template <typename U>
static YesType Test(const typename U::MoveOnlyTypeForCPP03*);
@@ -110,31 +114,10 @@ template <typename T> struct IsMoveOnlyType {
!std::is_const<T>::value;
};
-// Mark std::unique_ptr<T> and common containers using unique_ptr as MoveOnly
-// type for base::Callback, so it is stored by value and not a const reference
-// inside Callback.
-template<typename T, typename D>
-struct IsMoveOnlyType<std::unique_ptr<T, D>> : public std::true_type {};
-
-template<typename T, typename D, typename A>
-struct IsMoveOnlyType<std::vector<std::unique_ptr<T, D>, A>>
- : public std::true_type {};
-
-template<typename K, typename T, typename D, typename C, typename A>
-struct IsMoveOnlyType<std::map<K, std::unique_ptr<T, D>, C, A>>
- : public std::true_type {};
-
-// Returns |Then| as SelectType::Type if |condition| is true. Otherwise returns
-// |Else|.
-template <bool condition, typename Then, typename Else>
-struct SelectType {
- typedef Then Type;
-};
-
-template <typename Then, typename Else>
-struct SelectType<false, Then, Else> {
- typedef Else Type;
-};
+// Specialization of IsMoveOnlyType so that std::unique_ptr is still considered
+// move-only, even without the sentinel member.
+template <typename T>
+struct IsMoveOnlyType<std::unique_ptr<T>> : std::true_type {};
template <typename>
struct CallbackParamTraitsForMoveOnlyType;
@@ -159,15 +142,15 @@ struct CallbackParamTraitsForNonMoveOnlyType;
// break passing of C-string literals.
template <typename T>
struct CallbackParamTraits
- : SelectType<IsMoveOnlyType<T>::value,
+ : std::conditional<IsMoveOnlyType<T>::value,
CallbackParamTraitsForMoveOnlyType<T>,
- CallbackParamTraitsForNonMoveOnlyType<T> >::Type {
+ CallbackParamTraitsForNonMoveOnlyType<T>>::type {
};
template <typename T>
struct CallbackParamTraitsForNonMoveOnlyType {
- typedef const T& ForwardType;
- typedef T StorageType;
+ using ForwardType = const T&;
+ using StorageType = T;
};
// The Storage should almost be impossible to trigger unless someone manually
@@ -177,8 +160,8 @@ struct CallbackParamTraitsForNonMoveOnlyType {
// The ForwardType should only be used for unbound arguments.
template <typename T>
struct CallbackParamTraitsForNonMoveOnlyType<T&> {
- typedef T& ForwardType;
- typedef T StorageType;
+ using ForwardType = T&;
+ using StorageType = T;
};
// Note that for array types, we implicitly add a const in the conversion. This
@@ -188,15 +171,15 @@ struct CallbackParamTraitsForNonMoveOnlyType<T&> {
// restriction.
template <typename T, size_t n>
struct CallbackParamTraitsForNonMoveOnlyType<T[n]> {
- typedef const T* ForwardType;
- typedef const T* StorageType;
+ using ForwardType = const T*;
+ using StorageType = const T*;
};
// See comment for CallbackParamTraits<T[n]>.
template <typename T>
struct CallbackParamTraitsForNonMoveOnlyType<T[]> {
- typedef const T* ForwardType;
- typedef const T* StorageType;
+ using ForwardType = const T*;
+ using StorageType = const T*;
};
// Parameter traits for movable-but-not-copyable scopers.
@@ -214,8 +197,8 @@ struct CallbackParamTraitsForNonMoveOnlyType<T[]> {
// function or a cast would not be usable with Callback<> or Bind().
template <typename T>
struct CallbackParamTraitsForMoveOnlyType {
- typedef T ForwardType;
- typedef T StorageType;
+ using ForwardType = T;
+ using StorageType = T;
};
// CallbackForward() is a very limited simulation of C++11's std::forward()
@@ -227,7 +210,7 @@ struct CallbackParamTraitsForMoveOnlyType {
// default template compiles out to be a no-op.
//
// In C++11, std::forward would replace all uses of this function. However, it
-// is impossible to implement a general std::forward with C++11 due to a lack
+// is impossible to implement a general std::forward without C++11 due to a lack
// of rvalue references.
//
// In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to
@@ -243,26 +226,6 @@ typename std::enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward(
template <typename T>
typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(
T& t) {
- return t.Pass();
-}
-
-// Overload base::internal::CallbackForward() to forward unique_ptr and common
-// containers with unique_ptr by using std::move instead of default T::Pass()
-// used with scoped_ptr<U>.
-template <typename T, typename D>
-std::unique_ptr<T, D> CallbackForward(std::unique_ptr<T, D>& t) {
- return std::move(t);
-}
-
-template <typename T, typename D, typename A>
-std::vector<std::unique_ptr<T, D>, A>
-CallbackForward(std::vector<std::unique_ptr<T, D>, A>& t) {
- return std::move(t);
-}
-
-template <typename K, typename T, typename D, typename C, typename A>
-std::map<K, std::unique_ptr<T, D>, C, A>
-CallbackForward(std::map<K, std::unique_ptr<T, D>, C, A>& t) {
return std::move(t);
}
diff --git a/third_party/chromium/base/callback_list.h b/third_party/chromium/base/callback_list.h
index aeed5f1..7d6a478 100644
--- a/third_party/chromium/base/callback_list.h
+++ b/third_party/chromium/base/callback_list.h
@@ -7,11 +7,11 @@
#include <list>
-#include "base/basictypes.h"
#include "base/callback.h"
#include "base/callback_internal.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
// OVERVIEW:
@@ -185,10 +185,10 @@ class CallbackListBase {
} else {
++it;
}
-
- if (updated && !removal_callback_.is_null())
- removal_callback_.Run();
}
+
+ if (updated && !removal_callback_.is_null())
+ removal_callback_.Run();
}
private:
diff --git a/third_party/chromium/base/callback_list_unittest.cc b/third_party/chromium/base/callback_list_unittest.cc
index 3b50622..937910e 100644
--- a/third_party/chromium/base/callback_list_unittest.cc
+++ b/third_party/chromium/base/callback_list_unittest.cc
@@ -5,10 +5,11 @@
#include "base/callback_list.h"
#include <gtest/gtest.h>
+#include <utility>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
namespace base {
@@ -38,7 +39,7 @@ class Remover {
}
void SetSubscriptionToRemove(
scoped_ptr<CallbackList<void(void)>::Subscription> sub) {
- removal_subscription_ = sub.Pass();
+ removal_subscription_ = std::move(sub);
}
int total() const { return total_; }
@@ -99,6 +100,19 @@ class Summer {
DISALLOW_COPY_AND_ASSIGN(Summer);
};
+class Counter {
+ public:
+ Counter() : value_(0) {}
+
+ void Increment() { value_++; }
+
+ int value() const { return value_; }
+
+ private:
+ int value_;
+ DISALLOW_COPY_AND_ASSIGN(Counter);
+};
+
// Sanity check that we can instantiate a CallbackList for each arity.
TEST(CallbackListTest, ArityTest) {
Summer s;
@@ -235,9 +249,9 @@ TEST(CallbackListTest, RemoveCallbacksDuringIteration) {
cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));
// |remover_1| will remove itself.
- remover_1.SetSubscriptionToRemove(remover_1_sub.Pass());
+ remover_1.SetSubscriptionToRemove(std::move(remover_1_sub));
// |remover_2| will remove a.
- remover_2.SetSubscriptionToRemove(a_subscription.Pass());
+ remover_2.SetSubscriptionToRemove(std::move(a_subscription));
cb_reg.Notify();
@@ -288,5 +302,37 @@ TEST(CallbackListTest, EmptyList) {
cb_reg.Notify();
}
+TEST(CallbackList, RemovalCallback) {
+ Counter remove_count;
+ CallbackList<void(void)> cb_reg;
+ cb_reg.set_removal_callback(
+ Bind(&Counter::Increment, Unretained(&remove_count)));
+
+ scoped_ptr<CallbackList<void(void)>::Subscription> subscription =
+ cb_reg.Add(Bind(&DoNothing));
+
+ // Removing a subscription outside of iteration signals the callback.
+ EXPECT_EQ(0, remove_count.value());
+ subscription.reset();
+ EXPECT_EQ(1, remove_count.value());
+
+ // Configure two subscriptions to remove themselves.
+ Remover remover_1, remover_2;
+ scoped_ptr<CallbackList<void(void)>::Subscription> remover_1_sub =
+ cb_reg.Add(Bind(&Remover::IncrementTotalAndRemove,
+ Unretained(&remover_1)));
+ scoped_ptr<CallbackList<void(void)>::Subscription> remover_2_sub =
+ cb_reg.Add(Bind(&Remover::IncrementTotalAndRemove,
+ Unretained(&remover_2)));
+ remover_1.SetSubscriptionToRemove(std::move(remover_1_sub));
+ remover_2.SetSubscriptionToRemove(std::move(remover_2_sub));
+
+ // The callback should be signaled exactly once.
+ EXPECT_EQ(1, remove_count.value());
+ cb_reg.Notify();
+ EXPECT_EQ(2, remove_count.value());
+ EXPECT_TRUE(cb_reg.empty());
+}
+
} // namespace
} // namespace base
diff --git a/third_party/chromium/base/callback_unittest.cc b/third_party/chromium/base/callback_unittest.cc
index 3630176..bf9d76f 100644
--- a/third_party/chromium/base/callback_unittest.cc
+++ b/third_party/chromium/base/callback_unittest.cc
@@ -16,7 +16,9 @@ namespace base {
namespace {
struct FakeInvoker {
- typedef void(RunType)(internal::BindStateBase*);
+ // MSVC 2013 doesn't support Type Alias of function types.
+ // Revisit this after we update it to newer version.
+ typedef void RunType(internal::BindStateBase*);
static void Run(internal::BindStateBase*) {
}
};
@@ -24,8 +26,6 @@ struct FakeInvoker {
} // namespace
namespace internal {
-template <typename Runnable, typename RunType, typename BoundArgsType>
-struct BindState;
// White-box testpoints to inject into a Callback<> object for checking
// comparators and emptiness APIs. Use a BindState that is specialized
@@ -33,11 +33,11 @@ struct BindState;
// chance of colliding with another instantiation and breaking the
// one-definition-rule.
template <>
-struct BindState<void(void), void(void), void(FakeInvoker)>
+struct BindState<void(), void(), FakeInvoker>
: public BindStateBase {
public:
BindState() : BindStateBase(&Destroy) {}
- typedef FakeInvoker InvokerType;
+ using InvokerType = FakeInvoker;
private:
~BindState() {}
static void Destroy(BindStateBase* self) {
@@ -46,12 +46,11 @@ struct BindState<void(void), void(void), void(FakeInvoker)>
};
template <>
-struct BindState<void(void), void(void),
- void(FakeInvoker, FakeInvoker)>
+struct BindState<void(), void(), FakeInvoker, FakeInvoker>
: public BindStateBase {
public:
BindState() : BindStateBase(&Destroy) {}
- typedef FakeInvoker InvokerType;
+ using InvokerType = FakeInvoker;
private:
~BindState() {}
static void Destroy(BindStateBase* self) {
@@ -62,11 +61,9 @@ struct BindState<void(void), void(void),
namespace {
-typedef internal::BindState<void(void), void(void), void(FakeInvoker)>
- FakeBindState1;
-typedef internal::BindState<void(void), void(void),
- void(FakeInvoker, FakeInvoker)>
- FakeBindState2;
+using FakeBindState1 = internal::BindState<void(), void(), FakeInvoker>;
+using FakeBindState2 =
+ internal::BindState<void(), void(), FakeInvoker, FakeInvoker>;
class CallbackTest : public ::testing::Test {
public:
@@ -78,15 +75,15 @@ class CallbackTest : public ::testing::Test {
~CallbackTest() override {}
protected:
- Callback<void(void)> callback_a_;
- const Callback<void(void)> callback_b_; // Ensure APIs work with const.
- Callback<void(void)> null_callback_;
+ Callback<void()> callback_a_;
+ const Callback<void()> callback_b_; // Ensure APIs work with const.
+ Callback<void()> null_callback_;
};
// Ensure we can create unbound callbacks. We need this to be able to store
// them in class members that can be initialized later.
TEST_F(CallbackTest, DefaultConstruction) {
- Callback<void(void)> c0;
+ Callback<void()> c0;
Callback<void(int)> c1;
Callback<void(int,int)> c2;
Callback<void(int,int,int)> c3;
@@ -115,13 +112,13 @@ TEST_F(CallbackTest, Equals) {
EXPECT_FALSE(callback_b_.Equals(callback_a_));
// We should compare based on instance, not type.
- Callback<void(void)> callback_c(new FakeBindState1());
- Callback<void(void)> callback_a2 = callback_a_;
+ Callback<void()> callback_c(new FakeBindState1());
+ Callback<void()> callback_a2 = callback_a_;
EXPECT_TRUE(callback_a_.Equals(callback_a2));
EXPECT_FALSE(callback_a_.Equals(callback_c));
// Empty, however, is always equal to empty.
- Callback<void(void)> empty2;
+ Callback<void()> empty2;
EXPECT_TRUE(null_callback_.Equals(empty2));
}
diff --git a/third_party/chromium/base/compiler_specific.h b/third_party/chromium/base/compiler_specific.h
index 63297dc..339e9b7 100644
--- a/third_party/chromium/base/compiler_specific.h
+++ b/third_party/chromium/base/compiler_specific.h
@@ -9,6 +9,9 @@
#if defined(COMPILER_MSVC)
+// For _Printf_format_string_.
+#include <sal.h>
+
// Macros for suppressing and disabling warnings on MSVC.
//
// Warning numbers are enumerated at:
@@ -57,6 +60,7 @@
#else // Not MSVC
+#define _Printf_format_string_
#define MSVC_SUPPRESS_WARNING(n)
#define MSVC_PUSH_DISABLE_WARNING(n)
#define MSVC_PUSH_WARNING_LEVEL(n)
@@ -68,28 +72,6 @@
#endif // COMPILER_MSVC
-// The C++ standard requires that static const members have an out-of-class
-// definition (in a single compilation unit), but MSVC chokes on this (when
-// language extensions, which are required, are enabled). (You're only likely to
-// notice the need for a definition if you take the address of the member or,
-// more commonly, pass it to a function that takes it as a reference argument --
-// probably an STL function.) This macro makes MSVC do the right thing. See
-// http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx for more
-// information. Use like:
-//
-// In .h file:
-// struct Foo {
-// static const int kBar = 5;
-// };
-//
-// In .cc file:
-// STATIC_CONST_MEMBER_DEFINITION const int Foo::kBar;
-#if defined(COMPILER_MSVC)
-#define STATIC_CONST_MEMBER_DEFINITION __declspec(selectany)
-#else
-#define STATIC_CONST_MEMBER_DEFINITION
-#endif
-
// Annotate a variable indicating it's ok if the variable is not used.
// (Typically used to silence a compiler warning when the assignment
// is important for some other reason.)
@@ -101,7 +83,7 @@
// Annotate a typedef or function indicating it's ok if it's not used.
// Use like:
// typedef Foo Bar ALLOW_UNUSED_TYPE;
-#if defined(COMPILER_GCC)
+#if defined(COMPILER_GCC) || defined(__clang__)
#define ALLOW_UNUSED_TYPE __attribute__((unused))
#else
#define ALLOW_UNUSED_TYPE
@@ -130,7 +112,7 @@
// Return the byte alignment of the given type (available at compile time).
// Use like:
-// ALIGNOF(int32) // this would be 4
+// ALIGNOF(int32_t) // this would be 4
#if defined(COMPILER_MSVC)
#define ALIGNOF(type) __alignof(type)
#elif defined(COMPILER_GCC)
@@ -140,8 +122,9 @@
// Annotate a function indicating the caller must examine the return value.
// Use like:
// int foo() WARN_UNUSED_RESULT;
-// To explicitly ignore a result, see |ignore_result()| in <base/basictypes.h>.
-#if defined(COMPILER_GCC)
+// To explicitly ignore a result, see |ignore_result()| in base/macros.h.
+#undef WARN_UNUSED_RESULT
+#if defined(COMPILER_GCC) || defined(__clang__)
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
diff --git a/third_party/chromium/base/guid.h b/third_party/chromium/base/guid.h
index 11fd812..1bb9ab2 100644
--- a/third_party/chromium/base/guid.h
+++ b/third_party/chromium/base/guid.h
@@ -5,10 +5,11 @@
#ifndef BASE_GUID_H_
#define BASE_GUID_H_
+#include <stdint.h>
+
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "build/build_config.h"
namespace base {
@@ -21,7 +22,7 @@ std::string GenerateGUID();
#if defined(OS_POSIX)
// For unit testing purposes only. Do not use outside of tests.
-std::string RandomDataToGUIDString(const uint64 bytes[2]);
+std::string RandomDataToGUIDString(const uint64_t bytes[2]);
#endif
} // namespace base
diff --git a/third_party/chromium/base/guid_posix.cc b/third_party/chromium/base/guid_posix.cc
index f0fedc2..ec1ca51 100644
--- a/third_party/chromium/base/guid_posix.cc
+++ b/third_party/chromium/base/guid_posix.cc
@@ -4,13 +4,15 @@
#include "base/guid.h"
+#include <stdint.h>
+
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
namespace base {
std::string GenerateGUID() {
- uint64 sixteen_bytes[2] = { base::RandUint64(), base::RandUint64() };
+ uint64_t sixteen_bytes[2] = {base::RandUint64(), base::RandUint64()};
// Set the GUID to version 4 as described in RFC 4122, section 4.4.
// The format of GUID version 4 must be xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,
@@ -30,7 +32,7 @@ std::string GenerateGUID() {
// TODO(cmasone): Once we're comfortable this works, migrate Windows code to
// use this as well.
-std::string RandomDataToGUIDString(const uint64 bytes[2]) {
+std::string RandomDataToGUIDString(const uint64_t bytes[2]) {
return StringPrintf("%08X-%04X-%04X-%04X-%012llX",
static_cast<unsigned int>(bytes[0] >> 32),
static_cast<unsigned int>((bytes[0] >> 16) & 0x0000ffff),
diff --git a/third_party/chromium/base/guid_unittest.cc b/third_party/chromium/base/guid_unittest.cc
index 37b4edc..acbd1a2 100644
--- a/third_party/chromium/base/guid_unittest.cc
+++ b/third_party/chromium/base/guid_unittest.cc
@@ -4,11 +4,14 @@
#include "base/guid.h"
+#include <stdint.h>
+
#include <limits>
#include <gtest/gtest.h>
#include "base/strings/string_util.h"
+#include "build/build_config.h"
namespace base {
@@ -53,13 +56,13 @@ bool IsGUIDv4(const std::string& guid) {
} // namespace
TEST(GUIDTest, GUIDGeneratesAllZeroes) {
- uint64 bytes[] = { 0, 0 };
+ uint64_t bytes[] = {0, 0};
std::string clientid = RandomDataToGUIDString(bytes);
EXPECT_EQ("00000000-0000-0000-0000-000000000000", clientid);
}
TEST(GUIDTest, GUIDGeneratesCorrectly) {
- uint64 bytes[] = { 0x0123456789ABCDEFULL, 0xFEDCBA9876543210ULL };
+ uint64_t bytes[] = {0x0123456789ABCDEFULL, 0xFEDCBA9876543210ULL};
std::string clientid = RandomDataToGUIDString(bytes);
EXPECT_EQ("01234567-89AB-CDEF-FEDC-BA9876543210", clientid);
}
diff --git a/third_party/chromium/base/json/json_parser.cc b/third_party/chromium/base/json/json_parser.cc
index 964fcd4..304a7bd 100644
--- a/third_party/chromium/base/json/json_parser.cc
+++ b/third_party/chromium/base/json/json_parser.cc
@@ -7,6 +7,7 @@
#include <cmath>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
@@ -23,14 +24,14 @@ namespace {
const int kStackMaxDepth = 100;
-const int32 kExtendedASCIIStart = 0x80;
+const int32_t kExtendedASCIIStart = 0x80;
// This and the class below are used to own the JSON input string for when
// string tokens are stored as StringPiece instead of std::string. This
// optimization avoids about 2/3rds of string memory copies. The constructor
// takes ownership of the input string. The real root value is Swap()ed into
// the new instance.
-class DictionaryHiddenRootValue : public base::DictionaryValue {
+class DictionaryHiddenRootValue : public DictionaryValue {
public:
DictionaryHiddenRootValue(std::string* json, Value* root) : json_(json) {
DCHECK(root->IsType(Value::TYPE_DICTIONARY));
@@ -42,7 +43,7 @@ class DictionaryHiddenRootValue : public base::DictionaryValue {
// First deep copy to convert JSONStringValue to std::string and swap that
// copy with |other|, which contains the new contents of |this|.
- scoped_ptr<base::DictionaryValue> copy(DeepCopy());
+ scoped_ptr<DictionaryValue> copy(DeepCopy());
copy->Swap(other);
// Then erase the contents of the current dictionary and swap in the
@@ -80,7 +81,7 @@ class DictionaryHiddenRootValue : public base::DictionaryValue {
DISALLOW_COPY_AND_ASSIGN(DictionaryHiddenRootValue);
};
-class ListHiddenRootValue : public base::ListValue {
+class ListHiddenRootValue : public ListValue {
public:
ListHiddenRootValue(std::string* json, Value* root) : json_(json) {
DCHECK(root->IsType(Value::TYPE_LIST));
@@ -92,7 +93,7 @@ class ListHiddenRootValue : public base::ListValue {
// First deep copy to convert JSONStringValue to std::string and swap that
// copy with |other|, which contains the new contents of |this|.
- scoped_ptr<base::ListValue> copy(DeepCopy());
+ scoped_ptr<ListValue> copy(DeepCopy());
copy->Swap(other);
// Then erase the contents of the current list and swap in the new contents,
@@ -129,14 +130,14 @@ class ListHiddenRootValue : public base::ListValue {
// A variant on StringValue that uses StringPiece instead of copying the string
// into the Value. This can only be stored in a child of hidden root (above),
// otherwise the referenced string will not be guaranteed to outlive it.
-class JSONStringValue : public base::Value {
+class JSONStringValue : public Value {
public:
- explicit JSONStringValue(const base::StringPiece& piece)
+ explicit JSONStringValue(const StringPiece& piece)
: Value(TYPE_STRING),
string_piece_(piece) {
}
- // Overridden from base::Value:
+ // Overridden from Value:
bool GetAsString(std::string* out_value) const override {
string_piece_.CopyToString(out_value);
return true;
@@ -152,7 +153,7 @@ class JSONStringValue : public base::Value {
private:
// The location in the original input stream.
- base::StringPiece string_piece_;
+ StringPiece string_piece_;
DISALLOW_COPY_AND_ASSIGN(JSONStringValue);
};
@@ -222,9 +223,9 @@ Value* JSONParser::Parse(const StringPiece& input) {
// <0xEF 0xBB 0xBF>, advance the start position to avoid the
// ParseNextToken function mis-treating a Unicode BOM as an invalid
// character and returning NULL.
- if (CanConsume(3) && static_cast<uint8>(*pos_) == 0xEF &&
- static_cast<uint8>(*(pos_ + 1)) == 0xBB &&
- static_cast<uint8>(*(pos_ + 2)) == 0xBF) {
+ if (CanConsume(3) && static_cast<uint8_t>(*pos_) == 0xEF &&
+ static_cast<uint8_t>(*(pos_ + 1)) == 0xBB &&
+ static_cast<uint8_t>(*(pos_ + 2)) == 0xBF) {
NextNChars(3);
}
@@ -269,6 +270,14 @@ std::string JSONParser::GetErrorMessage() const {
JSONReader::ErrorCodeToString(error_code_));
}
+int JSONParser::error_line() const {
+ return error_line_;
+}
+
+int JSONParser::error_column() const {
+ return error_column_;
+}
+
// StringBuilder ///////////////////////////////////////////////////////////////
JSONParser::StringBuilder::StringBuilder()
@@ -608,7 +617,7 @@ bool JSONParser::ConsumeStringRaw(StringBuilder* out) {
StringBuilder string(NextChar());
int length = end_pos_ - start_pos_;
- int32 next_char = 0;
+ int32_t next_char = 0;
while (CanConsume(1)) {
pos_ = start_pos_ + index_; // CBU8_NEXT is postcrement.
@@ -769,13 +778,19 @@ bool JSONParser::DecodeUTF16(std::string* dest_string) {
return false;
}
- uint32 code_point = CBU16_GET_SUPPLEMENTARY(code_unit16_high,
- code_unit16_low);
+ uint32_t code_point =
+ CBU16_GET_SUPPLEMENTARY(code_unit16_high, code_unit16_low);
+ if (!IsValidCharacter(code_point))
+ return false;
+
offset = 0;
CBU8_APPEND_UNSAFE(code_unit8, offset, code_point);
} else {
// Not a surrogate.
DCHECK(CBU16_IS_SINGLE(code_unit16_high));
+ if (!IsValidCharacter(code_unit16_high))
+ return false;
+
CBU8_APPEND_UNSAFE(code_unit8, offset, code_unit16_high);
}
@@ -783,9 +798,11 @@ bool JSONParser::DecodeUTF16(std::string* dest_string) {
return true;
}
-void JSONParser::DecodeUTF8(const int32& point, StringBuilder* dest) {
+void JSONParser::DecodeUTF8(const int32_t& point, StringBuilder* dest) {
+ DCHECK(IsValidCharacter(point));
+
// Anything outside of the basic ASCII plane will need to be decoded from
- // int32 to a multi-byte sequence.
+ // int32_t to a multi-byte sequence.
if (point < kExtendedASCIIStart) {
dest->Append(static_cast<char>(point));
} else {
@@ -867,7 +884,7 @@ Value* JSONParser::ConsumeNumber() {
return new FundamentalValue(num_int);
double num_double;
- if (base::StringToDouble(num_string.as_string(), &num_double) &&
+ if (StringToDouble(num_string.as_string(), &num_double) &&
std::isfinite(num_double)) {
return new FundamentalValue(num_double);
}
diff --git a/third_party/chromium/base/json/json_parser.h b/third_party/chromium/base/json/json_parser.h
index c8ed0cd..fc04594 100644
--- a/third_party/chromium/base/json/json_parser.h
+++ b/third_party/chromium/base/json/json_parser.h
@@ -5,20 +5,22 @@
#ifndef BASE_JSON_JSON_PARSER_H_
#define BASE_JSON_JSON_PARSER_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/json/json_reader.h"
+#include "base/macros.h"
#include "base/strings/string_piece.h"
namespace base {
+
class Value;
-}
-namespace base {
namespace internal {
class JSONParserTest;
@@ -41,7 +43,7 @@ class JSONParserTest;
// of a token, such that the next iteration of the parser will be at the byte
// immediately following the token, which would likely be the first byte of the
// next token.
-class BASE_EXPORT_PRIVATE JSONParser {
+class BASE_EXPORT JSONParser {
public:
explicit JSONParser(int options);
~JSONParser();
@@ -56,6 +58,14 @@ class BASE_EXPORT_PRIVATE JSONParser {
// Returns the human-friendly error message.
std::string GetErrorMessage() const;
+ // Returns the error line number if parse error happened. Otherwise always
+ // returns 0.
+ int error_line() const;
+
+ // Returns the error column number if parse error happened. Otherwise always
+ // returns 0.
+ int error_column() const;
+
private:
enum Token {
T_OBJECT_BEGIN, // {
@@ -181,7 +191,7 @@ class BASE_EXPORT_PRIVATE JSONParser {
// Helper function for ConsumeStringRaw() that takes a single code point,
// decodes it into UTF-8 units, and appends it to the given builder. The
// point must be valid.
- void DecodeUTF8(const int32& point, StringBuilder* dest);
+ void DecodeUTF8(const int32_t& point, StringBuilder* dest);
// Assuming that the parser is wound to the start of a valid JSON number,
// this parses and converts it to either an int or double value.
diff --git a/third_party/chromium/base/json/json_parser_unittest.cc b/third_party/chromium/base/json/json_parser_unittest.cc
index c432eee..956e277 100644
--- a/third_party/chromium/base/json/json_parser_unittest.cc
+++ b/third_party/chromium/base/json/json_parser_unittest.cc
@@ -4,6 +4,8 @@
#include "base/json/json_parser.h"
+#include <stddef.h>
+
#include <gtest/gtest.h>
#include "base/json/json_reader.h"
@@ -204,17 +206,16 @@ TEST_F(JSONParserTest, ErrorMessages) {
// Error strings should not be modified in case of success.
std::string error_message;
int error_code = 0;
- scoped_ptr<Value> root;
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[42]", JSON_PARSE_RFC, &error_code, &error_message));
+ scoped_ptr<Value> root = JSONReader::ReadAndReturnError(
+ "[42]", JSON_PARSE_RFC, &error_code, &error_message);
EXPECT_TRUE(error_message.empty());
EXPECT_EQ(0, error_code);
// Test line and column counting
const char big_json[] = "[\n0,\n1,\n2,\n3,4,5,6 7,\n8,\n9\n]";
// error here ----------------------------------^
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- big_json, JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError(big_json, JSON_PARSE_RFC, &error_code,
+ &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(5, 10, JSONReader::kSyntaxError),
error_message);
@@ -226,16 +227,16 @@ TEST_F(JSONParserTest, ErrorMessages) {
const char big_json_crlf[] =
"[\r\n0,\r\n1,\r\n2,\r\n3,4,5,6 7,\r\n8,\r\n9\r\n]";
// error here ----------------------^
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- big_json_crlf, JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError(big_json_crlf, JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(5, 10, JSONReader::kSyntaxError),
error_message);
EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
// Test each of the error conditions
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "{},{}", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("{},{}", JSON_PARSE_RFC, &error_code,
+ &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 3,
JSONReader::kUnexpectedDataAfterRoot), error_message);
@@ -246,56 +247,56 @@ TEST_F(JSONParserTest, ErrorMessages) {
nested_json.insert(nested_json.begin(), '[');
nested_json.append(1, ']');
}
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- nested_json, JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError(nested_json, JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 100, JSONReader::kTooMuchNesting),
error_message);
EXPECT_EQ(JSONReader::JSON_TOO_MUCH_NESTING, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[1,]", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("[1,]", JSON_PARSE_RFC, &error_code,
+ &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 4, JSONReader::kTrailingComma),
error_message);
EXPECT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "{foo:\"bar\"}", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("{foo:\"bar\"}", JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2,
JSONReader::kUnquotedDictionaryKey), error_message);
EXPECT_EQ(JSONReader::JSON_UNQUOTED_DICTIONARY_KEY, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "{\"foo\":\"bar\",}", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("{\"foo\":\"bar\",}", JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 14, JSONReader::kTrailingComma),
error_message);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[nu]", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("[nu]", JSON_PARSE_RFC, &error_code,
+ &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 2, JSONReader::kSyntaxError),
error_message);
EXPECT_EQ(JSONReader::JSON_SYNTAX_ERROR, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[\"xxx\\xq\"]", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("[\"xxx\\xq\"]", JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
error_message);
EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[\"xxx\\uq\"]", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("[\"xxx\\uq\"]", JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
error_message);
EXPECT_EQ(JSONReader::JSON_INVALID_ESCAPE, error_code);
- root.reset(JSONReader::DeprecatedReadAndReturnError(
- "[\"xxx\\q\"]", JSON_PARSE_RFC, &error_code, &error_message));
+ root = JSONReader::ReadAndReturnError("[\"xxx\\q\"]", JSON_PARSE_RFC,
+ &error_code, &error_message);
EXPECT_FALSE(root.get());
EXPECT_EQ(JSONParser::FormatErrorMessage(1, 7, JSONReader::kInvalidEscape),
error_message);
@@ -309,10 +310,18 @@ TEST_F(JSONParserTest, Decode4ByteUtf8Char) {
"[\"😇\",[],[],[],{\"google:suggesttype\":[]}]";
std::string error_message;
int error_code = 0;
- scoped_ptr<Value> root(JSONReader::DeprecatedReadAndReturnError(
- kUtf8Data, JSON_PARSE_RFC, &error_code, &error_message));
+ scoped_ptr<Value> root = JSONReader::ReadAndReturnError(
+ kUtf8Data, JSON_PARSE_RFC, &error_code, &error_message);
EXPECT_TRUE(root.get()) << error_message;
}
+TEST_F(JSONParserTest, DecodeUnicodeNonCharacter) {
+ // Tests Unicode code points (encoded as escaped UTF-16) that are not valid
+ // characters.
+ EXPECT_FALSE(JSONReader::Read("[\"\\ufdd0\"]"));
+ EXPECT_FALSE(JSONReader::Read("[\"\\ufffe\"]"));
+ EXPECT_FALSE(JSONReader::Read("[\"\\ud83f\\udffe\"]"));
+}
+
} // namespace internal
} // namespace base
diff --git a/third_party/chromium/base/json/json_reader.cc b/third_party/chromium/base/json/json_reader.cc
index edff8dc..3ab5f75 100644
--- a/third_party/chromium/base/json/json_reader.cc
+++ b/third_party/chromium/base/json/json_reader.cc
@@ -11,8 +11,8 @@
namespace base {
// Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
-COMPILE_ASSERT(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
- json_reader_error_out_of_bounds);
+static_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
+ "JSONReader error out of bounds");
const char JSONReader::kInvalidEscape[] =
"Invalid escape sequence.";
@@ -43,41 +43,25 @@ JSONReader::~JSONReader() {
}
// static
-Value* JSONReader::DeprecatedRead(const std::string& json) {
- return Read(json).release();
-}
-
-// static
-scoped_ptr<Value> JSONReader::Read(const std::string& json) {
+scoped_ptr<Value> JSONReader::Read(const StringPiece& json) {
internal::JSONParser parser(JSON_PARSE_RFC);
return make_scoped_ptr(parser.Parse(json));
}
// static
-Value* JSONReader::DeprecatedRead(const std::string& json, int options) {
- return Read(json, options).release();
-}
-
-// static
-scoped_ptr<Value> JSONReader::Read(const std::string& json, int options) {
+scoped_ptr<Value> JSONReader::Read(const StringPiece& json, int options) {
internal::JSONParser parser(options);
return make_scoped_ptr(parser.Parse(json));
}
-// static
-Value* JSONReader::DeprecatedReadAndReturnError(const std::string& json,
- int options,
- int* error_code_out,
- std::string* error_msg_out) {
- return ReadAndReturnError(json, options, error_code_out, error_msg_out)
- .release();
-}
// static
-scoped_ptr<Value> JSONReader::ReadAndReturnError(const std::string& json,
+scoped_ptr<Value> JSONReader::ReadAndReturnError(const StringPiece& json,
int options,
int* error_code_out,
- std::string* error_msg_out) {
+ std::string* error_msg_out,
+ int* error_line_out,
+ int* error_column_out) {
internal::JSONParser parser(options);
scoped_ptr<Value> root(parser.Parse(json));
if (!root) {
@@ -85,6 +69,10 @@ scoped_ptr<Value> JSONReader::ReadAndReturnError(const std::string& json,
*error_code_out = parser.error_code();
if (error_msg_out)
*error_msg_out = parser.GetErrorMessage();
+ if (error_line_out)
+ *error_line_out = parser.error_line();
+ if (error_column_out)
+ *error_column_out = parser.error_column();
}
return root;
diff --git a/third_party/chromium/base/json/json_reader.h b/third_party/chromium/base/json/json_reader.h
index e177ab8..c6bcb52 100644
--- a/third_party/chromium/base/json/json_reader.h
+++ b/third_party/chromium/base/json/json_reader.h
@@ -31,8 +31,8 @@
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
namespace base {
@@ -93,30 +93,23 @@ class BASE_EXPORT JSONReader {
// Reads and parses |json|, returning a Value. The caller owns the returned
// instance. If |json| is not a properly formed JSON string, returns NULL.
- static scoped_ptr<Value> Read(const std::string& json);
- // TODO(estade): remove this bare pointer version.
- static Value* DeprecatedRead(const std::string& json);
+ static scoped_ptr<Value> Read(const StringPiece& json);
// Reads and parses |json|, returning a Value owned by the caller. The
// parser respects the given |options|. If the input is not properly formed,
// returns NULL.
- static scoped_ptr<Value> Read(const std::string& json, int options);
- // TODO(estade): remove this bare pointer version.
- static Value* DeprecatedRead(const std::string& json, int options);
+ static scoped_ptr<Value> Read(const StringPiece& json, int options);
// Reads and parses |json| like Read(). |error_code_out| and |error_msg_out|
// are optional. If specified and NULL is returned, they will be populated
// an error code and a formatted error message (including error location if
// appropriate). Otherwise, they will be unmodified.
- static scoped_ptr<Value> ReadAndReturnError(const std::string& json,
+ static scoped_ptr<Value> ReadAndReturnError(const StringPiece& json,
int options, // JSONParserOptions
int* error_code_out,
- std::string* error_msg_out);
- // TODO(estade): remove this bare pointer version.
- static Value* DeprecatedReadAndReturnError(const std::string& json,
- int options, // JSONParserOptions
- int* error_code_out,
- std::string* error_msg_out);
+ std::string* error_msg_out,
+ int* error_line_out = nullptr,
+ int* error_column_out = nullptr);
// Converts a JSON parse error code into a human readable message.
// Returns an empty string if error_code is JSON_NO_ERROR.
diff --git a/third_party/chromium/base/json/json_reader_unittest.cc b/third_party/chromium/base/json/json_reader_unittest.cc
index 35becef..2bfd10e 100644
--- a/third_party/chromium/base/json/json_reader_unittest.cc
+++ b/third_party/chromium/base/json/json_reader_unittest.cc
@@ -4,9 +4,12 @@
#include "base/json/json_reader.h"
+#include <stddef.h>
+
#include <gtest/gtest.h>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversion_utils.h"
@@ -17,8 +20,7 @@ namespace base {
TEST(JSONReaderTest, Reading) {
// some whitespace checking
- scoped_ptr<Value> root;
- root = JSONReader().ReadToValue(" null ");
+ scoped_ptr<Value> root = JSONReader().ReadToValue(" null ");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
@@ -240,61 +242,56 @@ TEST(JSONReaderTest, Reading) {
EXPECT_FALSE(root.get());
// Basic array
- root.reset(JSONReader::DeprecatedRead("[true, false, null]"));
+ root = JSONReader::Read("[true, false, null]");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
list = static_cast<ListValue*>(root.get());
EXPECT_EQ(3U, list->GetSize());
// Test with trailing comma. Should be parsed the same as above.
- scoped_ptr<Value> root2;
- root2.reset(JSONReader::DeprecatedRead("[true, false, null, ]",
- JSON_ALLOW_TRAILING_COMMAS));
+ scoped_ptr<Value> root2 =
+ JSONReader::Read("[true, false, null, ]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_TRUE(root->Equals(root2.get()));
// Empty array
- root.reset(JSONReader::DeprecatedRead("[]"));
+ root = JSONReader::Read("[]");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
list = static_cast<ListValue*>(root.get());
EXPECT_EQ(0U, list->GetSize());
// Nested arrays
- root.reset(
- JSONReader::DeprecatedRead("[[true], [], [false, [], [null]], null]"));
+ root = JSONReader::Read("[[true], [], [false, [], [null]], null]");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
list = static_cast<ListValue*>(root.get());
EXPECT_EQ(4U, list->GetSize());
// Lots of trailing commas.
- root2.reset(JSONReader::DeprecatedRead(
- "[[true], [], [false, [], [null, ] , ], null,]",
- JSON_ALLOW_TRAILING_COMMAS));
+ root2 = JSONReader::Read("[[true], [], [false, [], [null, ] , ], null,]",
+ JSON_ALLOW_TRAILING_COMMAS);
EXPECT_TRUE(root->Equals(root2.get()));
// Invalid, missing close brace.
- root.reset(
- JSONReader::DeprecatedRead("[[true], [], [false, [], [null]], null"));
+ root = JSONReader::Read("[[true], [], [false, [], [null]], null");
EXPECT_FALSE(root.get());
// Invalid, too many commas
- root.reset(JSONReader::DeprecatedRead("[true,, null]"));
+ root = JSONReader::Read("[true,, null]");
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("[true,, null]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[true,, null]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
// Invalid, no commas
- root.reset(JSONReader::DeprecatedRead("[true null]"));
+ root = JSONReader::Read("[true null]");
EXPECT_FALSE(root.get());
// Invalid, trailing comma
- root.reset(JSONReader::DeprecatedRead("[true,]"));
+ root = JSONReader::Read("[true,]");
EXPECT_FALSE(root.get());
// Valid if we set |allow_trailing_comma| to true.
- root.reset(JSONReader::DeprecatedRead("[true,]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[true,]", JSON_ALLOW_TRAILING_COMMAS);
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
list = static_cast<ListValue*>(root.get());
@@ -308,25 +305,22 @@ TEST(JSONReaderTest, Reading) {
// Don't allow empty elements, even if |allow_trailing_comma| is
// true.
- root.reset(JSONReader::DeprecatedRead("[,]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[,]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("[true,,]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[true,,]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("[,true,]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[,true,]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("[true,,false]", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("[true,,false]", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
// Test objects
- root.reset(JSONReader::DeprecatedRead("{}"));
+ root = JSONReader::Read("{}");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
- root.reset(JSONReader::DeprecatedRead(
- "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\" }"));
+ root = JSONReader::Read(
+ "{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\" }");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
DictionaryValue* dict_val = static_cast<DictionaryValue*>(root.get());
@@ -340,36 +334,36 @@ TEST(JSONReaderTest, Reading) {
EXPECT_TRUE(dict_val->GetString("S", &str_val));
EXPECT_EQ("str", str_val);
- root2.reset(JSONReader::DeprecatedRead(
+ root2 = JSONReader::Read(
"{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", }",
- JSON_ALLOW_TRAILING_COMMAS));
+ JSON_ALLOW_TRAILING_COMMAS);
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
// Test newline equivalence.
- root2.reset(JSONReader::DeprecatedRead(
+ root2 = JSONReader::Read(
"{\n"
" \"number\":9.87654321,\n"
" \"null\":null,\n"
" \"\\x53\":\"str\",\n"
"}\n",
- JSON_ALLOW_TRAILING_COMMAS));
+ JSON_ALLOW_TRAILING_COMMAS);
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
- root2.reset(JSONReader::DeprecatedRead(
+ root2 = JSONReader::Read(
"{\r\n"
" \"number\":9.87654321,\r\n"
" \"null\":null,\r\n"
" \"\\x53\":\"str\",\r\n"
"}\r\n",
- JSON_ALLOW_TRAILING_COMMAS));
+ JSON_ALLOW_TRAILING_COMMAS);
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
// Test nesting
- root.reset(JSONReader::DeprecatedRead(
- "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}"));
+ root = JSONReader::Read(
+ "{\"inner\":{\"array\":[true]},\"false\":false,\"d\":{}}");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
dict_val = static_cast<DictionaryValue*>(root.get());
@@ -384,14 +378,13 @@ TEST(JSONReaderTest, Reading) {
inner_dict = NULL;
EXPECT_TRUE(dict_val->GetDictionary("d", &inner_dict));
- root2.reset(JSONReader::DeprecatedRead(
+ root2 = JSONReader::Read(
"{\"inner\": {\"array\":[true] , },\"false\":false,\"d\":{},}",
- JSON_ALLOW_TRAILING_COMMAS));
+ JSON_ALLOW_TRAILING_COMMAS);
EXPECT_TRUE(root->Equals(root2.get()));
// Test keys with periods
- root.reset(JSONReader::DeprecatedRead(
- "{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}"));
+ root = JSONReader::Read("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
dict_val = static_cast<DictionaryValue*>(root.get());
@@ -408,7 +401,7 @@ TEST(JSONReaderTest, Reading) {
&integer_value));
EXPECT_EQ(1, integer_value);
- root.reset(JSONReader::DeprecatedRead("{\"a\":{\"b\":2},\"a.b\":1}"));
+ root = JSONReader::Read("{\"a\":{\"b\":2},\"a.b\":1}");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_DICTIONARY));
dict_val = static_cast<DictionaryValue*>(root.get());
@@ -418,47 +411,45 @@ TEST(JSONReaderTest, Reading) {
EXPECT_EQ(1, integer_value);
// Invalid, no closing brace
- root.reset(JSONReader::DeprecatedRead("{\"a\": true"));
+ root = JSONReader::Read("{\"a\": true");
EXPECT_FALSE(root.get());
// Invalid, keys must be quoted
- root.reset(JSONReader::DeprecatedRead("{foo:true}"));
+ root = JSONReader::Read("{foo:true}");
EXPECT_FALSE(root.get());
// Invalid, trailing comma
- root.reset(JSONReader::DeprecatedRead("{\"a\":true,}"));
+ root = JSONReader::Read("{\"a\":true,}");
EXPECT_FALSE(root.get());
// Invalid, too many commas
- root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}"));
+ root = JSONReader::Read("{\"a\":true,,\"b\":false}");
EXPECT_FALSE(root.get());
- root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}",
- JSON_ALLOW_TRAILING_COMMAS));
+ root =
+ JSONReader::Read("{\"a\":true,,\"b\":false}", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
// Invalid, no separator
- root.reset(JSONReader::DeprecatedRead("{\"a\" \"b\"}"));
+ root = JSONReader::Read("{\"a\" \"b\"}");
EXPECT_FALSE(root.get());
// Invalid, lone comma.
- root.reset(JSONReader::DeprecatedRead("{,}"));
+ root = JSONReader::Read("{,}");
EXPECT_FALSE(root.get());
- root.reset(JSONReader::DeprecatedRead("{,}", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("{,}", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("{\"a\":true,,}", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("{\"a\":true,,}", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(
- JSONReader::DeprecatedRead("{,\"a\":true}", JSON_ALLOW_TRAILING_COMMAS));
+ root = JSONReader::Read("{,\"a\":true}", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
- root.reset(JSONReader::DeprecatedRead("{\"a\":true,,\"b\":false}",
- JSON_ALLOW_TRAILING_COMMAS));
+ root =
+ JSONReader::Read("{\"a\":true,,\"b\":false}", JSON_ALLOW_TRAILING_COMMAS);
EXPECT_FALSE(root.get());
// Test stack overflow
std::string evil(1000000, '[');
evil.append(std::string(1000000, ']'));
- root.reset(JSONReader::DeprecatedRead(evil));
+ root = JSONReader::Read(evil);
EXPECT_FALSE(root.get());
// A few thousand adjacent lists is fine.
@@ -468,7 +459,7 @@ TEST(JSONReaderTest, Reading) {
not_evil.append("[],");
}
not_evil.append("[]]");
- root.reset(JSONReader::DeprecatedRead(not_evil));
+ root = JSONReader::Read(not_evil);
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->IsType(Value::TYPE_LIST));
list = static_cast<ListValue*>(root.get());
@@ -530,20 +521,20 @@ TEST(JSONReaderTest, Reading) {
}
// Test literal root objects.
- root.reset(JSONReader::DeprecatedRead("null"));
+ root = JSONReader::Read("null");
EXPECT_TRUE(root->IsType(Value::TYPE_NULL));
- root.reset(JSONReader::DeprecatedRead("true"));
+ root = JSONReader::Read("true");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->GetAsBoolean(&bool_value));
EXPECT_TRUE(bool_value);
- root.reset(JSONReader::DeprecatedRead("10"));
+ root = JSONReader::Read("10");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->GetAsInteger(&integer_value));
EXPECT_EQ(10, integer_value);
- root.reset(JSONReader::DeprecatedRead("\"root\""));
+ root = JSONReader::Read("\"root\"");
ASSERT_TRUE(root.get());
EXPECT_TRUE(root->GetAsString(&str_val));
EXPECT_EQ("root", str_val);
diff --git a/third_party/chromium/base/json/json_writer.cc b/third_party/chromium/base/json/json_writer.cc
index 8bf4c6f..be19c93 100644
--- a/third_party/chromium/base/json/json_writer.cc
+++ b/third_party/chromium/base/json/json_writer.cc
@@ -4,13 +4,17 @@
#include "base/json/json_writer.h"
+#include <stdint.h>
+
#include <cmath>
+#include <limits>
#include "base/json/string_escape.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/values.h"
+#include "build/build_config.h"
namespace base {
@@ -79,10 +83,10 @@ bool JSONWriter::BuildJSONString(const Value& node, size_t depth) {
bool result = node.GetAsDouble(&value);
DCHECK(result);
if (omit_double_type_preservation_ &&
- value <= kint64max &&
- value >= kint64min &&
+ value <= std::numeric_limits<int64_t>::max() &&
+ value >= std::numeric_limits<int64_t>::min() &&
std::floor(value) == value) {
- json_string_->append(Int64ToString(static_cast<int64>(value)));
+ json_string_->append(Int64ToString(static_cast<int64_t>(value)));
return result;
}
std::string real = DoubleToString(value);
diff --git a/third_party/chromium/base/json/json_writer.h b/third_party/chromium/base/json/json_writer.h
index 5711665..ef43341 100644
--- a/third_party/chromium/base/json/json_writer.h
+++ b/third_party/chromium/base/json/json_writer.h
@@ -5,10 +5,12 @@
#ifndef BASE_JSON_JSON_WRITER_H_
#define BASE_JSON_JSON_WRITER_H_
+#include <stddef.h>
+
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace base {
diff --git a/third_party/chromium/base/json/json_writer_unittest.cc b/third_party/chromium/base/json/json_writer_unittest.cc
index cb88cde..ca99f4d 100644
--- a/third_party/chromium/base/json/json_writer_unittest.cc
+++ b/third_party/chromium/base/json/json_writer_unittest.cc
@@ -7,6 +7,7 @@
#include <gtest/gtest.h>
#include "base/values.h"
+#include "build/build_config.h"
namespace base {
@@ -59,10 +60,10 @@ TEST(JSONWriterTest, NestedTypes) {
scoped_ptr<ListValue> list(new ListValue());
scoped_ptr<DictionaryValue> inner_dict(new DictionaryValue());
inner_dict->SetInteger("inner int", 10);
- list->Append(inner_dict.Pass());
+ list->Append(std::move(inner_dict));
list->Append(make_scoped_ptr(new ListValue()));
list->AppendBoolean(true);
- root_dict.Set("list", list.Pass());
+ root_dict.Set("list", std::move(list));
// Test the pretty-printer.
EXPECT_TRUE(JSONWriter::Write(root_dict, &output_js));
@@ -94,7 +95,7 @@ TEST(JSONWriterTest, KeysWithPeriods) {
period_dict.SetIntegerWithoutPathExpansion("c", 2);
scoped_ptr<DictionaryValue> period_dict2(new DictionaryValue());
period_dict2->SetIntegerWithoutPathExpansion("g.h.i.j", 1);
- period_dict.SetWithoutPathExpansion("d.e.f", period_dict2.Pass());
+ period_dict.SetWithoutPathExpansion("d.e.f", std::move(period_dict2));
EXPECT_TRUE(JSONWriter::Write(period_dict, &output_js));
EXPECT_EQ("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}", output_js);
diff --git a/third_party/chromium/base/json/string_escape.cc b/third_party/chromium/base/json/string_escape.cc
index 7ba612f..a5a38df 100644
--- a/third_party/chromium/base/json/string_escape.cc
+++ b/third_party/chromium/base/json/string_escape.cc
@@ -4,6 +4,10 @@
#include "base/json/string_escape.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
#include <string>
#include "base/logging.h"
@@ -20,15 +24,15 @@ namespace {
const char kU16EscapeFormat[] = "\\u%04X";
// The code point to output for an invalid input code unit.
-const uint32 kReplacementCodePoint = 0xFFFD;
+const uint32_t kReplacementCodePoint = 0xFFFD;
// Used below in EscapeSpecialCodePoint().
-COMPILE_ASSERT('<' == 0x3C, less_than_sign_is_0x3c);
+static_assert('<' == 0x3C, "less than sign must be 0x3c");
// Try to escape the |code_point| if it is a known special character. If
// successful, returns true and appends the escape sequence to |dest|. This
// isn't required by the spec, but it's more readable by humans.
-bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) {
+bool EscapeSpecialCodePoint(uint32_t code_point, std::string* dest) {
// WARNING: if you add a new case here, you need to update the reader as well.
// Note: \v is in the reader, but not here since the JSON spec doesn't
// allow it.
@@ -59,6 +63,14 @@ bool EscapeSpecialCodePoint(uint32 code_point, std::string* dest) {
case '<':
dest->append("\\u003C");
break;
+ // Escape the "Line Separator" and "Paragraph Separator" characters, since
+ // they should be treated like a new line \r or \n.
+ case 0x2028:
+ dest->append("\\u2028");
+ break;
+ case 0x2029:
+ dest->append("\\u2029");
+ break;
default:
return false;
}
@@ -72,12 +84,13 @@ bool EscapeJSONStringImpl(const S& str, bool put_in_quotes, std::string* dest) {
if (put_in_quotes)
dest->push_back('"');
- // Casting is necessary because ICU uses int32. Try and do so safely.
- CHECK_LE(str.length(), static_cast<size_t>(kint32max));
- const int32 length = static_cast<int32>(str.length());
+ // Casting is necessary because ICU uses int32_t. Try and do so safely.
+ CHECK_LE(str.length(),
+ static_cast<size_t>(std::numeric_limits<int32_t>::max()));
+ const int32_t length = static_cast<int32_t>(str.length());
- for (int32 i = 0; i < length; ++i) {
- uint32 code_point;
+ for (int32_t i = 0; i < length; ++i) {
+ uint32_t code_point;
if (!ReadUnicodeCharacter(str.data(), length, &i, &code_point)) {
code_point = kReplacementCodePoint;
did_replacement = true;
diff --git a/third_party/chromium/base/json/string_escape_unittest.cc b/third_party/chromium/base/json/string_escape_unittest.cc
index 615acc4..586c1e7 100644
--- a/third_party/chromium/base/json/string_escape_unittest.cc
+++ b/third_party/chromium/base/json/string_escape_unittest.cc
@@ -5,7 +5,9 @@
#include "base/json/string_escape.h"
#include <gtest/gtest.h>
+#include <stddef.h>
+#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
@@ -22,6 +24,8 @@ TEST(JSONStringEscapeTest, EscapeUTF8) {
{"b\x0f\x7f\xf0\xff!", // \xf0\xff is not a valid UTF-8 unit.
"b\\u000F\x7F\xEF\xBF\xBD\xEF\xBF\xBD!"},
{"c<>d", "c\\u003C>d"},
+ {"Hello\xe2\x80\xa8world", "Hello\\u2028world"},
+ {"\xe2\x80\xa9purple", "\\u2029purple"},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
diff --git a/third_party/chromium/base/location.h b/third_party/chromium/base/location.h
index 4a38264..67a0dfd 100644
--- a/third_party/chromium/base/location.h
+++ b/third_party/chromium/base/location.h
@@ -5,11 +5,12 @@
#ifndef BASE_LOCATION_H_
#define BASE_LOCATION_H_
+#include <stddef.h>
+
#include <cassert>
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
namespace tracked_objects {
diff --git a/third_party/chromium/base/logging.cc b/third_party/chromium/base/logging.cc
index 1fd047f..6306f47 100644
--- a/third_party/chromium/base/logging.cc
+++ b/third_party/chromium/base/logging.cc
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
@@ -79,6 +80,17 @@ int GetMinLogLevel() {
return g_min_log_level;
}
+bool ShouldCreateLogMessage(int severity) {
+ if (severity < g_min_log_level)
+ return false;
+
+ // Return true here unless we know ~LogMessage won't do anything. Note that
+ // ~LogMessage writes to stderr if severity_ >= kAlwaysPrintErrorLevel, even
+ // when g_logging_destination is LOG_NONE.
+ return g_logging_destination != LOG_NONE || log_message_handler ||
+ severity >= kAlwaysPrintErrorLevel;
+}
+
int GetVlogVerbosity() {
return std::max(-1, LOG_INFO - GetMinLogLevel());
}
@@ -121,6 +133,12 @@ LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
Init(file, line);
}
+LogMessage::LogMessage(const char* file, int line, const char* condition)
+ : severity_(LOG_FATAL), file_(file), line_(line) {
+ Init(file, line);
+ stream_ << "Check failed: " << condition << ". ";
+}
+
LogMessage::LogMessage(const char* file, int line, std::string* result)
: severity_(LOG_FATAL), file_(file), line_(line) {
Init(file, line);
@@ -187,7 +205,8 @@ void LogMessage::Init(const char* file, int line) {
stream_ << '[';
if (g_log_timestamp) {
time_t t = time(nullptr);
- struct tm local_time = {0};
+ struct tm local_time;
+ memset(&local_time, 0, sizeof(local_time));
#ifdef _MSC_VER
localtime_s(&local_time, &t);
#else
diff --git a/third_party/chromium/base/logging.h b/third_party/chromium/base/logging.h
index 339f8a6..ee10ae2 100644
--- a/third_party/chromium/base/logging.h
+++ b/third_party/chromium/base/logging.h
@@ -5,13 +5,16 @@
#ifndef BASE_LOGGING_H_
#define BASE_LOGGING_H_
+#include <stddef.h>
+
#include <cassert>
-#include <string>
#include <cstring>
#include <sstream>
+#include <string>
+#include <typeinfo>
#include "base/base_export.h"
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "build/build_config.h"
//
@@ -122,6 +125,34 @@
// There is the special severity of DFATAL, which logs FATAL in debug mode,
// ERROR in normal mode.
+// Note that "The behavior of a C++ program is undefined if it adds declarations
+// or definitions to namespace std or to a namespace within namespace std unless
+// otherwise specified." --C++11[namespace.std]
+//
+// We've checked that this particular definition has the intended behavior on
+// our implementations, but it's prone to breaking in the future, and please
+// don't imitate this in your own definitions without checking with some
+// standard library experts.
+namespace std {
+// These functions are provided as a convenience for logging, which is where we
+// use streams (it is against Google style to use streams in other places). It
+// is designed to allow you to emit non-ASCII Unicode strings to the log file,
+// which is normally ASCII. It is relatively slow, so try not to use it for
+// common cases. Non-ASCII characters will be converted to UTF-8 by these
+// operators.
+BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
+inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
+ return out << wstr.c_str();
+}
+
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::ostream&>::type operator<<(
+ std::ostream& out, T value) {
+ return out << static_cast<typename std::underlying_type<T>::type>(value);
+}
+
+} // namespace std
+
namespace logging {
// Where to record logging output? A flat file and/or system debug log
@@ -188,6 +219,9 @@ BASE_EXPORT void SetMinLogLevel(int level);
// Gets the current log level.
BASE_EXPORT int GetMinLogLevel();
+// Used by LOG_IS_ON to lazy-evaluate stream arguments.
+BASE_EXPORT bool ShouldCreateLogMessage(int severity);
+
// Gets the VLOG default verbosity level.
BASE_EXPORT int GetVlogVerbosity();
@@ -280,7 +314,7 @@ const LogSeverity LOG_DFATAL = LOG_FATAL;
// LOG_IS_ON(DFATAL) always holds in debug mode. In particular, CHECK()s will
// always fire if they fail.
#define LOG_IS_ON(severity) \
- ((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel())
+ (::logging::ShouldCreateLogMessage(::logging::LOG_##severity))
// We can't do any caching tricks with VLOG_IS_ON() like the
// google-glog version since it requires GCC extensions. This means
@@ -331,6 +365,21 @@ const LogSeverity LOG_DFATAL = LOG_FATAL;
#define EAT_STREAM_PARAMETERS \
true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL)
+// Captures the result of a CHECK_EQ (for example) and facilitates testing as a
+// boolean.
+class CheckOpResult {
+ public:
+ // |message| must be null if and only if the check failed.
+ CheckOpResult(std::string* message) : message_(message) {}
+ // Returns true if the check succeeded.
+ operator bool() const { return !message_; }
+ // Returns the message.
+ std::string* message() { return message_; }
+
+ private:
+ std::string* message_;
+};
+
// CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by NDEBUG, so the check will be executed regardless of
// compilation mode.
@@ -341,7 +390,7 @@ const LogSeverity LOG_DFATAL = LOG_FATAL;
#if defined(OFFICIAL_BUILD) && defined(NDEBUG) && !defined(OS_ANDROID)
// Make all CHECK functions discard their log strings to reduce code
-// bloat for official release builds.
+// bloat for official release builds (except Android).
// TODO(akalin): This would be more valuable if there were some way to
// remove BreakDebugger() from the backtrace, perhaps by turning it
@@ -355,20 +404,25 @@ const LogSeverity LOG_DFATAL = LOG_FATAL;
#else
-#define CHECK(condition) \
- LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
- << "Check failed: " #condition ". "
+// Do as much work as possible out of line to reduce inline code size.
+#define CHECK(condition) \
+ LAZY_STREAM(logging::LogMessage(__FILE__, __LINE__, #condition).stream(), \
+ !(condition))
// Helper macro for binary operators.
// Don't use this macro directly in your code, use CHECK_EQ et al below.
-//
-// TODO(akalin): Rewrite this so that constructs like if (...)
-// CHECK_EQ(...) else { ... } work properly.
-#define CHECK_OP(name, op, val1, val2) \
- if (std::string* _result = \
- logging::Check##name##Impl((val1), (val2), \
- #val1 " " #op " " #val2)) \
- logging::LogMessage(__FILE__, __LINE__, _result).stream()
+// The 'switch' is used to prevent the 'else' from being ambiguous when the
+// macro is used in an 'if' clause such as:
+// if (a == 1)
+// CHECK_EQ(2, a);
+#define CHECK_OP(name, op, val1, val2) \
+ switch (0) case 0: default: \
+ if (logging::CheckOpResult true_if_passed = \
+ logging::Check##name##Impl((val1), (val2), \
+ #val1 " " #op " " #val2)) \
+ ; \
+ else \
+ logging::LogMessage(__FILE__, __LINE__, true_if_passed.message()).stream()
#endif
@@ -430,7 +484,6 @@ DEFINE_CHECK_OP_IMPL(GT, > )
#define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2)
#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2)
-#define CHECK_IMPLIES(val1, val2) CHECK(!(val1) || (val2))
#if defined(NDEBUG)
#define ENABLE_DLOG 0
@@ -514,12 +567,20 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
// Helper macro for binary operators.
// Don't use this macro directly in your code, use DCHECK_EQ et al below.
-#define DCHECK_OP(name, op, val1, val2) \
- if (DCHECK_IS_ON()) \
- if (std::string* _result = logging::Check##name##Impl( \
- (val1), (val2), #val1 " " #op " " #val2)) \
- logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, _result) \
- .stream()
+// The 'switch' is used to prevent the 'else' from being ambiguous when the
+// macro is used in an 'if' clause such as:
+// if (a == 1)
+// DCHECK_EQ(2, a);
+#define DCHECK_OP(name, op, val1, val2) \
+ switch (0) case 0: default: \
+ if (logging::CheckOpResult true_if_passed = \
+ DCHECK_IS_ON() ? \
+ logging::Check##name##Impl((val1), (val2), \
+ #val1 " " #op " " #val2) : nullptr) \
+ ; \
+ else \
+ logging::LogMessage(__FILE__, __LINE__, ::logging::LOG_DCHECK, \
+ true_if_passed.message()).stream()
// Equality/Inequality checks - compare two values, and log a
// LOG_DCHECK message including the two values when the result is not
@@ -546,7 +607,6 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
#define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2)
#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
#define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2)
-#define DCHECK_IMPLIES(val1, val2) DCHECK(!(val1) || (val2))
#define NOTREACHED() DCHECK(false)
@@ -567,6 +627,9 @@ class BASE_EXPORT LogMessage {
// Used for LOG(severity).
LogMessage(const char* file, int line, LogSeverity severity);
+ // Used for CHECK(). Implied severity = LOG_FATAL.
+ LogMessage(const char* file, int line, const char* condition);
+
// Used for CHECK_EQ(), etc. Takes ownership of the given string.
// Implied severity = LOG_FATAL.
LogMessage(const char* file, int line, std::string* result);
@@ -595,7 +658,7 @@ class BASE_EXPORT LogMessage {
// A non-macro interface to the log facility; (useful
// when the logging level is not a compile-time constant).
-inline void LogAtLevel(int const log_level, std::string const &msg) {
+inline void LogAtLevel(int log_level, const std::string& msg) {
LogMessage(__FILE__, __LINE__, log_level).stream() << msg;
}
@@ -652,9 +715,9 @@ BASE_EXPORT void RawLog(int level, const char* message);
#define NOTIMPLEMENTED() EAT_STREAM_PARAMETERS
#elif NOTIMPLEMENTED_POLICY == 1
// TODO, figure out how to generate a warning
-#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
+#define NOTIMPLEMENTED() static_assert(false, "NOT_IMPLEMENTED")
#elif NOTIMPLEMENTED_POLICY == 2
-#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
+#define NOTIMPLEMENTED() static_assert(false, "NOT_IMPLEMENTED")
#elif NOTIMPLEMENTED_POLICY == 3
#define NOTIMPLEMENTED() NOTREACHED()
#elif NOTIMPLEMENTED_POLICY == 4
diff --git a/third_party/chromium/base/logging_unittest.cc b/third_party/chromium/base/logging_unittest.cc
index e3c84e3..d2c1177 100644
--- a/third_party/chromium/base/logging_unittest.cc
+++ b/third_party/chromium/base/logging_unittest.cc
@@ -7,8 +7,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
namespace logging {
@@ -115,7 +115,7 @@ TEST_F(LoggingTest, LogIsOn) {
EXPECT_TRUE(kDfatalIsFatal == LOG_IS_ON(DFATAL));
}
-TEST_F(LoggingTest, LoggingIsLazy) {
+TEST_F(LoggingTest, LoggingIsLazyBySeverity) {
MockLogSource mock_log_source;
EXPECT_CALL(mock_log_source, Log()).Times(0);
@@ -136,6 +136,24 @@ TEST_F(LoggingTest, LoggingIsLazy) {
DVLOG_IF(1, true) << mock_log_source.Log();
}
+TEST_F(LoggingTest, LoggingIsLazyByDestination) {
+ MockLogSource mock_log_source;
+ MockLogSource mock_log_source_error;
+ EXPECT_CALL(mock_log_source, Log()).Times(0);
+
+ // Severity >= ERROR is always printed to stderr.
+ EXPECT_CALL(mock_log_source_error, Log()).Times(1).
+ WillRepeatedly(Return("log message"));
+
+ LoggingSettings settings;
+ settings.logging_dest = LOG_NONE;
+ InitLogging(settings);
+
+ LOG(INFO) << mock_log_source.Log();
+ LOG(WARNING) << mock_log_source.Log();
+ LOG(ERROR) << mock_log_source_error.Log();
+}
+
// Official builds have CHECKs directly call BreakDebugger.
#if !defined(OFFICIAL_BUILD)
@@ -213,6 +231,30 @@ TEST_F(LoggingTest, DcheckReleaseBehavior) {
DCHECK_EQ(some_variable, 1) << "test";
}
+TEST_F(LoggingTest, DCheckEqStatements) {
+ bool reached = false;
+ if (false)
+ DCHECK_EQ(false, true); // Unreached.
+ else
+ DCHECK_EQ(true, reached = true); // Reached, passed.
+ ASSERT_EQ(DCHECK_IS_ON() ? true : false, reached);
+
+ if (false)
+ DCHECK_EQ(false, true); // Unreached.
+}
+
+TEST_F(LoggingTest, CheckEqStatements) {
+ bool reached = false;
+ if (false)
+ CHECK_EQ(false, true); // Unreached.
+ else
+ CHECK_EQ(true, reached = true); // Reached, passed.
+ ASSERT_TRUE(reached);
+
+ if (false)
+ CHECK_EQ(false, true); // Unreached.
+}
+
} // namespace
} // namespace logging
diff --git a/third_party/chromium/base/macros.h b/third_party/chromium/base/macros.h
index 0325e74..46ee1da 100644
--- a/third_party/chromium/base/macros.h
+++ b/third_party/chromium/base/macros.h
@@ -11,7 +11,6 @@
#define BASE_MACROS_H_
#include <stddef.h> // For size_t.
-#include <string.h> // For memcpy.
// Put this in the declarations for a class to be uncopyable.
#define DISALLOW_COPY(TypeName) \
@@ -27,13 +26,6 @@
TypeName(const TypeName&); \
void operator=(const TypeName&)
-// An older, deprecated, politically incorrect name for the above.
-// NOTE: The usage of this macro was banned from our code base, but some
-// third_party libraries are yet using it.
-// TODO(tfarina): Figure out how to fix the usage of this macro in the
-// third_party libraries and get rid of it.
-#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
-
// A macro to disallow all the implicit constructors, namely the
// default constructor, copy constructor and operator= functions.
//
@@ -41,13 +33,14 @@
// that wants to prevent anyone from instantiating it. This is
// especially useful for classes containing only static methods.
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
- TypeName(); \
+ TypeName() = delete; \
DISALLOW_COPY_AND_ASSIGN(TypeName)
-// The arraysize(arr) macro returns the # of elements in an array arr.
-// The expression is a compile-time constant, and therefore can be
-// used in defining new arrays, for example. If you use arraysize on
-// a pointer by mistake, you will get a compile-time error.
+// The arraysize(arr) macro returns the # of elements in an array arr. The
+// expression is a compile-time constant, and therefore can be used in defining
+// new arrays, for example. If you use arraysize on a pointer by mistake, you
+// will get a compile-time error. For the technical details, refer to
+// http://blogs.msdn.com/b/the1/archive/2004/05/07/128242.aspx.
// This template function declaration is used in defining arraysize.
// Note that the function doesn't need an implementation, as we only
@@ -55,110 +48,6 @@
template <typename T, size_t N> char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
-
-// Use implicit_cast as a safe version of static_cast or const_cast
-// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
-// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
-// a const pointer to Foo).
-// When you use implicit_cast, the compiler checks that the cast is safe.
-// Such explicit implicit_casts are necessary in surprisingly many
-// situations where C++ demands an exact type match instead of an
-// argument type convertible to a target type.
-//
-// The From type can be inferred, so the preferred syntax for using
-// implicit_cast is the same as for static_cast etc.:
-//
-// implicit_cast<ToType>(expr)
-//
-// implicit_cast would have been part of the C++ standard library,
-// but the proposal was submitted too late. It will probably make
-// its way into the language in the future.
-template<typename To, typename From>
-inline To implicit_cast(From const &f) {
- return f;
-}
-
-// The COMPILE_ASSERT macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
-//
-// COMPILE_ASSERT(arraysize(content_type_names) == CONTENT_NUM_TYPES,
-// content_type_names_incorrect_size);
-//
-// or to make sure a struct is smaller than a certain size:
-//
-// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-
-#undef COMPILE_ASSERT
-#define COMPILE_ASSERT(expr, msg) static_assert(expr, #msg)
-
-// bit_cast<Dest,Source> is a template function that implements the
-// equivalent of "*reinterpret_cast<Dest*>(&source)". We need this in
-// very low-level functions like the protobuf library and fast math
-// support.
-//
-// float f = 3.14159265358979;
-// int i = bit_cast<int32>(f);
-// // i = 0x40490fdb
-//
-// The classical address-casting method is:
-//
-// // WRONG
-// float f = 3.14159265358979; // WRONG
-// int i = * reinterpret_cast<int*>(&f); // WRONG
-//
-// The address-casting method actually produces undefined behavior
-// according to ISO C++ specification section 3.10 -15 -. Roughly, this
-// section says: if an object in memory has one type, and a program
-// accesses it with a different type, then the result is undefined
-// behavior for most values of "different type".
-//
-// This is true for any cast syntax, either *(int*)&f or
-// *reinterpret_cast<int*>(&f). And it is particularly true for
-// conversions between integral lvalues and floating-point lvalues.
-//
-// The purpose of 3.10 -15- is to allow optimizing compilers to assume
-// that expressions with different types refer to different memory. gcc
-// 4.0.1 has an optimizer that takes advantage of this. So a
-// non-conforming program quietly produces wildly incorrect output.
-//
-// The problem is not the use of reinterpret_cast. The problem is type
-// punning: holding an object in memory of one type and reading its bits
-// back using a different type.
-//
-// The C++ standard is more subtle and complex than this, but that
-// is the basic idea.
-//
-// Anyways ...
-//
-// bit_cast<> calls memcpy() which is blessed by the standard,
-// especially by the example in section 3.9 . Also, of course,
-// bit_cast<> wraps up the nasty logic in one place.
-//
-// Fortunately memcpy() is very fast. In optimized mode, with a
-// constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
-// code with the minimal amount of data movement. On a 32-bit system,
-// memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
-// compiles to two loads and two stores.
-//
-// I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
-//
-// WARNING: if Dest or Source is a non-POD type, the result of the memcpy
-// is likely to surprise you.
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
- COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual);
-
- Dest dest;
- memcpy(&dest, &source, sizeof(dest));
- return dest;
-}
-
// Used to explicitly mark the return value of a function as unused. If you are
// really sure you don't want to do anything with the return value of a function
// that has been marked WARN_UNUSED_RESULT, wrap it with this. Example:
diff --git a/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h b/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h
new file mode 100644
index 0000000..33bacba
--- /dev/null
+++ b/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h
@@ -0,0 +1,64 @@
+// 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 BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/template_util.h"
+#include "base/tuple.h"
+#include "build/build_config.h"
+
+// It is dangerous to post a task with a T* argument where T is a subtype of
+// RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
+// object may already have been deleted since it was not held with a
+// scoped_refptr. Example: http://crbug.com/27191
+// The following set of traits are designed to generate a compile error
+// whenever this antipattern is attempted.
+
+namespace base {
+
+// This is a base internal implementation file used by task.h and callback.h.
+// Not for public consumption, so we wrap it in namespace internal.
+namespace internal {
+
+template <typename T>
+struct NeedsScopedRefptrButGetsRawPtr {
+#if defined(OS_WIN)
+ enum {
+ value = base::false_type::value
+ };
+#else
+ enum {
+ // Human readable translation: you needed to be a scoped_refptr if you are a
+ // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
+ // type.
+ value = (std::is_pointer<T>::value &&
+ (std::is_convertible<T, subtle::RefCountedBase*>::value ||
+ std::is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
+ };
+#endif
+};
+
+template <typename Params>
+struct ParamsUseScopedRefptrCorrectly {
+ enum { value = 0 };
+};
+
+template <>
+struct ParamsUseScopedRefptrCorrectly<Tuple<>> {
+ enum { value = 1 };
+};
+
+template <typename Head, typename... Tail>
+struct ParamsUseScopedRefptrCorrectly<Tuple<Head, Tail...>> {
+ enum { value = !NeedsScopedRefptrButGetsRawPtr<Head>::value &&
+ ParamsUseScopedRefptrCorrectly<Tuple<Tail...>>::value };
+};
+
+} // namespace internal
+
+} // namespace base
+
+#endif // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
diff --git a/third_party/chromium/base/memory/ref_counted.h b/third_party/chromium/base/memory/ref_counted.h
index 52e8f00..95fa565 100644
--- a/third_party/chromium/base/memory/ref_counted.h
+++ b/third_party/chromium/base/memory/ref_counted.h
@@ -11,8 +11,8 @@
#include "base/base_export.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/logging.h"
-#include "base/move.h"
#include "build/build_config.h"
namespace base {
@@ -105,7 +105,7 @@ class BASE_EXPORT RefCountedThreadSafeBase {
// ~MyFoo();
// };
//
-// You should always make your destructor private, to avoid any code deleting
+// You should always make your destructor non-public, to avoid any code deleting
// the object accidently while there are references to it.
template <class T>
class RefCounted : public subtle::RefCountedBase {
@@ -252,7 +252,6 @@ class RefCountedData
//
template <class T>
class scoped_refptr {
- TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_refptr)
public:
typedef T element_type;
@@ -264,17 +263,24 @@ class scoped_refptr {
AddRef(ptr_);
}
+ // Copy constructor.
scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
if (ptr_)
AddRef(ptr_);
}
+ // Copy conversion constructor.
template <typename U>
scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
if (ptr_)
AddRef(ptr_);
}
+ // Move constructor. This is required in addition to the conversion
+ // constructor below in order for clang to warn about pessimizing moves.
+ scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; }
+
+ // Move conversion constructor.
template <typename U>
scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) {
r.ptr_ = nullptr;
@@ -318,13 +324,13 @@ class scoped_refptr {
}
scoped_refptr<T>& operator=(scoped_refptr<T>&& r) {
- scoped_refptr<T>(r.Pass()).swap(*this);
+ scoped_refptr<T>(std::move(r)).swap(*this);
return *this;
}
template <typename U>
scoped_refptr<T>& operator=(scoped_refptr<U>&& r) {
- scoped_refptr<T>(r.Pass()).swap(*this);
+ scoped_refptr<T>(std::move(r)).swap(*this);
return *this;
}
diff --git a/third_party/chromium/base/memory/ref_counted_unittest.cc b/third_party/chromium/base/memory/ref_counted_unittest.cc
index 9eda813..88ee981 100644
--- a/third_party/chromium/base/memory/ref_counted_unittest.cc
+++ b/third_party/chromium/base/memory/ref_counted_unittest.cc
@@ -169,26 +169,6 @@ TEST(RefCountedUnitTest, ConvertibleEquality) {
EXPECT_EQ(p2, p1);
}
-TEST(RefCountedUnitTest, SelfMoveAssignment) {
- ScopedRefPtrCountBase::reset_count();
-
- {
- ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
- scoped_refptr<ScopedRefPtrCountBase> p(raw);
- EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
- EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
-
- p = p.Pass();
- EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
- EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
- EXPECT_EQ(raw, p.get());
-
- // p goes out of scope.
- }
- EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
- EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
-}
-
TEST(RefCountedUnitTest, MoveAssignment1) {
ScopedRefPtrCountBase::reset_count();
@@ -201,7 +181,7 @@ TEST(RefCountedUnitTest, MoveAssignment1) {
{
scoped_refptr<ScopedRefPtrCountBase> p2;
- p2 = p1.Pass();
+ p2 = std::move(p1);
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(nullptr, p1.get());
@@ -232,7 +212,7 @@ TEST(RefCountedUnitTest, MoveAssignment2) {
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
- p1 = p2.Pass();
+ p1 = std::move(p2);
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(raw, p1.get());
@@ -263,7 +243,7 @@ TEST(RefCountedUnitTest, MoveAssignmentSameInstance1) {
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
- p1 = p2.Pass();
+ p1 = std::move(p2);
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(raw, p1.get());
@@ -294,7 +274,7 @@ TEST(RefCountedUnitTest, MoveAssignmentSameInstance2) {
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
- p2 = p1.Pass();
+ p2 = std::move(p1);
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(nullptr, p1.get());
@@ -326,7 +306,7 @@ TEST(RefCountedUnitTest, MoveAssignmentDifferentInstances) {
EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
- p1 = p2.Pass();
+ p1 = std::move(p2);
EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(raw2, p1.get());
@@ -363,7 +343,7 @@ TEST(RefCountedUnitTest, MoveAssignmentDerived) {
EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
- p1 = p2.Pass();
+ p1 = std::move(p2);
EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
@@ -396,7 +376,7 @@ TEST(RefCountedUnitTest, MoveConstructor) {
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
{
- scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
+ scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(nullptr, p1.get());
@@ -426,7 +406,7 @@ TEST(RefCountedUnitTest, MoveConstructorDerived) {
EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
{
- scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
+ scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
diff --git a/third_party/chromium/base/memory/scoped_ptr.h b/third_party/chromium/base/memory/scoped_ptr.h
index 2aa1b32..d68604e 100644
--- a/third_party/chromium/base/memory/scoped_ptr.h
+++ b/third_party/chromium/base/memory/scoped_ptr.h
@@ -37,42 +37,43 @@
// in that they are "movable but not copyable." You can use the scopers in
// the parameter and return types of functions to signify ownership transfer
// in to and out of a function. When calling a function that has a scoper
-// as the argument type, it must be called with the result of an analogous
-// scoper's Pass() function or another function that generates a temporary;
-// passing by copy will NOT work. Here is an example using scoped_ptr:
+// as the argument type, it must be called with an rvalue of a scoper, which
+// can be created by using std::move(), or the result of another function that
+// generates a temporary; passing by copy will NOT work. Here is an example
+// using scoped_ptr:
//
// void TakesOwnership(scoped_ptr<Foo> arg) {
-// // Do something with arg
+// // Do something with arg.
// }
// scoped_ptr<Foo> CreateFoo() {
-// // No need for calling Pass() because we are constructing a temporary
-// // for the return value.
+// // No need for calling std::move() for returning a move-only value, or
+// // when you already have an rvalue as we do here.
// return scoped_ptr<Foo>(new Foo("new"));
// }
// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
-// return arg.Pass();
+// return arg;
// }
//
// {
// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay").
-// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
+// TakesOwnership(std::move(ptr)); // ptr no longer owns Foo("yay").
// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
-// PassThru(ptr2.Pass()); // ptr2 is correspondingly nullptr.
+// PassThru(std::move(ptr2)); // ptr2 is correspondingly nullptr.
// }
//
-// Notice that if you do not call Pass() when returning from PassThru(), or
+// Notice that if you do not call std::move() when returning from PassThru(), or
// when invoking TakesOwnership(), the code will not compile because scopers
// are not copyable; they only implement move semantics which require calling
-// the Pass() function to signify a destructive transfer of state. CreateFoo()
-// is different though because we are constructing a temporary on the return
-// line and thus can avoid needing to call Pass().
+// the std::move() function to signify a destructive transfer of state.
+// CreateFoo() is different though because we are constructing a temporary on
+// the return line and thus can avoid needing to call std::move().
//
-// Pass() properly handles upcast in initialization, i.e. you can use a
-// scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
+// The conversion move-constructor properly handles upcast in initialization,
+// i.e. you can use a scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
//
// scoped_ptr<Foo> foo(new Foo());
-// scoped_ptr<FooParent> parent(foo.Pass());
+// scoped_ptr<FooParent> parent(std::move(foo));
#ifndef BASE_MEMORY_SCOPED_PTR_H_
#define BASE_MEMORY_SCOPED_PTR_H_
@@ -84,11 +85,13 @@
#include <stddef.h>
#include <stdlib.h>
-#include <algorithm> // For std::swap().
#include <iosfwd>
+#include <memory>
+#include <type_traits>
+#include <utility>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/move.h"
#include "base/template_util.h"
@@ -99,61 +102,6 @@ class RefCountedBase;
class RefCountedThreadSafeBase;
} // namespace subtle
-// 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 scoped_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 COMPILE_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) };
- COMPILE_ASSERT((std::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 scoped_ptr<int[10]>.
- COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
-};
-
// Function object which invokes 'free' on its parameter, which must be
// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
//
@@ -175,17 +123,6 @@ template <typename T> struct IsNotRefCounted {
};
};
-template <typename T>
-struct ShouldAbortOnSelfReset {
- template <typename U>
- static NoType Test(const typename U::AllowSelfReset*);
-
- template <typename U>
- static YesType Test(...);
-
- static const bool value = sizeof(Test<T>(0)) == sizeof(YesType);
-};
-
// Minimal implementation of the core logic of scoped_ptr, suitable for
// reuse in both scoped_ptr and its specializations.
template <class T, class D>
@@ -216,37 +153,28 @@ class scoped_ptr_impl {
}
~scoped_ptr_impl() {
- if (data_.ptr != nullptr) {
- // Not using get_deleter() saves one function call in non-optimized
- // builds.
- static_cast<D&>(data_)(data_.ptr);
- }
+ // Match libc++, which calls reset() in its destructor.
+ // Use nullptr as the new value for three reasons:
+ // 1. libc++ does it.
+ // 2. Avoids infinitely recursing into destructors if two classes are owned
+ // in a reference cycle (see ScopedPtrTest.ReferenceCycle).
+ // 3. If |this| is accessed in the future, in a use-after-free bug, attempts
+ // to dereference |this|'s pointer should cause either a failure or a
+ // segfault closer to the problem. If |this| wasn't reset to nullptr,
+ // the access would cause the deleted memory to be read or written
+ // leading to other more subtle issues.
+ reset(nullptr);
}
void reset(T* p) {
- // This is a self-reset, which is no longer allowed for default deleters:
- // https://crbug.com/162971
- assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr);
-
- // Note that running data_.ptr = p can lead to undefined behavior if
- // get_deleter()(get()) deletes this. In order to prevent this, reset()
- // should update the stored pointer before deleting its old value.
- //
- // However, changing reset() to use that behavior may cause current code to
- // break in unexpected ways. If the destruction of the owned object
- // dereferences the scoped_ptr when it is destroyed by a call to reset(),
- // then it will incorrectly dispatch calls to |p| rather than the original
- // value of |data_.ptr|.
- //
- // During the transition period, set the stored pointer to nullptr while
- // deleting the object. Eventually, this safety check will be removed to
- // prevent the scenario initially described from occuring and
- // http://crbug.com/176091 can be closed.
+ // Match C++11's definition of unique_ptr::reset(), which requires changing
+ // the pointer before invoking the deleter on the old pointer. This prevents
+ // |this| from being accessed after the deleter is run, which may destroy
+ // |this|.
T* old = data_.ptr;
- data_.ptr = nullptr;
+ data_.ptr = p;
if (old != nullptr)
static_cast<D&>(data_)(old);
- data_.ptr = p;
}
T* get() const { return data_.ptr; }
@@ -300,25 +228,27 @@ class scoped_ptr_impl {
// dereference it, you get the thread safety guarantees of T.
//
// The size of scoped_ptr is small. On most compilers, when using the
-// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
-// increase the size proportional to whatever state they need to have. See
+// std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters
+// will increase the size proportional to whatever state they need to have. See
// comments inside scoped_ptr_impl<> for details.
//
// Current implementation targets having a strict subset of C++11's
// unique_ptr<> features. Known deficiencies include not supporting move-only
// deleteres, function pointers as deleters, and deleters with reference
// types.
-template <class T, class D = base::DefaultDeleter<T> >
+template <class T, class D = std::default_delete<T>>
class scoped_ptr {
- MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
+ DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr)
- COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value,
- T_is_refcounted_type_and_needs_scoped_refptr);
+ static_assert(!std::is_array<T>::value,
+ "scoped_ptr doesn't support array with size");
+ static_assert(base::internal::IsNotRefCounted<T>::value,
+ "T is a refcounted type and needs a scoped_refptr");
public:
// The element and deleter types.
- typedef T element_type;
- typedef D deleter_type;
+ using element_type = T;
+ using deleter_type = D;
// Constructor. Defaults to initializing with nullptr.
scoped_ptr() : impl_(nullptr) {}
@@ -330,44 +260,87 @@ class scoped_ptr {
scoped_ptr(element_type* p, const D& d) : impl_(p, d) {}
// Constructor. Allows construction from a nullptr.
- scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
+ scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
+
+ // Move constructor.
+ //
+ // IMPLEMENTATION NOTE: Clang requires a move constructor to be defined (and
+ // not just the conversion constructor) in order to warn on pessimizing moves.
+ // The requirements for the move constructor are specified in C++11
+ // 20.7.1.2.1.15-17, which has some subtleties around reference deleters. As
+ // we don't support reference (or move-only) deleters, the post conditions are
+ // trivially true: we always copy construct the deleter from other's deleter.
+ scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
- // Constructor. Allows construction from a scoped_ptr rvalue for a
+ // Conversion constructor. Allows construction from a scoped_ptr rvalue for a
// convertible type and deleter.
//
- // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
- // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
- // has different post-conditions if D is a reference type. Since this
- // implementation does not support deleters with reference type,
- // we do not need a separate move constructor allowing us to avoid one
- // use of SFINAE. You only need to care about this if you modify the
- // implementation of scoped_ptr.
- template <typename U, typename V>
- scoped_ptr(scoped_ptr<U, V>&& other)
- : impl_(&other.impl_) {
- COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
+ // IMPLEMENTATION NOTE: C++ 20.7.1.2.1.19 requires this constructor to only
+ // participate in overload resolution if all the following are true:
+ // - U is implicitly convertible to T: this is important for 2 reasons:
+ // 1. So type traits don't incorrectly return true, e.g.
+ // std::is_convertible<scoped_ptr<Base>, scoped_ptr<Derived>>::value
+ // should be false.
+ // 2. To make sure code like this compiles:
+ // void F(scoped_ptr<int>);
+ // void F(scoped_ptr<Base>);
+ // // Ambiguous since both conversion constructors match.
+ // F(scoped_ptr<Derived>());
+ // - U is not an array type: to prevent conversions from scoped_ptr<T[]> to
+ // scoped_ptr<T>.
+ // - D is a reference type and E is the same type, or D is not a reference
+ // type and E is implicitly convertible to D: again, we don't support
+ // reference deleters, so we only worry about the latter requirement.
+ template <typename U,
+ typename E,
+ typename std::enable_if<!std::is_array<U>::value &&
+ std::is_convertible<U*, T*>::value &&
+ std::is_convertible<E, D>::value>::type* =
+ nullptr>
+ scoped_ptr(scoped_ptr<U, E>&& other)
+ : impl_(&other.impl_) {}
+
+ // operator=.
+ //
+ // IMPLEMENTATION NOTE: Unlike the move constructor, Clang does not appear to
+ // require a move assignment operator to trigger the pessimizing move warning:
+ // in this case, the warning triggers when moving a temporary. For consistency
+ // with the move constructor, we define it anyway. C++11 20.7.1.2.3.1-3
+ // defines several requirements around this: like the move constructor, the
+ // requirements are simplified by the fact that we don't support move-only or
+ // reference deleters.
+ scoped_ptr& operator=(scoped_ptr&& rhs) {
+ impl_.TakeState(&rhs.impl_);
+ return *this;
}
// operator=. Allows assignment from a scoped_ptr rvalue for a convertible
// type and deleter.
//
// IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
- // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
- // form has different requirements on for move-only Deleters. Since this
- // implementation does not support move-only Deleters, we do not need a
- // separate move assignment operator allowing us to avoid one use of SFINAE.
- // You only need to care about this if you modify the implementation of
- // scoped_ptr.
- template <typename U, typename V>
- scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) {
- COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
+ // the normal move assignment operator. C++11 20.7.1.2.3.4-7 contains the
+ // requirement for this operator, but like the conversion constructor, the
+ // requirements are greatly simplified by not supporting move-only or
+ // reference deleters.
+ template <typename U,
+ typename E,
+ typename std::enable_if<!std::is_array<U>::value &&
+ std::is_convertible<U*, T*>::value &&
+ // Note that this really should be
+ // std::is_assignable, but <type_traits>
+ // appears to be missing this on some
+ // platforms. This is close enough (though
+ // it's not the same).
+ std::is_convertible<D, E>::value>::type* =
+ nullptr>
+ scoped_ptr& operator=(scoped_ptr<U, E>&& rhs) {
impl_.TakeState(&rhs.impl_);
return *this;
}
// operator=. Allows assignment from a nullptr. Deletes the currently owned
// object, if any.
- scoped_ptr& operator=(decltype(nullptr)) {
+ scoped_ptr& operator=(std::nullptr_t) {
reset();
return *this;
}
@@ -408,12 +381,6 @@ class scoped_ptr {
return impl_.get() ? &scoped_ptr::impl_ : nullptr;
}
- // Comparison operators.
- // These return whether two scoped_ptr refer to the same object, not just to
- // two different but equal objects.
- bool operator==(const element_type* p) const { return impl_.get() == p; }
- bool operator!=(const element_type* p) const { return impl_.get() != p; }
-
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
@@ -434,23 +401,16 @@ class scoped_ptr {
// Forbidden for API compatibility with std::unique_ptr.
explicit scoped_ptr(int disallow_construction_from_null);
-
- // Forbid comparison of scoped_ptr types. If U != T, it totally
- // doesn't make sense, and if U == T, it still doesn't make sense
- // because you should never have the same object owned by two different
- // scoped_ptrs.
- template <class U> bool operator==(scoped_ptr<U> const& p2) const;
- template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
template <class T, class D>
class scoped_ptr<T[], D> {
- MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
+ DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr)
public:
// The element and deleter types.
- typedef T element_type;
- typedef D deleter_type;
+ using element_type = T;
+ using deleter_type = D;
// Constructor. Defaults to initializing with nullptr.
scoped_ptr() : impl_(nullptr) {}
@@ -465,13 +425,11 @@ class scoped_ptr<T[], D> {
// (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 implicit_cast<const T*>().
- // However, because of the first bullet in this comment, users MUST
- // NOT use implicit_cast<Base*>() to upcast the static type of the array.
+ // to work around this may use const_cast<const T*>().
explicit scoped_ptr(element_type* array) : impl_(array) {}
// Constructor. Allows construction from a nullptr.
- scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
+ scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
// Constructor. Allows construction from a scoped_ptr rvalue.
scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
@@ -484,7 +442,7 @@ class scoped_ptr<T[], D> {
// operator=. Allows assignment from a nullptr. Deletes the currently owned
// array, if any.
- scoped_ptr& operator=(decltype(nullptr)) {
+ scoped_ptr& operator=(std::nullptr_t) {
reset();
return *this;
}
@@ -515,12 +473,6 @@ class scoped_ptr<T[], D> {
return impl_.get() ? &scoped_ptr::impl_ : nullptr;
}
- // Comparison operators.
- // These return whether two scoped_ptr refer to the same object, not just to
- // two different but equal objects.
- bool operator==(element_type* array) const { return impl_.get() == array; }
- bool operator!=(element_type* array) const { return impl_.get() != array; }
-
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
@@ -553,13 +505,6 @@ class scoped_ptr<T[], D> {
// reasons as the constructor above.
template <typename U> void reset(U* array);
void reset(int disallow_reset_from_null);
-
- // Forbid comparison of scoped_ptr types. If U != T, it totally
- // doesn't make sense, and if U == T, it still doesn't make sense
- // because you should never have the same object owned by two different
- // scoped_ptrs.
- template <class U> bool operator==(scoped_ptr<U> const& p2) const;
- template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
// Free functions
@@ -568,14 +513,84 @@ void swap(scoped_ptr<T, D>& p1, scoped_ptr<T, D>& p2) {
p1.swap(p2);
}
+template <class T1, class D1, class T2, class D2>
+bool operator==(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return p1.get() == p2.get();
+}
+template <class T, class D>
+bool operator==(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ return p.get() == nullptr;
+}
+template <class T, class D>
+bool operator==(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ return p.get() == nullptr;
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator!=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return !(p1 == p2);
+}
+template <class T, class D>
+bool operator!=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ return !(p == nullptr);
+}
+template <class T, class D>
+bool operator!=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ return !(p == nullptr);
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator<(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return p1.get() < p2.get();
+}
+template <class T, class D>
+bool operator<(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ auto* ptr = p.get();
+ return ptr < static_cast<decltype(ptr)>(nullptr);
+}
+template <class T, class D>
+bool operator<(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ auto* ptr = p.get();
+ return static_cast<decltype(ptr)>(nullptr) < ptr;
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator>(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return p2 < p1;
+}
+template <class T, class D>
+bool operator>(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ return nullptr < p;
+}
+template <class T, class D>
+bool operator>(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ return p < nullptr;
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator<=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return !(p1 > p2);
+}
+template <class T, class D>
+bool operator<=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ return !(p > nullptr);
+}
template <class T, class D>
-bool operator==(T* p1, const scoped_ptr<T, D>& p2) {
- return p1 == p2.get();
+bool operator<=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ return !(nullptr > p);
}
+template <class T1, class D1, class T2, class D2>
+bool operator>=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+ return !(p1 < p2);
+}
+template <class T, class D>
+bool operator>=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+ return !(p < nullptr);
+}
template <class T, class D>
-bool operator!=(T* p1, const scoped_ptr<T, D>& p2) {
- return p1 != p2.get();
+bool operator>=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+ return !(nullptr < p);
}
// A function to convert T* into scoped_ptr<T>
diff --git a/third_party/chromium/base/memory/scoped_ptr_unittest.cc b/third_party/chromium/base/memory/scoped_ptr_unittest.cc
index d4ff410..c1eb469 100644
--- a/third_party/chromium/base/memory/scoped_ptr_unittest.cc
+++ b/third_party/chromium/base/memory/scoped_ptr_unittest.cc
@@ -4,13 +4,16 @@
#include "base/memory/scoped_ptr.h"
+#include <stddef.h>
+
#include <sstream>
#include <gtest/gtest.h>
-#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
+#include "base/macros.h"
+#include "build/build_config.h"
namespace {
@@ -85,7 +88,7 @@ int OverloadedNewAndDelete::g_new_count = 0;
int OverloadedNewAndDelete::g_delete_count = 0;
scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
- return logger.Pass();
+ return logger;
}
void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
@@ -103,8 +106,8 @@ TEST(ScopedPtrTest, ScopedPtr) {
int constructed = 0;
// Ensure size of scoped_ptr<> doesn't increase unexpectedly.
- COMPILE_ASSERT(sizeof(int*) >= sizeof(scoped_ptr<int>),
- scoped_ptr_larger_than_raw_ptr);
+ static_assert(sizeof(int*) >= sizeof(scoped_ptr<int>),
+ "scoped_ptr shouldn't be larger than the raw pointer");
{
scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
@@ -147,25 +150,25 @@ TEST(ScopedPtrTest, ScopedPtr) {
}
EXPECT_EQ(0, constructed);
- // Test swap(), == and !=
+ // Test swap().
{
scoped_ptr<ConDecLogger> scoper1;
scoped_ptr<ConDecLogger> scoper2;
- EXPECT_TRUE(scoper1 == scoper2.get());
- EXPECT_FALSE(scoper1 != scoper2.get());
+ EXPECT_TRUE(scoper1.get() == scoper2.get());
+ EXPECT_FALSE(scoper1.get() != scoper2.get());
ConDecLogger* logger = new ConDecLogger(&constructed);
scoper1.reset(logger);
EXPECT_EQ(logger, scoper1.get());
EXPECT_FALSE(scoper2.get());
- EXPECT_FALSE(scoper1 == scoper2.get());
- EXPECT_TRUE(scoper1 != scoper2.get());
+ EXPECT_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != 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_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != scoper2.get());
}
EXPECT_EQ(0, constructed);
}
@@ -179,7 +182,7 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper.get());
- scoped_ptr<ConDecLoggerParent> scoper_parent(scoper.Pass());
+ scoped_ptr<ConDecLoggerParent> scoper_parent(std::move(scoper));
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper_parent.get());
EXPECT_FALSE(scoper.get());
@@ -197,7 +200,7 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_TRUE(scoper.get());
scoped_ptr<ConDecLoggerParent> scoper_parent;
- scoper_parent = scoper.Pass();
+ scoper_parent = std::move(scoper);
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper_parent.get());
EXPECT_FALSE(scoper.get());
@@ -210,7 +213,7 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper.get());
- scoped_ptr<const ConDecLogger> scoper_const(scoper.Pass());
+ scoped_ptr<const ConDecLogger> scoper_const(std::move(scoper));
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper_const.get());
EXPECT_FALSE(scoper.get());
@@ -228,7 +231,7 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_TRUE(scoper.get());
scoped_ptr<const ConDecLogger> scoper_const;
- scoper_const = scoper.Pass();
+ scoper_const = std::move(scoper);
EXPECT_EQ(1, constructed);
EXPECT_TRUE(scoper_const.get());
EXPECT_FALSE(scoper.get());
@@ -252,7 +255,7 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_EQ(0, alternate_deletes);
// Test this compiles and correctly overwrites the deleter state.
- scoper = scoper_child.Pass();
+ scoper = std::move(scoper_child);
EXPECT_TRUE(scoper);
EXPECT_FALSE(scoper_child);
EXPECT_EQ(1, deletes);
@@ -268,7 +271,8 @@ TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
EXPECT_TRUE(scoper_child);
EXPECT_EQ(1, deletes);
EXPECT_EQ(1, alternate_deletes);
- scoped_ptr<double, CountingDeleter> scoper_construct(scoper_child.Pass());
+ scoped_ptr<double, CountingDeleter> scoper_construct(
+ std::move(scoper_child));
EXPECT_TRUE(scoper_construct);
EXPECT_FALSE(scoper_child);
EXPECT_EQ(1, deletes);
@@ -328,12 +332,12 @@ TEST(ScopedPtrTest, ScopedPtrWithArray) {
}
EXPECT_EQ(0, constructed);
- // Test swap(), ==, !=, and type-safe Boolean.
+ // Test swap() and type-safe Boolean.
{
scoped_ptr<ConDecLogger[]> scoper1;
scoped_ptr<ConDecLogger[]> scoper2;
- EXPECT_TRUE(scoper1 == scoper2.get());
- EXPECT_FALSE(scoper1 != scoper2.get());
+ EXPECT_TRUE(scoper1.get() == scoper2.get());
+ EXPECT_FALSE(scoper1.get() != scoper2.get());
ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
for (int i = 0; i < kNumLoggers; ++i) {
@@ -344,14 +348,14 @@ TEST(ScopedPtrTest, ScopedPtrWithArray) {
EXPECT_EQ(loggers, scoper1.get());
EXPECT_FALSE(scoper2);
EXPECT_FALSE(scoper2.get());
- EXPECT_FALSE(scoper1 == scoper2.get());
- EXPECT_TRUE(scoper1 != scoper2.get());
+ EXPECT_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != 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_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != scoper2.get());
}
EXPECT_EQ(0, constructed);
@@ -364,13 +368,13 @@ TEST(ScopedPtrTest, ScopedPtrWithArray) {
}
EXPECT_EQ(kNumLoggers, constructed);
- // Test Pass() with constructor;
- scoped_ptr<ConDecLogger[]> scoper2(scoper.Pass());
+ // Test moving with constructor;
+ scoped_ptr<ConDecLogger[]> scoper2(std::move(scoper));
EXPECT_EQ(kNumLoggers, constructed);
- // Test Pass() with assignment;
+ // Test moving with assignment;
scoped_ptr<ConDecLogger[]> scoper3;
- scoper3 = scoper2.Pass();
+ scoper3 = std::move(scoper2);
EXPECT_EQ(kNumLoggers, constructed);
EXPECT_FALSE(scoper);
EXPECT_FALSE(scoper2);
@@ -379,27 +383,30 @@ TEST(ScopedPtrTest, ScopedPtrWithArray) {
EXPECT_EQ(0, constructed);
}
-TEST(ScopedPtrTest, PassBehavior) {
+TEST(ScopedPtrTest, MoveBehavior) {
int constructed = 0;
{
ConDecLogger* logger = new ConDecLogger(&constructed);
scoped_ptr<ConDecLogger> scoper(logger);
EXPECT_EQ(1, constructed);
- // Test Pass() with constructor;
- scoped_ptr<ConDecLogger> scoper2(scoper.Pass());
+ // Test moving with constructor;
+ scoped_ptr<ConDecLogger> scoper2(std::move(scoper));
EXPECT_EQ(1, constructed);
- // Test Pass() with assignment;
+ // Test moving with assignment;
scoped_ptr<ConDecLogger> scoper3;
- scoper3 = scoper2.Pass();
+ scoper3 = std::move(scoper2);
EXPECT_EQ(1, constructed);
EXPECT_FALSE(scoper.get());
EXPECT_FALSE(scoper2.get());
EXPECT_TRUE(scoper3.get());
}
- // Test uncaught Pass() does not have side effects.
+#if !defined(OS_ANDROID) && !defined(OS_LINUX)
+ // Test uncaught Pass() does not have side effects, because Pass()
+ // is implemented by std::move().
+ // TODO(danakj): Remove this test case when we remove Pass().
{
ConDecLogger* logger = new ConDecLogger(&constructed);
scoped_ptr<ConDecLogger> scoper(logger);
@@ -412,6 +419,7 @@ TEST(ScopedPtrTest, PassBehavior) {
EXPECT_TRUE(rvalue);
}
EXPECT_EQ(0, constructed);
+#endif
// Test that passing to function which does nothing does not leak.
{
@@ -420,7 +428,7 @@ TEST(ScopedPtrTest, PassBehavior) {
EXPECT_EQ(1, constructed);
// Should auto-destruct logger by end of scope.
- GrabAndDrop(scoper.Pass());
+ GrabAndDrop(std::move(scoper));
EXPECT_FALSE(scoper.get());
}
EXPECT_EQ(0, constructed);
@@ -435,7 +443,7 @@ TEST(ScopedPtrTest, ReturnTypeBehavior) {
scoped_ptr<ConDecLogger> scoper(logger);
EXPECT_EQ(1, constructed);
- PassThru(scoper.Pass());
+ PassThru(std::move(scoper));
EXPECT_FALSE(scoper.get());
}
EXPECT_EQ(0, constructed);
@@ -447,7 +455,7 @@ TEST(ScopedPtrTest, ReturnTypeBehavior) {
EXPECT_EQ(1, constructed);
// Should auto-destruct logger by end of scope.
- PassThru(scoper.Pass());
+ PassThru(std::move(scoper));
EXPECT_FALSE(scoper.get());
}
EXPECT_EQ(0, constructed);
@@ -538,8 +546,8 @@ TEST(ScopedPtrTest, CustomDeleter) {
// Pass the second deleter through a constructor and an operator=. Then
// reinitialize the empty scopers to ensure that each one is deleting
// properly.
- scoped_ptr<double, CountingDeleter> scoper3(scoper2.Pass());
- scoper = scoper3.Pass();
+ scoped_ptr<double, CountingDeleter> scoper3(std::move(scoper2));
+ scoper = std::move(scoper3);
EXPECT_EQ(1, deletes);
scoper2.reset(&dummy_value2);
@@ -550,33 +558,33 @@ TEST(ScopedPtrTest, CustomDeleter) {
EXPECT_EQ(1, deletes);
EXPECT_EQ(3, alternate_deletes);
- // Test swap(), ==, !=, and type-safe Boolean.
+ // Test swap(), and type-safe Boolean.
{
scoped_ptr<double, CountingDeleter> scoper1(NULL,
CountingDeleter(&deletes));
scoped_ptr<double, CountingDeleter> scoper2(NULL,
CountingDeleter(&deletes));
- EXPECT_TRUE(scoper1 == scoper2.get());
- EXPECT_FALSE(scoper1 != scoper2.get());
+ EXPECT_TRUE(scoper1.get() == scoper2.get());
+ EXPECT_FALSE(scoper1.get() != 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());
+ EXPECT_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != 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());
+ EXPECT_FALSE(scoper1.get() == scoper2.get());
+ EXPECT_TRUE(scoper1.get() != scoper2.get());
}
}
// Sanity check test for overloaded new and delete operators. Does not do full
-// coverage of reset/release/Pass() operations as that is redundant with the
+// coverage of reset/release/move operations as that is redundant with the
// above.
TEST(ScopedPtrTest, OverloadedNewAndDelete) {
{
@@ -584,7 +592,7 @@ TEST(ScopedPtrTest, OverloadedNewAndDelete) {
scoped_ptr<OverloadedNewAndDelete> scoper(new OverloadedNewAndDelete());
EXPECT_TRUE(scoper.get());
- scoped_ptr<OverloadedNewAndDelete> scoper2(scoper.Pass());
+ scoped_ptr<OverloadedNewAndDelete> scoper2(std::move(scoper));
}
EXPECT_EQ(1, OverloadedNewAndDelete::delete_count());
EXPECT_EQ(1, OverloadedNewAndDelete::new_count());
@@ -633,55 +641,15 @@ TEST(ScopedPtrTest, Conversion) {
scoped_ptr<Sub> sub1(new Sub);
scoped_ptr<Sub> sub2(new Sub);
- // Upcast with Pass() works.
- scoped_ptr<Super> super1 = sub1.Pass();
- super1 = sub2.Pass();
+ // Upcast with move works.
+ scoped_ptr<Super> super1 = std::move(sub1);
+ super1 = std::move(sub2);
// Upcast with an rvalue works.
scoped_ptr<Super> super2 = SubClassReturn();
super2 = SubClassReturn();
}
-// Android death tests don't work properly with assert(). Yay.
-#if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultDeleter) {
- scoped_ptr<int> x(new int);
- EXPECT_DEATH(x.reset(x.get()), "");
-}
-
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultArrayDeleter) {
- scoped_ptr<int[]> y(new int[4]);
- EXPECT_DEATH(y.reset(y.get()), "");
-}
-
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultFreeDeleter) {
- scoped_ptr<int, base::FreeDeleter> z(static_cast<int*>(malloc(sizeof(int))));
- EXPECT_DEATH(z.reset(z.get()), "");
-}
-
-// A custom deleter that doesn't opt out should still crash.
-TEST(ScopedPtrTest, SelfResetAbortsWithCustomDeleter) {
- struct CustomDeleter {
- inline void operator()(int* x) { delete x; }
- };
- scoped_ptr<int, CustomDeleter> x(new int);
- EXPECT_DEATH(x.reset(x.get()), "");
-}
-#endif
-
-TEST(ScopedPtrTest, SelfResetWithCustomDeleterOptOut) {
- // A custom deleter should be able to opt out of self-reset abort behavior.
- struct NoOpDeleter {
-#if !defined(NDEBUG)
- typedef void AllowSelfReset;
-#endif
- inline void operator()(int*) {}
- };
- scoped_ptr<int> owner(new int);
- scoped_ptr<int, NoOpDeleter> x(owner.get());
- x.reset(x.get());
-}
-
// Logging a scoped_ptr<T> to an ostream shouldn't convert it to a boolean
// value first.
TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) {
@@ -694,3 +662,182 @@ TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) {
EXPECT_EQ(s2.str(), s1.str());
}
+
+TEST(ScopedPtrTest, ReferenceCycle) {
+ struct StructB;
+ struct StructA {
+ scoped_ptr<StructB> b;
+ };
+
+ struct StructB {
+ scoped_ptr<StructA> a;
+ };
+
+ // Create a reference cycle.
+ StructA* a = new StructA;
+ a->b.reset(new StructB);
+ a->b->a.reset(a);
+
+ // Break the cycle by calling reset(). This will cause |a| (and hence, |a->b|)
+ // to be deleted before the call to reset() returns. This tests that the
+ // implementation of scoped_ptr::reset() doesn't access |this| after it
+ // deletes the underlying pointer. This behaviour is consistent with the
+ // definition of unique_ptr::reset in C++11.
+ a->b.reset();
+
+ // Go again, but this time, break the cycle by invoking |a|'s destructor. This
+ // tests that the implementation of ~scoped_ptr doesn't infinitely recurse
+ // into the destructors of |a| and |a->b|. Note, deleting |a| instead will
+ // cause |a| to be double-free'd because |a->b| owns |a| and deletes it via
+ // its destructor.
+ a = new StructA;
+ a->b.reset(new StructB);
+ a->b->a.reset(a);
+ a->~StructA();
+}
+
+TEST(ScopedPtrTest, Operators) {
+ struct Parent {};
+ struct Child : public Parent {};
+
+ scoped_ptr<Parent> p(new Parent);
+ scoped_ptr<Parent> p2(new Parent);
+ scoped_ptr<Child> c(new Child);
+ scoped_ptr<Parent> pnull;
+
+ // Operator==.
+ EXPECT_TRUE(p == p);
+ EXPECT_FALSE(p == c);
+ EXPECT_FALSE(p == p2);
+ EXPECT_FALSE(p == pnull);
+
+ EXPECT_FALSE(p == nullptr);
+ EXPECT_FALSE(nullptr == p);
+ EXPECT_TRUE(pnull == nullptr);
+ EXPECT_TRUE(nullptr == pnull);
+
+ // Operator!=.
+ EXPECT_FALSE(p != p);
+ EXPECT_TRUE(p != c);
+ EXPECT_TRUE(p != p2);
+ EXPECT_TRUE(p != pnull);
+
+ EXPECT_TRUE(p != nullptr);
+ EXPECT_TRUE(nullptr != p);
+ EXPECT_FALSE(pnull != nullptr);
+ EXPECT_FALSE(nullptr != pnull);
+
+ // Compare two scoped_ptr<T>.
+ EXPECT_EQ(p.get() < p2.get(), p < p2);
+ EXPECT_EQ(p.get() <= p2.get(), p <= p2);
+ EXPECT_EQ(p.get() > p2.get(), p > p2);
+ EXPECT_EQ(p.get() >= p2.get(), p >= p2);
+ EXPECT_EQ(p2.get() < p.get(), p2 < p);
+ EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
+ EXPECT_EQ(p2.get() > p.get(), p2 > p);
+ EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
+
+ // And convertible scoped_ptr<T> and scoped_ptr<U>.
+ EXPECT_EQ(p.get() < c.get(), p < c);
+ EXPECT_EQ(p.get() <= c.get(), p <= c);
+ EXPECT_EQ(p.get() > c.get(), p > c);
+ EXPECT_EQ(p.get() >= c.get(), p >= c);
+ EXPECT_EQ(c.get() < p.get(), c < p);
+ EXPECT_EQ(c.get() <= p.get(), c <= p);
+ EXPECT_EQ(c.get() > p.get(), c > p);
+ EXPECT_EQ(c.get() >= p.get(), c >= p);
+
+ // Compare to nullptr.
+ EXPECT_TRUE(p > nullptr);
+ EXPECT_FALSE(nullptr > p);
+ EXPECT_FALSE(pnull > nullptr);
+ EXPECT_FALSE(nullptr > pnull);
+
+ EXPECT_TRUE(p >= nullptr);
+ EXPECT_FALSE(nullptr >= p);
+ EXPECT_TRUE(pnull >= nullptr);
+ EXPECT_TRUE(nullptr >= pnull);
+
+ EXPECT_FALSE(p < nullptr);
+ EXPECT_TRUE(nullptr < p);
+ EXPECT_FALSE(pnull < nullptr);
+ EXPECT_FALSE(nullptr < pnull);
+
+ EXPECT_FALSE(p <= nullptr);
+ EXPECT_TRUE(nullptr <= p);
+ EXPECT_TRUE(pnull <= nullptr);
+ EXPECT_TRUE(nullptr <= pnull);
+};
+
+TEST(ScopedPtrTest, ArrayOperators) {
+ struct Parent {};
+ struct Child : public Parent {};
+
+ scoped_ptr<Parent[]> p(new Parent[1]);
+ scoped_ptr<Parent[]> p2(new Parent[1]);
+ scoped_ptr<Child[]> c(new Child[1]);
+ scoped_ptr<Parent[]> pnull;
+
+ // Operator==.
+ EXPECT_TRUE(p == p);
+ EXPECT_FALSE(p == c);
+ EXPECT_FALSE(p == p2);
+ EXPECT_FALSE(p == pnull);
+
+ EXPECT_FALSE(p == nullptr);
+ EXPECT_FALSE(nullptr == p);
+ EXPECT_TRUE(pnull == nullptr);
+ EXPECT_TRUE(nullptr == pnull);
+
+ // Operator!=.
+ EXPECT_FALSE(p != p);
+ EXPECT_TRUE(p != c);
+ EXPECT_TRUE(p != p2);
+ EXPECT_TRUE(p != pnull);
+
+ EXPECT_TRUE(p != nullptr);
+ EXPECT_TRUE(nullptr != p);
+ EXPECT_FALSE(pnull != nullptr);
+ EXPECT_FALSE(nullptr != pnull);
+
+ // Compare two scoped_ptr<T>.
+ EXPECT_EQ(p.get() < p2.get(), p < p2);
+ EXPECT_EQ(p.get() <= p2.get(), p <= p2);
+ EXPECT_EQ(p.get() > p2.get(), p > p2);
+ EXPECT_EQ(p.get() >= p2.get(), p >= p2);
+ EXPECT_EQ(p2.get() < p.get(), p2 < p);
+ EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
+ EXPECT_EQ(p2.get() > p.get(), p2 > p);
+ EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
+
+ // And convertible scoped_ptr<T> and scoped_ptr<U>.
+ EXPECT_EQ(p.get() < c.get(), p < c);
+ EXPECT_EQ(p.get() <= c.get(), p <= c);
+ EXPECT_EQ(p.get() > c.get(), p > c);
+ EXPECT_EQ(p.get() >= c.get(), p >= c);
+ EXPECT_EQ(c.get() < p.get(), c < p);
+ EXPECT_EQ(c.get() <= p.get(), c <= p);
+ EXPECT_EQ(c.get() > p.get(), c > p);
+ EXPECT_EQ(c.get() >= p.get(), c >= p);
+
+ // Compare to nullptr.
+ EXPECT_TRUE(p > nullptr);
+ EXPECT_FALSE(nullptr > p);
+ EXPECT_FALSE(pnull > nullptr);
+ EXPECT_FALSE(nullptr > pnull);
+
+ EXPECT_TRUE(p >= nullptr);
+ EXPECT_FALSE(nullptr >= p);
+ EXPECT_TRUE(pnull >= nullptr);
+ EXPECT_TRUE(nullptr >= pnull);
+
+ EXPECT_FALSE(p < nullptr);
+ EXPECT_TRUE(nullptr < p);
+ EXPECT_FALSE(pnull < nullptr);
+ EXPECT_FALSE(nullptr < pnull);
+
+ EXPECT_FALSE(p <= nullptr);
+ EXPECT_TRUE(nullptr <= p);
+ EXPECT_TRUE(pnull <= nullptr);
+ EXPECT_TRUE(nullptr <= pnull);
+}
diff --git a/third_party/chromium/base/memory/weak_ptr.h b/third_party/chromium/base/memory/weak_ptr.h
index e07beeb..c1c52ee 100644
--- a/third_party/chromium/base/memory/weak_ptr.h
+++ b/third_party/chromium/base/memory/weak_ptr.h
@@ -16,6 +16,7 @@
//
// class Controller {
// public:
+// Controller() : weak_factory_(this) {}
// void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
// void WorkComplete(const Result& result) { ... }
// private:
@@ -58,15 +59,20 @@
// off to other task runners, e.g. to use to post tasks back to object on the
// bound sequence.
//
-// Invalidating the factory's WeakPtrs un-binds it from the sequence, allowing
-// it to be passed for a different sequence to use or delete it.
+// If all WeakPtr objects are destroyed or invalidated then the factory is
+// unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be
+// destroyed, or new WeakPtr objects may be used, from a different sequence.
+//
+// Thus, at least one WeakPtr object must exist and have been dereferenced on
+// the correct thread to enforce that other WeakPtr objects will enforce they
+// are used on the desired thread.
#ifndef BASE_MEMORY_WEAK_PTR_H_
#define BASE_MEMORY_WEAK_PTR_H_
-#include "base/basictypes.h"
#include "base/base_export.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/ref_counted.h"
namespace base {
@@ -152,8 +158,8 @@ class SupportsWeakPtrBase {
static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
typedef std::is_convertible<Derived*, internal::SupportsWeakPtrBase*>
convertible;
- COMPILE_ASSERT(convertible::value,
- AsWeakPtr_argument_inherits_from_SupportsWeakPtr);
+ static_assert(convertible::value,
+ "AsWeakPtr argument must inherit from SupportsWeakPtr");
return AsWeakPtrImpl<Derived>(t, *t);
}
diff --git a/third_party/chromium/base/move.h b/third_party/chromium/base/move.h
index 87dc52d..24bf9d7 100644
--- a/third_party/chromium/base/move.h
+++ b/third_party/chromium/base/move.h
@@ -5,230 +5,53 @@
#ifndef BASE_MOVE_H_
#define BASE_MOVE_H_
+#include <utility>
+
#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "build/build_config.h"
-// Macro with the boilerplate that makes a type move-only in C++03.
-//
-// USAGE
-//
-// This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create
-// a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be
-// the first line in a class declaration.
-//
-// A class using this macro must call .Pass() (or somehow be an r-value already)
-// before it can be:
-//
-// * Passed as a function argument
-// * Used as the right-hand side of an assignment
-// * Returned from a function
-//
-// Each class will still need to define their own "move constructor" and "move
-// operator=" to make this useful. Here's an example of the macro, the move
-// constructor, and the move operator= from the scoped_ptr class:
-//
-// template <typename T>
-// class scoped_ptr {
-// MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
-// public:
-// scoped_ptr(RValue& other) : ptr_(other.release()) { }
-// scoped_ptr& operator=(RValue& other) {
-// swap(other);
-// return *this;
-// }
-// };
-//
-// Note that the constructor must NOT be marked explicit.
-//
-// For consistency, the second parameter to the macro should always be RValue
-// unless you have a strong reason to do otherwise. It is only exposed as a
-// macro parameter so that the move constructor and move operator= don't look
-// like they're using a phantom type.
-//
-//
-// HOW THIS WORKS
-//
-// For a thorough explanation of this technique, see:
-//
-// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
-//
-// The summary is that we take advantage of 2 properties:
-//
-// 1) non-const references will not bind to r-values.
-// 2) C++ can apply one user-defined conversion when initializing a
-// variable.
-//
-// The first lets us disable the copy constructor and assignment operator
-// by declaring private version of them with a non-const reference parameter.
-//
-// For l-values, direct initialization still fails like in
-// DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment
-// operators are private.
-//
-// For r-values, the situation is different. The copy constructor and
-// assignment operator are not viable due to (1), so we are trying to call
-// a non-existent constructor and non-existing operator= rather than a private
-// one. Since we have not committed an error quite yet, we can provide an
-// alternate conversion sequence and a constructor. We add
-//
-// * a private struct named "RValue"
-// * a user-defined conversion "operator RValue()"
-// * a "move constructor" and "move operator=" that take the RValue& as
-// their sole parameter.
-//
-// Only r-values will trigger this sequence and execute our "move constructor"
-// or "move operator=." L-values will match the private copy constructor and
-// operator= first giving a "private in this context" error. This combination
-// gives us a move-only type.
-//
-// For signaling a destructive transfer of data from an l-value, we provide a
-// method named Pass() which creates an r-value for the current instance
-// triggering the move constructor or move operator=.
-//
-// Other ways to get r-values is to use the result of an expression like a
-// function call.
-//
-// Here's an example with comments explaining what gets triggered where:
-//
-// class Foo {
-// MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue);
-//
-// public:
-// ... API ...
-// Foo(RValue other); // Move constructor.
-// Foo& operator=(RValue rhs); // Move operator=
-// };
-//
-// Foo MakeFoo(); // Function that returns a Foo.
-//
-// Foo f;
-// Foo f_copy(f); // ERROR: Foo(Foo&) is private in this context.
-// Foo f_assign;
-// f_assign = f; // ERROR: operator=(Foo&) is private in this context.
-//
-//
-// Foo f(MakeFoo()); // R-value so alternate conversion executed.
-// Foo f_copy(f.Pass()); // R-value so alternate conversion executed.
-// f = f_copy.Pass(); // R-value so alternate conversion executed.
-//
-//
-// IMPLEMENTATION SUBTLETIES WITH RValue
-//
-// The RValue struct is just a container for a pointer back to the original
-// object. It should only ever be created as a temporary, and no external
-// class should ever declare it or use it in a parameter.
-//
-// It is tempting to want to use the RValue type in function parameters, but
-// excluding the limited usage here for the move constructor and move
-// operator=, doing so would mean that the function could take both r-values
-// and l-values equially which is unexpected. See COMPARED To Boost.Move for
-// more details.
-//
-// An alternate, and incorrect, implementation of the RValue class used by
-// Boost.Move makes RValue a fieldless child of the move-only type. RValue&
-// is then used in place of RValue in the various operators. The RValue& is
-// "created" by doing *reinterpret_cast<RValue*>(this). This has the appeal
-// of never creating a temporary RValue struct even with optimizations
-// disabled. Also, by virtue of inheritance you can treat the RValue
-// reference as if it were the move-only type itself. Unfortunately,
-// using the result of this reinterpret_cast<> is actually undefined behavior
-// due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer
-// will generate non-working code.
-//
-// In optimized builds, both implementations generate the same assembly so we
-// choose the one that adheres to the standard.
-//
+// TODO(crbug.com/566182): DEPRECATED!
+// Use DISALLOW_COPY_AND_ASSIGN instead, or if your type will be used in
+// Callbacks, use DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND instead.
+#define MOVE_ONLY_TYPE_FOR_CPP_03(type) \
+ DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type)
+
+// A macro to disallow the copy constructor and copy assignment functions.
+// This should be used in the private: declarations for a class.
//
-// WHY HAVE typedef void MoveOnlyTypeForCPP03
+// Use this macro instead of DISALLOW_COPY_AND_ASSIGN if you want to pass
+// ownership of the type through a base::Callback without heap-allocating it
+// into a scoped_ptr. The class must define a move constructor and move
+// assignment operator to make this work.
//
-// Callback<>/Bind() needs to understand movable-but-not-copyable semantics
-// to call .Pass() appropriately when it is expected to transfer the value.
-// The cryptic typedef MoveOnlyTypeForCPP03 is added to make this check
-// easy and automatic in helper templates for Callback<>/Bind().
+// This version of the macro adds a Pass() function and a cryptic
+// MoveOnlyTypeForCPP03 typedef for the base::Callback implementation to use.
// See IsMoveOnlyType template and its usage in base/callback_internal.h
// for more details.
-//
-//
-// COMPARED TO C++11
-//
-// In C++11, you would implement this functionality using an r-value reference
-// and our .Pass() method would be replaced with a call to std::move().
-//
-// This emulation also has a deficiency where it uses up the single
-// user-defined conversion allowed by C++ during initialization. This can
-// cause problems in some API edge cases. For instance, in scoped_ptr, it is
-// impossible to make a function "void Foo(scoped_ptr<Parent> p)" accept a
-// value of type scoped_ptr<Child> even if you add a constructor to
-// scoped_ptr<> that would make it look like it should work. C++11 does not
-// have this deficiency.
-//
-//
-// COMPARED TO Boost.Move
-//
-// Our implementation similar to Boost.Move, but we keep the RValue struct
-// private to the move-only type, and we don't use the reinterpret_cast<> hack.
-//
-// In Boost.Move, RValue is the boost::rv<> template. This type can be used
-// when writing APIs like:
-//
-// void MyFunc(boost::rv<Foo>& f)
-//
-// that can take advantage of rv<> to avoid extra copies of a type. However you
-// would still be able to call this version of MyFunc with an l-value:
-//
-// Foo f;
-// MyFunc(f); // Uh oh, we probably just destroyed |f| w/o calling Pass().
-//
-// unless someone is very careful to also declare a parallel override like:
-//
-// void MyFunc(const Foo& f)
-//
-// that would catch the l-values first. This was declared unsafe in C++11 and
-// a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot
-// ensure this in C++03.
-//
-// Since we have no need for writing such APIs yet, our implementation keeps
-// RValue private and uses a .Pass() method to do the conversion instead of
-// trying to write a version of "std::move()." Writing an API like std::move()
-// would require the RValue struct to be public.
-//
-//
-// CAVEATS
-//
-// If you include a move-only type as a field inside a class that does not
-// explicitly declare a copy constructor, the containing class's implicit
-// copy constructor will change from Containing(const Containing&) to
-// Containing(Containing&). This can cause some unexpected errors.
-//
-// http://llvm.org/bugs/show_bug.cgi?id=11528
-//
-// The workaround is to explicitly declare your copy constructor.
-//
-#define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
- private: \
- struct rvalue_type { \
- explicit rvalue_type(type* object) : object(object) {} \
- type* object; \
- }; \
- type(type&); \
- void operator=(type&); \
- public: \
- operator rvalue_type() { return rvalue_type(this); } \
- type Pass() WARN_UNUSED_RESULT { return type(rvalue_type(this)); } \
- typedef void MoveOnlyTypeForCPP03; \
+// TODO(crbug.com/566182): Remove this macro and use DISALLOW_COPY_AND_ASSIGN
+// everywhere instead.
+#if defined(OS_ANDROID) || defined(OS_LINUX)
+#define DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type) \
+ private: \
+ type(const type&) = delete; \
+ void operator=(const type&) = delete; \
+ \
+ public: \
+ typedef void MoveOnlyTypeForCPP03; \
+ \
private:
-
-#define MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
- private: \
- type(const type&); \
- void operator=(const type&); \
- public: \
- type&& Pass() WARN_UNUSED_RESULT { return static_cast<type&&>(*this); } \
- typedef void MoveOnlyTypeForCPP03; \
- private:
-
-#define TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(type) \
- public: \
- type&& Pass() WARN_UNUSED_RESULT { return static_cast<type&&>(*this); } \
+#else
+#define DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(type) \
+ private: \
+ type(const type&) = delete; \
+ void operator=(const type&) = delete; \
+ \
+ public: \
+ type&& Pass() WARN_UNUSED_RESULT { return std::move(*this); } \
+ typedef void MoveOnlyTypeForCPP03; \
+ \
private:
+#endif
#endif // BASE_MOVE_H_
diff --git a/third_party/chromium/base/move_unittest.cc b/third_party/chromium/base/move_unittest.cc
deleted file mode 100644
index bebcfd8..0000000
--- a/third_party/chromium/base/move_unittest.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2015 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.
-
-#include "base/move.h"
-
-#include <gtest/gtest.h>
-
-namespace {
-
-class MoveOnly {
- MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(MoveOnly)
-
- public:
- MoveOnly() {}
-
- MoveOnly(MoveOnly&& other) {}
- MoveOnly& operator=(MoveOnly&& other) { return *this; }
-};
-
-class Container {
- public:
- Container() = default;
- Container(const Container& other) = default;
- Container& operator=(const Container& other) = default;
-
- Container(Container&& other) { value_ = other.value_.Pass(); }
-
- Container& operator=(Container&& other) {
- value_ = other.value_.Pass();
- return *this;
- }
-
- private:
- MoveOnly value_;
-};
-
-Container GetContainerRvalue() {
- Container x;
- return x;
-}
-
-TEST(MoveTest, CopyableContainerCanBeMoved) {
- // Container should be move-constructible and move-assignable.
- Container y = GetContainerRvalue();
- y = GetContainerRvalue();
-}
-
-} // namespace
diff --git a/third_party/chromium/base/numerics/safe_conversions.h b/third_party/chromium/base/numerics/safe_conversions.h
index 5dd5191..baac188 100644
--- a/third_party/chromium/base/numerics/safe_conversions.h
+++ b/third_party/chromium/base/numerics/safe_conversions.h
@@ -5,7 +5,10 @@
#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_
#define BASE_NUMERICS_SAFE_CONVERSIONS_H_
+#include <stddef.h>
+
#include <limits>
+#include <type_traits>
#include "base/logging.h"
#include "base/numerics/safe_conversions_impl.h"
@@ -20,6 +23,24 @@ inline bool IsValueInRangeForNumericType(Src value) {
internal::RANGE_VALID;
}
+// Convenience function for determining if a numeric value is negative without
+// throwing compiler warnings on: unsigned(value) < 0.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
+IsValueNegative(T value) {
+ static_assert(std::numeric_limits<T>::is_specialized,
+ "Argument must be numeric.");
+ return value < 0;
+}
+
+template <typename T>
+typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
+ IsValueNegative(T) {
+ static_assert(std::numeric_limits<T>::is_specialized,
+ "Argument must be numeric.");
+ return false;
+}
+
// checked_cast<> is analogous to static_cast<> for numeric types,
// except that it CHECKs that the specified numeric conversion will not
// overflow or underflow. NaN source will always trigger a CHECK.
@@ -29,10 +50,30 @@ inline Dst checked_cast(Src value) {
return static_cast<Dst>(value);
}
+// HandleNaN will cause this class to CHECK(false).
+struct SaturatedCastNaNBehaviorCheck {
+ template <typename T>
+ static T HandleNaN() {
+ CHECK(false);
+ return T();
+ }
+};
+
+// HandleNaN will return 0 in this case.
+struct SaturatedCastNaNBehaviorReturnZero {
+ template <typename T>
+ static T HandleNaN() {
+ return T();
+ }
+};
+
// saturated_cast<> is analogous to static_cast<> for numeric types, except
// that the specified numeric conversion will saturate rather than overflow or
-// underflow. NaN assignment to an integral will trigger a CHECK condition.
-template <typename Dst, typename Src>
+// underflow. NaN assignment to an integral will defer the behavior to a
+// specified class. By default, it will return 0.
+template <typename Dst,
+ class NaNHandler = SaturatedCastNaNBehaviorReturnZero,
+ typename Src>
inline Dst saturated_cast(Src value) {
// Optimization for floating point values, which already saturate.
if (std::numeric_limits<Dst>::is_iec559)
@@ -50,8 +91,7 @@ inline Dst saturated_cast(Src value) {
// Should fail only on attempting to assign NaN to a saturated integer.
case internal::RANGE_INVALID:
- CHECK(false);
- return std::numeric_limits<Dst>::max();
+ return NaNHandler::template HandleNaN<Dst>();
}
NOTREACHED();
diff --git a/third_party/chromium/base/numerics/safe_conversions_impl.h b/third_party/chromium/base/numerics/safe_conversions_impl.h
index d07221e..e1d376a 100644
--- a/third_party/chromium/base/numerics/safe_conversions_impl.h
+++ b/third_party/chromium/base/numerics/safe_conversions_impl.h
@@ -5,6 +5,9 @@
#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
#define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
+#include <limits.h>
+#include <stdint.h>
+
#include <limits>
namespace base {
@@ -106,6 +109,55 @@ inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound,
(is_in_lower_bound ? 0 : RANGE_UNDERFLOW));
}
+// The following helper template addresses a corner case in range checks for
+// conversion from a floating-point type to an integral type of smaller range
+// but larger precision (e.g. float -> unsigned). The problem is as follows:
+// 1. Integral maximum is always one less than a power of two, so it must be
+// truncated to fit the mantissa of the floating point. The direction of
+// rounding is implementation defined, but by default it's always IEEE
+// floats, which round to nearest and thus result in a value of larger
+// magnitude than the integral value.
+// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX
+// // is 4294967295u.
+// 2. If the floating point value is equal to the promoted integral maximum
+// value, a range check will erroneously pass.
+// Example: (4294967296f <= 4294967295u) // This is true due to a precision
+// // loss in rounding up to float.
+// 3. When the floating point value is then converted to an integral, the
+// resulting value is out of range for the target integral type and
+// thus is implementation defined.
+// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0.
+// To fix this bug we manually truncate the maximum value when the destination
+// type is an integral of larger precision than the source floating-point type,
+// such that the resulting maximum is represented exactly as a floating point.
+template <typename Dst, typename Src>
+struct NarrowingRange {
+ typedef typename std::numeric_limits<Src> SrcLimits;
+ typedef typename std::numeric_limits<Dst> DstLimits;
+
+ static Dst max() {
+ // The following logic avoids warnings where the max function is
+ // instantiated with invalid values for a bit shift (even though
+ // such a function can never be called).
+ static const int shift =
+ (MaxExponent<Src>::value > MaxExponent<Dst>::value &&
+ SrcLimits::digits < DstLimits::digits && SrcLimits::is_iec559 &&
+ DstLimits::is_integer)
+ ? (DstLimits::digits - SrcLimits::digits)
+ : 0;
+
+ // We use UINTMAX_C below to avoid compiler warnings about shifting floating
+ // points. Since it's a compile time calculation, it shouldn't have any
+ // performance impact.
+ return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1);
+ }
+
+ static Dst min() {
+ return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max()
+ : DstLimits::min();
+ }
+};
+
template <
typename Dst,
typename Src,
@@ -133,7 +185,7 @@ struct DstRangeRelationToSrcRangeImpl<Dst,
DstSign,
SrcSign,
NUMERIC_RANGE_CONTAINED> {
- static RangeConstraint Check(Src value) { return RANGE_VALID; }
+ static RangeConstraint Check(Src /* value */) { return RANGE_VALID; }
};
// Signed to signed narrowing: Both the upper and lower boundaries may be
@@ -145,11 +197,8 @@ struct DstRangeRelationToSrcRangeImpl<Dst,
INTEGER_REPRESENTATION_SIGNED,
NUMERIC_RANGE_NOT_CONTAINED> {
static RangeConstraint Check(Src value) {
- return std::numeric_limits<Dst>::is_iec559
- ? GetRangeConstraint((value < std::numeric_limits<Dst>::max()),
- (value > -std::numeric_limits<Dst>::max()))
- : GetRangeConstraint((value < std::numeric_limits<Dst>::max()),
- (value > std::numeric_limits<Dst>::min()));
+ return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()),
+ (value >= NarrowingRange<Dst, Src>::min()));
}
};
@@ -161,7 +210,7 @@ struct DstRangeRelationToSrcRangeImpl<Dst,
INTEGER_REPRESENTATION_UNSIGNED,
NUMERIC_RANGE_NOT_CONTAINED> {
static RangeConstraint Check(Src value) {
- return GetRangeConstraint(value < std::numeric_limits<Dst>::max(), true);
+ return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true);
}
};
@@ -176,7 +225,7 @@ struct DstRangeRelationToSrcRangeImpl<Dst,
return sizeof(Dst) > sizeof(Src)
? RANGE_VALID
: GetRangeConstraint(
- value < static_cast<Src>(std::numeric_limits<Dst>::max()),
+ value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
true);
}
};
@@ -193,7 +242,7 @@ struct DstRangeRelationToSrcRangeImpl<Dst,
return (MaxExponent<Dst>::value >= MaxExponent<Src>::value)
? GetRangeConstraint(true, value >= static_cast<Src>(0))
: GetRangeConstraint(
- value < static_cast<Src>(std::numeric_limits<Dst>::max()),
+ value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
value >= static_cast<Src>(0));
}
};
diff --git a/third_party/chromium/base/numerics/safe_math.h b/third_party/chromium/base/numerics/safe_math.h
index a596d4b..ddffb6e 100644
--- a/third_party/chromium/base/numerics/safe_math.h
+++ b/third_party/chromium/base/numerics/safe_math.h
@@ -5,6 +5,8 @@
#ifndef BASE_NUMERICS_SAFE_MATH_H_
#define BASE_NUMERICS_SAFE_MATH_H_
+#include <stddef.h>
+
#include "base/numerics/safe_math_impl.h"
namespace base {
@@ -36,9 +38,8 @@ namespace internal {
// CheckedNumeric<int> checked_int = untrusted_input_value;
// int x = checked_int.ValueOrDefault(0) | kFlagValues;
// Comparison:
-// CheckedNumeric<size_t> checked_size;
-// CheckedNumeric<int> checked_size = untrusted_input_value;
-// checked_size = checked_size + HEADER LENGTH;
+// CheckedNumeric<size_t> checked_size = untrusted_input_value;
+// checked_size += HEADER LENGTH;
// if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size)
// Do stuff...
template <typename T>
@@ -145,6 +146,14 @@ class CheckedNumeric {
return CheckedNumeric<T>(value, validity);
}
+ // This function is available only for integral types. It returns an unsigned
+ // integer of the same width as the source type, containing the absolute value
+ // of the source, and properly handling signed min.
+ CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const {
+ return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
+ CheckedUnsignedAbs(state_.value()), state_.validity());
+ }
+
CheckedNumeric& operator++() {
*this += 1;
return *this;
@@ -188,6 +197,16 @@ class CheckedNumeric {
static const CheckedNumeric<T>& cast(const CheckedNumeric<T>& u) { return u; }
private:
+ template <typename NumericType>
+ struct UnderlyingType {
+ using type = NumericType;
+ };
+
+ template <typename NumericType>
+ struct UnderlyingType<CheckedNumeric<NumericType>> {
+ using type = NumericType;
+ };
+
CheckedNumericState<T> state_;
};
@@ -224,7 +243,8 @@ class CheckedNumeric {
template <typename T> \
template <typename Src> \
CheckedNumeric<T>& CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) { \
- *this = CheckedNumeric<T>::cast(*this) OP CheckedNumeric<Src>::cast(rhs); \
+ *this = CheckedNumeric<T>::cast(*this) \
+ OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs); \
return *this; \
} \
/* Binary arithmetic operator for CheckedNumeric of different type. */ \
diff --git a/third_party/chromium/base/numerics/safe_math_impl.h b/third_party/chromium/base/numerics/safe_math_impl.h
index 0ae1dfe..487b3bc 100644
--- a/third_party/chromium/base/numerics/safe_math_impl.h
+++ b/third_party/chromium/base/numerics/safe_math_impl.h
@@ -5,11 +5,13 @@
#ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_
#define BASE_NUMERICS_SAFE_MATH_IMPL_H_
+#include <stddef.h>
#include <stdint.h>
#include <cmath>
#include <cstdlib>
#include <limits>
+#include <type_traits>
#include "base/numerics/safe_conversions.h"
@@ -86,7 +88,27 @@ struct TwiceWiderInteger {
template <typename Integer>
struct PositionOfSignBit {
static const typename std::enable_if<std::numeric_limits<Integer>::is_integer,
- size_t>::type value = 8 * sizeof(Integer) - 1;
+ size_t>::type value =
+ 8 * sizeof(Integer) - 1;
+};
+
+// This is used for UnsignedAbs, where we need to support floating-point
+// template instantiations even though we don't actually support the operations.
+// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs,
+// so the float versions will not compile.
+template <typename Numeric,
+ bool IsInteger = std::numeric_limits<Numeric>::is_integer,
+ bool IsFloat = std::numeric_limits<Numeric>::is_iec559>
+struct UnsignedOrFloatForSize;
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, true, false> {
+ typedef typename UnsignedIntegerForSize<Numeric>::type type;
+};
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, false, true> {
+ typedef Numeric type;
};
// Helper templates for integer manipulations.
@@ -159,9 +181,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 std::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 =
@@ -202,9 +224,9 @@ CheckedMul(T x, T y, RangeConstraint* validity) {
template <typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer &&
- !std::numeric_limits<T>::is_signed &&
- (sizeof(T) * 2 > sizeof(uintmax_t)),
- T>::type
+ !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
@@ -230,27 +252,27 @@ T CheckedDiv(T x,
}
template <typename T>
-typename std::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 std::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 std::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;
@@ -259,9 +281,9 @@ CheckedNeg(T value, RangeConstraint* validity) {
}
template <typename T>
-typename std::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;
@@ -270,9 +292,9 @@ CheckedNeg(T value, RangeConstraint* validity) {
}
template <typename T>
-typename std::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;
@@ -280,23 +302,43 @@ CheckedAbs(T value, RangeConstraint* validity) {
}
template <typename T>
-typename std::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.
+ // T is unsigned, so |value| must already be positive.
*validity = RANGE_VALID;
return value;
}
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ std::numeric_limits<T>::is_signed,
+ typename UnsignedIntegerForSize<T>::type>::type
+CheckedUnsignedAbs(T value) {
+ typedef typename UnsignedIntegerForSize<T>::type UnsignedT;
+ return value == std::numeric_limits<T>::min()
+ ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1
+ : static_cast<UnsignedT>(std::abs(value));
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer &&
+ !std::numeric_limits<T>::is_signed,
+ T>::type
+CheckedUnsignedAbs(T value) {
+ // T is unsigned, so |value| must already be positive.
+ return value;
+}
+
// 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> \
+#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; \
+ Checked##NAME(T, T, RangeConstraint*) { \
+ NOTREACHED(); \
+ return 0; \
}
BASE_FLOAT_ARITHMETIC_STUBS(Add)
@@ -399,7 +441,7 @@ class CheckedNumericState<T, NUMERIC_FLOATING> {
template <typename Src>
CheckedNumericState(
Src value,
- RangeConstraint validity,
+ RangeConstraint /* validity */,
typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type =
0) {
switch (DstRangeRelationToSrcRange<T>(value)) {
diff --git a/third_party/chromium/base/numerics/safe_numerics_unittest.cc b/third_party/chromium/base/numerics/safe_numerics_unittest.cc
index 96b579a..8ac7b0c 100644
--- a/third_party/chromium/base/numerics/safe_numerics_unittest.cc
+++ b/third_party/chromium/base/numerics/safe_numerics_unittest.cc
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
-#include <mmintrin.h>
-#endif
+#include <stddef.h>
#include <stdint.h>
#include <limits>
+#include <type_traits>
#include <gtest/gtest.h>
@@ -19,6 +18,8 @@
using std::numeric_limits;
using base::CheckedNumeric;
using base::checked_cast;
+using base::IsValueInRangeForNumericType;
+using base::IsValueNegative;
using base::SizeT;
using base::StrictNumeric;
using base::saturated_cast;
@@ -28,7 +29,7 @@ using base::internal::RANGE_VALID;
using base::internal::RANGE_INVALID;
using base::internal::RANGE_OVERFLOW;
using base::internal::RANGE_UNDERFLOW;
-using std::enable_if;
+using base::internal::SignedIntegerForSize;
// These tests deliberately cause arithmetic overflows. If the compiler is
// aggressive enough, it can const fold these overflows. Disable warnings about
@@ -37,6 +38,26 @@ using std::enable_if;
#pragma warning(disable:4756)
#endif
+// This is a helper function for finding the maximum value in Src that can be
+// wholy represented as the destination floating-point type.
+template <typename Dst, typename Src>
+Dst GetMaxConvertibleToFloat() {
+ typedef numeric_limits<Dst> DstLimits;
+ typedef numeric_limits<Src> SrcLimits;
+ static_assert(SrcLimits::is_specialized, "Source must be numeric.");
+ static_assert(DstLimits::is_specialized, "Destination must be numeric.");
+ CHECK(DstLimits::is_iec559);
+
+ if (SrcLimits::digits <= DstLimits::digits &&
+ MaxExponent<Src>::value <= MaxExponent<Dst>::value)
+ return SrcLimits::max();
+ Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
+ while (max != static_cast<Src>(static_cast<Dst>(max))) {
+ max /= 2;
+ }
+ return static_cast<Dst>(max);
+}
+
// Helper macros to wrap displaying the conversion types and line numbers.
#define TEST_EXPECTED_VALIDITY(expected, actual) \
EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \
@@ -54,9 +75,9 @@ template <typename Dst>
static void TestSpecializedArithmetic(
const char* dst,
int line,
- typename enable_if<
- numeric_limits<Dst>::is_integer&& numeric_limits<Dst>::is_signed,
- int>::type = 0) {
+ typename std::enable_if<numeric_limits<Dst>::is_integer &&
+ numeric_limits<Dst>::is_signed,
+ int>::type = 0) {
typedef numeric_limits<Dst> DstLimits;
TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW,
-CheckedNumeric<Dst>(DstLimits::min()));
@@ -110,9 +131,9 @@ template <typename Dst>
static void TestSpecializedArithmetic(
const char* dst,
int line,
- typename enable_if<
- numeric_limits<Dst>::is_integer && !numeric_limits<Dst>::is_signed,
- int>::type = 0) {
+ typename std::enable_if<numeric_limits<Dst>::is_integer &&
+ !numeric_limits<Dst>::is_signed,
+ int>::type = 0) {
typedef numeric_limits<Dst> DstLimits;
TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
TEST_EXPECTED_VALIDITY(RANGE_VALID,
@@ -123,6 +144,13 @@ static void TestSpecializedArithmetic(
CheckedNumeric<Dst>(DstLimits::min()) - 1);
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
+ TEST_EXPECTED_VALIDITY(RANGE_VALID,
+ CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
+ TEST_EXPECTED_VALIDITY(
+ RANGE_VALID,
+ CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
+ std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
+ .UnsignedAbs());
// Modulus is legal only for integers.
TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
@@ -143,7 +171,7 @@ template <typename Dst>
void TestSpecializedArithmetic(
const char* dst,
int line,
- typename enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
+ typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
typedef numeric_limits<Dst> DstLimits;
TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min()));
@@ -318,7 +346,6 @@ struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
"Comparison must be sign preserving and value preserving");
const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
- ;
TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst);
if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
@@ -371,6 +398,18 @@ struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+ if (DstLimits::is_integer) {
+ if (SrcLimits::digits < DstLimits::digits) {
+ TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
+ static_cast<Src>(DstLimits::max()));
+ } else {
+ TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+ }
+ TEST_EXPECTED_RANGE(
+ RANGE_VALID,
+ static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+ TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+ }
} else if (SrcLimits::is_signed) {
TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
@@ -429,6 +468,18 @@ struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+ if (DstLimits::is_integer) {
+ if (SrcLimits::digits < DstLimits::digits) {
+ TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
+ static_cast<Src>(DstLimits::max()));
+ } else {
+ TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+ }
+ TEST_EXPECTED_RANGE(
+ RANGE_VALID,
+ static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+ TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+ }
} else {
TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
}
@@ -579,6 +630,18 @@ TEST(SafeNumerics, CastTests) {
EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
+ EXPECT_TRUE(IsValueNegative(-1));
+ EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
+ EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
+ EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
+ EXPECT_FALSE(IsValueNegative(0));
+ EXPECT_FALSE(IsValueNegative(1));
+ EXPECT_FALSE(IsValueNegative(0u));
+ EXPECT_FALSE(IsValueNegative(1u));
+ EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
+ EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
+ EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
+
// These casts and coercions will fail to compile:
// EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
// EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
@@ -599,5 +662,120 @@ TEST(SafeNumerics, CastTests) {
EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
+
+ float not_a_number = std::numeric_limits<float>::infinity() -
+ std::numeric_limits<float>::infinity();
+ EXPECT_TRUE(std::isnan(not_a_number));
+ EXPECT_EQ(0, saturated_cast<int>(not_a_number));
}
+#if GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, SaturatedCastChecks) {
+ float not_a_number = std::numeric_limits<float>::infinity() -
+ std::numeric_limits<float>::infinity();
+ EXPECT_TRUE(std::isnan(not_a_number));
+ EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(
+ not_a_number)), "");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, IsValueInRangeForNumericType) {
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
+ std::numeric_limits<int32_t>::min()));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
+ std::numeric_limits<int64_t>::min()));
+
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
+ std::numeric_limits<int32_t>::min()));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
+ static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
+ static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
+ EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
+ std::numeric_limits<int64_t>::min()));
+
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
+ std::numeric_limits<int32_t>::min()));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
+ EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
+ std::numeric_limits<int64_t>::min()));
+
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
+ EXPECT_TRUE(
+ IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
+ EXPECT_TRUE(
+ IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
+ EXPECT_FALSE(
+ IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
+ EXPECT_FALSE(
+ IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+ std::numeric_limits<int32_t>::min()));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+ static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+ EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+ std::numeric_limits<int64_t>::min()));
+}
+
+TEST(SafeNumerics, CompoundNumericOperations) {
+ CheckedNumeric<int> a = 1;
+ CheckedNumeric<int> b = 2;
+ CheckedNumeric<int> c = 3;
+ CheckedNumeric<int> d = 4;
+ a += b;
+ EXPECT_EQ(3, a.ValueOrDie());
+ a -= c;
+ EXPECT_EQ(0, a.ValueOrDie());
+ d /= b;
+ EXPECT_EQ(2, d.ValueOrDie());
+ d *= d;
+ EXPECT_EQ(4, d.ValueOrDie());
+
+ CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
+ EXPECT_TRUE(too_large.IsValid());
+ too_large += d;
+ EXPECT_FALSE(too_large.IsValid());
+ too_large -= d;
+ EXPECT_FALSE(too_large.IsValid());
+ too_large /= d;
+ EXPECT_FALSE(too_large.IsValid());
+}
diff --git a/third_party/chromium/base/observer_list.h b/third_party/chromium/base/observer_list.h
index 3baf910..bb76091 100644
--- a/third_party/chromium/base/observer_list.h
+++ b/third_party/chromium/base/observer_list.h
@@ -5,12 +5,14 @@
#ifndef BASE_OBSERVER_LIST_H_
#define BASE_OBSERVER_LIST_H_
+#include <stddef.h>
+
#include <algorithm>
#include <limits>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
///////////////////////////////////////////////////////////////////////////////
@@ -152,8 +154,8 @@ ObserverType* ObserverListBase<ObserverType>::Iterator::GetNext() {
template <class ObserverType>
void ObserverListBase<ObserverType>::AddObserver(ObserverType* obs) {
DCHECK(obs);
- if (std::find(observers_.begin(), observers_.end(), obs)
- != observers_.end()) {
+ auto it = std::find(observers_.begin(), observers_.end(), obs);
+ if (it != observers_.end()) {
NOTREACHED() << "Observers can only be added once!";
return;
}
diff --git a/third_party/chromium/base/rand_util.cc b/third_party/chromium/base/rand_util.cc
index a55cdbd..c02c875 100644
--- a/third_party/chromium/base/rand_util.cc
+++ b/third_party/chromium/base/rand_util.cc
@@ -4,13 +4,13 @@
#include "base/rand_util.h"
+#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <algorithm>
#include <limits>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
@@ -19,8 +19,11 @@ namespace base {
int RandInt(int min, int max) {
DCHECK_LE(min, max);
- uint64 range = static_cast<uint64>(max) - min + 1;
- int result = min + static_cast<int>(base::RandGenerator(range));
+ uint64_t range = static_cast<uint64_t>(max) - min + 1;
+ // |range| is at most UINT_MAX + 1, so the result of RandGenerator(range)
+ // is at most UINT_MAX. Hence it's safe to cast it from uint64_t to int64_t.
+ int result =
+ static_cast<int>(min + static_cast<int64_t>(base::RandGenerator(range)));
DCHECK_GE(result, min);
DCHECK_LE(result, max);
return result;
@@ -30,31 +33,32 @@ double RandDouble() {
return BitsToOpenEndedUnitInterval(base::RandUint64());
}
-double BitsToOpenEndedUnitInterval(uint64 bits) {
+double BitsToOpenEndedUnitInterval(uint64_t bits) {
// We try to get maximum precision by masking out as many bits as will fit
// in the target type's mantissa, and raising it to an appropriate power to
// produce output in the range [0, 1). For IEEE 754 doubles, the mantissa
// is expected to accommodate 53 bits.
- COMPILE_ASSERT(std::numeric_limits<double>::radix == 2, otherwise_use_scalbn);
+ static_assert(std::numeric_limits<double>::radix == 2,
+ "otherwise use scalbn");
static const int kBits = std::numeric_limits<double>::digits;
- uint64 random_bits = bits & ((UINT64_C(1) << kBits) - 1);
+ uint64_t random_bits = bits & ((UINT64_C(1) << kBits) - 1);
double result = ldexp(static_cast<double>(random_bits), -1 * kBits);
DCHECK_GE(result, 0.0);
DCHECK_LT(result, 1.0);
return result;
}
-uint64 RandGenerator(uint64 range) {
+uint64_t RandGenerator(uint64_t range) {
DCHECK_GT(range, 0u);
// We must discard random results above this number, as they would
// make the random generator non-uniform (consider e.g. if
// MAX_UINT64 was 7 and |range| was 5, then a result of 1 would be twice
// as likely as a result of 3 or 4).
- uint64 max_acceptable_value =
- (std::numeric_limits<uint64>::max() / range) * range - 1;
+ uint64_t max_acceptable_value =
+ (std::numeric_limits<uint64_t>::max() / range) * range - 1;
- uint64 value;
+ uint64_t value;
do {
value = base::RandUint64();
} while (value > max_acceptable_value);
diff --git a/third_party/chromium/base/rand_util.h b/third_party/chromium/base/rand_util.h
index e29a9ce..ff52aad 100644
--- a/third_party/chromium/base/rand_util.h
+++ b/third_party/chromium/base/rand_util.h
@@ -5,15 +5,18 @@
#ifndef BASE_RAND_UTIL_H_
#define BASE_RAND_UTIL_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
+#include "build/build_config.h"
namespace base {
-// Returns a random number in range [0, kuint64max]. Thread-safe.
-uint64 RandUint64();
+// Returns a random number in range [0, UINT64_MAX]. Thread-safe.
+uint64_t RandUint64();
// Returns a random number between min and max (inclusive). Thread-safe.
int RandInt(int min, int max);
@@ -23,14 +26,14 @@ int RandInt(int min, int max);
// Note that this can be used as an adapter for std::random_shuffle():
// Given a pre-populated |std::vector<int> myvector|, shuffle it as
// std::random_shuffle(myvector.begin(), myvector.end(), base::RandGenerator);
-uint64 RandGenerator(uint64 range);
+uint64_t RandGenerator(uint64_t range);
// Returns a random double in range [0, 1). Thread-safe.
double RandDouble();
// Given input |bits|, convert with maximum precision to a double in
// the range [0, 1). Thread-safe.
-double BitsToOpenEndedUnitInterval(uint64 bits);
+double BitsToOpenEndedUnitInterval(uint64_t bits);
// Fills |output_length| bytes of |output| with random data.
//
diff --git a/third_party/chromium/base/rand_util_posix.cc b/third_party/chromium/base/rand_util_posix.cc
index 76a5dab..2f51804 100644
--- a/third_party/chromium/base/rand_util_posix.cc
+++ b/third_party/chromium/base/rand_util_posix.cc
@@ -6,6 +6,8 @@
#include <errno.h>
#include <fcntl.h>
+#include <stddef.h>
+#include <stdint.h>
#include <unistd.h>
#include "base/logging.h"
@@ -44,8 +46,8 @@ bool ReadFromFD(int fd, char* buffer, size_t bytes) {
namespace base {
// NOTE: This function must be cryptographically secure. http://crbug.com/140076
-uint64 RandUint64() {
- uint64 number;
+uint64_t RandUint64() {
+ uint64_t number;
RandBytes(&number, sizeof(number));
return number;
}
diff --git a/third_party/chromium/base/rand_util_unittest.cc b/third_party/chromium/base/rand_util_unittest.cc
index 384125b..fc0233d 100644
--- a/third_party/chromium/base/rand_util_unittest.cc
+++ b/third_party/chromium/base/rand_util_unittest.cc
@@ -4,6 +4,9 @@
#include "base/rand_util.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <algorithm>
#include <limits>
@@ -20,10 +23,16 @@ const int kIntMax = std::numeric_limits<int>::max();
} // namespace
-TEST(RandUtilTest, SameMinAndMax) {
+TEST(RandUtilTest, RandInt) {
EXPECT_EQ(base::RandInt(0, 0), 0);
EXPECT_EQ(base::RandInt(kIntMin, kIntMin), kIntMin);
EXPECT_EQ(base::RandInt(kIntMax, kIntMax), kIntMax);
+
+ // Check that the DCHECKS in RandInt() don't fire due to internal overflow.
+ // There was a 50% chance of that happening, so calling it 40 times means
+ // the chances of this passing by accident are tiny (9e-13).
+ for (int i = 0; i < 40; ++i)
+ base::RandInt(kIntMin, kIntMax);
}
TEST(RandUtilTest, RandDouble) {
@@ -62,7 +71,7 @@ TEST(RandUtilTest, RandBytesAsString) {
TEST(RandUtilTest, RandGeneratorForRandomShuffle) {
EXPECT_EQ(base::RandGenerator(1), 0U);
EXPECT_LE(std::numeric_limits<ptrdiff_t>::max(),
- std::numeric_limits<int64>::max());
+ std::numeric_limits<int64_t>::max());
}
TEST(RandUtilTest, RandGeneratorIsUniform) {
@@ -78,16 +87,17 @@ TEST(RandUtilTest, RandGeneratorIsUniform) {
// top half. A bit of calculus care of jar@ shows that the largest
// measurable delta is when the top of the range is 3/4ths of the
// way, so that's what we use in the test.
- const uint64 kTopOfRange = (std::numeric_limits<uint64>::max() / 4ULL) * 3ULL;
- const uint64 kExpectedAverage = kTopOfRange / 2ULL;
- const uint64 kAllowedVariance = kExpectedAverage / 50ULL; // +/- 2%
+ const uint64_t kTopOfRange =
+ (std::numeric_limits<uint64_t>::max() / 4ULL) * 3ULL;
+ const uint64_t kExpectedAverage = kTopOfRange / 2ULL;
+ const uint64_t kAllowedVariance = kExpectedAverage / 50ULL; // +/- 2%
const int kMinAttempts = 1000;
const int kMaxAttempts = 1000000;
double cumulative_average = 0.0;
int count = 0;
while (count < kMaxAttempts) {
- uint64 value = base::RandGenerator(kTopOfRange);
+ uint64_t value = base::RandGenerator(kTopOfRange);
cumulative_average = (count * cumulative_average + value) / (count + 1);
// Don't quit too quickly for things to start converging, or we may have
@@ -108,13 +118,13 @@ TEST(RandUtilTest, RandGeneratorIsUniform) {
TEST(RandUtilTest, RandUint64ProducesBothValuesOfAllBits) {
// This tests to see that our underlying random generator is good
// enough, for some value of good enough.
- uint64 kAllZeros = 0ULL;
- uint64 kAllOnes = ~kAllZeros;
- uint64 found_ones = kAllZeros;
- uint64 found_zeros = kAllOnes;
+ uint64_t kAllZeros = 0ULL;
+ uint64_t kAllOnes = ~kAllZeros;
+ uint64_t found_ones = kAllZeros;
+ uint64_t found_zeros = kAllOnes;
for (size_t i = 0; i < 1000; ++i) {
- uint64 value = base::RandUint64();
+ uint64_t value = base::RandUint64();
found_ones |= value;
found_zeros &= value;
diff --git a/third_party/chromium/base/scoped_clear_errno.h b/third_party/chromium/base/scoped_clear_errno.h
index 7b972fc..585f6f7 100644
--- a/third_party/chromium/base/scoped_clear_errno.h
+++ b/third_party/chromium/base/scoped_clear_errno.h
@@ -7,7 +7,7 @@
#include <errno.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
namespace base {
diff --git a/third_party/chromium/base/scoped_observer.h b/third_party/chromium/base/scoped_observer.h
index 422701b..79bcec5 100644
--- a/third_party/chromium/base/scoped_observer.h
+++ b/third_party/chromium/base/scoped_observer.h
@@ -5,11 +5,13 @@
#ifndef BASE_SCOPED_OBSERVER_H_
#define BASE_SCOPED_OBSERVER_H_
+#include <stddef.h>
+
#include <algorithm>
#include <vector>
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/macros.h"
// ScopedObserver is used to keep track of the set of sources an object has
// attached itself to as an observer. When ScopedObserver is destroyed it
@@ -44,8 +46,7 @@ class ScopedObserver {
}
bool IsObserving(Source* source) const {
- return std::find(sources_.begin(), sources_.end(), source) !=
- sources_.end();
+ return ContainsValue(sources_, source);
}
bool IsObservingSources() const { return !sources_.empty(); }
diff --git a/third_party/chromium/base/strings/string_number_conversions.cc b/third_party/chromium/base/strings/string_number_conversions.cc
index b5463fb..ac0fd46 100644
--- a/third_party/chromium/base/strings/string_number_conversions.cc
+++ b/third_party/chromium/base/strings/string_number_conversions.cc
@@ -12,84 +12,44 @@
#include <limits>
#include "base/logging.h"
-#include "base/scoped_clear_errno.h"
-#include "base/third_party/dmg_fp/dmg_fp.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
namespace base {
namespace {
-template <typename STR, typename INT, typename UINT, bool NEG>
+template <typename STR, typename INT>
struct IntToStringT {
- // This is to avoid a compiler warning about unary minus on unsigned type.
- // For example, say you had the following code:
- // template <typename INT>
- // INT abs(INT value) { return value < 0 ? -value : value; }
- // Even though if INT is unsigned, it's impossible for value < 0, so the
- // unary minus will never be taken, the compiler will still generate a
- // warning. We do a little specialization dance...
- template <typename INT2, typename UINT2, bool NEG2>
- struct ToUnsignedT {};
-
- template <typename INT2, typename UINT2>
- struct ToUnsignedT<INT2, UINT2, false> {
- static UINT2 ToUnsigned(INT2 value) {
- return static_cast<UINT2>(value);
- }
- };
-
- template <typename INT2, typename UINT2>
- struct ToUnsignedT<INT2, UINT2, true> {
- static UINT2 ToUnsigned(INT2 value) {
- return static_cast<UINT2>(value < 0 ? -value : value);
- }
- };
-
- // This set of templates is very similar to the above templates, but
- // for testing whether an integer is negative.
- template <typename INT2, bool NEG2>
- struct TestNegT {};
- template <typename INT2>
- struct TestNegT<INT2, false> {
- static bool TestNeg(INT2 value) {
- // value is unsigned, and can never be negative.
- return false;
- }
- };
- template <typename INT2>
- struct TestNegT<INT2, true> {
- static bool TestNeg(INT2 value) {
- return value < 0;
- }
- };
-
static STR IntToString(INT value) {
// log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4.
// So round up to allocate 3 output characters per byte, plus 1 for '-'.
- const int kOutputBufSize = 3 * sizeof(INT) + 1;
+ const size_t kOutputBufSize =
+ 3 * sizeof(INT) + std::numeric_limits<INT>::is_signed;
- // Allocate the whole string right away, we will right back to front, and
+ // Create the string in a temporary buffer, write it back to front, and
// then return the substr of what we ended up using.
- STR outbuf(kOutputBufSize, 0);
+ using CHR = typename STR::value_type;
+ CHR outbuf[kOutputBufSize];
- bool is_neg = TestNegT<INT, NEG>::TestNeg(value);
- // Even though is_neg will never be true when INT is parameterized as
- // unsigned, even the presence of the unary operation causes a warning.
- UINT res = ToUnsignedT<INT, UINT, NEG>::ToUnsigned(value);
+ // The ValueOrDie call below can never fail, because UnsignedAbs is valid
+ // for all valid inputs.
+ auto res = CheckedNumeric<INT>(value).UnsignedAbs().ValueOrDie();
- typename STR::iterator it(outbuf.end());
+ CHR* end = outbuf + kOutputBufSize;
+ CHR* i = end;
do {
- --it;
- DCHECK(it != outbuf.begin());
- *it = static_cast<typename STR::value_type>((res % 10) + '0');
+ --i;
+ DCHECK(i != outbuf);
+ *i = static_cast<CHR>((res % 10) + '0');
res /= 10;
} while (res != 0);
- if (is_neg) {
- --it;
- DCHECK(it != outbuf.begin());
- *it = static_cast<typename STR::value_type>('-');
+ if (IsValueNegative(value)) {
+ --i;
+ DCHECK(i != outbuf);
+ *i = static_cast<CHR>('-');
}
- return STR(it, outbuf.end());
+ return STR(i, end);
}
};
@@ -100,9 +60,9 @@ template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit {
// Faster specialization for bases <= 10
template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> {
public:
- static bool Convert(CHAR c, uint8* digit) {
+ static bool Convert(CHAR c, uint8_t* digit) {
if (c >= '0' && c < '0' + BASE) {
- *digit = static_cast<uint8>(c - '0');
+ *digit = static_cast<uint8_t>(c - '0');
return true;
}
return false;
@@ -112,7 +72,7 @@ template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> {
// Specialization for bases where 10 < base <= 36
template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> {
public:
- static bool Convert(CHAR c, uint8* digit) {
+ static bool Convert(CHAR c, uint8_t* digit) {
if (c >= '0' && c <= '9') {
*digit = c - '0';
} else if (c >= 'a' && c < 'a' + BASE - 10) {
@@ -126,14 +86,15 @@ template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> {
}
};
-template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8* digit) {
+template <int BASE, typename CHAR>
+bool CharToDigit(CHAR c, uint8_t* digit) {
return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit);
}
-// There is an IsWhitespace for wchars defined in string_util.h, but it is
-// locale independent, whereas the functions we are replacing were
-// locale-dependent. TBD what is desired, but for the moment let's not introduce
-// a change in behaviour.
+// There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it
+// is locale independent, whereas the functions we are replacing were
+// locale-dependent. TBD what is desired, but for the moment let's not
+// introduce a change in behaviour.
template<typename CHAR> class WhitespaceHelper {
};
@@ -216,7 +177,7 @@ class IteratorRangeToNumber {
}
for (const_iterator current = begin; current != end; ++current) {
- uint8 new_digit = 0;
+ uint8_t new_digit = 0;
if (!CharToDigit<traits::kBase>(*current, &new_digit)) {
return false;
@@ -237,7 +198,7 @@ class IteratorRangeToNumber {
class Positive : public Base<Positive> {
public:
- static bool CheckBounds(value_type* output, uint8 new_digit) {
+ static bool CheckBounds(value_type* output, uint8_t new_digit) {
if (*output > static_cast<value_type>(traits::max() / traits::kBase) ||
(*output == static_cast<value_type>(traits::max() / traits::kBase) &&
new_digit > traits::max() % traits::kBase)) {
@@ -246,14 +207,14 @@ class IteratorRangeToNumber {
}
return true;
}
- static void Increment(uint8 increment, value_type* output) {
+ static void Increment(uint8_t increment, value_type* output) {
*output += increment;
}
};
class Negative : public Base<Negative> {
public:
- static bool CheckBounds(value_type* output, uint8 new_digit) {
+ static bool CheckBounds(value_type* output, uint8_t new_digit) {
if (*output < traits::min() / traits::kBase ||
(*output == traits::min() / traits::kBase &&
new_digit > 0 - traits::min() % traits::kBase)) {
@@ -262,7 +223,7 @@ class IteratorRangeToNumber {
}
return true;
}
- static void Increment(uint8 increment, value_type* output) {
+ static void Increment(uint8_t increment, value_type* output) {
*output -= increment;
}
};
@@ -287,20 +248,17 @@ class BaseHexIteratorRangeToIntTraits
: public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> {
};
-template<typename ITERATOR>
+template <typename ITERATOR>
class BaseHexIteratorRangeToUIntTraits
- : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32, 16> {
-};
+ : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32_t, 16> {};
-template<typename ITERATOR>
+template <typename ITERATOR>
class BaseHexIteratorRangeToInt64Traits
- : public BaseIteratorRangeToNumberTraits<ITERATOR, int64, 16> {
-};
+ : public BaseIteratorRangeToNumberTraits<ITERATOR, int64_t, 16> {};
-template<typename ITERATOR>
+template <typename ITERATOR>
class BaseHexIteratorRangeToUInt64Traits
- : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64, 16> {
-};
+ : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64_t, 16> {};
typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator>
HexIteratorRangeToIntTraits;
@@ -314,15 +272,15 @@ typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator>
typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator>
HexIteratorRangeToUInt64Traits;
-template<typename STR>
-bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) {
+template <typename STR>
+bool HexStringToBytesT(const STR& input, std::vector<uint8_t>* output) {
DCHECK_EQ(output->size(), 0u);
size_t count = input.size();
if (count == 0 || (count % 2) != 0)
return false;
for (uintptr_t i = 0; i < count / 2; ++i) {
- uint8 msb = 0; // most significant 4 bits
- uint8 lsb = 0; // least significant 4 bits
+ uint8_t msb = 0; // most significant 4 bits
+ uint8_t lsb = 0; // least significant 4 bits
if (!CharToDigit<16>(input[i * 2], &msb) ||
!CharToDigit<16>(input[i * 2 + 1], &lsb))
return false;
@@ -347,32 +305,38 @@ bool StringToIntImpl(const StringPiece& input, VALUE* output) {
} // namespace
std::string IntToString(int value) {
- return IntToStringT<std::string, int, unsigned int, true>::
- IntToString(value);
+ return IntToStringT<std::string, int>::IntToString(value);
}
std::string UintToString(unsigned int value) {
- return IntToStringT<std::string, unsigned int, unsigned int, false>::
- IntToString(value);
+ return IntToStringT<std::string, unsigned int>::IntToString(value);
}
-std::string Int64ToString(int64 value) {
- return IntToStringT<std::string, int64, uint64, true>::IntToString(value);
+std::string Int64ToString(int64_t value) {
+ return IntToStringT<std::string, int64_t>::IntToString(value);
}
-std::string Uint64ToString(uint64 value) {
- return IntToStringT<std::string, uint64, uint64, false>::IntToString(value);
+std::string Uint64ToString(uint64_t value) {
+ return IntToStringT<std::string, uint64_t>::IntToString(value);
}
std::string SizeTToString(size_t value) {
- return IntToStringT<std::string, size_t, size_t, false>::IntToString(value);
+ return IntToStringT<std::string, size_t>::IntToString(value);
}
std::string DoubleToString(double value) {
- // According to g_fmt.cc, it is sufficient to declare a buffer of size 32.
- char buffer[32];
- dmg_fp::g_fmt(buffer, value);
- return std::string(buffer);
+ auto ret = std::to_string(value);
+ // If this returned an integer, don't do anything.
+ if (ret.find('.') == std::string::npos) {
+ return ret;
+ }
+ // Otherwise, it has an annoying tendency to leave trailing zeros.
+ size_t len = ret.size();
+ while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') {
+ --len;
+ }
+ ret.erase(len);
+ return ret;
}
bool StringToInt(const StringPiece& input, int* output) {
@@ -383,11 +347,11 @@ bool StringToUint(const StringPiece& input, unsigned* output) {
return StringToIntImpl(input, output);
}
-bool StringToInt64(const StringPiece& input, int64* output) {
+bool StringToInt64(const StringPiece& input, int64_t* output) {
return StringToIntImpl(input, output);
}
-bool StringToUint64(const StringPiece& input, uint64* output) {
+bool StringToUint64(const StringPiece& input, uint64_t* output) {
return StringToIntImpl(input, output);
}
@@ -396,14 +360,10 @@ bool StringToSizeT(const StringPiece& input, size_t* output) {
}
bool StringToDouble(const std::string& input, double* output) {
- // Thread-safe? It is on at least Mac, Linux, and Windows.
- ScopedClearErrno clear_errno;
-
- char* endptr = NULL;
- *output = dmg_fp::strtod(input.c_str(), &endptr);
+ char* endptr = nullptr;
+ *output = strtod(input.c_str(), &endptr);
// Cases to return false:
- // - If errno is ERANGE, there was an overflow or underflow.
// - If the input string is empty, there was nothing to parse.
// - If endptr does not point to the end of the string, there are either
// characters remaining in the string after a parsed number, or the string
@@ -411,10 +371,11 @@ bool StringToDouble(const std::string& input, double* output) {
// expected end given the string's stated length to correctly catch cases
// where the string contains embedded NUL characters.
// - If the first character is a space, there was leading whitespace
- return errno == 0 &&
- !input.empty() &&
+ return !input.empty() &&
input.c_str() + input.length() == endptr &&
- !isspace(input[0]);
+ !isspace(input[0]) &&
+ *output != std::numeric_limits<double>::infinity() &&
+ *output != -std::numeric_limits<double>::infinity();
}
// Note: if you need to add String16ToDouble, first ask yourself if it's
@@ -444,22 +405,22 @@ bool HexStringToInt(const StringPiece& input, int* output) {
input.begin(), input.end(), output);
}
-bool HexStringToUInt(const StringPiece& input, uint32* output) {
+bool HexStringToUInt(const StringPiece& input, uint32_t* output) {
return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke(
input.begin(), input.end(), output);
}
-bool HexStringToInt64(const StringPiece& input, int64* output) {
+bool HexStringToInt64(const StringPiece& input, int64_t* output) {
return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke(
input.begin(), input.end(), output);
}
-bool HexStringToUInt64(const StringPiece& input, uint64* output) {
+bool HexStringToUInt64(const StringPiece& input, uint64_t* output) {
return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke(
input.begin(), input.end(), output);
}
-bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) {
+bool HexStringToBytes(const std::string& input, std::vector<uint8_t>* output) {
return HexStringToBytesT(input, output);
}
diff --git a/third_party/chromium/base/strings/string_number_conversions.h b/third_party/chromium/base/strings/string_number_conversions.h
index c68d0af..af0faa6 100644
--- a/third_party/chromium/base/strings/string_number_conversions.h
+++ b/third_party/chromium/base/strings/string_number_conversions.h
@@ -5,11 +5,13 @@
#ifndef BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_
#define BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/strings/string_piece.h"
// ----------------------------------------------------------------------------
@@ -32,12 +34,13 @@ std::string IntToString(int value);
std::string UintToString(unsigned value);
-std::string Int64ToString(int64 value);
+std::string Int64ToString(int64_t value);
-std::string Uint64ToString(uint64 value);
+std::string Uint64ToString(uint64_t value);
std::string SizeTToString(size_t value);
+// Deprecated: prefer std::to_string(double) instead.
// DoubleToString converts the double to a string format that ignores the
// locale. If you want to use locale specific formatting, use ICU.
std::string DoubleToString(double value);
@@ -58,22 +61,27 @@ std::string DoubleToString(double value);
// - No characters parseable as a number at the beginning of the string.
// |*output| will be set to 0.
// - Empty string. |*output| will be set to 0.
+// WARNING: Will write to |output| even when returning false.
+// Read the comments above carefully.
bool StringToInt(const StringPiece& input, int* output);
bool StringToUint(const StringPiece& input, unsigned* output);
-bool StringToInt64(const StringPiece& input, int64* output);
+bool StringToInt64(const StringPiece& input, int64_t* output);
-bool StringToUint64(const StringPiece& input, uint64* output);
+bool StringToUint64(const StringPiece& input, uint64_t* output);
bool StringToSizeT(const StringPiece& input, size_t* output);
+// Deprecated: prefer std::stod() instead.
// For floating-point conversions, only conversions of input strings in decimal
// form are defined to work. Behavior with strings representing floating-point
-// numbers in hexadecimal, and strings representing non-fininte values (such as
+// numbers in hexadecimal, and strings representing non-finite values (such as
// NaN and inf) is undefined. Otherwise, these behave the same as the integral
// variants. This expects the input string to NOT be specific to the locale.
// If your input is locale specific, use ICU to read the number.
+// WARNING: Will write to |output| even when returning false.
+// Read the comments here and above StringToInt() carefully.
bool StringToDouble(const std::string& input, double* output);
// Hex encoding ----------------------------------------------------------------
@@ -95,24 +103,25 @@ bool HexStringToInt(const StringPiece& input, int* output);
// Will only successful parse hex values that will fit into |output|, i.e.
// 0x00000000 < |input| < 0xFFFFFFFF.
// The string is not required to start with 0x.
-bool HexStringToUInt(const StringPiece& input, uint32* output);
+bool HexStringToUInt(const StringPiece& input, uint32_t* output);
// Best effort conversion, see StringToInt above for restrictions.
// Will only successful parse hex values that will fit into |output|, i.e.
// -0x8000000000000000 < |input| < 0x7FFFFFFFFFFFFFFF.
-bool HexStringToInt64(const StringPiece& input, int64* output);
+bool HexStringToInt64(const StringPiece& input, int64_t* output);
// Best effort conversion, see StringToInt above for restrictions.
// Will only successful parse hex values that will fit into |output|, i.e.
// 0x0000000000000000 < |input| < 0xFFFFFFFFFFFFFFFF.
// The string is not required to start with 0x.
-bool HexStringToUInt64(const StringPiece& input, uint64* output);
+bool HexStringToUInt64(const StringPiece& input, uint64_t* output);
// Similar to the previous functions, except that output is a vector of bytes.
// |*output| will contain as many bytes as were successfully parsed prior to the
// error. There is no overflow, but input.size() must be evenly divisible by 2.
// Leading 0x or +/- are not allowed.
-bool HexStringToBytes(const std::string& input, std::vector<uint8>* output);
+bool HexStringToBytes(const std::string& input,
+ std::vector<uint8_t>* output);
} // namespace base
diff --git a/third_party/chromium/base/strings/string_number_conversions_unittest.cc b/third_party/chromium/base/strings/string_number_conversions_unittest.cc
index 80d1471..1cfb2c8 100644
--- a/third_party/chromium/base/strings/string_number_conversions_unittest.cc
+++ b/third_party/chromium/base/strings/string_number_conversions_unittest.cc
@@ -5,6 +5,8 @@
#include "base/strings/string_number_conversions.h"
#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -13,6 +15,7 @@
#include <gtest/gtest.h>
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversion_utils.h"
@@ -36,15 +39,15 @@ TEST(StringNumberConversionsTest, IntToString) {
{ std::numeric_limits<int>::max(), "2147483647", "2147483647" },
{ std::numeric_limits<int>::min(), "-2147483648", "2147483648" },
};
- static const IntToStringTest<int64> int64_tests[] = {
- { 0, "0", "0" },
- { -1, "-1", "18446744073709551615" },
- { std::numeric_limits<int64>::max(),
- "9223372036854775807",
- "9223372036854775807", },
- { std::numeric_limits<int64>::min(),
- "-9223372036854775808",
- "9223372036854775808" },
+ static const IntToStringTest<int64_t> int64_tests[] = {
+ {0, "0", "0"},
+ {-1, "-1", "18446744073709551615"},
+ {
+ std::numeric_limits<int64_t>::max(), "9223372036854775807",
+ "9223372036854775807",
+ },
+ {std::numeric_limits<int64_t>::min(), "-9223372036854775808",
+ "9223372036854775808"},
};
for (size_t i = 0; i < arraysize(int_tests); ++i) {
@@ -53,7 +56,7 @@ TEST(StringNumberConversionsTest, IntToString) {
EXPECT_EQ(UintToString(test->num), test->uexpected);
}
for (size_t i = 0; i < arraysize(int64_tests); ++i) {
- const IntToStringTest<int64>* test = &int64_tests[i];
+ const IntToStringTest<int64_t>* test = &int64_tests[i];
EXPECT_EQ(Int64ToString(test->num), test->sexpected);
EXPECT_EQ(Uint64ToString(test->num), test->uexpected);
}
@@ -61,13 +64,13 @@ TEST(StringNumberConversionsTest, IntToString) {
TEST(StringNumberConversionsTest, Uint64ToString) {
static const struct {
- uint64 input;
+ uint64_t input;
std::string output;
} cases[] = {
- {0, "0"},
- {42, "42"},
- {INT_MAX, "2147483647"},
- {kuint64max, "18446744073709551615"},
+ {0, "0"},
+ {42, "42"},
+ {INT_MAX, "2147483647"},
+ {std::numeric_limits<uint64_t>::max(), "18446744073709551615"},
};
for (size_t i = 0; i < arraysize(cases); ++i)
@@ -197,44 +200,44 @@ TEST(StringNumberConversionsTest, StringToUint) {
TEST(StringNumberConversionsTest, StringToInt64) {
static const struct {
std::string input;
- int64 output;
+ int64_t output;
bool success;
} cases[] = {
- {"0", 0, true},
- {"42", 42, true},
- {"-2147483648", INT_MIN, true},
- {"2147483647", INT_MAX, true},
- {"-2147483649", INT64_C(-2147483649), true},
- {"-99999999999", INT64_C(-99999999999), true},
- {"2147483648", INT64_C(2147483648), true},
- {"99999999999", INT64_C(99999999999), true},
- {"9223372036854775807", kint64max, true},
- {"-9223372036854775808", kint64min, true},
- {"09", 9, true},
- {"-09", -9, true},
- {"", 0, false},
- {" 42", 42, false},
- {"42 ", 42, false},
- {"0x42", 0, false},
- {"\t\n\v\f\r 42", 42, false},
- {"blah42", 0, false},
- {"42blah", 42, false},
- {"blah42blah", 0, false},
- {"-273.15", -273, false},
- {"+98.6", 98, false},
- {"--123", 0, false},
- {"++123", 0, false},
- {"-+123", 0, false},
- {"+-123", 0, false},
- {"-", 0, false},
- {"-9223372036854775809", kint64min, false},
- {"-99999999999999999999", kint64min, false},
- {"9223372036854775808", kint64max, false},
- {"99999999999999999999", kint64max, false},
+ {"0", 0, true},
+ {"42", 42, true},
+ {"-2147483648", INT_MIN, true},
+ {"2147483647", INT_MAX, true},
+ {"-2147483649", INT64_C(-2147483649), true},
+ {"-99999999999", INT64_C(-99999999999), true},
+ {"2147483648", INT64_C(2147483648), true},
+ {"99999999999", INT64_C(99999999999), true},
+ {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
+ {"-9223372036854775808", std::numeric_limits<int64_t>::min(), true},
+ {"09", 9, true},
+ {"-09", -9, true},
+ {"", 0, false},
+ {" 42", 42, false},
+ {"42 ", 42, false},
+ {"0x42", 0, false},
+ {"\t\n\v\f\r 42", 42, false},
+ {"blah42", 0, false},
+ {"42blah", 42, false},
+ {"blah42blah", 0, false},
+ {"-273.15", -273, false},
+ {"+98.6", 98, false},
+ {"--123", 0, false},
+ {"++123", 0, false},
+ {"-+123", 0, false},
+ {"+-123", 0, false},
+ {"-", 0, false},
+ {"-9223372036854775809", std::numeric_limits<int64_t>::min(), false},
+ {"-99999999999999999999", std::numeric_limits<int64_t>::min(), false},
+ {"9223372036854775808", std::numeric_limits<int64_t>::max(), false},
+ {"99999999999999999999", std::numeric_limits<int64_t>::max(), false},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- int64 output = 0;
+ int64_t output = 0;
EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -244,7 +247,7 @@ TEST(StringNumberConversionsTest, StringToInt64) {
// interpreted as junk after the number.
const char input[] = "6\06";
std::string input_string(input, arraysize(input) - 1);
- int64 output;
+ int64_t output;
EXPECT_FALSE(StringToInt64(input_string, &output));
EXPECT_EQ(6, output);
}
@@ -252,46 +255,46 @@ TEST(StringNumberConversionsTest, StringToInt64) {
TEST(StringNumberConversionsTest, StringToUint64) {
static const struct {
std::string input;
- uint64 output;
+ uint64_t output;
bool success;
} cases[] = {
- {"0", 0, true},
- {"42", 42, true},
- {"-2147483648", 0, false},
- {"2147483647", INT_MAX, true},
- {"-2147483649", 0, false},
- {"-99999999999", 0, false},
- {"2147483648", UINT64_C(2147483648), true},
- {"99999999999", UINT64_C(99999999999), true},
- {"9223372036854775807", kint64max, true},
- {"-9223372036854775808", 0, false},
- {"09", 9, true},
- {"-09", 0, false},
- {"", 0, false},
- {" 42", 42, false},
- {"42 ", 42, false},
- {"0x42", 0, false},
- {"\t\n\v\f\r 42", 42, false},
- {"blah42", 0, false},
- {"42blah", 42, false},
- {"blah42blah", 0, false},
- {"-273.15", 0, false},
- {"+98.6", 98, false},
- {"--123", 0, false},
- {"++123", 0, false},
- {"-+123", 0, false},
- {"+-123", 0, false},
- {"-", 0, false},
- {"-9223372036854775809", 0, false},
- {"-99999999999999999999", 0, false},
- {"9223372036854775808", UINT64_C(9223372036854775808), true},
- {"99999999999999999999", kuint64max, false},
- {"18446744073709551615", kuint64max, true},
- {"18446744073709551616", kuint64max, false},
+ {"0", 0, true},
+ {"42", 42, true},
+ {"-2147483648", 0, false},
+ {"2147483647", INT_MAX, true},
+ {"-2147483649", 0, false},
+ {"-99999999999", 0, false},
+ {"2147483648", UINT64_C(2147483648), true},
+ {"99999999999", UINT64_C(99999999999), true},
+ {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
+ {"-9223372036854775808", 0, false},
+ {"09", 9, true},
+ {"-09", 0, false},
+ {"", 0, false},
+ {" 42", 42, false},
+ {"42 ", 42, false},
+ {"0x42", 0, false},
+ {"\t\n\v\f\r 42", 42, false},
+ {"blah42", 0, false},
+ {"42blah", 42, false},
+ {"blah42blah", 0, false},
+ {"-273.15", 0, false},
+ {"+98.6", 98, false},
+ {"--123", 0, false},
+ {"++123", 0, false},
+ {"-+123", 0, false},
+ {"+-123", 0, false},
+ {"-", 0, false},
+ {"-9223372036854775809", 0, false},
+ {"-99999999999999999999", 0, false},
+ {"9223372036854775808", UINT64_C(9223372036854775808), true},
+ {"99999999999999999999", std::numeric_limits<uint64_t>::max(), false},
+ {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true},
+ {"18446744073709551616", std::numeric_limits<uint64_t>::max(), false},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- uint64 output = 0;
+ uint64_t output = 0;
EXPECT_EQ(cases[i].success, StringToUint64(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -301,7 +304,7 @@ TEST(StringNumberConversionsTest, StringToUint64) {
// interpreted as junk after the number.
const char input[] = "6\06";
std::string input_string(input, arraysize(input) - 1);
- uint64 output;
+ uint64_t output;
EXPECT_FALSE(StringToUint64(input_string, &output));
EXPECT_EQ(6U, output);
}
@@ -368,7 +371,7 @@ TEST(StringNumberConversionsTest, StringToSizeT) {
TEST(StringNumberConversionsTest, HexStringToInt) {
static const struct {
std::string input;
- int64 output;
+ int64_t output;
bool success;
} cases[] = {
{"0", 0, true},
@@ -420,50 +423,55 @@ TEST(StringNumberConversionsTest, HexStringToInt) {
TEST(StringNumberConversionsTest, HexStringToUInt) {
static const struct {
std::string input;
- uint32 output;
+ uint32_t output;
bool success;
} cases[] = {
- {"0", 0, true},
- {"42", 0x42, true},
- {"-42", 0, false},
- {"+42", 0x42, true},
- {"7fffffff", INT_MAX, true},
- {"-80000000", 0, false},
- {"ffffffff", 0xffffffff, true},
- {"DeadBeef", 0xdeadbeef, true},
- {"0x42", 0x42, true},
- {"-0x42", 0, false},
- {"+0x42", 0x42, true},
- {"0x7fffffff", INT_MAX, true},
- {"-0x80000000", 0, false},
- {"0xffffffff", kuint32max, true},
- {"0XDeadBeef", 0xdeadbeef, true},
- {"0x7fffffffffffffff", kuint32max, false}, // Overflow test.
- {"-0x8000000000000000", 0, false},
- {"0x8000000000000000", kuint32max, false}, // Overflow test.
- {"-0x8000000000000001", 0, false},
- {"0xFFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test.
- {"FFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test.
- {"0x0000000000000000", 0, true},
- {"0000000000000000", 0, true},
- {"1FFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test.
- {"0x0f", 0x0f, true},
- {"0f", 0x0f, true},
- {" 45", 0x45, false},
- {"\t\n\v\f\r 0x45", 0x45, false},
- {" 45", 0x45, false},
- {"45 ", 0x45, false},
- {"45:", 0x45, false},
- {"efgh", 0xef, false},
- {"0xefgh", 0xef, false},
- {"hgfe", 0, false},
- {"-", 0, false},
- {"", 0, false},
- {"0x", 0, false},
+ {"0", 0, true},
+ {"42", 0x42, true},
+ {"-42", 0, false},
+ {"+42", 0x42, true},
+ {"7fffffff", INT_MAX, true},
+ {"-80000000", 0, false},
+ {"ffffffff", 0xffffffff, true},
+ {"DeadBeef", 0xdeadbeef, true},
+ {"0x42", 0x42, true},
+ {"-0x42", 0, false},
+ {"+0x42", 0x42, true},
+ {"0x7fffffff", INT_MAX, true},
+ {"-0x80000000", 0, false},
+ {"0xffffffff", std::numeric_limits<uint32_t>::max(), true},
+ {"0XDeadBeef", 0xdeadbeef, true},
+ {"0x7fffffffffffffff", std::numeric_limits<uint32_t>::max(),
+ false}, // Overflow test.
+ {"-0x8000000000000000", 0, false},
+ {"0x8000000000000000", std::numeric_limits<uint32_t>::max(),
+ false}, // Overflow test.
+ {"-0x8000000000000001", 0, false},
+ {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
+ false}, // Overflow test.
+ {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
+ false}, // Overflow test.
+ {"0x0000000000000000", 0, true},
+ {"0000000000000000", 0, true},
+ {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
+ false}, // Overflow test.
+ {"0x0f", 0x0f, true},
+ {"0f", 0x0f, true},
+ {" 45", 0x45, false},
+ {"\t\n\v\f\r 0x45", 0x45, false},
+ {" 45", 0x45, false},
+ {"45 ", 0x45, false},
+ {"45:", 0x45, false},
+ {"efgh", 0xef, false},
+ {"0xefgh", 0xef, false},
+ {"hgfe", 0, false},
+ {"-", 0, false},
+ {"", 0, false},
+ {"0x", 0, false},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- uint32 output = 0;
+ uint32_t output = 0;
EXPECT_EQ(cases[i].success, HexStringToUInt(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -472,7 +480,7 @@ TEST(StringNumberConversionsTest, HexStringToUInt) {
// interpreted as junk after the number.
const char input[] = "0xc0ffee\0" "9";
std::string input_string(input, arraysize(input) - 1);
- uint32 output;
+ uint32_t output;
EXPECT_FALSE(HexStringToUInt(input_string, &output));
EXPECT_EQ(0xc0ffeeU, output);
}
@@ -480,47 +488,49 @@ TEST(StringNumberConversionsTest, HexStringToUInt) {
TEST(StringNumberConversionsTest, HexStringToInt64) {
static const struct {
std::string input;
- int64 output;
+ int64_t output;
bool success;
} cases[] = {
- {"0", 0, true},
- {"42", 66, true},
- {"-42", -66, true},
- {"+42", 66, true},
- {"40acd88557b", INT64_C(4444444448123), true},
- {"7fffffff", INT_MAX, true},
- {"-80000000", INT_MIN, true},
- {"ffffffff", 0xffffffff, true},
- {"DeadBeef", 0xdeadbeef, true},
- {"0x42", 66, true},
- {"-0x42", -66, true},
- {"+0x42", 66, true},
- {"0x40acd88557b", INT64_C(4444444448123), true},
- {"0x7fffffff", INT_MAX, true},
- {"-0x80000000", INT_MIN, true},
- {"0xffffffff", 0xffffffff, true},
- {"0XDeadBeef", 0xdeadbeef, true},
- {"0x7fffffffffffffff", kint64max, true},
- {"-0x8000000000000000", kint64min, true},
- {"0x8000000000000000", kint64max, false}, // Overflow test.
- {"-0x8000000000000001", kint64min, false}, // Underflow test.
- {"0x0f", 15, true},
- {"0f", 15, true},
- {" 45", 0x45, false},
- {"\t\n\v\f\r 0x45", 0x45, false},
- {" 45", 0x45, false},
- {"45 ", 0x45, false},
- {"45:", 0x45, false},
- {"efgh", 0xef, false},
- {"0xefgh", 0xef, false},
- {"hgfe", 0, false},
- {"-", 0, false},
- {"", 0, false},
- {"0x", 0, false},
+ {"0", 0, true},
+ {"42", 66, true},
+ {"-42", -66, true},
+ {"+42", 66, true},
+ {"40acd88557b", INT64_C(4444444448123), true},
+ {"7fffffff", INT_MAX, true},
+ {"-80000000", INT_MIN, true},
+ {"ffffffff", 0xffffffff, true},
+ {"DeadBeef", 0xdeadbeef, true},
+ {"0x42", 66, true},
+ {"-0x42", -66, true},
+ {"+0x42", 66, true},
+ {"0x40acd88557b", INT64_C(4444444448123), true},
+ {"0x7fffffff", INT_MAX, true},
+ {"-0x80000000", INT_MIN, true},
+ {"0xffffffff", 0xffffffff, true},
+ {"0XDeadBeef", 0xdeadbeef, true},
+ {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
+ {"-0x8000000000000000", std::numeric_limits<int64_t>::min(), true},
+ {"0x8000000000000000", std::numeric_limits<int64_t>::max(),
+ false}, // Overflow test.
+ {"-0x8000000000000001", std::numeric_limits<int64_t>::min(),
+ false}, // Underflow test.
+ {"0x0f", 15, true},
+ {"0f", 15, true},
+ {" 45", 0x45, false},
+ {"\t\n\v\f\r 0x45", 0x45, false},
+ {" 45", 0x45, false},
+ {"45 ", 0x45, false},
+ {"45:", 0x45, false},
+ {"efgh", 0xef, false},
+ {"0xefgh", 0xef, false},
+ {"hgfe", 0, false},
+ {"-", 0, false},
+ {"", 0, false},
+ {"0x", 0, false},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- int64 output = 0;
+ int64_t output = 0;
EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -529,7 +539,7 @@ TEST(StringNumberConversionsTest, HexStringToInt64) {
// interpreted as junk after the number.
const char input[] = "0xc0ffee\0" "9";
std::string input_string(input, arraysize(input) - 1);
- int64 output;
+ int64_t output;
EXPECT_FALSE(HexStringToInt64(input_string, &output));
EXPECT_EQ(0xc0ffee, output);
}
@@ -537,52 +547,53 @@ TEST(StringNumberConversionsTest, HexStringToInt64) {
TEST(StringNumberConversionsTest, HexStringToUInt64) {
static const struct {
std::string input;
- uint64 output;
+ uint64_t output;
bool success;
} cases[] = {
- {"0", 0, true},
- {"42", 66, true},
- {"-42", 0, false},
- {"+42", 66, true},
- {"40acd88557b", INT64_C(4444444448123), true},
- {"7fffffff", INT_MAX, true},
- {"-80000000", 0, false},
- {"ffffffff", 0xffffffff, true},
- {"DeadBeef", 0xdeadbeef, true},
- {"0x42", 66, true},
- {"-0x42", 0, false},
- {"+0x42", 66, true},
- {"0x40acd88557b", INT64_C(4444444448123), true},
- {"0x7fffffff", INT_MAX, true},
- {"-0x80000000", 0, false},
- {"0xffffffff", 0xffffffff, true},
- {"0XDeadBeef", 0xdeadbeef, true},
- {"0x7fffffffffffffff", kint64max, true},
- {"-0x8000000000000000", 0, false},
- {"0x8000000000000000", UINT64_C(0x8000000000000000), true},
- {"-0x8000000000000001", 0, false},
- {"0xFFFFFFFFFFFFFFFF", kuint64max, true},
- {"FFFFFFFFFFFFFFFF", kuint64max, true},
- {"0x0000000000000000", 0, true},
- {"0000000000000000", 0, true},
- {"1FFFFFFFFFFFFFFFF", kuint64max, false}, // Overflow test.
- {"0x0f", 15, true},
- {"0f", 15, true},
- {" 45", 0x45, false},
- {"\t\n\v\f\r 0x45", 0x45, false},
- {" 45", 0x45, false},
- {"45 ", 0x45, false},
- {"45:", 0x45, false},
- {"efgh", 0xef, false},
- {"0xefgh", 0xef, false},
- {"hgfe", 0, false},
- {"-", 0, false},
- {"", 0, false},
- {"0x", 0, false},
+ {"0", 0, true},
+ {"42", 66, true},
+ {"-42", 0, false},
+ {"+42", 66, true},
+ {"40acd88557b", INT64_C(4444444448123), true},
+ {"7fffffff", INT_MAX, true},
+ {"-80000000", 0, false},
+ {"ffffffff", 0xffffffff, true},
+ {"DeadBeef", 0xdeadbeef, true},
+ {"0x42", 66, true},
+ {"-0x42", 0, false},
+ {"+0x42", 66, true},
+ {"0x40acd88557b", INT64_C(4444444448123), true},
+ {"0x7fffffff", INT_MAX, true},
+ {"-0x80000000", 0, false},
+ {"0xffffffff", 0xffffffff, true},
+ {"0XDeadBeef", 0xdeadbeef, true},
+ {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
+ {"-0x8000000000000000", 0, false},
+ {"0x8000000000000000", UINT64_C(0x8000000000000000), true},
+ {"-0x8000000000000001", 0, false},
+ {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
+ {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
+ {"0x0000000000000000", 0, true},
+ {"0000000000000000", 0, true},
+ {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(),
+ false}, // Overflow test.
+ {"0x0f", 15, true},
+ {"0f", 15, true},
+ {" 45", 0x45, false},
+ {"\t\n\v\f\r 0x45", 0x45, false},
+ {" 45", 0x45, false},
+ {"45 ", 0x45, false},
+ {"45:", 0x45, false},
+ {"efgh", 0xef, false},
+ {"0xefgh", 0xef, false},
+ {"hgfe", 0, false},
+ {"-", 0, false},
+ {"", 0, false},
+ {"0x", 0, false},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
- uint64 output = 0;
+ uint64_t output = 0;
EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output));
EXPECT_EQ(cases[i].output, output);
}
@@ -591,7 +602,7 @@ TEST(StringNumberConversionsTest, HexStringToUInt64) {
// interpreted as junk after the number.
const char input[] = "0xc0ffee\0" "9";
std::string input_string(input, arraysize(input) - 1);
- uint64 output;
+ uint64_t output;
EXPECT_FALSE(HexStringToUInt64(input_string, &output));
EXPECT_EQ(0xc0ffeeU, output);
}
@@ -624,12 +635,12 @@ TEST(StringNumberConversionsTest, HexStringToBytes) {
for (size_t i = 0; i < arraysize(cases); ++i) {
- std::vector<uint8> output;
- std::vector<uint8> compare;
+ std::vector<uint8_t> output;
+ std::vector<uint8_t> compare;
EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) <<
i << ": " << cases[i].input;
for (size_t j = 0; j < cases[i].output_len; ++j)
- compare.push_back(static_cast<uint8>(cases[i].output[j]));
+ compare.push_back(static_cast<uint8_t>(cases[i].output[j]));
ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input;
EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) <<
i << ": " << cases[i].input;
@@ -651,8 +662,10 @@ TEST(StringNumberConversionsTest, StringToDouble) {
{"2.99792458e8", 299792458.0, true},
{"149597870.691E+3", 149597870691.0, true},
{"6.", 6.0, true},
- {"9e99999999999999999999", HUGE_VAL, false},
- {"-9e99999999999999999999", -HUGE_VAL, false},
+ {"9e99999999999999999999", std::numeric_limits<double>::infinity(),
+ false},
+ {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(),
+ false},
{"1e-2", 0.01, true},
{"42 ", 42.0, false},
{" 1e-2", 0.01, false},
@@ -675,7 +688,8 @@ TEST(StringNumberConversionsTest, StringToDouble) {
for (size_t i = 0; i < arraysize(cases); ++i) {
double output;
errno = 1;
- EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
+ EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output))
+ << "for input=" << cases[i].input << "got output=" << output;
if (cases[i].success)
EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged.
EXPECT_DOUBLE_EQ(cases[i].output, output);
@@ -696,13 +710,13 @@ TEST(StringNumberConversionsTest, DoubleToString) {
double input;
const char* expected;
} cases[] = {
- {0.0, "0"},
+ {0.0, "0.0"},
{1.25, "1.25"},
- {1.33518e+012, "1.33518e+12"},
- {1.33489e+012, "1.33489e+12"},
- {1.33505e+012, "1.33505e+12"},
- {1.33545e+009, "1335450000"},
- {1.33503e+009, "1335030000"},
+ {1.33518e+012, "1335180000000.0"},
+ {1.33489e+012, "1334890000000.0"},
+ {1.33505e+012, "1335050000000.0"},
+ {1.33545e+009, "1335450000.0"},
+ {1.33503e+009, "1335030000.0"},
};
for (size_t i = 0; i < arraysize(cases); ++i) {
@@ -713,12 +727,12 @@ TEST(StringNumberConversionsTest, DoubleToString) {
const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
double input = 0;
memcpy(&input, input_bytes, arraysize(input_bytes));
- EXPECT_EQ("1335179083776", DoubleToString(input));
+ EXPECT_EQ("1335179083776.0", DoubleToString(input));
const char input_bytes2[8] =
{0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'};
input = 0;
memcpy(&input, input_bytes2, arraysize(input_bytes2));
- EXPECT_EQ("1334890332160", DoubleToString(input));
+ EXPECT_EQ("1334890332160.0", DoubleToString(input));
}
TEST(StringNumberConversionsTest, HexEncode) {
diff --git a/third_party/chromium/base/strings/string_piece.cc b/third_party/chromium/base/strings/string_piece.cc
index aa0695d..482c9fc 100644
--- a/third_party/chromium/base/strings/string_piece.cc
+++ b/third_party/chromium/base/strings/string_piece.cc
@@ -5,9 +5,13 @@
#include "base/strings/string_piece.h"
+#include <limits.h>
+
#include <algorithm>
#include <ostream>
+#include "base/logging.h"
+
namespace base {
namespace {
diff --git a/third_party/chromium/base/strings/string_piece.h b/third_party/chromium/base/strings/string_piece.h
index 14ee635..c79d9fa 100644
--- a/third_party/chromium/base/strings/string_piece.h
+++ b/third_party/chromium/base/strings/string_piece.h
@@ -28,7 +28,7 @@
#include <string>
#include "base/base_export.h"
-#include "base/basictypes.h"
+#include "base/logging.h"
namespace base {
@@ -112,9 +112,13 @@ template <typename STRING_TYPE> class BasicStringPiece {
BasicStringPiece(const value_type* offset, size_type len)
: ptr_(offset), length_(len) {}
BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
- const typename STRING_TYPE::const_iterator& end)
- : ptr_((end > begin) ? &(*begin) : NULL),
- length_((end > begin) ? (size_type)(end - begin) : 0) {}
+ const typename STRING_TYPE::const_iterator& end) {
+ length_ = static_cast<size_t>(std::distance(begin, end));
+
+ // The length test before assignment is to avoid dereferencing an iterator
+ // that may point to the end() of a string.
+ ptr_ = length_ > 0 ? &*begin : nullptr;
+ }
// data() may return a pointer to a buffer with embedded NULs, and the
// returned buffer may or may not be null terminated. Therefore it is
@@ -283,12 +287,12 @@ BasicStringPiece<STRING_TYPE>::npos =
// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
-extern template class BasicStringPiece<std::string>;
+extern template class BASE_EXPORT BasicStringPiece<std::string>;
#endif
// StingPiece operators --------------------------------------------------------
-bool operator==(const StringPiece& x, const StringPiece& y);
+BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
inline bool operator!=(const StringPiece& x, const StringPiece& y) {
return !(x == y);
diff --git a/third_party/chromium/base/strings/string_piece_unittest.cc b/third_party/chromium/base/strings/string_piece_unittest.cc
index 2c2b0a6..5772acd 100644
--- a/third_party/chromium/base/strings/string_piece_unittest.cc
+++ b/third_party/chromium/base/strings/string_piece_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <string>
#include <gtest/gtest.h>
diff --git a/third_party/chromium/base/strings/string_util.cc b/third_party/chromium/base/strings/string_util.cc
index 4042b39..eb0c546 100644
--- a/third_party/chromium/base/strings/string_util.cc
+++ b/third_party/chromium/base/strings/string_util.cc
@@ -4,9 +4,14 @@
#include "base/strings/string_util.h"
+#include <stdint.h>
+#include <limits>
+#include "base/macros.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/third_party/icu/icu_utf.h"
+namespace base {
+
namespace {
typedef uintptr_t MachineWord;
@@ -30,8 +35,72 @@ template<> struct NonASCIIMask<8, char> {
};
} // namespace
+namespace {
-namespace base {
+template<typename StringType>
+StringType ToLowerASCIIImpl(BasicStringPiece<StringType> str) {
+ StringType ret;
+ ret.reserve(str.size());
+ for (size_t i = 0; i < str.size(); i++)
+ ret.push_back(ToLowerASCII(str[i]));
+ return ret;
+}
+
+template<typename StringType>
+StringType ToUpperASCIIImpl(BasicStringPiece<StringType> str) {
+ StringType ret;
+ ret.reserve(str.size());
+ for (size_t i = 0; i < str.size(); i++)
+ ret.push_back(ToUpperASCII(str[i]));
+ return ret;
+}
+
+} // namespace
+
+std::string ToLowerASCII(StringPiece str) {
+ return ToLowerASCIIImpl<std::string>(str);
+}
+
+std::string ToUpperASCII(StringPiece str) {
+ return ToUpperASCIIImpl<std::string>(str);
+}
+
+template<class StringType>
+int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a,
+ BasicStringPiece<StringType> b) {
+ // Find the first characters that aren't equal and compare them. If the end
+ // of one of the strings is found before a nonequal character, the lengths
+ // of the strings are compared.
+ size_t i = 0;
+ while (i < a.length() && i < b.length()) {
+ typename StringType::value_type lower_a = ToLowerASCII(a[i]);
+ typename StringType::value_type lower_b = ToLowerASCII(b[i]);
+ if (lower_a < lower_b)
+ return -1;
+ if (lower_a > lower_b)
+ return 1;
+ i++;
+ }
+
+ // End of one string hit before finding a different character. Expect the
+ // common case to be "strings equal" at this point so check that first.
+ if (a.length() == b.length())
+ return 0;
+
+ if (a.length() < b.length())
+ return -1;
+ return 1;
+}
+
+int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b) {
+ return CompareCaseInsensitiveASCIIT<std::string>(a, b);
+}
+
+bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) {
+ if (a.length() != b.length())
+ return false;
+ return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0;
+}
template<typename STR>
bool ReplaceCharsT(const STR& input,
@@ -54,7 +123,7 @@ bool ReplaceCharsT(const STR& input,
}
bool ReplaceChars(const std::string& input,
- const base::StringPiece& replace_chars,
+ const StringPiece& replace_chars,
const std::string& replace_with,
std::string* output) {
return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output);
@@ -97,7 +166,7 @@ TrimPositions TrimStringT(const Str& input,
}
bool TrimString(const std::string& input,
- base::StringPiece trim_chars,
+ StringPiece trim_chars,
std::string* output) {
return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE;
}
@@ -114,7 +183,7 @@ BasicStringPiece<Str> TrimStringPieceT(BasicStringPiece<Str> input,
}
StringPiece TrimString(StringPiece input,
- const base::StringPiece& trim_chars,
+ const StringPiece& trim_chars,
TrimPositions positions) {
return TrimStringPieceT(input, trim_chars, positions);
}
@@ -161,11 +230,11 @@ bool IsStringASCII(const StringPiece& str) {
bool IsStringUTF8(const StringPiece& str) {
const char *src = str.data();
- int32 src_len = static_cast<int32>(str.length());
- int32 char_index = 0;
+ int32_t src_len = static_cast<int32_t>(str.length());
+ int32_t char_index = 0;
while (char_index < src_len) {
- int32 code_point;
+ int32_t code_point;
CBU8_NEXT(src, char_index, src_len, code_point);
if (!IsValidCharacter(code_point))
return false;
diff --git a/third_party/chromium/base/strings/string_util.h b/third_party/chromium/base/strings/string_util.h
index 4b41357..d6b6e10 100644
--- a/third_party/chromium/base/strings/string_util.h
+++ b/third_party/chromium/base/strings/string_util.h
@@ -9,14 +9,15 @@
#include <ctype.h>
#include <stdarg.h> // va_list
+#include <stddef.h>
+#include <stdint.h>
#include <string>
#include <vector>
-#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/strings/string_piece.h" // For implicit conversions.
+#include "build/build_config.h"
// On Android, bionic's stdio.h defines an snprintf macro when being built with
// clang. Undefine it here so it won't collide with base::snprintf().
@@ -24,10 +25,10 @@
namespace base {
-// C standard-library functions like "strncasecmp" and "snprintf" that aren't
-// cross-platform are provided as "base::strncasecmp", and their prototypes
-// are listed below. These functions are then implemented as inline calls
-// to the platform-specific equivalents in the platform-specific headers.
+// C standard-library functions that aren't cross-platform are provided as
+// "base::...", and their prototypes are listed below. These functions are
+// then implemented as inline calls to the platform-specific equivalents in the
+// platform-specific headers.
// Wrapper for vsnprintf that always null-terminates and always returns the
// number of characters that would be in an untruncated formatted
@@ -39,9 +40,14 @@ int vsnprintf(char* buffer, size_t size, const char* format, va_list arguments)
// We separate the declaration from the implementation of this inline
// function just so the PRINTF_FORMAT works.
-inline int snprintf(char* buffer, size_t size, const char* format, ...)
- PRINTF_FORMAT(3, 4);
-inline int snprintf(char* buffer, size_t size, const char* format, ...) {
+inline int snprintf(char* buffer,
+ size_t size,
+ _Printf_format_string_ const char* format,
+ ...) PRINTF_FORMAT(3, 4);
+inline int snprintf(char* buffer,
+ size_t size,
+ _Printf_format_string_ const char* format,
+ ...) {
va_list arguments;
va_start(arguments, format);
int result = vsnprintf(buffer, size, format, arguments);
@@ -49,6 +55,59 @@ inline int snprintf(char* buffer, size_t size, const char* format, ...) {
return result;
}
+// BSD-style safe and consistent string copy functions.
+// Copies |src| to |dst|, where |dst_size| is the total allocated size of |dst|.
+// Copies at most |dst_size|-1 characters, and always NULL terminates |dst|, as
+// long as |dst_size| is not 0. Returns the length of |src| in characters.
+// If the return value is >= dst_size, then the output was truncated.
+// NOTE: All sizes are in number of characters, NOT in bytes.
+size_t strlcpy(char* dst, const char* src, size_t dst_size);
+
+// ASCII-specific tolower. The standard library's tolower is locale sensitive,
+// so we don't want to use it here.
+inline char ToLowerASCII(char c) {
+ return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
+}
+
+// ASCII-specific toupper. The standard library's toupper is locale sensitive,
+// so we don't want to use it here.
+inline char ToUpperASCII(char c) {
+ return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c;
+}
+// Converts the given string to it's ASCII-lowercase equivalent.
+std::string ToLowerASCII(StringPiece str);
+// Converts the given string to it's ASCII-uppercase equivalent.
+std::string ToUpperASCII(StringPiece str);
+
+// Functor for case-insensitive ASCII comparisons for STL algorithms like
+// std::search.
+//
+// Note that a full Unicode version of this functor is not possible to write
+// because case mappings might change the number of characters, depend on
+// context (combining accents), and require handling UTF-16. If you need
+// proper Unicode support, use base::i18n::ToLower/FoldCase and then just
+// use a normal operator== on the result.
+template<typename Char> struct CaseInsensitiveCompareASCII {
+ public:
+ bool operator()(Char x, Char y) const {
+ return ToLowerASCII(x) == ToLowerASCII(y);
+ }
+};
+
+// Like strcasecmp for case-insensitive ASCII characters only. Returns:
+// -1 (a < b)
+// 0 (a == b)
+// 1 (a > b)
+// (unlike strcasecmp which can return values greater or less than 1/-1). For
+// full Unicode support, use base::i18n::ToLower or base::i18h::FoldCase
+// and then just call the normal string operators on the result.
+int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b);
+
+// Equality for ASCII case-insensitive comparisons. For full Unicode support,
+// use base::i18n::ToLower or base::i18h::FoldCase and then compare with either
+// == or !=.
+bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b);
+
// Contains the set of characters representing whitespace in the corresponding
// encoding. Null-terminated. The ASCII versions are the whitespaces as defined
// by HTML5, and don't include control characters.
@@ -60,7 +119,7 @@ extern const char kWhitespaceASCII[];
// |replace_chars| must be null-terminated.
// NOTE: Safe to use the same variable for both |input| and |output|.
bool ReplaceChars(const std::string& input,
- const base::StringPiece& replace_chars,
+ const StringPiece& replace_chars,
const std::string& replace_with,
std::string* output);
@@ -77,32 +136,26 @@ enum TrimPositions {
// It is safe to use the same variable for both |input| and |output| (this is
// the normal usage to trim in-place).
bool TrimString(const std::string& input,
- base::StringPiece trim_chars,
+ StringPiece trim_chars,
std::string* output);
// StringPiece versions of the above. The returned pieces refer to the original
// buffer.
StringPiece TrimString(StringPiece input,
- const base::StringPiece& trim_chars,
+ const StringPiece& trim_chars,
TrimPositions positions);
-// Trims any whitespace from either end of the input string. Returns where
-// whitespace was found.
-// The non-wide version has two functions:
-// * TrimWhitespaceASCII()
-// This function is for ASCII strings and only looks for ASCII whitespace;
-// Please choose the best one according to your usage.
+// Trims any whitespace from either end of the input string.
+//
+// The StringPiece versions return a substring referencing the input buffer.
+// The ASCII versions look only for ASCII whitespace.
+//
+// The std::string versions return where whitespace was found.
// NOTE: Safe to use the same variable for both input and output.
TrimPositions TrimWhitespaceASCII(const std::string& input,
TrimPositions positions,
std::string* output);
-// Deprecated. This function is only for backward compatibility and calls
-// TrimWhitespaceASCII().
-TrimPositions TrimWhitespace(const std::string& input,
- TrimPositions positions,
- std::string* output);
-
// Returns true if the specified string matches the criteria. How can a wide
// string be 8-bit or UTF8? It contains only characters that are < 256 (in the
// first case) or characters that use only 8-bits and whose 8-bit
diff --git a/third_party/chromium/base/strings/string_util_posix.h b/third_party/chromium/base/strings/string_util_posix.h
index ccfff10..07a89e4 100644
--- a/third_party/chromium/base/strings/string_util_posix.h
+++ b/third_party/chromium/base/strings/string_util_posix.h
@@ -6,6 +6,7 @@
#define BASE_STRINGS_STRING_UTIL_POSIX_H_
#include <stdarg.h>
+#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
@@ -18,7 +19,6 @@ inline int vsnprintf(char* buffer, size_t size,
const char* format, va_list arguments) {
return ::vsnprintf(buffer, size, format, arguments);
}
-
} // namespace base
#endif // BASE_STRINGS_STRING_UTIL_POSIX_H_
diff --git a/third_party/chromium/base/strings/string_util_unittest.cc b/third_party/chromium/base/strings/string_util_unittest.cc
index 1a75218..451fbd8 100644
--- a/third_party/chromium/base/strings/string_util_unittest.cc
+++ b/third_party/chromium/base/strings/string_util_unittest.cc
@@ -6,13 +6,15 @@
#include <math.h>
#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
#include <algorithm>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
#include "base/strings/utf_string_conversion_utils.h"
using ::testing::ElementsAre;
diff --git a/third_party/chromium/base/strings/stringprintf.cc b/third_party/chromium/base/strings/stringprintf.cc
index 5f1ad9b..8147ed3 100644
--- a/third_party/chromium/base/strings/stringprintf.cc
+++ b/third_party/chromium/base/strings/stringprintf.cc
@@ -5,12 +5,13 @@
#include "base/strings/stringprintf.h"
#include <errno.h>
+#include <stddef.h>
#include <vector>
-#include "base/logging.h"
#include "base/scoped_clear_errno.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
namespace base {
diff --git a/third_party/chromium/base/strings/stringprintf.h b/third_party/chromium/base/strings/stringprintf.h
index 06962b7..4c81400 100644
--- a/third_party/chromium/base/strings/stringprintf.h
+++ b/third_party/chromium/base/strings/stringprintf.h
@@ -11,6 +11,7 @@
#include "base/base_export.h"
#include "base/compiler_specific.h"
+#include "build/build_config.h"
namespace base {
diff --git a/third_party/chromium/base/strings/stringprintf_unittest.cc b/third_party/chromium/base/strings/stringprintf_unittest.cc
index 88a9675..e70499d 100644
--- a/third_party/chromium/base/strings/stringprintf_unittest.cc
+++ b/third_party/chromium/base/strings/stringprintf_unittest.cc
@@ -5,10 +5,12 @@
#include "base/strings/stringprintf.h"
#include <errno.h>
+#include <stddef.h>
#include <gtest/gtest.h>
-#include "base/basictypes.h"
+#include "base/macros.h"
+#include "build/build_config.h"
namespace base {
@@ -145,10 +147,10 @@ TEST(StringPrintfTest, GrowBoundary) {
EXPECT_STREQ(src, out.c_str());
}
-// TODO(evanm): what's the proper cross-platform test here?
#if defined(OS_WIN)
-// sprintf in Visual Studio fails when given U+FFFF. This tests that the
-// failure case is gracefuly handled.
+// vswprintf in Visual Studio 2013 fails when given U+FFFF. This tests that the
+// failure case is gracefuly handled. In Visual Studio 2015 the bad character
+// is passed through.
TEST(StringPrintfTest, Invalid) {
wchar_t invalid[2];
invalid[0] = 0xffff;
@@ -156,7 +158,11 @@ TEST(StringPrintfTest, Invalid) {
std::wstring out;
SStringPrintf(&out, L"%ls", invalid);
+#if _MSC_VER >= 1900
+ EXPECT_STREQ(invalid, out.c_str());
+#else
EXPECT_STREQ(L"", out.c_str());
+#endif
}
#endif
diff --git a/third_party/chromium/base/strings/utf_string_conversion_utils.cc b/third_party/chromium/base/strings/utf_string_conversion_utils.cc
index 05bd122..3091241 100644
--- a/third_party/chromium/base/strings/utf_string_conversion_utils.cc
+++ b/third_party/chromium/base/strings/utf_string_conversion_utils.cc
@@ -11,15 +11,15 @@ namespace base {
// ReadUnicodeCharacter --------------------------------------------------------
bool ReadUnicodeCharacter(const char* src,
- int32 src_len,
- int32* char_index,
- uint32* code_point_out) {
+ int32_t src_len,
+ int32_t* char_index,
+ uint32_t* code_point_out) {
// U8_NEXT expects to be able to use -1 to signal an error, so we must
// use a signed type for code_point. But this function returns false
// on error anyway, so code_point_out is unsigned.
- int32 code_point;
+ int32_t code_point;
CBU8_NEXT(src, *char_index, src_len, code_point);
- *code_point_out = static_cast<uint32>(code_point);
+ *code_point_out = static_cast<uint32_t>(code_point);
// The ICU macro above moves to the next char, we want to point to the last
// char consumed.
@@ -31,7 +31,7 @@ bool ReadUnicodeCharacter(const char* src,
// WriteUnicodeCharacter -------------------------------------------------------
-size_t WriteUnicodeCharacter(uint32 code_point, std::string* output) {
+size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output) {
if (code_point <= 0x7f) {
// Fast path the common case of one byte.
output->push_back(static_cast<char>(code_point));
diff --git a/third_party/chromium/base/strings/utf_string_conversion_utils.h b/third_party/chromium/base/strings/utf_string_conversion_utils.h
index d932d9f..a29b181 100644
--- a/third_party/chromium/base/strings/utf_string_conversion_utils.h
+++ b/third_party/chromium/base/strings/utf_string_conversion_utils.h
@@ -9,12 +9,14 @@
// This should only be used by the various UTF string conversion files.
+#include <stddef.h>
+#include <stdint.h>
+
#include "base/base_export.h"
-#include "base/basictypes.h"
namespace base {
-inline bool IsValidCodepoint(uint32 code_point) {
+inline bool IsValidCodepoint(uint32_t code_point) {
// Excludes the surrogate code points ([0xD800, 0xDFFF]) and
// codepoints larger than 0x10FFFF (the highest codepoint allowed).
// Non-characters and unassigned codepoints are allowed.
@@ -22,7 +24,7 @@ inline bool IsValidCodepoint(uint32 code_point) {
(code_point >= 0xE000u && code_point <= 0x10FFFFu);
}
-inline bool IsValidCharacter(uint32 code_point) {
+inline bool IsValidCharacter(uint32_t code_point) {
// Excludes non-characters (U+FDD0..U+FDEF, and all codepoints ending in
// 0xFFFE or 0xFFFF) from the set of valid code points.
return code_point < 0xD800u || (code_point >= 0xE000u &&
@@ -40,16 +42,16 @@ inline bool IsValidCharacter(uint32 code_point) {
//
// Returns true on success. On false, |*code_point| will be invalid.
bool ReadUnicodeCharacter(const char* src,
- int32 src_len,
- int32* char_index,
- uint32* code_point_out);
+ int32_t src_len,
+ int32_t* char_index,
+ uint32_t* code_point_out);
#if defined(WCHAR_T_IS_UTF32)
// Reads UTF-32 character. The usage is the same as the 8-bit version above.
bool ReadUnicodeCharacter(const wchar_t* src,
- int32 src_len,
- int32* char_index,
- uint32* code_point);
+ int32_t src_len,
+ int32_t* char_index,
+ uint32_t* code_point);
#endif // defined(WCHAR_T_IS_UTF32)
// WriteUnicodeCharacter -------------------------------------------------------
@@ -57,12 +59,12 @@ bool ReadUnicodeCharacter(const wchar_t* src,
// Appends a UTF-8 character to the given 8-bit string. Returns the number of
// bytes written.
// TODO(brettw) Bug 79631: This function should not be exposed.
-size_t WriteUnicodeCharacter(uint32 code_point, std::string* output);
+size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output);
#if defined(WCHAR_T_IS_UTF32)
// Appends the given UTF-32 character to the given 32-bit string. Returns the
// number of 32-bit values written.
-inline size_t WriteUnicodeCharacter(uint32 code_point, std::wstring* output) {
+inline size_t WriteUnicodeCharacter(uint32_t code_point, std::wstring* output) {
// This is the easy case, just append the character.
output->push_back(code_point);
return 1;
diff --git a/third_party/chromium/base/template_util.h b/third_party/chromium/base/template_util.h
index 4b1c808..7b61d24 100644
--- a/third_party/chromium/base/template_util.h
+++ b/third_party/chromium/base/template_util.h
@@ -5,7 +5,7 @@
#ifndef BASE_TEMPLATE_UTIL_H_
#define BASE_TEMPLATE_UTIL_H_
-#include <cstddef> // For size_t.
+#include <stddef.h>
#include <type_traits>
#include "build/build_config.h"
diff --git a/third_party/chromium/base/template_util_unittest.cc b/third_party/chromium/base/template_util_unittest.cc
index 7c86355..ce029af 100644
--- a/third_party/chromium/base/template_util_unittest.cc
+++ b/third_party/chromium/base/template_util_unittest.cc
@@ -6,7 +6,6 @@
#include <gtest/gtest.h>
-#include "base/basictypes.h"
namespace base {
namespace {
@@ -26,23 +25,24 @@ using std::is_class;
using std::is_member_function_pointer;
// is_pointer<Type>
-COMPILE_ASSERT(!is_pointer<int>::value, IsPointer);
-COMPILE_ASSERT(!is_pointer<int&>::value, IsPointer);
-COMPILE_ASSERT(is_pointer<int*>::value, IsPointer);
-COMPILE_ASSERT(is_pointer<const int*>::value, IsPointer);
+static_assert(!is_pointer<int>::value, "IsPointer");
+static_assert(!is_pointer<int&>::value, "IsPointer");
+static_assert(is_pointer<int*>::value, "IsPointer");
+static_assert(is_pointer<const int*>::value, "IsPointer");
// is_array<Type>
-COMPILE_ASSERT(!is_array<int>::value, IsArray);
-COMPILE_ASSERT(!is_array<int*>::value, IsArray);
-COMPILE_ASSERT(!is_array<int(*)[3]>::value, IsArray);
-COMPILE_ASSERT(is_array<int[]>::value, IsArray);
-COMPILE_ASSERT(is_array<const int[]>::value, IsArray);
-COMPILE_ASSERT(is_array<int[3]>::value, IsArray);
+static_assert(!is_array<int>::value, "IsArray");
+static_assert(!is_array<int*>::value, "IsArray");
+static_assert(!is_array<int (*)[3]>::value, "IsArray");
+static_assert(is_array<int[]>::value, "IsArray");
+static_assert(is_array<const int[]>::value, "IsArray");
+static_assert(is_array<int[3]>::value, "IsArray");
// is_non_const_reference<Type>
-COMPILE_ASSERT(!is_non_const_reference<int>::value, IsNonConstReference);
-COMPILE_ASSERT(!is_non_const_reference<const int&>::value, IsNonConstReference);
-COMPILE_ASSERT(is_non_const_reference<int&>::value, IsNonConstReference);
+static_assert(!is_non_const_reference<int>::value, "IsNonConstReference");
+static_assert(!is_non_const_reference<const int&>::value,
+ "IsNonConstReference");
+static_assert(is_non_const_reference<int&>::value, "IsNonConstReference");
// is_convertible<From, To>
@@ -52,66 +52,64 @@ COMPILE_ASSERT(is_non_const_reference<int&>::value, IsNonConstReference);
// (is_convertible < Child), (Parent > ::value)
//
// Silly C++.
-COMPILE_ASSERT( (is_convertible<Child, Parent>::value), IsConvertible);
-COMPILE_ASSERT(!(is_convertible<Parent, Child>::value), IsConvertible);
-COMPILE_ASSERT(!(is_convertible<Parent, AStruct>::value), IsConvertible);
-COMPILE_ASSERT( (is_convertible<int, double>::value), IsConvertible);
-COMPILE_ASSERT( (is_convertible<int*, void*>::value), IsConvertible);
-COMPILE_ASSERT(!(is_convertible<void*, int*>::value), IsConvertible);
+static_assert((is_convertible<Child, Parent>::value), "IsConvertible");
+static_assert(!(is_convertible<Parent, Child>::value), "IsConvertible");
+static_assert(!(is_convertible<Parent, AStruct>::value), "IsConvertible");
+static_assert((is_convertible<int, double>::value), "IsConvertible");
+static_assert((is_convertible<int*, void*>::value), "IsConvertible");
+static_assert(!(is_convertible<void*, int*>::value), "IsConvertible");
// Array types are an easy corner case. Make sure to test that
// it does indeed compile.
-COMPILE_ASSERT(!(is_convertible<int[10], double>::value), IsConvertible);
-COMPILE_ASSERT(!(is_convertible<double, int[10]>::value), IsConvertible);
-COMPILE_ASSERT( (is_convertible<int[10], int*>::value), IsConvertible);
+static_assert(!(is_convertible<int[10], double>::value), "IsConvertible");
+static_assert(!(is_convertible<double, int[10]>::value), "IsConvertible");
+static_assert((is_convertible<int[10], int*>::value), "IsConvertible");
// is_same<Type1, Type2>
-COMPILE_ASSERT(!(is_same<Child, Parent>::value), IsSame);
-COMPILE_ASSERT(!(is_same<Parent, Child>::value), IsSame);
-COMPILE_ASSERT( (is_same<Parent, Parent>::value), IsSame);
-COMPILE_ASSERT( (is_same<int*, int*>::value), IsSame);
-COMPILE_ASSERT( (is_same<int, int>::value), IsSame);
-COMPILE_ASSERT( (is_same<void, void>::value), IsSame);
-COMPILE_ASSERT(!(is_same<int, double>::value), IsSame);
-
+static_assert(!(is_same<Child, Parent>::value), "IsSame");
+static_assert(!(is_same<Parent, Child>::value), "IsSame");
+static_assert((is_same<Parent, Parent>::value), "IsSame");
+static_assert((is_same<int*, int*>::value), "IsSame");
+static_assert((is_same<int, int>::value), "IsSame");
+static_assert((is_same<void, void>::value), "IsSame");
+static_assert(!(is_same<int, double>::value), "IsSame");
// is_class<Type>
-COMPILE_ASSERT(is_class<AStruct>::value, IsClass);
-COMPILE_ASSERT(is_class<AClass>::value, IsClass);
-COMPILE_ASSERT(!is_class<AnEnum>::value, IsClass);
-COMPILE_ASSERT(!is_class<int>::value, IsClass);
-COMPILE_ASSERT(!is_class<char*>::value, IsClass);
-COMPILE_ASSERT(!is_class<int&>::value, IsClass);
-COMPILE_ASSERT(!is_class<char[3]>::value, IsClass);
-
-
-COMPILE_ASSERT(!is_member_function_pointer<int>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<int*>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<void*>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<AStruct>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<AStruct*>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<void(*)()>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<int(*)(int)>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(!is_member_function_pointer<int(*)(int, int)>::value,
- IsMemberFunctionPointer);
-
-COMPILE_ASSERT(is_member_function_pointer<void (AStruct::*)()>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(is_member_function_pointer<void (AStruct::*)(int)>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(is_member_function_pointer<int (AStruct::*)(int)>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(is_member_function_pointer<int (AStruct::*)(int) const>::value,
- IsMemberFunctionPointer);
-COMPILE_ASSERT(is_member_function_pointer<int (AStruct::*)(int, int)>::value,
- IsMemberFunctionPointer);
+static_assert(is_class<AStruct>::value, "IsClass");
+static_assert(is_class<AClass>::value, "IsClass");
+static_assert(!is_class<AnEnum>::value, "IsClass");
+static_assert(!is_class<int>::value, "IsClass");
+static_assert(!is_class<char*>::value, "IsClass");
+static_assert(!is_class<int&>::value, "IsClass");
+static_assert(!is_class<char[3]>::value, "IsClass");
+
+static_assert(!is_member_function_pointer<int>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<int*>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<void*>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<AStruct>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<AStruct*>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<void (*)()>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<int (*)(int)>::value,
+ "IsMemberFunctionPointer");
+static_assert(!is_member_function_pointer<int (*)(int, int)>::value,
+ "IsMemberFunctionPointer");
+
+static_assert(is_member_function_pointer<void (AStruct::*)()>::value,
+ "IsMemberFunctionPointer");
+static_assert(is_member_function_pointer<void (AStruct::*)(int)>::value,
+ "IsMemberFunctionPointer");
+static_assert(is_member_function_pointer<int (AStruct::*)(int)>::value,
+ "IsMemberFunctionPointer");
+static_assert(is_member_function_pointer<int (AStruct::*)(int) const>::value,
+ "IsMemberFunctionPointer");
+static_assert(is_member_function_pointer<int (AStruct::*)(int, int)>::value,
+ "IsMemberFunctionPointer");
} // namespace
} // namespace base
diff --git a/third_party/chromium/base/third_party/icu/icu_utf.cc b/third_party/chromium/base/third_party/icu/icu_utf.cc
index b47c8ac..3c877b3 100644
--- a/third_party/chromium/base/third_party/icu/icu_utf.cc
+++ b/third_party/chromium/base/third_party/icu/icu_utf.cc
@@ -74,7 +74,7 @@ namespace base_icu {
* lead bytes above 0xf4 are illegal.
* We keep them in this table for skipping long ISO 10646-UTF-8 sequences.
*/
-const uint8
+const uint8_t
utf8_countTrailBytes[256]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -134,11 +134,15 @@ utf8_errorValue[6]={
* Note that a UBool is the same as an int8_t.
*/
UChar32
-utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c, UBool strict) {
- int32 i=*pi;
- uint8 count=CBU8_COUNT_TRAIL_BYTES(c);
+utf8_nextCharSafeBody(const uint8_t *s,
+ int32_t *pi,
+ int32_t length,
+ UChar32 c,
+ UBool strict) {
+ int32_t i=*pi;
+ uint8_t count=CBU8_COUNT_TRAIL_BYTES(c);
if((i)+count<=(length)) {
- uint8 trail, illegal=0;
+ uint8_t trail, illegal=0;
CBU8_MASK_LEAD_BYTE((c), count);
/* count==0 for illegally leading trail bytes and the illegal bytes 0xfe and 0xff */
@@ -192,7 +196,7 @@ utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c, UBool
/* illegal is also set if count>=4 */
if(illegal || (c)<utf8_minLegal[count] || (CBU_IS_SURROGATE(c) && strict!=-2)) {
/* error handling */
- uint8 errorCount=count;
+ uint8_t errorCount=count;
/* don't go beyond this sequence */
i=*pi;
while(count>0 && CBU8_IS_TRAIL(s[i])) {
@@ -210,7 +214,7 @@ utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c, UBool
}
} else /* too few bytes left */ {
/* error handling */
- int32 i0=i;
+ int32_t i0=i;
/* don't just set (i)=(length) in case there is an illegal sequence */
while((i)<(length) && CBU8_IS_TRAIL(s[i])) {
++(i);
diff --git a/third_party/chromium/base/third_party/icu/icu_utf.h b/third_party/chromium/base/third_party/icu/icu_utf.h
index 2b993b0..e50cdab 100644
--- a/third_party/chromium/base/third_party/icu/icu_utf.h
+++ b/third_party/chromium/base/third_party/icu/icu_utf.h
@@ -17,13 +17,13 @@
#ifndef BASE_THIRD_PARTY_ICU_ICU_UTF_H_
#define BASE_THIRD_PARTY_ICU_ICU_UTF_H_
-#include "base/basictypes.h"
+#include <stdint.h>
namespace base_icu {
-typedef int32 UChar32;
-typedef uint16 UChar;
-typedef int8 UBool;
+typedef int32_t UChar32;
+typedef uint16_t UChar;
+typedef int8_t UBool;
// General ---------------------------------------------------------------------
// from utf.h
@@ -56,8 +56,8 @@ typedef int8 UBool;
*/
#define CBU_IS_UNICODE_NONCHAR(c) \
((c)>=0xfdd0 && \
- ((uint32)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \
- (uint32)(c)<=0x10ffff)
+ ((uint32_t)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \
+ (uint32_t)(c)<=0x10ffff)
/**
* Is c a Unicode code point value (0..U+10ffff)
@@ -77,9 +77,9 @@ typedef int8 UBool;
* @stable ICU 2.4
*/
#define CBU_IS_UNICODE_CHAR(c) \
- ((uint32)(c)<0xd800 || \
- ((uint32)(c)>0xdfff && \
- (uint32)(c)<=0x10ffff && \
+ ((uint32_t)(c)<0xd800 || \
+ ((uint32_t)(c)>0xdfff && \
+ (uint32_t)(c)<=0x10ffff && \
!CBU_IS_UNICODE_NONCHAR(c)))
/**
@@ -103,13 +103,13 @@ typedef int8 UBool;
// UTF-8 macros ----------------------------------------------------------------
// from utf8.h
-extern const uint8 utf8_countTrailBytes[256];
+extern const uint8_t utf8_countTrailBytes[256];
/**
* Count the trail bytes for a UTF-8 lead byte.
* @internal
*/
-#define CBU8_COUNT_TRAIL_BYTES(leadByte) (base_icu::utf8_countTrailBytes[(uint8)leadByte])
+#define CBU8_COUNT_TRAIL_BYTES(leadByte) (base_icu::utf8_countTrailBytes[(uint8_t)leadByte])
/**
* Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value.
@@ -131,7 +131,7 @@ extern const uint8 utf8_countTrailBytes[256];
* @return TRUE or FALSE
* @stable ICU 2.4
*/
-#define CBU8_IS_LEAD(c) ((uint8)((c)-0xc0)<0x3e)
+#define CBU8_IS_LEAD(c) ((uint8_t)((c)-0xc0)<0x3e)
/**
* Is this code unit (byte) a UTF-8 trail byte?
@@ -149,11 +149,11 @@ extern const uint8 utf8_countTrailBytes[256];
* @stable ICU 2.4
*/
#define CBU8_LENGTH(c) \
- ((uint32)(c)<=0x7f ? 1 : \
- ((uint32)(c)<=0x7ff ? 2 : \
- ((uint32)(c)<=0xd7ff ? 3 : \
- ((uint32)(c)<=0xdfff || (uint32)(c)>0x10ffff ? 0 : \
- ((uint32)(c)<=0xffff ? 3 : 4)\
+ ((uint32_t)(c)<=0x7f ? 1 : \
+ ((uint32_t)(c)<=0x7ff ? 2 : \
+ ((uint32_t)(c)<=0xd7ff ? 3 : \
+ ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \
+ ((uint32_t)(c)<=0xffff ? 3 : 4)\
) \
) \
) \
@@ -170,7 +170,7 @@ extern const uint8 utf8_countTrailBytes[256];
* Function for handling "next code point" with error-checking.
* @internal
*/
-UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c, UBool strict);
+UChar32 utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict);
/**
* Get a code point from a string at a code point boundary offset,
@@ -183,7 +183,7 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
* If the offset points to a trail byte or an illegal UTF-8 sequence, then
* c is set to a negative value.
*
- * @param s const uint8 * string
+ * @param s const uint8_t * string
* @param i string offset, i<length
* @param length string length
* @param c output UChar32 variable, set to <0 in case of an error
@@ -192,9 +192,9 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
*/
#define CBU8_NEXT(s, i, length, c) { \
(c)=(s)[(i)++]; \
- if(((uint8)(c))>=0x80) { \
+ if(((uint8_t)(c))>=0x80) { \
if(CBU8_IS_LEAD(c)) { \
- (c)=base_icu::utf8_nextCharSafeBody((const uint8 *)s, &(i), (int32)(length), c, -1); \
+ (c)=base_icu::utf8_nextCharSafeBody((const uint8_t *)s, &(i), (int32_t)(length), c, -1); \
} else { \
(c)=CBU_SENTINEL; \
} \
@@ -208,28 +208,28 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
* "Unsafe" macro, assumes a valid code point and sufficient space in the string.
* Otherwise, the result is undefined.
*
- * @param s const uint8 * string buffer
+ * @param s const uint8_t * string buffer
* @param i string offset
* @param c code point to append
* @see CBU8_APPEND
* @stable ICU 2.4
*/
#define CBU8_APPEND_UNSAFE(s, i, c) { \
- if((uint32)(c)<=0x7f) { \
- (s)[(i)++]=(uint8)(c); \
+ if((uint32_t)(c)<=0x7f) { \
+ (s)[(i)++]=(uint8_t)(c); \
} else { \
- if((uint32)(c)<=0x7ff) { \
- (s)[(i)++]=(uint8)(((c)>>6)|0xc0); \
+ if((uint32_t)(c)<=0x7ff) { \
+ (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \
} else { \
- if((uint32)(c)<=0xffff) { \
- (s)[(i)++]=(uint8)(((c)>>12)|0xe0); \
+ if((uint32_t)(c)<=0xffff) { \
+ (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \
} else { \
- (s)[(i)++]=(uint8)(((c)>>18)|0xf0); \
- (s)[(i)++]=(uint8)((((c)>>12)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \
+ (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \
} \
- (s)[(i)++]=(uint8)((((c)>>6)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \
} \
- (s)[(i)++]=(uint8)(((c)&0x3f)|0x80); \
+ (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \
} \
}
@@ -325,7 +325,7 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
* @return 1 or 2
* @stable ICU 2.4
*/
-#define CBU16_LENGTH(c) ((uint32)(c)<=0xffff ? 1 : 2)
+#define CBU16_LENGTH(c) ((uint32_t)(c)<=0xffff ? 1 : 2)
/**
* The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff).
@@ -356,7 +356,7 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
#define CBU16_NEXT(s, i, length, c) { \
(c)=(s)[(i)++]; \
if(CBU16_IS_LEAD(c)) { \
- uint16 __c2; \
+ uint16_t __c2; \
if((i)<(length) && CBU16_IS_TRAIL(__c2=(s)[(i)])) { \
++(i); \
(c)=CBU16_GET_SUPPLEMENTARY((c), __c2); \
@@ -378,11 +378,11 @@ UChar32 utf8_nextCharSafeBody(const uint8 *s, int32 *pi, int32 length, UChar32 c
* @stable ICU 2.4
*/
#define CBU16_APPEND_UNSAFE(s, i, c) { \
- if((uint32)(c)<=0xffff) { \
- (s)[(i)++]=(uint16)(c); \
+ if((uint32_t)(c)<=0xffff) { \
+ (s)[(i)++]=(uint16_t)(c); \
} else { \
- (s)[(i)++]=(uint16)(((c)>>10)+0xd7c0); \
- (s)[(i)++]=(uint16)(((c)&0x3ff)|0xdc00); \
+ (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \
+ (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \
} \
}
diff --git a/third_party/chromium/base/time/time.cc b/third_party/chromium/base/time/time.cc
index 7006407..0dc892a 100644
--- a/third_party/chromium/base/time/time.cc
+++ b/third_party/chromium/base/time/time.cc
@@ -11,6 +11,7 @@
#include <sstream>
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
namespace base {
@@ -19,7 +20,7 @@ namespace base {
// static
TimeDelta TimeDelta::Max() {
- return TimeDelta(std::numeric_limits<int64>::max());
+ return TimeDelta(std::numeric_limits<int64_t>::max());
}
int TimeDelta::InDays() const {
@@ -54,10 +55,10 @@ double TimeDelta::InSecondsF() const {
return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond;
}
-int64 TimeDelta::InSeconds() const {
+int64_t TimeDelta::InSeconds() const {
if (is_max()) {
// Preserve max to prevent overflow.
- return std::numeric_limits<int64>::max();
+ return std::numeric_limits<int64_t>::max();
}
return delta_ / Time::kMicrosecondsPerSecond;
}
@@ -70,46 +71,46 @@ double TimeDelta::InMillisecondsF() const {
return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond;
}
-int64 TimeDelta::InMilliseconds() const {
+int64_t TimeDelta::InMilliseconds() const {
if (is_max()) {
// Preserve max to prevent overflow.
- return std::numeric_limits<int64>::max();
+ return std::numeric_limits<int64_t>::max();
}
return delta_ / Time::kMicrosecondsPerMillisecond;
}
-int64 TimeDelta::InMillisecondsRoundedUp() const {
+int64_t TimeDelta::InMillisecondsRoundedUp() const {
if (is_max()) {
// Preserve max to prevent overflow.
- return std::numeric_limits<int64>::max();
+ return std::numeric_limits<int64_t>::max();
}
return (delta_ + Time::kMicrosecondsPerMillisecond - 1) /
Time::kMicrosecondsPerMillisecond;
}
-int64 TimeDelta::InMicroseconds() const {
+int64_t TimeDelta::InMicroseconds() const {
if (is_max()) {
// Preserve max to prevent overflow.
- return std::numeric_limits<int64>::max();
+ return std::numeric_limits<int64_t>::max();
}
return delta_;
}
namespace time_internal {
-int64 SaturatedAdd(TimeDelta delta, int64 value) {
- CheckedNumeric<int64> rv(delta.delta_);
+int64_t SaturatedAdd(TimeDelta delta, int64_t value) {
+ CheckedNumeric<int64_t> rv(delta.delta_);
rv += value;
return FromCheckedNumeric(rv);
}
-int64 SaturatedSub(TimeDelta delta, int64 value) {
- CheckedNumeric<int64> rv(delta.delta_);
+int64_t SaturatedSub(TimeDelta delta, int64_t value) {
+ CheckedNumeric<int64_t> rv(delta.delta_);
rv -= value;
return FromCheckedNumeric(rv);
}
-int64 FromCheckedNumeric(const CheckedNumeric<int64> value) {
+int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value) {
if (value.IsValid())
return value.ValueUnsafe();
@@ -117,7 +118,7 @@ int64 FromCheckedNumeric(const CheckedNumeric<int64> value) {
// is. Instead, return max/(-max), which is something that clients can reason
// about.
// TODO(rvargas) crbug.com/332611: don't use internal values.
- int64 limit = std::numeric_limits<int64>::max();
+ int64_t limit = std::numeric_limits<int64_t>::max();
if (value.validity() == internal::RANGE_UNDERFLOW)
limit = -limit;
return value.ValueOrDefault(limit);
@@ -133,7 +134,7 @@ std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) {
// static
Time Time::Max() {
- return Time(std::numeric_limits<int64>::max());
+ return Time(std::numeric_limits<int64_t>::max());
}
// static
@@ -142,7 +143,7 @@ Time Time::FromTimeT(time_t tt) {
return Time(); // Preserve 0 so we can tell it doesn't exist.
if (tt == std::numeric_limits<time_t>::max())
return Max();
- return Time((tt * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset);
+ return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSeconds(tt);
}
time_t Time::ToTimeT() const {
@@ -152,7 +153,7 @@ time_t Time::ToTimeT() const {
// Preserve max without offset to prevent overflow.
return std::numeric_limits<time_t>::max();
}
- if (std::numeric_limits<int64>::max() - kTimeTToMicrosecondsOffset <= us_) {
+ if (std::numeric_limits<int64_t>::max() - kTimeTToMicrosecondsOffset <= us_) {
DLOG(WARNING) << "Overflow when converting base::Time with internal " <<
"value " << us_ << " to time_t.";
return std::numeric_limits<time_t>::max();
@@ -164,11 +165,7 @@ time_t Time::ToTimeT() const {
Time Time::FromDoubleT(double dt) {
if (dt == 0 || std::isnan(dt))
return Time(); // Preserve 0 so we can tell it doesn't exist.
- if (dt == std::numeric_limits<double>::infinity())
- return Max();
- return Time(static_cast<int64>((dt *
- static_cast<double>(kMicrosecondsPerSecond)) +
- kTimeTToMicrosecondsOffset));
+ return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSecondsD(dt);
}
double Time::ToDoubleT() const {
@@ -195,10 +192,8 @@ Time Time::FromTimeSpec(const timespec& ts) {
Time Time::FromJsTime(double ms_since_epoch) {
// The epoch is a valid time, so this constructor doesn't interpret
// 0 as the null time.
- if (ms_since_epoch == std::numeric_limits<double>::infinity())
- return Max();
- return Time(static_cast<int64>(ms_since_epoch * kMicrosecondsPerMillisecond) +
- kTimeTToMicrosecondsOffset);
+ return Time(kTimeTToMicrosecondsOffset) +
+ TimeDelta::FromMillisecondsD(ms_since_epoch);
}
double Time::ToJsTime() const {
@@ -214,14 +209,14 @@ double Time::ToJsTime() const {
kMicrosecondsPerMillisecond);
}
-int64 Time::ToJavaTime() const {
+int64_t Time::ToJavaTime() const {
if (is_null()) {
// Preserve 0 so the invalid result doesn't depend on the platform.
return 0;
}
if (is_max()) {
// Preserve max without offset to prevent overflow.
- return std::numeric_limits<int64>::max();
+ return std::numeric_limits<int64_t>::max();
}
return ((us_ - kTimeTToMicrosecondsOffset) /
kMicrosecondsPerMillisecond);
@@ -301,11 +296,6 @@ std::ostream& operator<<(std::ostream& os, ThreadTicks thread_ticks) {
return os << as_time_delta.InMicroseconds() << " bogo-thread-microseconds";
}
-std::ostream& operator<<(std::ostream& os, TraceTicks trace_ticks) {
- const TimeDelta as_time_delta = trace_ticks - TraceTicks();
- return os << as_time_delta.InMicroseconds() << " bogo-trace-microseconds";
-}
-
// Time::Exploded -------------------------------------------------------------
inline bool is_in_range(int value, int lo, int hi) {
diff --git a/third_party/chromium/base/time/time.h b/third_party/chromium/base/time/time.h
index 1fe1b85..9456cc7 100644
--- a/third_party/chromium/base/time/time.h
+++ b/third_party/chromium/base/time/time.h
@@ -13,13 +13,13 @@
// TimeDelta represents a duration of time, internally represented in
// microseconds.
//
-// TimeTicks, ThreadTicks, and TraceTicks represent an abstract time that is
-// most of the time incrementing, for use in measuring time durations.
-// Internally, they are represented in microseconds. They can not be converted
-// to a human-readable time, but are guaranteed not to decrease (unlike the Time
-// class). Note that TimeTicks may "stand still" (e.g., if the computer is
-// suspended), and ThreadTicks will "stand still" whenever the thread has been
-// de-scheduled by the operating system.
+// TimeTicks and ThreadTicks represent an abstract time that is most of the time
+// incrementing, for use in measuring time durations. Internally, they are
+// represented in microseconds. They can not be converted to a human-readable
+// time, but are guaranteed not to decrease (unlike the Time class). Note that
+// TimeTicks may "stand still" (e.g., if the computer is suspended), and
+// ThreadTicks will "stand still" whenever the thread has been de-scheduled by
+// the operating system.
//
// All time classes are copyable, assignable, and occupy 64-bits per
// instance. Thus, they can be efficiently passed by-value (as opposed to
@@ -45,22 +45,17 @@
//
// ThreadTicks: Benchmarking how long the current thread has been doing actual
// work.
-//
-// TraceTicks: This is only meant to be used by the event tracing
-// infrastructure, and by outside code modules in special
-// circumstances. Please be sure to consult a
-// base/trace_event/OWNER before committing any new code that
-// uses this.
#ifndef BASE_TIME_TIME_H_
#define BASE_TIME_TIME_H_
+#include <stdint.h>
#include <time.h>
#include <iosfwd>
+#include <limits>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/numerics/safe_math.h"
#include "build/build_config.h"
@@ -79,9 +74,9 @@
// For FILETIME in FromFileTime, until it moves to a new converter class.
// See TODO(iyengar) below.
#include <windows.h>
-#endif
-#include <limits>
+#include "base/gtest_prod_util.h"
+#endif
namespace base {
@@ -92,14 +87,14 @@ class TimeDelta;
// time classes instead.
namespace time_internal {
-// Add or subtract |value| from a TimeDelta. The int64 argument and return value
-// are in terms of a microsecond timebase.
-BASE_EXPORT int64 SaturatedAdd(TimeDelta delta, int64 value);
-BASE_EXPORT int64 SaturatedSub(TimeDelta delta, int64 value);
+// Add or subtract |value| from a TimeDelta. The int64_t argument and return
+// value are in terms of a microsecond timebase.
+BASE_EXPORT int64_t SaturatedAdd(TimeDelta delta, int64_t value);
+BASE_EXPORT int64_t SaturatedSub(TimeDelta delta, int64_t value);
-// Clamp |value| on overflow and underflow conditions. The int64 argument and
+// Clamp |value| on overflow and underflow conditions. The int64_t argument and
// return value are in terms of a microsecond timebase.
-BASE_EXPORT int64 FromCheckedNumeric(const CheckedNumeric<int64> value);
+BASE_EXPORT int64_t FromCheckedNumeric(const CheckedNumeric<int64_t> value);
} // namespace time_internal
@@ -114,11 +109,11 @@ class BASE_EXPORT TimeDelta {
static TimeDelta FromDays(int days);
static TimeDelta FromHours(int hours);
static TimeDelta FromMinutes(int minutes);
- static TimeDelta FromSeconds(int64 secs);
- static TimeDelta FromMilliseconds(int64 ms);
+ static TimeDelta FromSeconds(int64_t secs);
+ static TimeDelta FromMilliseconds(int64_t ms);
static TimeDelta FromSecondsD(double secs);
static TimeDelta FromMillisecondsD(double ms);
- static TimeDelta FromMicroseconds(int64 us);
+ static TimeDelta FromMicroseconds(int64_t us);
#if defined(OS_WIN)
static TimeDelta FromQPCValue(LONGLONG qpc_value);
#endif
@@ -127,9 +122,7 @@ class BASE_EXPORT TimeDelta {
// when deserializing a |TimeDelta| structure, using a value known to be
// compatible. It is not provided as a constructor because the integer type
// may be unclear from the perspective of a caller.
- static TimeDelta FromInternalValue(int64 delta) {
- return TimeDelta(delta);
- }
+ static TimeDelta FromInternalValue(int64_t delta) { return TimeDelta(delta); }
// Returns the maximum time delta, which should be greater than any reasonable
// time delta we might compare it to. Adding or subtracting the maximum time
@@ -140,16 +133,14 @@ class BASE_EXPORT TimeDelta {
// use this and do arithmetic on it, as it is more error prone than using the
// provided operators.
// For serializing, use FromInternalValue to reconstitute.
- int64 ToInternalValue() const {
- return delta_;
- }
+ int64_t ToInternalValue() const { return delta_; }
// Returns the magnitude (absolute value) of this TimeDelta.
TimeDelta magnitude() const {
// Some toolchains provide an incomplete C++11 implementation and lack an
- // int64 overload for std::abs(). The following is a simple branchless
+ // int64_t overload for std::abs(). The following is a simple branchless
// implementation:
- const int64 mask = delta_ >> (sizeof(delta_) * 8 - 1);
+ const int64_t mask = delta_ >> (sizeof(delta_) * 8 - 1);
return TimeDelta((delta_ + mask) ^ mask);
}
@@ -159,9 +150,7 @@ class BASE_EXPORT TimeDelta {
}
// Returns true if the time delta is the maximum time delta.
- bool is_max() const {
- return delta_ == std::numeric_limits<int64>::max();
- }
+ bool is_max() const { return delta_ == std::numeric_limits<int64_t>::max(); }
#if defined(OS_POSIX)
struct timespec ToTimeSpec() const;
@@ -176,11 +165,11 @@ class BASE_EXPORT TimeDelta {
int InHours() const;
int InMinutes() const;
double InSecondsF() const;
- int64 InSeconds() const;
+ int64_t InSeconds() const;
double InMillisecondsF() const;
- int64 InMilliseconds() const;
- int64 InMillisecondsRoundedUp() const;
- int64 InMicroseconds() const;
+ int64_t InMilliseconds() const;
+ int64_t InMillisecondsRoundedUp() const;
+ int64_t InMicroseconds() const;
TimeDelta& operator=(TimeDelta other) {
delta_ = other.delta_;
@@ -208,13 +197,13 @@ class BASE_EXPORT TimeDelta {
// Computations with numeric types.
template<typename T>
TimeDelta operator*(T a) const {
- CheckedNumeric<int64> rv(delta_);
+ CheckedNumeric<int64_t> rv(delta_);
rv *= a;
return TimeDelta(time_internal::FromCheckedNumeric(rv));
}
template<typename T>
TimeDelta operator/(T a) const {
- CheckedNumeric<int64> rv(delta_);
+ CheckedNumeric<int64_t> rv(delta_);
rv /= a;
return TimeDelta(time_internal::FromCheckedNumeric(rv));
}
@@ -227,9 +216,7 @@ class BASE_EXPORT TimeDelta {
return *this = (*this / a);
}
- int64 operator/(TimeDelta a) const {
- return delta_ / a.delta_;
- }
+ int64_t operator/(TimeDelta a) const { return delta_ / a.delta_; }
TimeDelta operator%(TimeDelta a) const {
return TimeDelta(delta_ % a.delta_);
}
@@ -255,17 +242,19 @@ class BASE_EXPORT TimeDelta {
}
private:
- friend int64 time_internal::SaturatedAdd(TimeDelta delta, int64 value);
- friend int64 time_internal::SaturatedSub(TimeDelta delta, int64 value);
+ friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value);
+ friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value);
// Constructs a delta given the duration in microseconds. This is private
// to avoid confusion by callers with an integer constructor. Use
// FromSeconds, FromMilliseconds, etc. instead.
- explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
- }
+ explicit TimeDelta(int64_t delta_us) : delta_(delta_us) {}
+
+ // Private method to build a delta from a double.
+ static TimeDelta FromDouble(double value);
// Delta in microseconds.
- int64 delta_;
+ int64_t delta_;
};
template<typename T>
@@ -290,20 +279,21 @@ namespace time_internal {
template<class TimeClass>
class TimeBase {
public:
- static const int64 kHoursPerDay = 24;
- static const int64 kMillisecondsPerSecond = 1000;
- static const int64 kMillisecondsPerDay = kMillisecondsPerSecond * 60 * 60 *
- kHoursPerDay;
- static const int64 kMicrosecondsPerMillisecond = 1000;
- static const int64 kMicrosecondsPerSecond = kMicrosecondsPerMillisecond *
- kMillisecondsPerSecond;
- static const int64 kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
- static const int64 kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
- static const int64 kMicrosecondsPerDay = kMicrosecondsPerHour * kHoursPerDay;
- static const int64 kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
- static const int64 kNanosecondsPerMicrosecond = 1000;
- static const int64 kNanosecondsPerSecond = kNanosecondsPerMicrosecond *
- kMicrosecondsPerSecond;
+ static const int64_t kHoursPerDay = 24;
+ static const int64_t kMillisecondsPerSecond = 1000;
+ static const int64_t kMillisecondsPerDay =
+ kMillisecondsPerSecond * 60 * 60 * kHoursPerDay;
+ static const int64_t kMicrosecondsPerMillisecond = 1000;
+ static const int64_t kMicrosecondsPerSecond =
+ kMicrosecondsPerMillisecond * kMillisecondsPerSecond;
+ static const int64_t kMicrosecondsPerMinute = kMicrosecondsPerSecond * 60;
+ static const int64_t kMicrosecondsPerHour = kMicrosecondsPerMinute * 60;
+ static const int64_t kMicrosecondsPerDay =
+ kMicrosecondsPerHour * kHoursPerDay;
+ static const int64_t kMicrosecondsPerWeek = kMicrosecondsPerDay * 7;
+ static const int64_t kNanosecondsPerMicrosecond = 1000;
+ static const int64_t kNanosecondsPerSecond =
+ kNanosecondsPerMicrosecond * kMicrosecondsPerSecond;
// Returns true if this object has not been initialized.
//
@@ -315,16 +305,12 @@ class TimeBase {
}
// Returns true if this object represents the maximum time.
- bool is_max() const {
- return us_ == std::numeric_limits<int64>::max();
- }
+ bool is_max() const { return us_ == std::numeric_limits<int64_t>::max(); }
// For serializing only. Use FromInternalValue() to reconstitute. Please don't
// use this and do arithmetic on it, as it is more error prone than using the
// provided operators.
- int64 ToInternalValue() const {
- return us_;
- }
+ int64_t ToInternalValue() const { return us_; }
TimeClass& operator=(TimeClass other) {
us_ = other.us_;
@@ -376,16 +362,13 @@ class TimeBase {
// when deserializing a |TimeClass| structure, using a value known to be
// compatible. It is not provided as a constructor because the integer type
// may be unclear from the perspective of a caller.
- static TimeClass FromInternalValue(int64 us) {
- return TimeClass(us);
- }
+ static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
protected:
- explicit TimeBase(int64 us) : us_(us) {
- }
+ explicit TimeBase(int64_t us) : us_(us) {}
// Time value in a microsecond timebase.
- int64 us_;
+ int64_t us_;
};
} // namespace time_internal
@@ -403,7 +386,7 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
public:
// The representation of Jan 1, 1970 UTC in microseconds since the
// platform-dependent epoch.
- static const int64 kTimeTToMicrosecondsOffset;
+ static const int64_t kTimeTToMicrosecondsOffset;
#if !defined(OS_WIN)
// On Mac & Linux, this value is the delta from the Windows epoch of 1601 to
@@ -411,12 +394,12 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
// 1970-based epochs to the new 1601-based ones. It should be removed from
// this global header and put in the platform-specific ones when we remove the
// migration code.
- static const int64 kWindowsEpochDeltaMicroseconds;
+ static const int64_t kWindowsEpochDeltaMicroseconds;
#else
// To avoid overflow in QPC to Microseconds calculations, since we multiply
// by kMicrosecondsPerSecond, then the QPC value should not exceed
// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.
- static const int64 kQPCOverflowThreshold = 0x8637BD05AF7;
+ enum : int64_t{kQPCOverflowThreshold = 0x8637BD05AF7};
#endif
// Represents an exploded time that can be formatted nicely. This is kind of
@@ -491,7 +474,7 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
// Converts to Java convention for times, a number of
// milliseconds since the epoch.
- int64 ToJavaTime() const;
+ int64_t ToJavaTime() const;
#if defined(OS_POSIX)
static Time FromTimeVal(struct timeval t);
@@ -555,8 +538,7 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
private:
friend class time_internal::TimeBase<Time>;
- explicit Time(int64 us) : TimeBase(us) {
- }
+ explicit Time(int64_t us) : TimeBase(us) {}
// Explodes the given time to either local time |is_local = true| or UTC
// |is_local = false|.
@@ -571,7 +553,6 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
// static
inline TimeDelta TimeDelta::FromDays(int days) {
- // Preserve max to prevent overflow.
if (days == std::numeric_limits<int>::max())
return Max();
return TimeDelta(days * Time::kMicrosecondsPerDay);
@@ -579,7 +560,6 @@ inline TimeDelta TimeDelta::FromDays(int days) {
// static
inline TimeDelta TimeDelta::FromHours(int hours) {
- // Preserve max to prevent overflow.
if (hours == std::numeric_limits<int>::max())
return Max();
return TimeDelta(hours * Time::kMicrosecondsPerHour);
@@ -587,52 +567,47 @@ inline TimeDelta TimeDelta::FromHours(int hours) {
// static
inline TimeDelta TimeDelta::FromMinutes(int minutes) {
- // Preserve max to prevent overflow.
if (minutes == std::numeric_limits<int>::max())
return Max();
return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
}
// static
-inline TimeDelta TimeDelta::FromSeconds(int64 secs) {
- // Preserve max to prevent overflow.
- if (secs == std::numeric_limits<int64>::max())
- return Max();
- return TimeDelta(secs * Time::kMicrosecondsPerSecond);
+inline TimeDelta TimeDelta::FromSeconds(int64_t secs) {
+ return TimeDelta(secs) * Time::kMicrosecondsPerSecond;
}
// static
-inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) {
- // Preserve max to prevent overflow.
- if (ms == std::numeric_limits<int64>::max())
- return Max();
- return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
+inline TimeDelta TimeDelta::FromMilliseconds(int64_t ms) {
+ return TimeDelta(ms) * Time::kMicrosecondsPerMillisecond;
}
// static
inline TimeDelta TimeDelta::FromSecondsD(double secs) {
- // Preserve max to prevent overflow.
- if (secs == std::numeric_limits<double>::infinity())
- return Max();
- return TimeDelta(static_cast<int64>(secs * Time::kMicrosecondsPerSecond));
+ return FromDouble(secs * Time::kMicrosecondsPerSecond);
}
// static
inline TimeDelta TimeDelta::FromMillisecondsD(double ms) {
- // Preserve max to prevent overflow.
- if (ms == std::numeric_limits<double>::infinity())
- return Max();
- return TimeDelta(static_cast<int64>(ms * Time::kMicrosecondsPerMillisecond));
+ return FromDouble(ms * Time::kMicrosecondsPerMillisecond);
}
// static
-inline TimeDelta TimeDelta::FromMicroseconds(int64 us) {
- // Preserve max to prevent overflow.
- if (us == std::numeric_limits<int64>::max())
- return Max();
+inline TimeDelta TimeDelta::FromMicroseconds(int64_t us) {
return TimeDelta(us);
}
+// static
+inline TimeDelta TimeDelta::FromDouble(double value) {
+ double max_magnitude = std::numeric_limits<int64_t>::max();
+ TimeDelta delta = TimeDelta(static_cast<int64_t>(value));
+ if (value > max_magnitude)
+ delta = Max();
+ else if (value < -max_magnitude)
+ delta = -Max();
+ return delta;
+}
+
// For logging use only.
BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time);
@@ -663,12 +638,14 @@ class TimeTicks : public time_internal::TimeBase<TimeTicks> {
static TimeTicks FromQPCValue(LONGLONG qpc_value);
#endif
- // Get the TimeTick value at the time of the UnixEpoch. This is useful when
- // you need to relate the value of TimeTicks to a real time and date.
- // Note: Upon first invocation, this function takes a snapshot of the realtime
- // clock to establish a reference point. This function will return the same
- // value for the duration of the application, but will be different in future
- // application runs.
+ // Get an estimate of the TimeTick value at the time of the UnixEpoch. Because
+ // Time and TimeTicks respond differently to user-set time and NTP
+ // adjustments, this number is only an estimate. Nevertheless, this can be
+ // useful when you need to relate the value of TimeTicks to a real time and
+ // date. Note: Upon first invocation, this function takes a snapshot of the
+ // realtime clock to establish a reference point. This function will return
+ // the same value for the duration of the application, but will be different
+ // in future application runs.
static TimeTicks UnixEpoch();
// Returns |this| snapped to the next tick, given a |tick_phase| and
@@ -688,8 +665,7 @@ class TimeTicks : public time_internal::TimeBase<TimeTicks> {
// Please use Now() to create a new object. This is for internal use
// and testing.
- explicit TimeTicks(int64 us) : TimeBase(us) {
- }
+ explicit TimeTicks(int64_t us) : TimeBase(us) {}
};
// For logging use only.
@@ -709,16 +685,28 @@ class ThreadTicks : public time_internal::TimeBase<ThreadTicks> {
#if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
(defined(OS_MACOSX) && !defined(OS_IOS)) || defined(OS_ANDROID)
return true;
+#elif defined(OS_WIN)
+ return IsSupportedWin();
#else
return false;
#endif
}
+ // Waits until the initialization is completed. Needs to be guarded with a
+ // call to IsSupported().
+ static void WaitUntilInitialized() {
+#if defined(OS_WIN)
+ WaitUntilInitializedWin();
+#endif
+ }
+
// Returns thread-specific CPU-time on systems that support this feature.
// Needs to be guarded with a call to IsSupported(). Use this timer
// to (approximately) measure how much time the calling thread spent doing
// actual work vs. being de-scheduled. May return bogus results if the thread
- // migrates to another CPU between two calls.
+ // migrates to another CPU between two calls. Returns an empty ThreadTicks
+ // object until the initialization is completed. If a clock reading is
+ // absolutely needed, call WaitUntilInitialized() before this method.
static ThreadTicks Now();
private:
@@ -726,58 +714,12 @@ class ThreadTicks : public time_internal::TimeBase<ThreadTicks> {
// Please use Now() to create a new object. This is for internal use
// and testing.
- explicit ThreadTicks(int64 us) : TimeBase(us) {
- }
-};
-
-// For logging use only.
-std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks);
-
-// TraceTicks ----------------------------------------------------------------
-
-// Represents high-resolution system trace clock time.
-class TraceTicks : public time_internal::TimeBase<TraceTicks> {
- public:
- // We define this even without OS_CHROMEOS for seccomp sandbox testing.
-#if defined(OS_LINUX)
- // Force definition of the system trace clock; it is a chromeos-only api
- // at the moment and surfacing it in the right place requires mucking
- // with glibc et al.
- static const clockid_t kClockSystemTrace = 11;
-#endif
-
- TraceTicks() : TimeBase(0) {
- }
-
- // Returns the current system trace time or, if not available on this
- // platform, a high-resolution time value; or a low-resolution time value if
- // neither are avalable. On systems where a global trace clock is defined,
- // timestamping TraceEvents's with this value guarantees synchronization
- // between events collected inside chrome and events collected outside
- // (e.g. kernel, X server).
- //
- // On some platforms, the clock source used for tracing can vary depending on
- // hardware and/or kernel support. Do not make any assumptions without
- // consulting the documentation for this functionality in the time_win.cc,
- // time_posix.cc, etc. files.
- //
- // NOTE: This is only meant to be used by the event tracing infrastructure,
- // and by outside code modules in special circumstances. Please be sure to
- // consult a base/trace_event/OWNER before committing any new code that uses
- // this.
- static TraceTicks Now();
+ explicit ThreadTicks(int64_t us) : TimeBase(us) {}
- private:
- friend class time_internal::TimeBase<TraceTicks>;
-
- // Please use Now() to create a new object. This is for internal use
- // and testing.
- explicit TraceTicks(int64 us) : TimeBase(us) {
- }
};
// For logging use only.
-std::ostream& operator<<(std::ostream& os, TraceTicks time_ticks);
+std::ostream& operator<<(std::ostream& os, ThreadTicks time_ticks);
} // namespace base
diff --git a/third_party/chromium/base/time/time_posix.cc b/third_party/chromium/base/time/time_posix.cc
index e8e56c2..4b37b4a 100644
--- a/third_party/chromium/base/time/time_posix.cc
+++ b/third_party/chromium/base/time/time_posix.cc
@@ -15,7 +15,6 @@
#include <limits>
#include <ostream>
-#include "base/basictypes.h"
#include "base/logging.h"
#include "build/build_config.h"
@@ -60,8 +59,8 @@ void SysTimeToTimeStruct(SysTime t, struct tm* timestruct, bool is_local) {
}
#endif // OS_ANDROID
-int64 ConvertTimespecToMicros(const struct timespec& ts) {
- base::CheckedNumeric<int64> result(ts.tv_sec);
+int64_t ConvertTimespecToMicros(const struct timespec& ts) {
+ base::CheckedNumeric<int64_t> result(ts.tv_sec);
result *= base::Time::kMicrosecondsPerSecond;
result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond);
return result.ValueOrDie();
@@ -74,7 +73,7 @@ int64 ConvertTimespecToMicros(const struct timespec& ts) {
#if (defined(OS_POSIX) && \
defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0) || \
defined(OS_BSD) || defined(OS_ANDROID)
-int64 ClockNow(clockid_t clk_id) {
+int64_t ClockNow(clockid_t clk_id) {
struct timespec ts;
if (clock_gettime(clk_id, &ts) != 0) {
NOTREACHED() << "clock_gettime(" << clk_id << ") failed.";
@@ -92,7 +91,7 @@ int64 ClockNow(clockid_t clk_id) {
namespace base {
struct timespec TimeDelta::ToTimeSpec() const {
- int64 microseconds = InMicroseconds();
+ int64_t microseconds = InMicroseconds();
time_t seconds = 0;
if (microseconds >= Time::kMicrosecondsPerSecond) {
seconds = InSeconds();
@@ -117,16 +116,16 @@ struct timespec TimeDelta::ToTimeSpec() const {
// => Thu Jan 01 00:00:00 UTC 1970
// irb(main):011:0> Time.at(-11644473600).getutc()
// => Mon Jan 01 00:00:00 UTC 1601
-static const int64 kWindowsEpochDeltaSeconds = 11644473600ll;
+static const int64_t kWindowsEpochDeltaSeconds = 11644473600ll;
// static
-const int64 Time::kWindowsEpochDeltaMicroseconds =
+const int64_t Time::kWindowsEpochDeltaMicroseconds =
kWindowsEpochDeltaSeconds * Time::kMicrosecondsPerSecond;
// Some functions in time.cc use time_t directly, so we provide an offset
// to convert from time_t (Unix epoch) and internal (Windows epoch).
// static
-const int64 Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds;
+const int64_t Time::kTimeTToMicrosecondsOffset = kWindowsEpochDeltaMicroseconds;
// static
Time Time::Now() {
@@ -156,9 +155,9 @@ void Time::Explode(bool is_local, Exploded* exploded) const {
// Time stores times with microsecond resolution, but Exploded only carries
// millisecond resolution, so begin by being lossy. Adjust from Windows
// epoch (1601) to Unix epoch (1970);
- int64 microseconds = us_ - kWindowsEpochDeltaMicroseconds;
+ int64_t microseconds = us_ - kWindowsEpochDeltaMicroseconds;
// The following values are all rounded towards -infinity.
- int64 milliseconds; // Milliseconds since epoch.
+ int64_t milliseconds; // Milliseconds since epoch.
SysTime seconds; // Seconds since epoch.
int millisecond; // Exploded millisecond value (0-999).
if (microseconds >= 0) {
@@ -208,8 +207,7 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) {
timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
#endif
-
- int64 milliseconds;
+ int64_t milliseconds;
SysTime seconds;
// Certain exploded dates do not really exist due to daylight saving times,
@@ -227,11 +225,11 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) {
// to UTC 00:00:00 that isn't -1.
timestruct = timestruct0;
timestruct.tm_isdst = 0;
- int64 seconds_isdst0 = SysTimeFromTimeStruct(&timestruct, is_local);
+ int64_t seconds_isdst0 = SysTimeFromTimeStruct(&timestruct, is_local);
timestruct = timestruct0;
timestruct.tm_isdst = 1;
- int64 seconds_isdst1 = SysTimeFromTimeStruct(&timestruct, is_local);
+ int64_t seconds_isdst1 = SysTimeFromTimeStruct(&timestruct, is_local);
// seconds_isdst0 or seconds_isdst1 can be -1 for some timezones.
// E.g. "CLST" (Chile Summer Time) returns -1 for 'tm_isdt == 1'.
@@ -264,14 +262,14 @@ Time Time::FromExploded(bool is_local, const Exploded& exploded) {
// 999ms to avoid the time being less than any other possible value that
// this function can return.
- // On Android, SysTime is int64, special care must be taken to avoid
+ // On Android, SysTime is int64_t, special care must be taken to avoid
// overflows.
- const int64 min_seconds = (sizeof(SysTime) < sizeof(int64))
- ? std::numeric_limits<SysTime>::min()
- : std::numeric_limits<int32_t>::min();
- const int64 max_seconds = (sizeof(SysTime) < sizeof(int64))
- ? std::numeric_limits<SysTime>::max()
- : std::numeric_limits<int32_t>::max();
+ const int64_t min_seconds = (sizeof(SysTime) < sizeof(int64_t))
+ ? std::numeric_limits<SysTime>::min()
+ : std::numeric_limits<int32_t>::min();
+ const int64_t max_seconds = (sizeof(SysTime) < sizeof(int64_t))
+ ? std::numeric_limits<SysTime>::max()
+ : std::numeric_limits<int32_t>::max();
if (exploded.year < 1969) {
milliseconds = min_seconds * kMillisecondsPerSecond;
} else {
@@ -309,27 +307,6 @@ ThreadTicks ThreadTicks::Now() {
#endif
}
-// Use the Chrome OS specific system-wide clock.
-#if defined(OS_CHROMEOS)
-// static
-TraceTicks TraceTicks::Now() {
- struct timespec ts;
- if (clock_gettime(kClockSystemTrace, &ts) != 0) {
- // NB: fall-back for a chrome os build running on linux
- return TraceTicks(ClockNow(CLOCK_MONOTONIC));
- }
- return TraceTicks(ConvertTimespecToMicros(ts));
-}
-
-#else // !defined(OS_CHROMEOS)
-
-// static
-TraceTicks TraceTicks::Now() {
- return TraceTicks(ClockNow(CLOCK_MONOTONIC));
-}
-
-#endif // defined(OS_CHROMEOS)
-
#endif // !OS_MACOSX
// static
@@ -341,10 +318,8 @@ Time Time::FromTimeVal(struct timeval t) {
if (t.tv_usec == static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1 &&
t.tv_sec == std::numeric_limits<time_t>::max())
return Max();
- return Time(
- (static_cast<int64>(t.tv_sec) * Time::kMicrosecondsPerSecond) +
- t.tv_usec +
- kTimeTToMicrosecondsOffset);
+ return Time((static_cast<int64_t>(t.tv_sec) * Time::kMicrosecondsPerSecond) +
+ t.tv_usec + kTimeTToMicrosecondsOffset);
}
struct timeval Time::ToTimeVal() const {
@@ -359,7 +334,7 @@ struct timeval Time::ToTimeVal() const {
result.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
return result;
}
- int64 us = us_ - kTimeTToMicrosecondsOffset;
+ int64_t us = us_ - kTimeTToMicrosecondsOffset;
result.tv_sec = us / Time::kMicrosecondsPerSecond;
result.tv_usec = us % Time::kMicrosecondsPerSecond;
return result;
diff --git a/third_party/chromium/base/time/time_unittest.cc b/third_party/chromium/base/time/time_unittest.cc
index 737796c..c471a76 100644
--- a/third_party/chromium/base/time/time_unittest.cc
+++ b/third_party/chromium/base/time/time_unittest.cc
@@ -13,6 +13,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
+#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
@@ -289,52 +290,6 @@ TEST_F(TimeTest, ExplodeBeforeUnixEpoch) {
EXPECT_EQ(1, exploded.millisecond);
}
-TEST_F(TimeTest, TimeDeltaMax) {
- TimeDelta max = TimeDelta::Max();
- EXPECT_TRUE(max.is_max());
- EXPECT_EQ(max, TimeDelta::Max());
- EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
- EXPECT_GT(max, TimeDelta());
-}
-
-TEST_F(TimeTest, TimeDeltaMaxConversions) {
- TimeDelta t = TimeDelta::Max();
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
-
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp());
-
- t = TimeDelta::FromDays(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromHours(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromSeconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMilliseconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMicroseconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-}
-
TEST_F(TimeTest, Max) {
Time max = Time::Max();
EXPECT_TRUE(max.is_max());
@@ -345,7 +300,7 @@ TEST_F(TimeTest, Max) {
TEST_F(TimeTest, MaxConversions) {
Time t = Time::Max();
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.ToInternalValue());
t = Time::FromDoubleT(std::numeric_limits<double>::infinity());
EXPECT_TRUE(t.is_max());
@@ -392,7 +347,7 @@ TEST_F(TimeTest, MaxConversions) {
#if defined(OS_MACOSX)
TEST_F(TimeTest, TimeTOverflow) {
- Time t = Time::FromInternalValue(std::numeric_limits<int64>::max() - 1);
+ Time t = Time::FromInternalValue(std::numeric_limits<int64_t>::max() - 1);
EXPECT_FALSE(t.is_max());
EXPECT_EQ(std::numeric_limits<time_t>::max(), t.ToTimeT());
}
@@ -461,12 +416,6 @@ TEST(TimeTicks, HighRes) {
HighResClockTest(&TimeTicks::Now);
}
-TEST(TraceTicks, NowFromSystemTraceTime) {
- // Re-use HighRes test for now since clock properties are identical.
- using NowFunction = TimeTicks (*)(void);
- HighResClockTest(reinterpret_cast<NowFunction>(&TraceTicks::Now));
-}
-
TEST(TimeTicks, SnappedToNextTickBasic) {
base::TimeTicks phase = base::TimeTicks::FromInternalValue(4000);
base::TimeDelta interval = base::TimeDelta::FromMicroseconds(1000);
@@ -546,6 +495,7 @@ TEST(TimeDelta, FromAndIn) {
EXPECT_EQ(13, TimeDelta::FromMillisecondsD(13.3).InMilliseconds());
EXPECT_EQ(13.3, TimeDelta::FromMillisecondsD(13.3).InMillisecondsF());
EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).InMicroseconds());
+ EXPECT_EQ(3.456, TimeDelta::FromMillisecondsD(3.45678).InMillisecondsF());
}
#if defined(OS_POSIX)
@@ -600,25 +550,102 @@ std::string AnyToString(Any any) {
}
TEST(TimeDelta, Magnitude) {
- const int64 zero = 0;
+ const int64_t zero = 0;
EXPECT_EQ(TimeDelta::FromMicroseconds(zero),
TimeDelta::FromMicroseconds(zero).magnitude());
- const int64 one = 1;
- const int64 negative_one = -1;
+ const int64_t one = 1;
+ const int64_t negative_one = -1;
EXPECT_EQ(TimeDelta::FromMicroseconds(one),
TimeDelta::FromMicroseconds(one).magnitude());
EXPECT_EQ(TimeDelta::FromMicroseconds(one),
TimeDelta::FromMicroseconds(negative_one).magnitude());
- const int64 max_int64_minus_one = std::numeric_limits<int64>::max() - 1;
- const int64 min_int64_plus_two = std::numeric_limits<int64>::min() + 2;
+ const int64_t max_int64_minus_one = std::numeric_limits<int64_t>::max() - 1;
+ const int64_t min_int64_plus_two = std::numeric_limits<int64_t>::min() + 2;
EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one),
TimeDelta::FromMicroseconds(max_int64_minus_one).magnitude());
EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one),
TimeDelta::FromMicroseconds(min_int64_plus_two).magnitude());
}
+TEST(TimeDelta, Max) {
+ TimeDelta max = TimeDelta::Max();
+ EXPECT_TRUE(max.is_max());
+ EXPECT_EQ(max, TimeDelta::Max());
+ EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
+ EXPECT_GT(max, TimeDelta());
+}
+
+bool IsMin(TimeDelta delta) {
+ return (-delta).is_max();
+}
+
+TEST(TimeDelta, MaxConversions) {
+ TimeDelta t = TimeDelta::Max();
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.ToInternalValue());
+
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.InSeconds());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.InMilliseconds());
+ EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.InMillisecondsRoundedUp());
+
+ t = TimeDelta::FromDays(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromHours(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ int64_t max_int = std::numeric_limits<int64_t>::max();
+
+ t = TimeDelta::FromSeconds(max_int / Time::kMicrosecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMilliseconds(max_int / Time::kMillisecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMicroseconds(max_int);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromSeconds(-max_int / Time::kMicrosecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMilliseconds(-max_int / Time::kMillisecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMicroseconds(-max_int);
+ EXPECT_TRUE(IsMin(t));
+
+ t = -TimeDelta::FromMicroseconds(std::numeric_limits<int64_t>::min());
+ EXPECT_FALSE(IsMin(t));
+
+ t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
+ EXPECT_TRUE(t.is_max());
+
+ double max_d = max_int;
+
+ t = TimeDelta::FromSecondsD(max_d / Time::kMicrosecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMillisecondsD(max_d / Time::kMillisecondsPerSecond * 2);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromSecondsD(-max_d / Time::kMicrosecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMillisecondsD(-max_d / Time::kMillisecondsPerSecond * 2);
+ EXPECT_TRUE(IsMin(t));
+}
TEST(TimeDelta, NumericOperators) {
double d = 0.5;
@@ -645,7 +672,6 @@ TEST(TimeDelta, NumericOperators) {
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
f * TimeDelta::FromMilliseconds(1000));
-
int i = 2;
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
TimeDelta::FromMilliseconds(1000) * i);
@@ -670,7 +696,6 @@ TEST(TimeDelta, NumericOperators) {
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
i64 * TimeDelta::FromMilliseconds(1000));
-
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
TimeDelta::FromMilliseconds(1000) * 0.5);
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
@@ -694,10 +719,6 @@ TEST(TimeDelta, NumericOperators) {
2 * TimeDelta::FromMilliseconds(1000));
}
-bool IsMin(TimeDelta delta) {
- return (-delta).is_max();
-}
-
TEST(TimeDelta, Overflows) {
// Some sanity checks.
EXPECT_TRUE(TimeDelta::Max().is_max());
diff --git a/third_party/chromium/base/tuple.h b/third_party/chromium/base/tuple.h
index ef51d85..e5872cc 100644
--- a/third_party/chromium/base/tuple.h
+++ b/third_party/chromium/base/tuple.h
@@ -28,7 +28,10 @@
#ifndef BASE_TUPLE_H_
#define BASE_TUPLE_H_
+#include <stddef.h>
+
#include "base/bind_helpers.h"
+#include "build/build_config.h"
namespace base {
@@ -150,7 +153,7 @@ template <size_t N, typename T>
struct TupleLeaf;
template <typename... Ts>
-struct Tuple : TupleBase<Ts...> {
+struct Tuple final : TupleBase<Ts...> {
Tuple() : TupleBase<Ts...>() {}
explicit Tuple(typename TupleTraits<Ts>::ParamType... args)
: TupleBase<Ts...>(args...) {}
@@ -158,7 +161,7 @@ struct Tuple : TupleBase<Ts...> {
// Avoids ambiguity between Tuple's two constructors.
template <>
-struct Tuple<> {};
+struct Tuple<> final {};
template <size_t... Ns, typename... Ts>
struct TupleBaseImpl<IndexSequence<Ns...>, Ts...> : TupleLeaf<Ns, Ts>... {
@@ -241,11 +244,6 @@ inline Tuple<Ts&...> MakeRefTuple(Ts&... arg) {
// Non-Static Dispatchers with no out params.
-template <typename ObjT, typename Method, typename A>
-inline void DispatchToMethod(ObjT* obj, Method method, const A& arg) {
- (obj->*method)(base::internal::UnwrapTraits<A>::Unwrap(arg));
-}
-
template <typename ObjT, typename Method, typename... Ts, size_t... Ns>
inline void DispatchToMethodImpl(ObjT* obj,
Method method,
@@ -263,11 +261,6 @@ inline void DispatchToMethod(ObjT* obj,
// Static Dispatchers with no out params.
-template <typename Function, typename A>
-inline void DispatchToMethod(Function function, const A& arg) {
- (*function)(base::internal::UnwrapTraits<A>::Unwrap(arg));
-}
-
template <typename Function, typename... Ts, size_t... Ns>
inline void DispatchToFunctionImpl(Function function,
const Tuple<Ts...>& arg,
@@ -284,29 +277,6 @@ inline void DispatchToFunction(Function function, const Tuple<Ts...>& arg) {
template <typename ObjT,
typename Method,
- typename In,
- typename... OutTs,
- size_t... OutNs>
-inline void DispatchToMethodImpl(ObjT* obj,
- Method method,
- const In& in,
- Tuple<OutTs...>* out,
- IndexSequence<OutNs...>) {
- (obj->*method)(base::internal::UnwrapTraits<In>::Unwrap(in),
- &get<OutNs>(*out)...);
-}
-
-template <typename ObjT, typename Method, typename In, typename... OutTs>
-inline void DispatchToMethod(ObjT* obj,
- Method method,
- const In& in,
- Tuple<OutTs...>* out) {
- DispatchToMethodImpl(obj, method, in, out,
- MakeIndexSequence<sizeof...(OutTs)>());
-}
-
-template <typename ObjT,
- typename Method,
typename... InTs,
typename... OutTs,
size_t... InNs,
diff --git a/third_party/chromium/base/values.cc b/third_party/chromium/base/values.cc
index 689fdd7..55719da 100644
--- a/third_party/chromium/base/values.cc
+++ b/third_party/chromium/base/values.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <cmath>
#include <ostream>
+#include <utility>
#include "base/json/json_writer.h"
#include "base/logging.h"
@@ -32,7 +33,7 @@ scoped_ptr<ListValue> CopyListWithoutEmptyChildren(const ListValue& list) {
if (child_copy) {
if (!copy)
copy.reset(new ListValue);
- copy->Append(child_copy.Pass());
+ copy->Append(std::move(child_copy));
}
}
return copy;
@@ -46,7 +47,7 @@ scoped_ptr<DictionaryValue> CopyDictionaryWithoutEmptyChildren(
if (child_copy) {
if (!copy)
copy.reset(new DictionaryValue);
- copy->SetWithoutPathExpansion(it.key(), child_copy.Pass());
+ copy->SetWithoutPathExpansion(it.key(), std::move(child_copy));
}
}
return copy;
@@ -92,23 +93,23 @@ scoped_ptr<Value> Value::CreateNullValue() {
return make_scoped_ptr(new Value(TYPE_NULL));
}
-bool Value::GetAsBinary(const BinaryValue** out_value) const {
+bool Value::GetAsBinary(const BinaryValue** /* out_value */) const {
return false;
}
-bool Value::GetAsBoolean(bool* out_value) const {
+bool Value::GetAsBoolean(bool* /* out_value */) const {
return false;
}
-bool Value::GetAsInteger(int* out_value) const {
+bool Value::GetAsInteger(int* /* out_value */) const {
return false;
}
-bool Value::GetAsDouble(double* out_value) const {
+bool Value::GetAsDouble(double* /* out_value */) const {
return false;
}
-bool Value::GetAsString(std::string* out_value) const {
+bool Value::GetAsString(std::string* /* out_value */) const {
return false;
}
@@ -116,19 +117,19 @@ bool Value::GetAsString(const StringValue** out_value) const {
return false;
}
-bool Value::GetAsList(ListValue** out_value) {
+bool Value::GetAsList(ListValue** /* out_value */) {
return false;
}
-bool Value::GetAsList(const ListValue** out_value) const {
+bool Value::GetAsList(const ListValue** /* out_value */) const {
return false;
}
-bool Value::GetAsDictionary(DictionaryValue** out_value) {
+bool Value::GetAsDictionary(DictionaryValue** /* out_value */) {
return false;
}
-bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
+bool Value::GetAsDictionary(const DictionaryValue** /* out_value */) const {
return false;
}
@@ -298,10 +299,7 @@ BinaryValue::BinaryValue()
}
BinaryValue::BinaryValue(scoped_ptr<char[]> buffer, size_t size)
- : Value(TYPE_BINARY),
- buffer_(buffer.Pass()),
- size_(size) {
-}
+ : Value(TYPE_BINARY), buffer_(std::move(buffer)), size_(size) {}
BinaryValue::~BinaryValue() {
}
@@ -312,7 +310,7 @@ BinaryValue* BinaryValue::CreateWithCopiedBuffer(const char* buffer,
char* buffer_copy = new char[size];
memcpy(buffer_copy, buffer, size);
scoped_ptr<char[]> scoped_buffer_copy(buffer_copy);
- return new BinaryValue(scoped_buffer_copy.Pass(), size);
+ return new BinaryValue(std::move(scoped_buffer_copy), size);
}
bool BinaryValue::GetAsBinary(const BinaryValue** out_value) const {
@@ -336,6 +334,16 @@ bool BinaryValue::Equals(const Value* other) const {
///////////////////// DictionaryValue ////////////////////
+// static
+scoped_ptr<DictionaryValue> DictionaryValue::From(scoped_ptr<Value> value) {
+ DictionaryValue* out;
+ if (value && value->GetAsDictionary(&out)) {
+ ignore_result(value.release());
+ return make_scoped_ptr(out);
+ }
+ return nullptr;
+}
+
DictionaryValue::DictionaryValue()
: Value(TYPE_DICTIONARY) {
}
@@ -394,7 +402,8 @@ void DictionaryValue::Set(const std::string& path, scoped_ptr<Value> in_value) {
current_path.erase(0, delimiter_position + 1);
}
- current_dictionary->SetWithoutPathExpansion(current_path, in_value.Pass());
+ current_dictionary->SetWithoutPathExpansion(current_path,
+ std::move(in_value));
}
void DictionaryValue::Set(const std::string& path, Value* in_value) {
@@ -457,27 +466,30 @@ void DictionaryValue::SetStringWithoutPathExpansion(
SetWithoutPathExpansion(path, new StringValue(in_value));
}
-bool DictionaryValue::Get(const std::string& path,
+bool DictionaryValue::Get(StringPiece path,
const Value** out_value) const {
DCHECK(IsStringUTF8(path));
- std::string current_path(path);
+ StringPiece current_path(path);
const DictionaryValue* current_dictionary = this;
for (size_t delimiter_position = current_path.find('.');
delimiter_position != std::string::npos;
delimiter_position = current_path.find('.')) {
const DictionaryValue* child_dictionary = NULL;
- if (!current_dictionary->GetDictionary(
- current_path.substr(0, delimiter_position), &child_dictionary))
+ if (!current_dictionary->GetDictionaryWithoutPathExpansion(
+ current_path.substr(0, delimiter_position).as_string(),
+ &child_dictionary)) {
return false;
+ }
current_dictionary = child_dictionary;
- current_path.erase(0, delimiter_position + 1);
+ current_path = current_path.substr(delimiter_position + 1);
}
- return current_dictionary->GetWithoutPathExpansion(current_path, out_value);
+ return current_dictionary->GetWithoutPathExpansion(current_path.as_string(),
+ out_value);
}
-bool DictionaryValue::Get(const std::string& path, Value** out_value) {
+bool DictionaryValue::Get(StringPiece path, Value** out_value) {
return static_cast<const DictionaryValue&>(*this).Get(
path,
const_cast<const Value**>(out_value));
@@ -554,7 +566,7 @@ bool DictionaryValue::GetBinary(const std::string& path,
const_cast<const BinaryValue**>(out_value));
}
-bool DictionaryValue::GetDictionary(const std::string& path,
+bool DictionaryValue::GetDictionary(StringPiece path,
const DictionaryValue** out_value) const {
const Value* value;
bool result = Get(path, &value);
@@ -567,7 +579,7 @@ bool DictionaryValue::GetDictionary(const std::string& path,
return true;
}
-bool DictionaryValue::GetDictionary(const std::string& path,
+bool DictionaryValue::GetDictionary(StringPiece path,
DictionaryValue** out_value) {
return static_cast<const DictionaryValue&>(*this).GetDictionary(
path,
@@ -824,6 +836,16 @@ bool DictionaryValue::Equals(const Value* other) const {
///////////////////// ListValue ////////////////////
+// static
+scoped_ptr<ListValue> ListValue::From(scoped_ptr<Value> value) {
+ ListValue* out;
+ if (value && value->GetAsList(&out)) {
+ ignore_result(value.release());
+ return make_scoped_ptr(out);
+ }
+ return nullptr;
+}
+
ListValue::ListValue() : Value(TYPE_LIST) {
}
diff --git a/third_party/chromium/base/values.h b/third_party/chromium/base/values.h
index 7ae52a9..25d2a79 100644
--- a/third_party/chromium/base/values.h
+++ b/third_party/chromium/base/values.h
@@ -9,7 +9,7 @@
// JavaScript. As such, it is NOT a generalized variant type, since only the
// types supported by JavaScript/JSON are supported.
//
-// IN PARTICULAR this means that there is no support for int64 or unsigned
+// IN PARTICULAR this means that there is no support for int64_t or unsigned
// numbers. Writing JSON with such types would violate the spec. If you need
// something like this, either use a double or make a string value containing
// the number you want.
@@ -18,6 +18,7 @@
#define BASE_VALUES_H_
#include <stddef.h>
+#include <stdint.h>
#include <iosfwd>
#include <map>
@@ -26,9 +27,10 @@
#include <vector>
#include "base/base_export.h"
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_piece.h"
namespace base {
@@ -202,6 +204,9 @@ class BASE_EXPORT BinaryValue : public Value {
// are |std::string|s and should be UTF-8 encoded.
class BASE_EXPORT DictionaryValue : public Value {
public:
+ // Returns |value| if it is a dictionary, nullptr otherwise.
+ static scoped_ptr<DictionaryValue> From(scoped_ptr<Value> value);
+
DictionaryValue();
~DictionaryValue() override;
@@ -261,8 +266,8 @@ class BASE_EXPORT DictionaryValue : public Value {
// Otherwise, it will return false and |out_value| will be untouched.
// Note that the dictionary always owns the value that's returned.
// |out_value| is optional and will only be set if non-NULL.
- bool Get(const std::string& path, const Value** out_value) const;
- bool Get(const std::string& path, Value** out_value);
+ bool Get(StringPiece path, const Value** out_value) const;
+ bool Get(StringPiece path, Value** out_value);
// These are convenience forms of Get(). The value will be retrieved
// and the return value will be true if the path is valid and the value at
@@ -277,9 +282,9 @@ class BASE_EXPORT DictionaryValue : public Value {
bool GetStringASCII(const std::string& path, std::string* out_value) const;
bool GetBinary(const std::string& path, const BinaryValue** out_value) const;
bool GetBinary(const std::string& path, BinaryValue** out_value);
- bool GetDictionary(const std::string& path,
+ bool GetDictionary(StringPiece path,
const DictionaryValue** out_value) const;
- bool GetDictionary(const std::string& path, DictionaryValue** out_value);
+ bool GetDictionary(StringPiece path, DictionaryValue** out_value);
bool GetList(const std::string& path, const ListValue** out_value) const;
bool GetList(const std::string& path, ListValue** out_value);
@@ -374,6 +379,9 @@ class BASE_EXPORT ListValue : public Value {
typedef ValueVector::iterator iterator;
typedef ValueVector::const_iterator const_iterator;
+ // Returns |value| if it is a list, nullptr otherwise.
+ static scoped_ptr<ListValue> From(scoped_ptr<Value> value);
+
ListValue();
~ListValue() override;
diff --git a/third_party/chromium/base/values_unittest.cc b/third_party/chromium/base/values_unittest.cc
index d246691..b5e47dd 100644
--- a/third_party/chromium/base/values_unittest.cc
+++ b/third_party/chromium/base/values_unittest.cc
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
#include <limits>
+#include <utility>
#include <gtest/gtest.h>
@@ -34,13 +37,13 @@ TEST(ValuesTest, Basic) {
settings.GetList("global.toolbar.bookmarks", &toolbar_bookmarks));
scoped_ptr<ListValue> new_toolbar_bookmarks(new ListValue);
- settings.Set("global.toolbar.bookmarks", new_toolbar_bookmarks.Pass());
+ settings.Set("global.toolbar.bookmarks", std::move(new_toolbar_bookmarks));
ASSERT_TRUE(settings.GetList("global.toolbar.bookmarks", &toolbar_bookmarks));
scoped_ptr<DictionaryValue> new_bookmark(new DictionaryValue);
new_bookmark->SetString("name", "Froogle");
new_bookmark->SetString("url", "http://froogle.com");
- toolbar_bookmarks->Append(new_bookmark.Pass());
+ toolbar_bookmarks->Append(std::move(new_bookmark));
ListValue* bookmark_list;
ASSERT_TRUE(settings.GetList("global.toolbar.bookmarks", &bookmark_list));
@@ -114,7 +117,7 @@ TEST(ValuesTest, BinaryValue) {
// Test the common case of a non-empty buffer
scoped_ptr<char[]> buffer(new char[15]);
char* original_buffer = buffer.get();
- binary.reset(new BinaryValue(buffer.Pass(), 15));
+ binary.reset(new BinaryValue(std::move(buffer), 15));
ASSERT_TRUE(binary.get());
ASSERT_TRUE(binary->GetBuffer());
ASSERT_EQ(original_buffer, binary->GetBuffer());
@@ -236,7 +239,7 @@ TEST(ValuesTest, ListRemoval) {
ListValue list;
scoped_ptr<DeletionTestValue> value(new DeletionTestValue(&deletion_flag));
DeletionTestValue* original_value = value.get();
- list.Append(value.Pass());
+ list.Append(std::move(value));
EXPECT_FALSE(deletion_flag);
size_t index = 0;
list.Remove(*original_value, &index);
@@ -379,41 +382,41 @@ TEST(ValuesTest, DeepCopy) {
DictionaryValue original_dict;
scoped_ptr<Value> scoped_null = Value::CreateNullValue();
Value* original_null = scoped_null.get();
- original_dict.Set("null", scoped_null.Pass());
+ original_dict.Set("null", std::move(scoped_null));
scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
FundamentalValue* original_bool = scoped_bool.get();
- original_dict.Set("bool", scoped_bool.Pass());
+ original_dict.Set("bool", std::move(scoped_bool));
scoped_ptr<FundamentalValue> scoped_int(new FundamentalValue(42));
FundamentalValue* original_int = scoped_int.get();
- original_dict.Set("int", scoped_int.Pass());
+ original_dict.Set("int", std::move(scoped_int));
scoped_ptr<FundamentalValue> scoped_double(new FundamentalValue(3.14));
FundamentalValue* original_double = scoped_double.get();
- original_dict.Set("double", scoped_double.Pass());
+ original_dict.Set("double", std::move(scoped_double));
scoped_ptr<StringValue> scoped_string(new StringValue("hello"));
StringValue* original_string = scoped_string.get();
- original_dict.Set("string", scoped_string.Pass());
+ original_dict.Set("string", std::move(scoped_string));
scoped_ptr<char[]> original_buffer(new char[42]);
memset(original_buffer.get(), '!', 42);
scoped_ptr<BinaryValue> scoped_binary(
- new BinaryValue(original_buffer.Pass(), 42));
+ new BinaryValue(std::move(original_buffer), 42));
BinaryValue* original_binary = scoped_binary.get();
- original_dict.Set("binary", scoped_binary.Pass());
+ original_dict.Set("binary", std::move(scoped_binary));
scoped_ptr<ListValue> scoped_list(new ListValue());
Value* original_list = scoped_list.get();
scoped_ptr<FundamentalValue> scoped_list_element_0(new FundamentalValue(0));
Value* original_list_element_0 = scoped_list_element_0.get();
- scoped_list->Append(scoped_list_element_0.Pass());
+ scoped_list->Append(std::move(scoped_list_element_0));
scoped_ptr<FundamentalValue> scoped_list_element_1(new FundamentalValue(1));
Value* original_list_element_1 = scoped_list_element_1.get();
- scoped_list->Append(scoped_list_element_1.Pass());
- original_dict.Set("list", scoped_list.Pass());
+ scoped_list->Append(std::move(scoped_list_element_1));
+ original_dict.Set("list", std::move(scoped_list));
scoped_ptr<DictionaryValue> scoped_nested_dictionary(new DictionaryValue());
Value* original_nested_dictionary = scoped_nested_dictionary.get();
scoped_nested_dictionary->SetString("key", "value");
- original_dict.Set("dictionary", scoped_nested_dictionary.Pass());
+ original_dict.Set("dictionary", std::move(scoped_nested_dictionary));
scoped_ptr<DictionaryValue> copy_dict = original_dict.CreateDeepCopy();
ASSERT_TRUE(copy_dict.get());
@@ -534,9 +537,9 @@ TEST(ValuesTest, Equals) {
list->Append(make_scoped_ptr(new DictionaryValue));
scoped_ptr<Value> list_copy(list->CreateDeepCopy());
- dv.Set("f", list.Pass());
+ dv.Set("f", std::move(list));
EXPECT_FALSE(dv.Equals(copy.get()));
- copy->Set("f", list_copy.Pass());
+ copy->Set("f", std::move(list_copy));
EXPECT_TRUE(dv.Equals(copy.get()));
original_list->Append(make_scoped_ptr(new FundamentalValue(true)));
@@ -577,34 +580,34 @@ TEST(ValuesTest, DeepCopyCovariantReturnTypes) {
DictionaryValue original_dict;
scoped_ptr<Value> scoped_null(Value::CreateNullValue());
Value* original_null = scoped_null.get();
- original_dict.Set("null", scoped_null.Pass());
+ original_dict.Set("null", std::move(scoped_null));
scoped_ptr<FundamentalValue> scoped_bool(new FundamentalValue(true));
Value* original_bool = scoped_bool.get();
- original_dict.Set("bool", scoped_bool.Pass());
+ original_dict.Set("bool", std::move(scoped_bool));
scoped_ptr<FundamentalValue> scoped_int(new FundamentalValue(42));
Value* original_int = scoped_int.get();
- original_dict.Set("int", scoped_int.Pass());
+ original_dict.Set("int", std::move(scoped_int));
scoped_ptr<FundamentalValue> scoped_double(new FundamentalValue(3.14));
Value* original_double = scoped_double.get();
- original_dict.Set("double", scoped_double.Pass());
+ original_dict.Set("double", std::move(scoped_double));
scoped_ptr<StringValue> scoped_string(new StringValue("hello"));
Value* original_string = scoped_string.get();
- original_dict.Set("string", scoped_string.Pass());
+ original_dict.Set("string", std::move(scoped_string));
scoped_ptr<char[]> original_buffer(new char[42]);
memset(original_buffer.get(), '!', 42);
scoped_ptr<BinaryValue> scoped_binary(
- new BinaryValue(original_buffer.Pass(), 42));
+ new BinaryValue(std::move(original_buffer), 42));
Value* original_binary = scoped_binary.get();
- original_dict.Set("binary", scoped_binary.Pass());
+ original_dict.Set("binary", std::move(scoped_binary));
scoped_ptr<ListValue> scoped_list(new ListValue());
Value* original_list = scoped_list.get();
scoped_ptr<FundamentalValue> scoped_list_element_0(new FundamentalValue(0));
- scoped_list->Append(scoped_list_element_0.Pass());
+ scoped_list->Append(std::move(scoped_list_element_0));
scoped_ptr<FundamentalValue> scoped_list_element_1(new FundamentalValue(1));
- scoped_list->Append(scoped_list_element_1.Pass());
- original_dict.Set("list", scoped_list.Pass());
+ scoped_list->Append(std::move(scoped_list_element_1));
+ original_dict.Set("list", std::move(scoped_list));
scoped_ptr<Value> copy_dict = original_dict.CreateDeepCopy();
scoped_ptr<Value> copy_null = original_null->CreateDeepCopy();
@@ -657,7 +660,7 @@ TEST(ValuesTest, RemoveEmptyChildren) {
scoped_ptr<DictionaryValue> inner(new DictionaryValue);
inner->Set("empty_dict", make_scoped_ptr(new DictionaryValue));
inner->Set("empty_list", make_scoped_ptr(new ListValue));
- root->Set("dict_with_empty_children", inner.Pass());
+ root->Set("dict_with_empty_children", std::move(inner));
root = root->DeepCopyWithoutEmptyChildren();
EXPECT_EQ(2U, root->size());
}
@@ -665,7 +668,7 @@ TEST(ValuesTest, RemoveEmptyChildren) {
scoped_ptr<ListValue> inner(new ListValue);
inner->Append(make_scoped_ptr(new DictionaryValue));
inner->Append(make_scoped_ptr(new ListValue));
- root->Set("list_with_empty_children", inner.Pass());
+ root->Set("list_with_empty_children", std::move(inner));
root = root->DeepCopyWithoutEmptyChildren();
EXPECT_EQ(2U, root->size());
}
@@ -675,11 +678,11 @@ TEST(ValuesTest, RemoveEmptyChildren) {
scoped_ptr<ListValue> inner(new ListValue());
inner->Append(make_scoped_ptr(new DictionaryValue));
inner->Append(make_scoped_ptr(new ListValue));
- root->Set("list_with_empty_children", inner.Pass());
+ root->Set("list_with_empty_children", std::move(inner));
scoped_ptr<DictionaryValue> inner2(new DictionaryValue);
inner2->Set("empty_dict", make_scoped_ptr(new DictionaryValue));
inner2->Set("empty_list", make_scoped_ptr(new ListValue));
- root->Set("dict_with_empty_children", inner2.Pass());
+ root->Set("dict_with_empty_children", std::move(inner2));
root = root->DeepCopyWithoutEmptyChildren();
EXPECT_EQ(2U, root->size());
}
@@ -690,8 +693,8 @@ TEST(ValuesTest, RemoveEmptyChildren) {
scoped_ptr<ListValue> inner2(new ListValue);
inner2->Append(make_scoped_ptr(new StringValue("hello")));
inner->Append(make_scoped_ptr(new DictionaryValue));
- inner->Append(inner2.Pass());
- root->Set("list_with_empty_children", inner.Pass());
+ inner->Append(std::move(inner2));
+ root->Set("list_with_empty_children", std::move(inner));
root = root->DeepCopyWithoutEmptyChildren();
EXPECT_EQ(3U, root->size());
@@ -710,7 +713,7 @@ TEST(ValuesTest, MergeDictionary) {
scoped_ptr<DictionaryValue> base_sub_dict(new DictionaryValue);
base_sub_dict->SetString("sub_base_key", "sub_base_key_value_base");
base_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_base");
- base->Set("sub_dict_key", base_sub_dict.Pass());
+ base->Set("sub_dict_key", std::move(base_sub_dict));
scoped_ptr<DictionaryValue> merge(new DictionaryValue);
merge->SetString("merge_key", "merge_key_value_merge");
@@ -718,7 +721,7 @@ TEST(ValuesTest, MergeDictionary) {
scoped_ptr<DictionaryValue> merge_sub_dict(new DictionaryValue);
merge_sub_dict->SetString("sub_merge_key", "sub_merge_key_value_merge");
merge_sub_dict->SetString("sub_collide_key", "sub_collide_key_value_merge");
- merge->Set("sub_dict_key", merge_sub_dict.Pass());
+ merge->Set("sub_dict_key", std::move(merge_sub_dict));
base->MergeDictionary(merge.get());
@@ -759,7 +762,7 @@ TEST(ValuesTest, MergeDictionaryDeepCopy) {
EXPECT_EQ("value", value);
scoped_ptr<DictionaryValue> base(new DictionaryValue);
- base->Set("dict", child.Pass());
+ base->Set("dict", std::move(child));
EXPECT_EQ(1U, base->size());
DictionaryValue* ptr;
diff --git a/third_party/chromium/crypto/p224.cc b/third_party/chromium/crypto/p224.cc
index 81bce3a..ce3b7ee 100644
--- a/third_party/chromium/crypto/p224.cc
+++ b/third_party/chromium/crypto/p224.cc
@@ -11,17 +11,14 @@
#include <string.h>
-namespace crypto {
-namespace p224 {
-
namespace {
-inline uint32 ByteSwap(uint32 x) {
+inline uint32_t ByteSwap(uint32_t x) {
return ((x & 0x000000fful) << 24) | ((x & 0x0000ff00ul) << 8) |
((x & 0x00ff0000ul) >> 8) | ((x & 0xff000000ul) >> 24);
}
-inline uint32 HostToNet32(uint32 x) {
+inline uint32_t HostToNet32(uint32_t x) {
#if defined(ARCH_CPU_LITTLE_ENDIAN)
return ByteSwap(x);
#else
@@ -29,7 +26,7 @@ inline uint32 HostToNet32(uint32 x) {
#endif
}
-inline uint32 NetToHost32(uint32 x) {
+inline uint32_t NetToHost32(uint32_t x) {
#if defined(ARCH_CPU_LITTLE_ENDIAN)
return ByteSwap(x);
#else
@@ -42,13 +39,15 @@ inline uint32 NetToHost32(uint32 x) {
// The field that we're dealing with is ℤ/pℤ where p = 2**224 - 2**96 + 1.
//
// Field elements are represented by a FieldElement, which is a typedef to an
-// array of 8 uint32's. The value of a FieldElement, a, is:
+// array of 8 uint32_t's. The value of a FieldElement, a, is:
// a[0] + 2**28·a[1] + 2**56·a[1] + ... + 2**196·a[7]
//
// Using 28-bit limbs means that there's only 4 bits of headroom, which is less
// than we would really like. But it has the useful feature that we hit 2**224
// exactly, making the reflections during a reduce much nicer.
+using crypto::p224::FieldElement;
+
// kP is the P224 prime.
const FieldElement kP = {
1, 0, 0, 268431360,
@@ -58,12 +57,12 @@ const FieldElement kP = {
void Contract(FieldElement* inout);
// IsZero returns 0xffffffff if a == 0 mod p and 0 otherwise.
-uint32 IsZero(const FieldElement& a) {
+uint32_t IsZero(const FieldElement& a) {
FieldElement minimal;
memcpy(&minimal, &a, sizeof(minimal));
Contract(&minimal);
- uint32 is_zero = 0, is_p = 0;
+ uint32_t is_zero = 0, is_p = 0;
for (unsigned i = 0; i < 8; i++) {
is_zero |= minimal[i];
is_p |= minimal[i] - kP[i];
@@ -85,7 +84,7 @@ uint32 IsZero(const FieldElement& a) {
// For is_zero and is_p, the LSB is 0 iff all the bits are zero.
is_zero &= is_p & 1;
is_zero = (~is_zero) << 31;
- is_zero = static_cast<int32>(is_zero) >> 31;
+ is_zero = static_cast<int32_t>(is_zero) >> 31;
return is_zero;
}
@@ -98,9 +97,9 @@ void Add(FieldElement* out, const FieldElement& a, const FieldElement& b) {
}
}
-static const uint32 kTwo31p3 = (1u << 31) + (1u << 3);
-static const uint32 kTwo31m3 = (1u << 31) - (1u << 3);
-static const uint32 kTwo31m15m3 = (1u << 31) - (1u << 15) - (1u << 3);
+static const uint32_t kTwo31p3 = (1u << 31) + (1u << 3);
+static const uint32_t kTwo31m3 = (1u << 31) - (1u << 3);
+static const uint32_t kTwo31m15m3 = (1u << 31) - (1u << 15) - (1u << 3);
// kZero31ModP is 0 mod p where bit 31 is set in all limbs so that we can
// subtract smaller amounts without underflow. See the section "Subtraction" in
// [1] for why.
@@ -120,22 +119,22 @@ void Subtract(FieldElement* out, const FieldElement& a, const FieldElement& b) {
}
}
-static const uint64 kTwo63p35 = (1ull<<63) + (1ull<<35);
-static const uint64 kTwo63m35 = (1ull<<63) - (1ull<<35);
-static const uint64 kTwo63m35m19 = (1ull<<63) - (1ull<<35) - (1ull<<19);
+static const uint64_t kTwo63p35 = (1ull << 63) + (1ull << 35);
+static const uint64_t kTwo63m35 = (1ull << 63) - (1ull << 35);
+static const uint64_t kTwo63m35m19 = (1ull << 63) - (1ull << 35) - (1ull << 19);
// kZero63ModP is 0 mod p where bit 63 is set in all limbs. See the section
// "Subtraction" in [1] for why.
-static const uint64 kZero63ModP[8] = {
- kTwo63p35, kTwo63m35, kTwo63m35, kTwo63m35,
- kTwo63m35m19, kTwo63m35, kTwo63m35, kTwo63m35,
+static const uint64_t kZero63ModP[8] = {
+ kTwo63p35, kTwo63m35, kTwo63m35, kTwo63m35,
+ kTwo63m35m19, kTwo63m35, kTwo63m35, kTwo63m35,
};
-static const uint32 kBottom28Bits = 0xfffffff;
+static const uint32_t kBottom28Bits = 0xfffffff;
// LargeFieldElement also represents an element of the field. The limbs are
// still spaced 28-bits apart and in little-endian order. So the limbs are at
// 0, 28, 56, ..., 392 bits, each 64-bits wide.
-typedef uint64 LargeFieldElement[15];
+typedef uint64_t LargeFieldElement[15];
// ReduceLarge converts a LargeFieldElement to a FieldElement.
//
@@ -170,21 +169,21 @@ void ReduceLarge(FieldElement* out, LargeFieldElement* inptr) {
// 32-bit operations.
for (int i = 1; i < 8; i++) {
in[i+1] += in[i] >> 28;
- (*out)[i] = static_cast<uint32>(in[i] & kBottom28Bits);
+ (*out)[i] = static_cast<uint32_t>(in[i] & kBottom28Bits);
}
// Eliminate the term at 2*224 that we introduced while keeping the same
// value mod p.
in[0] -= in[8]; // reflection off the "+1" term of p.
- (*out)[3] += static_cast<uint32>(in[8] & 0xffff) << 12; // "-2**96" term
- (*out)[4] += static_cast<uint32>(in[8] >> 16); // rest of "-2**96" term
+ (*out)[3] += static_cast<uint32_t>(in[8] & 0xffff) << 12; // "-2**96" term
+ (*out)[4] += static_cast<uint32_t>(in[8] >> 16); // rest of "-2**96" term
// in[0] < 2**64
// out[3] < 2**29
// out[4] < 2**29
// out[1,2,5..7] < 2**28
- (*out)[0] = static_cast<uint32>(in[0] & kBottom28Bits);
- (*out)[1] += static_cast<uint32>((in[0] >> 28) & kBottom28Bits);
- (*out)[2] += static_cast<uint32>(in[0] >> 56);
+ (*out)[0] = static_cast<uint32_t>(in[0] & kBottom28Bits);
+ (*out)[1] += static_cast<uint32_t>((in[0] >> 28) & kBottom28Bits);
+ (*out)[2] += static_cast<uint32_t>(in[0] >> 56);
// out[0] < 2**28
// out[1..4] < 2**29
// out[5..7] < 2**28
@@ -206,7 +205,7 @@ void Mul(FieldElement* out, const FieldElement& a, const FieldElement& b) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
- tmp[i+j] += static_cast<uint64>(a[i]) * static_cast<uint64>(b[j]);
+ tmp[i + j] += static_cast<uint64_t>(a[i]) * static_cast<uint64_t>(b[j]);
}
}
@@ -223,7 +222,7 @@ void Square(FieldElement* out, const FieldElement& a) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j <= i; j++) {
- uint64 r = static_cast<uint64>(a[i]) * static_cast<uint64>(a[j]);
+ uint64_t r = static_cast<uint64_t>(a[i]) * static_cast<uint64_t>(a[j]);
if (i == j) {
tmp[i+j] += r;
} else {
@@ -246,16 +245,16 @@ void Reduce(FieldElement* in_out) {
a[i+1] += a[i] >> 28;
a[i] &= kBottom28Bits;
}
- uint32 top = a[7] >> 28;
+ uint32_t top = a[7] >> 28;
a[7] &= kBottom28Bits;
// top < 2**4
// Constant-time: mask = (top != 0) ? 0xffffffff : 0
- uint32 mask = top;
+ uint32_t mask = top;
mask |= mask >> 2;
mask |= mask >> 1;
mask <<= 31;
- mask = static_cast<uint32>(static_cast<int32>(mask) >> 31);
+ mask = static_cast<uint32_t>(static_cast<int32_t>(mask) >> 31);
// Eliminate top while maintaining the same value mod p.
a[0] -= top;
@@ -332,7 +331,7 @@ void Contract(FieldElement* inout) {
out[i+1] += out[i] >> 28;
out[i] &= kBottom28Bits;
}
- uint32 top = out[7] >> 28;
+ uint32_t top = out[7] >> 28;
out[7] &= kBottom28Bits;
// Eliminate top while maintaining the same value mod p.
@@ -343,7 +342,7 @@ void Contract(FieldElement* inout) {
// out[0] negative then we know that out[3] is sufficiently positive
// because we just added to it.
for (int i = 0; i < 3; i++) {
- uint32 mask = static_cast<uint32>(static_cast<int32>(out[i]) >> 31);
+ uint32_t mask = static_cast<uint32_t>(static_cast<int32_t>(out[i]) >> 31);
out[i] += (1 << 28) & mask;
out[i+1] -= 1 & mask;
}
@@ -376,7 +375,7 @@ void Contract(FieldElement* inout) {
// As before, if we made out[0] negative then we know that out[3] is
// sufficiently positive.
for (int i = 0; i < 3; i++) {
- uint32 mask = static_cast<uint32>(static_cast<int32>(out[i]) >> 31);
+ uint32_t mask = static_cast<uint32_t>(static_cast<int32_t>(out[i]) >> 31);
out[i] += (1 << 28) & mask;
out[i+1] -= 1 & mask;
}
@@ -388,7 +387,7 @@ void Contract(FieldElement* inout) {
// equal to bottom28Bits if the whole value is >= p. If top_4_all_ones
// ends up with any zero bits in the bottom 28 bits, then this wasn't
// true.
- uint32 top_4_all_ones = 0xffffffffu;
+ uint32_t top_4_all_ones = 0xffffffffu;
for (int i = 4; i < 8; i++) {
top_4_all_ones &= out[i];
}
@@ -400,37 +399,39 @@ void Contract(FieldElement* inout) {
top_4_all_ones &= top_4_all_ones >> 2;
top_4_all_ones &= top_4_all_ones >> 1;
top_4_all_ones =
- static_cast<uint32>(static_cast<int32>(top_4_all_ones << 31) >> 31);
+ static_cast<uint32_t>(static_cast<int32_t>(top_4_all_ones << 31) >> 31);
// Now we test whether the bottom three limbs are non-zero.
- uint32 bottom_3_non_zero = out[0] | out[1] | out[2];
+ uint32_t bottom_3_non_zero = out[0] | out[1] | out[2];
bottom_3_non_zero |= bottom_3_non_zero >> 16;
bottom_3_non_zero |= bottom_3_non_zero >> 8;
bottom_3_non_zero |= bottom_3_non_zero >> 4;
bottom_3_non_zero |= bottom_3_non_zero >> 2;
bottom_3_non_zero |= bottom_3_non_zero >> 1;
bottom_3_non_zero =
- static_cast<uint32>(static_cast<int32>(bottom_3_non_zero) >> 31);
+ static_cast<uint32_t>(static_cast<int32_t>(bottom_3_non_zero) >> 31);
// Everything depends on the value of out[3].
// If it's > 0xffff000 and top_4_all_ones != 0 then the whole value is >= p
// If it's = 0xffff000 and top_4_all_ones != 0 and bottom_3_non_zero != 0,
// then the whole value is >= p
// If it's < 0xffff000, then the whole value is < p
- uint32 n = out[3] - 0xffff000;
- uint32 out_3_equal = n;
+ uint32_t n = out[3] - 0xffff000;
+ uint32_t out_3_equal = n;
out_3_equal |= out_3_equal >> 16;
out_3_equal |= out_3_equal >> 8;
out_3_equal |= out_3_equal >> 4;
out_3_equal |= out_3_equal >> 2;
out_3_equal |= out_3_equal >> 1;
out_3_equal =
- ~static_cast<uint32>(static_cast<int32>(out_3_equal << 31) >> 31);
+ ~static_cast<uint32_t>(static_cast<int32_t>(out_3_equal << 31) >> 31);
// If out[3] > 0xffff000 then n's MSB will be zero.
- uint32 out_3_gt = ~static_cast<uint32>(static_cast<int32>(n << 31) >> 31);
+ uint32_t out_3_gt =
+ ~static_cast<uint32_t>(static_cast<int32_t>(n << 31) >> 31);
- uint32 mask = top_4_all_ones & ((out_3_equal & bottom_3_non_zero) | out_3_gt);
+ uint32_t mask =
+ top_4_all_ones & ((out_3_equal & bottom_3_non_zero) | out_3_gt);
out[0] -= 1 & mask;
out[3] -= 0xffff000 & mask;
out[4] -= 0xfffffff & mask;
@@ -445,13 +446,15 @@ void Contract(FieldElement* inout) {
// These functions deal with group elements. The group is an elliptic curve
// group with a = -3 defined in FIPS 186-3, section D.2.2.
+using crypto::p224::Point;
+
// kB is parameter of the elliptic curve.
const FieldElement kB = {
55967668, 11768882, 265861671, 185302395,
39211076, 180311059, 84673715, 188764328,
};
-void CopyConditional(Point* out, const Point& a, uint32 mask);
+void CopyConditional(Point* out, const Point& a, uint32_t mask);
void DoubleJacobian(Point* out, const Point& a);
// AddJacobian computes *out = a+b where a != b.
@@ -461,8 +464,8 @@ void AddJacobian(Point *out,
// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
FieldElement z1z1, z2z2, u1, u2, s1, s2, h, i, j, r, v;
- uint32 z1_is_zero = IsZero(a.z);
- uint32 z2_is_zero = IsZero(b.z);
+ uint32_t z1_is_zero = IsZero(a.z);
+ uint32_t z2_is_zero = IsZero(b.z);
// Z1Z1 = Z1²
Square(&z1z1, a.z);
@@ -487,7 +490,7 @@ void AddJacobian(Point *out,
// H = U2-U1
Subtract(&h, u2, u1);
Reduce(&h);
- uint32 x_equal = IsZero(h);
+ uint32_t x_equal = IsZero(h);
// I = (2*H)²
for (int k = 0; k < 8; k++) {
@@ -501,7 +504,7 @@ void AddJacobian(Point *out,
// r = 2*(S2-S1)
Subtract(&r, s2, s1);
Reduce(&r);
- uint32 y_equal = IsZero(r);
+ uint32_t y_equal = IsZero(r);
if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
// The two input points are the same therefore we must use the dedicated
@@ -608,9 +611,7 @@ void DoubleJacobian(Point* out, const Point& a) {
// CopyConditional sets *out=a if mask is 0xffffffff. mask must be either 0 of
// 0xffffffff.
-void CopyConditional(Point* out,
- const Point& a,
- uint32 mask) {
+void CopyConditional(Point* out, const Point& a, uint32_t mask) {
for (int i = 0; i < 8; i++) {
out->x[i] ^= mask & (a.x[i] ^ out->x[i]);
out->y[i] ^= mask & (a.y[i] ^ out->y[i]);
@@ -620,15 +621,17 @@ void CopyConditional(Point* out,
// ScalarMult calculates *out = a*scalar where scalar is a big-endian number of
// length scalar_len and != 0.
-void ScalarMult(Point* out, const Point& a,
- const uint8* scalar, size_t scalar_len) {
+void ScalarMult(Point* out,
+ const Point& a,
+ const uint8_t* scalar,
+ size_t scalar_len) {
memset(out, 0, sizeof(*out));
Point tmp;
for (size_t i = 0; i < scalar_len; i++) {
for (unsigned int bit_num = 0; bit_num < 8; bit_num++) {
DoubleJacobian(out, *out);
- uint32 bit = static_cast<uint32>(static_cast<int32>(
+ uint32_t bit = static_cast<uint32_t>(static_cast<int32_t>(
(((scalar[i] >> (7 - bit_num)) & 1) << 31) >> 31));
AddJacobian(&tmp, a, *out);
CopyConditional(out, tmp, bit);
@@ -638,7 +641,7 @@ void ScalarMult(Point* out, const Point& a,
// Get224Bits reads 7 words from in and scatters their contents in
// little-endian form into 8 words at out, 28 bits per output word.
-void Get224Bits(uint32* out, const uint32* in) {
+void Get224Bits(uint32_t* out, const uint32_t* in) {
out[0] = NetToHost32(in[6]) & kBottom28Bits;
out[1] = ((NetToHost32(in[5]) << 4) |
(NetToHost32(in[6]) >> 28)) & kBottom28Bits;
@@ -658,7 +661,7 @@ void Get224Bits(uint32* out, const uint32* in) {
// Put224Bits performs the inverse operation to Get224Bits: taking 28 bits from
// each of 8 input words and writing them in big-endian order to 7 words at
// out.
-void Put224Bits(uint32* out, const uint32* in) {
+void Put224Bits(uint32_t* out, const uint32_t* in) {
out[6] = HostToNet32((in[0] >> 0) | (in[1] << 28));
out[5] = HostToNet32((in[1] >> 4) | (in[2] << 24));
out[4] = HostToNet32((in[2] >> 8) | (in[3] << 20));
@@ -670,10 +673,14 @@ void Put224Bits(uint32* out, const uint32* in) {
} // anonymous namespace
-bool Point::SetFromString(const std::string& in) {
+namespace crypto {
+
+namespace p224 {
+
+bool Point::SetFromString(const base::StringPiece& in) {
if (in.size() != 2*28)
return false;
- const uint32* inwords = reinterpret_cast<const uint32*>(in.data());
+ const uint32_t* inwords = reinterpret_cast<const uint32_t*>(in.data());
Get224Bits(x, inwords);
Get224Bits(y, inwords + 7);
memset(&z, 0, sizeof(z));
@@ -696,7 +703,7 @@ bool Point::SetFromString(const std::string& in) {
Subtract(&rhs, rhs, three_x);
Reduce(&rhs);
- Add(&rhs, rhs, kB);
+ ::Add(&rhs, rhs, kB);
Contract(&rhs);
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
}
@@ -719,27 +726,27 @@ std::string Point::ToString() const {
Contract(&xx);
Contract(&yy);
- uint32 outwords[14];
+ uint32_t outwords[14];
Put224Bits(outwords, xx);
Put224Bits(outwords + 7, yy);
return std::string(reinterpret_cast<const char*>(outwords), sizeof(outwords));
}
-void ScalarMult(const Point& in, const uint8* scalar, Point* out) {
- ScalarMult(out, in, scalar, 28);
+void ScalarMult(const Point& in, const uint8_t* scalar, Point* out) {
+ ::ScalarMult(out, in, scalar, 28);
}
// kBasePoint is the base point (generator) of the elliptic curve group.
static const Point kBasePoint = {
{22813985, 52956513, 34677300, 203240812,
- 12143107, 133374265, 225162431, 191946955},
+ 12143107, 133374265, 225162431, 191946955},
{83918388, 223877528, 122119236, 123340192,
- 266784067, 263504429, 146143011, 198407736},
+ 266784067, 263504429, 146143011, 198407736},
{1, 0, 0, 0, 0, 0, 0, 0},
};
-void ScalarBaseMult(const uint8* scalar, Point* out) {
- ScalarMult(out, kBasePoint, scalar, 28);
+void ScalarBaseMult(const uint8_t* scalar, Point* out) {
+ ::ScalarMult(out, kBasePoint, scalar, 28);
}
void Add(const Point& a, const Point& b, Point* out) {
@@ -765,4 +772,5 @@ void Negate(const Point& in, Point* out) {
}
} // namespace p224
+
} // namespace crypto
diff --git a/third_party/chromium/crypto/p224.h b/third_party/chromium/crypto/p224.h
index 7574389..e9976e6 100644
--- a/third_party/chromium/crypto/p224.h
+++ b/third_party/chromium/crypto/p224.h
@@ -5,9 +5,12 @@
#ifndef LIBWEAVE_THIRD_PARTY_CHROMIUM_P224_H_
#define LIBWEAVE_THIRD_PARTY_CHROMIUM_P224_H_
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
-#include <base/basictypes.h>
+#include "base/strings/string_piece.h"
namespace crypto {
@@ -17,14 +20,14 @@ namespace p224 {
// An element of the field (ℤ/pℤ) is represented with 8, 28-bit limbs in
// little endian order.
-typedef uint32 FieldElement[8];
+typedef uint32_t FieldElement[8];
struct Point {
// SetFromString the value of the point from the 56 byte, external
// representation. The external point representation is an (x, y) pair of a
// point on the curve. Each field element is represented as a big-endian
// number < p.
- bool SetFromString(const std::string& in);
+ bool SetFromString(const base::StringPiece& in);
// ToString returns an external representation of the Point.
std::string ToString() const;
@@ -39,11 +42,11 @@ static const size_t kScalarBytes = 28;
// ScalarMult computes *out = in*scalar where scalar is a 28-byte, big-endian
// number.
-void ScalarMult(const Point& in, const uint8* scalar, Point* out);
+void ScalarMult(const Point& in, const uint8_t* scalar, Point* out);
// ScalarBaseMult computes *out = g*scalar where g is the base point of the
// curve and scalar is a 28-byte, big-endian number.
-void ScalarBaseMult(const uint8* scalar, Point* out);
+void ScalarBaseMult(const uint8_t* scalar, Point* out);
// Add computes *out = a+b.
void Add(const Point& a, const Point& b, Point* out);
@@ -52,6 +55,7 @@ void Add(const Point& a, const Point& b, Point* out);
void Negate(const Point& a, Point* out);
} // namespace p224
+
} // namespace crypto
#endif // LIBWEAVE_THIRD_PARTY_CHROMIUM_P224_H_
diff --git a/third_party/chromium/crypto/p224_spake.cc b/third_party/chromium/crypto/p224_spake.cc
index 6d82322..d55d2a7 100644
--- a/third_party/chromium/crypto/p224_spake.cc
+++ b/third_party/chromium/crypto/p224_spake.cc
@@ -14,8 +14,6 @@
#include "third_party/chromium/crypto/p224.h"
-namespace crypto {
-
namespace {
// The following two points (M and N in the protocol) are verifiable random
@@ -79,19 +77,19 @@ namespace {
// return 0;
// }
-const p224::Point kM = {
+const crypto::p224::Point kM = {
{174237515, 77186811, 235213682, 33849492,
- 33188520, 48266885, 177021753, 81038478},
+ 33188520, 48266885, 177021753, 81038478},
{104523827, 245682244, 266509668, 236196369,
- 28372046, 145351378, 198520366, 113345994},
+ 28372046, 145351378, 198520366, 113345994},
{1, 0, 0, 0, 0, 0, 0, 0},
};
-const p224::Point kN = {
+const crypto::p224::Point kN = {
{136176322, 263523628, 251628795, 229292285,
- 5034302, 185981975, 171998428, 11653062},
+ 5034302, 185981975, 171998428, 11653062},
{197567436, 51226044, 60372156, 175772188,
- 42075930, 8083165, 160827401, 65097570},
+ 42075930, 8083165, 160827401, 65097570},
{1, 0, 0, 0, 0, 0, 0, 0},
};
@@ -114,9 +112,12 @@ bool SecureMemEqual(const uint8_t* s1_ptr, const uint8_t* s2_ptr, size_t n) {
} // anonymous namespace
-P224EncryptedKeyExchange::P224EncryptedKeyExchange(PeerType peer_type,
- const std::string& password)
- : state_(kStateInitial), is_server_(peer_type == kPeerTypeServer) {
+namespace crypto {
+
+P224EncryptedKeyExchange::P224EncryptedKeyExchange(
+ PeerType peer_type, const base::StringPiece& password)
+ : state_(kStateInitial),
+ is_server_(peer_type == kPeerTypeServer) {
memset(&x_, 0, sizeof(x_));
memset(&expected_authenticator_, 0, sizeof(expected_authenticator_));
@@ -163,7 +164,7 @@ const std::string& P224EncryptedKeyExchange::GetNextMessage() {
}
P224EncryptedKeyExchange::Result P224EncryptedKeyExchange::ProcessMessage(
- const std::string& message) {
+ const base::StringPiece& message) {
if (state_ == kStateRecvHash) {
// This is the final state of the protocol: we are reading the peer's
// authentication hash and checking that it matches the one that we expect.
@@ -210,23 +211,23 @@ P224EncryptedKeyExchange::Result P224EncryptedKeyExchange::ProcessMessage(
std::string client_masked_dh, server_masked_dh;
if (is_server_) {
- client_masked_dh = message;
+ client_masked_dh = message.as_string();
server_masked_dh = next_message_;
} else {
client_masked_dh = next_message_;
- server_masked_dh = message;
+ server_masked_dh = message.as_string();
}
// Now we calculate the hashes that each side will use to prove to the other
// that they derived the correct value for K.
- uint8 client_hash[kSHA256Length], server_hash[kSHA256Length];
+ uint8_t client_hash[kSHA256Length], server_hash[kSHA256Length];
CalculateHash(kPeerTypeClient, client_masked_dh, server_masked_dh, key_,
client_hash);
CalculateHash(kPeerTypeServer, client_masked_dh, server_masked_dh, key_,
server_hash);
- const uint8* my_hash = is_server_ ? server_hash : client_hash;
- const uint8* their_hash = is_server_ ? client_hash : server_hash;
+ const uint8_t* my_hash = is_server_ ? server_hash : client_hash;
+ const uint8_t* their_hash = is_server_ ? client_hash : server_hash;
next_message_ =
std::string(reinterpret_cast<const char*>(my_hash), kSHA256Length);
@@ -240,7 +241,7 @@ void P224EncryptedKeyExchange::CalculateHash(
const std::string& client_masked_dh,
const std::string& server_masked_dh,
const std::string& k,
- uint8* out_digest) {
+ uint8_t* out_digest) {
std::string hash_contents;
if (peer_type == kPeerTypeServer) {
diff --git a/third_party/chromium/crypto/p224_spake.h b/third_party/chromium/crypto/p224_spake.h
index dcfd0fe..122ea46 100644
--- a/third_party/chromium/crypto/p224_spake.h
+++ b/third_party/chromium/crypto/p224_spake.h
@@ -3,10 +3,12 @@
// found in the LICENSE file.
#ifndef LIBWEAVE_THIRD_PARTY_CHROMIUM_P224_SPAKE_H_
+#define LIBWEAVE_THIRD_PARTY_CHROMIUM_P224_SPAKE_H_
-#include <string>
+#include <stdint.h>
#include <base/gtest_prod_util.h>
+#include <base/strings/string_piece.h>
#include "third_party/chromium/crypto/p224.h"
#include "third_party/chromium/crypto/sha2.h"
@@ -53,7 +55,8 @@ class P224EncryptedKeyExchange {
// password: secret session password. Both parties to the
// authentication must pass the same value. For the case of a
// TLS connection, see RFC 5705.
- P224EncryptedKeyExchange(PeerType peer_type, const std::string& password);
+ P224EncryptedKeyExchange(PeerType peer_type,
+ const base::StringPiece& password);
// GetNextMessage returns a byte string which must be passed to the other
// party in the authentication.
@@ -61,7 +64,7 @@ class P224EncryptedKeyExchange {
// ProcessMessage processes a message which must have been generated by a
// call to GetNextMessage() by the other party.
- Result ProcessMessage(const std::string& message);
+ Result ProcessMessage(const base::StringPiece& message);
// In the event that ProcessMessage() returns kResultFailed, error will
// return a human readable error message.
@@ -101,22 +104,21 @@ class P224EncryptedKeyExchange {
// CalculateHash computes the verification hash for the given peer and writes
// |kSHA256Length| bytes at |out_digest|.
- void CalculateHash(
- PeerType peer_type,
- const std::string& client_masked_dh,
- const std::string& server_masked_dh,
- const std::string& k,
- uint8* out_digest);
+ void CalculateHash(PeerType peer_type,
+ const std::string& client_masked_dh,
+ const std::string& server_masked_dh,
+ const std::string& k,
+ uint8_t* out_digest);
// x_ is the secret Diffie-Hellman exponent (see paper referenced in .cc
// file).
- uint8 x_[p224::kScalarBytes];
- // pw_ is SHA256(P(password), P(session))[:28] where P() prepends a uint32,
+ uint8_t x_[p224::kScalarBytes];
+ // pw_ is SHA256(P(password), P(session))[:28] where P() prepends a uint32_t,
// big-endian length prefix (see paper referenced in .cc file).
- uint8 pw_[p224::kScalarBytes];
+ uint8_t pw_[p224::kScalarBytes];
// expected_authenticator_ is used to store the hash value expected from the
// other party.
- uint8 expected_authenticator_[kSHA256Length];
+ uint8_t expected_authenticator_[kSHA256Length];
std::string key_;
};
diff --git a/third_party/chromium/crypto/p224_spake_unittest.cc b/third_party/chromium/crypto/p224_spake_unittest.cc
index 9a9f9d2..373bb28 100644
--- a/third_party/chromium/crypto/p224_spake_unittest.cc
+++ b/third_party/chromium/crypto/p224_spake_unittest.cc
@@ -4,6 +4,9 @@
#include "third_party/chromium/crypto/p224_spake.h"
+#include <stddef.h>
+#include <stdint.h>
+
#include <string>
#include <base/logging.h>
@@ -125,7 +128,7 @@ TEST(MutualAuth, Fuzz) {
// We'll only be testing small values of i, but we don't want that to bias
// the test coverage. So we disperse the value of i by multiplying by the
// FNV, 32-bit prime, producing a poor-man's PRNG.
- const uint32 rand = i * 16777619;
+ const uint32_t rand = i * 16777619;
for (unsigned round = 0;; round++) {
std::string client_message, server_message;
diff --git a/third_party/chromium/crypto/p224_unittest.cc b/third_party/chromium/crypto/p224_unittest.cc
index 0540dbb..331fc3c 100644
--- a/third_party/chromium/crypto/p224_unittest.cc
+++ b/third_party/chromium/crypto/p224_unittest.cc
@@ -4,9 +4,12 @@
#include "third_party/chromium/crypto/p224.h"
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
+#include "base/macros.h"
#include <gtest/gtest.h>
namespace crypto {
@@ -14,22 +17,20 @@ namespace crypto {
using p224::Point;
// kBasePointExternal is the P224 base point in external representation.
-static const uint8 kBasePointExternal[56] = {
- 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f,
- 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x03, 0xc1, 0xd3,
- 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
- 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88,
- 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
- 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
- 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
+static const uint8_t kBasePointExternal[56] = {
+ 0xb7, 0x0e, 0x0c, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9,
+ 0x4a, 0x03, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6,
+ 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb,
+ 0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
+ 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34,
};
// TestVector represents a test of scalar multiplication of the base point.
// |scalar| is a big-endian scalar and |affine| is the external representation
// of g*scalar.
struct TestVector {
- uint8 scalar[28];
- uint8 affine[28*2];
+ uint8_t scalar[28];
+ uint8_t affine[28 * 2];
};
static const int kNumNISTTestVectors = 52;
@@ -770,15 +771,15 @@ static const TestVector kNISTTestVectors[kNumNISTTestVectors] = {
TEST(P224, ExternalToInternalAndBack) {
Point point;
- EXPECT_TRUE(point.SetFromString(
- std::string(reinterpret_cast<const char*>(kBasePointExternal),
- sizeof(kBasePointExternal))));
+ EXPECT_TRUE(point.SetFromString(base::StringPiece(
+ reinterpret_cast<const char *>(kBasePointExternal),
+ sizeof(kBasePointExternal))));
const std::string external = point.ToString();
ASSERT_EQ(external.size(), 56u);
- EXPECT_EQ(0, memcmp(external.data(), kBasePointExternal,
- sizeof(kBasePointExternal)));
+ EXPECT_TRUE(memcmp(external.data(), kBasePointExternal,
+ sizeof(kBasePointExternal)) == 0);
}
TEST(P224, ScalarBaseMult) {
@@ -788,22 +789,22 @@ TEST(P224, ScalarBaseMult) {
p224::ScalarBaseMult(kNISTTestVectors[i].scalar, &point);
const std::string external = point.ToString();
ASSERT_EQ(external.size(), 56u);
- EXPECT_EQ(0, memcmp(external.data(), kNISTTestVectors[i].affine,
- external.size()));
+ EXPECT_TRUE(memcmp(external.data(), kNISTTestVectors[i].affine,
+ external.size()) == 0);
}
}
TEST(P224, Addition) {
Point a, b, minus_b, sum, a_again;
- ASSERT_TRUE(a.SetFromString(std::string(
- reinterpret_cast<const char*>(kNISTTestVectors[10].affine), 56)));
- ASSERT_TRUE(b.SetFromString(std::string(
- reinterpret_cast<const char*>(kNISTTestVectors[11].affine), 56)));
+ ASSERT_TRUE(a.SetFromString(base::StringPiece(
+ reinterpret_cast<const char *>(kNISTTestVectors[10].affine), 56)));
+ ASSERT_TRUE(b.SetFromString(base::StringPiece(
+ reinterpret_cast<const char *>(kNISTTestVectors[11].affine), 56)));
p224::Negate(b, &minus_b);
p224::Add(a, b, &sum);
- EXPECT_NE(0, memcmp(&sum, &a, sizeof(sum)));
+ EXPECT_TRUE(memcmp(&sum, &a, sizeof(sum)) != 0);
p224::Add(minus_b, sum, &a_again);
EXPECT_TRUE(a_again.ToString() == a.ToString());
}
@@ -814,8 +815,8 @@ TEST(P224, Infinity) {
// Test that x^0 = ∞.
Point a;
- p224::ScalarBaseMult(reinterpret_cast<const uint8*>(zeros), &a);
- EXPECT_EQ(0, memcmp(zeros, a.ToString().data(), sizeof(zeros)));
+ p224::ScalarBaseMult(reinterpret_cast<const uint8_t*>(zeros), &a);
+ EXPECT_TRUE(memcmp(zeros, a.ToString().data(), sizeof(zeros)) == 0);
// We shouldn't allow ∞ to be imported.
EXPECT_FALSE(a.SetFromString(std::string(zeros, sizeof(zeros))));
diff --git a/third_party/chromium/crypto/sha2_unittest.cc b/third_party/chromium/crypto/sha2_unittest.cc
index 0c30f45..42dffb5 100644
--- a/third_party/chromium/crypto/sha2_unittest.cc
+++ b/third_party/chromium/crypto/sha2_unittest.cc
@@ -4,7 +4,6 @@
#include "third_party/chromium/crypto/sha2.h"
-#include <base/basictypes.h>
#include <gtest/gtest.h>
namespace weave {
@@ -21,12 +20,12 @@ TEST(Sha256Test, Test1) {
0xb4, 0x10, 0xff, 0x61,
0xf2, 0x00, 0x15, 0xad };
- uint8 output1[crypto::kSHA256Length];
+ uint8_t output1[crypto::kSHA256Length];
crypto::SHA256HashString(input1, output1, sizeof(output1));
for (size_t i = 0; i < crypto::kSHA256Length; i++)
EXPECT_EQ(expected1[i], static_cast<int>(output1[i]));
- uint8 output_truncated1[4]; // 4 bytes == 32 bits
+ uint8_t output_truncated1[4]; // 4 bytes == 32 bits
crypto::SHA256HashString(input1,
output_truncated1, sizeof(output_truncated1));
for (size_t i = 0; i < sizeof(output_truncated1); i++)
@@ -49,7 +48,7 @@ TEST(Sha256Test, Test1_String) {
std::string output1 = crypto::SHA256HashString(input1);
ASSERT_EQ(crypto::kSHA256Length, output1.size());
for (size_t i = 0; i < crypto::kSHA256Length; i++)
- EXPECT_EQ(expected1[i], static_cast<uint8>(output1[i]));
+ EXPECT_EQ(expected1[i], static_cast<uint8_t>(output1[i]));
}
TEST(Sha256Test, Test2) {
@@ -65,12 +64,12 @@ TEST(Sha256Test, Test2) {
0xf6, 0xec, 0xed, 0xd4,
0x19, 0xdb, 0x06, 0xc1 };
- uint8 output2[crypto::kSHA256Length];
+ uint8_t output2[crypto::kSHA256Length];
crypto::SHA256HashString(input2, output2, sizeof(output2));
for (size_t i = 0; i < crypto::kSHA256Length; i++)
EXPECT_EQ(expected2[i], static_cast<int>(output2[i]));
- uint8 output_truncated2[6];
+ uint8_t output_truncated2[6];
crypto::SHA256HashString(input2,
output_truncated2, sizeof(output_truncated2));
for (size_t i = 0; i < sizeof(output_truncated2); i++)
@@ -89,12 +88,12 @@ TEST(Sha256Test, Test3) {
0x04, 0x6d, 0x39, 0xcc,
0xc7, 0x11, 0x2c, 0xd0 };
- uint8 output3[crypto::kSHA256Length];
+ uint8_t output3[crypto::kSHA256Length];
crypto::SHA256HashString(input3, output3, sizeof(output3));
for (size_t i = 0; i < crypto::kSHA256Length; i++)
EXPECT_EQ(expected3[i], static_cast<int>(output3[i]));
- uint8 output_truncated3[12];
+ uint8_t output_truncated3[12];
crypto::SHA256HashString(input3,
output_truncated3, sizeof(output_truncated3));
for (size_t i = 0; i < sizeof(output_truncated3); i++)