aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/stubs
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/stubs')
-rw-r--r--src/google/protobuf/stubs/atomic_sequence_num.h54
-rw-r--r--src/google/protobuf/stubs/atomicops.h242
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h325
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm_gcc.h151
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_arm_qnx.h146
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h122
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h231
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_gcc.h155
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_mips_gcc.h313
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_power.h440
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h155
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_solaris.h188
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_tsan.h219
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc137
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_gcc.h293
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc113
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_x86_msvc.h150
-rw-r--r--src/google/protobuf/stubs/bytestream.h25
-rw-r--r--src/google/protobuf/stubs/callback.h37
-rw-r--r--src/google/protobuf/stubs/casts.h5
-rw-r--r--[-rwxr-xr-x]src/google/protobuf/stubs/common.cc86
-rw-r--r--src/google/protobuf/stubs/common.h17
-rw-r--r--src/google/protobuf/stubs/common_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/hash.h13
-rw-r--r--src/google/protobuf/stubs/int128.cc52
-rw-r--r--src/google/protobuf/stubs/io_win32.cc174
-rw-r--r--src/google/protobuf/stubs/io_win32.h27
-rw-r--r--src/google/protobuf/stubs/io_win32_unittest.cc221
-rw-r--r--src/google/protobuf/stubs/map_util.h7
-rw-r--r--src/google/protobuf/stubs/mathlimits.h2
-rw-r--r--src/google/protobuf/stubs/mutex.h54
-rw-r--r--src/google/protobuf/stubs/once.cc99
-rw-r--r--src/google/protobuf/stubs/once.h71
-rw-r--r--src/google/protobuf/stubs/once_unittest.cc254
-rw-r--r--src/google/protobuf/stubs/platform_macros.h11
-rw-r--r--src/google/protobuf/stubs/port.h77
-rw-r--r--src/google/protobuf/stubs/scoped_ptr.h236
-rw-r--r--src/google/protobuf/stubs/shared_ptr.h471
-rw-r--r--src/google/protobuf/stubs/singleton.h1
-rw-r--r--src/google/protobuf/stubs/status.cc2
-rw-r--r--src/google/protobuf/stubs/status.h2
-rw-r--r--src/google/protobuf/stubs/stringprintf.cc2
-rw-r--r--src/google/protobuf/stubs/stringprintf.h2
-rw-r--r--src/google/protobuf/stubs/structurally_valid.cc31
-rw-r--r--src/google/protobuf/stubs/structurally_valid_unittest.cc30
-rw-r--r--src/google/protobuf/stubs/strutil.cc22
-rw-r--r--src/google/protobuf/stubs/strutil.h20
-rw-r--r--src/google/protobuf/stubs/strutil_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/time.cc4
-rw-r--r--src/google/protobuf/stubs/time_test.cc53
-rw-r--r--src/google/protobuf/stubs/type_traits.h364
-rw-r--r--src/google/protobuf/stubs/type_traits_unittest.cc631
52 files changed, 604 insertions, 5937 deletions
diff --git a/src/google/protobuf/stubs/atomic_sequence_num.h b/src/google/protobuf/stubs/atomic_sequence_num.h
deleted file mode 100644
index bb20942f..00000000
--- a/src/google/protobuf/stubs/atomic_sequence_num.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2014 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_
-#define GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_
-
-#include <google/protobuf/stubs/atomicops.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-class SequenceNumber {
- public:
- SequenceNumber() : word_(0) {}
-
- AtomicWord GetNext() {
- return NoBarrier_AtomicIncrement(&word_, 1) - 1;
- }
- private:
- AtomicWord word_;
-};
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_
diff --git a/src/google/protobuf/stubs/atomicops.h b/src/google/protobuf/stubs/atomicops.h
deleted file mode 100644
index 64c838fb..00000000
--- a/src/google/protobuf/stubs/atomicops.h
+++ /dev/null
@@ -1,242 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The routines exported by this module are subtle. If you use them, even if
-// you get the code right, it will depend on careful reasoning about atomicity
-// and memory ordering; it will be less readable, and harder to maintain. If
-// you plan to use these routines, you should have a good reason, such as solid
-// evidence that performance would otherwise suffer, or there being no
-// alternative. You should assume only properties explicitly guaranteed by the
-// specifications in this file. You are almost certainly _not_ writing code
-// just for the x86; if you assume x86 semantics, x86 hardware bugs and
-// implementations on other archtectures will cause your code to break. If you
-// do not know what you are doing, avoid these routines, and use a Mutex.
-//
-// It is incorrect to make direct assignments to/from an atomic variable.
-// You should use one of the Load or Store routines. The NoBarrier
-// versions are provided when no barriers are needed:
-// NoBarrier_Store()
-// NoBarrier_Load()
-// Although there are currently no compiler enforcement, you are encouraged
-// to use these.
-
-// This header and the implementations for each platform (located in
-// atomicops_internals_*) must be kept in sync with the upstream code (V8).
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_H_
-
-// Don't include this file for people not concerned about thread safety.
-#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/platform_macros.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-#ifdef GOOGLE_PROTOBUF_ARCH_32_BIT
- typedef intptr_t Atomic32;
- typedef int64 Atomic64;
-#else
- typedef int32 Atomic32;
- // We need to be able to go between Atomic64 and AtomicWord implicitly. This
- // means Atomic64 and AtomicWord should be the same type on 64-bit.
- #if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL)
- // NaCl's intptr_t is not actually 64-bits on 64-bit!
- // http://code.google.com/p/nativeclient/issues/detail?id=1162
- // sparcv9's pointer type is 32bits
- typedef int64 Atomic64;
- #else
- typedef intptr_t Atomic64;
- #endif
-#endif
-
-// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
-// Atomic64 routines below, depending on your architecture.
-typedef intptr_t AtomicWord;
-
-// Atomically execute:
-// result = *ptr;
-// if (*ptr == old_value)
-// *ptr = new_value;
-// return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value);
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr. This routine implies no memory barriers.
-Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
-
-// Atomically increment *ptr by "increment". Returns the new value of
-// *ptr with the increment applied. This routine implies no memory barriers.
-Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
-
-Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment);
-
-// These following lower-level operations are typically useful only to people
-// implementing higher-level synchronization operations like spinlocks,
-// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or
-// a store with appropriate memory-ordering instructions. "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation. "Barrier" operations have both "Acquire" and "Release"
-// semantics. A MemoryBarrierInternal() has "Barrier" semantics, but does no
-// memory access.
-Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value);
-Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value);
-
-// This function was renamed from MemoryBarrier to MemoryBarrierInternal
-// because MemoryBarrier is a define in Windows ARM builds and we do not
-// undefine it because we call it from this function.
-void MemoryBarrierInternal();
-void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
-void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
-void Release_Store(volatile Atomic32* ptr, Atomic32 value);
-
-Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
-Atomic32 Acquire_Load(volatile const Atomic32* ptr);
-Atomic32 Release_Load(volatile const Atomic32* ptr);
-
-// 64-bit atomic operations (only available on 64-bit processors).
-#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
-Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value);
-Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
-Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
-Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
-
-Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value);
-Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value);
-void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
-void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
-void Release_Store(volatile Atomic64* ptr, Atomic64 value);
-Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
-Atomic64 Acquire_Load(volatile const Atomic64* ptr);
-Atomic64 Release_Load(volatile const Atomic64* ptr);
-#endif // GOOGLE_PROTOBUF_ARCH_64_BIT
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-// Include our platform specific implementation.
-#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
-"Atomic operations are not supported on your platform"
-
-// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
-#if defined(THREAD_SANITIZER)
-#include <google/protobuf/stubs/atomicops_internals_tsan.h>
-// MSVC.
-#elif defined(_MSC_VER)
-#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) || defined(GOOGLE_PROTOBUF_ARCH_ARM)
-#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
-#else
-#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
-#endif
-
-// Solaris
-#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS)
-#include <google/protobuf/stubs/atomicops_internals_solaris.h>
-
-// AIX
-#elif defined(GOOGLE_PROTOBUF_OS_AIX)
-#include <google/protobuf/stubs/atomicops_internals_power.h>
-
-// GCC.
-#elif defined(__GNUC__)
-#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
-#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
-#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__)
-#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
-#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
-#else
-#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
-#endif
-#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
-#include <google/protobuf/stubs/atomicops_internals_arm64_gcc.h>
-#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
-#include <google/protobuf/stubs/atomicops_internals_arm_qnx.h>
-#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64)
-#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
-#elif defined(GOOGLE_PROTOBUF_ARCH_POWER)
-#include <google/protobuf/stubs/atomicops_internals_power.h>
-#elif defined(__native_client__)
-// The static_asserts in the C++11 atomics implementation cause it to fail
-// with certain compilers, e.g. nvcc on macOS. Don't use elsewhere unless
-// the TODO in that file is addressed.
-#include <google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h>
-#elif defined(GOOGLE_PROTOBUF_ARCH_PPC)
-#include <google/protobuf/stubs/atomicops_internals_ppc_gcc.h>
-#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
-#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
-#elif defined(__clang__)
-#if __has_extension(c_atomic)
-#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
-#else
-#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
-#endif
-#else
-#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
-#endif
-
-// Unknown.
-#else
-#error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
-#endif
-
-// On some platforms we need additional declarations to make AtomicWord
-// compatible with our other Atomic* types.
-#if defined(GOOGLE_PROTOBUF_OS_APPLE)
-#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
-#endif
-
-#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
-
-#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
deleted file mode 100644
index 9a69d21a..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
+++ /dev/null
@@ -1,325 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline void MemoryBarrierInternal() {
- __asm__ __volatile__ ("dmb ish" ::: "memory"); // NOLINT
-}
-
-// NoBarrier versions of the operation include "memory" in the clobber list.
-// This is not required for direct usage of the NoBarrier versions of the
-// operations. However this is required for correctness when they are used as
-// part of the Acquire or Release versions, to ensure that nothing from outside
-// the call is reordered between the operation and the memory barrier. This does
-// not change the code generated, so has no or minimal impact on the
-// NoBarrier operations.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %w[prev], %[ptr] \n\t" // Load the previous value.
- "cmp %w[prev], %w[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
- "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
- "1: \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"IJr" (old_value),
- [new_value]"r" (new_value)
- : "cc", "memory"
- ); // NOLINT
-
- return prev;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- Atomic32 result;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %w[result], %[ptr] \n\t" // Load the previous value.
- "stxr %w[temp], %w[new_value], %[ptr] \n\t" // Try to store the new value.
- "cbnz %w[temp], 0b \n\t" // Retry if it did not work.
- : [result]"=&r" (result),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [new_value]"r" (new_value)
- : "memory"
- ); // NOLINT
-
- return result;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 result;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %w[result], %[ptr] \n\t" // Load the previous value.
- "add %w[result], %w[result], %w[increment]\n\t"
- "stxr %w[temp], %w[result], %[ptr] \n\t" // Try to store the result.
- "cbnz %w[temp], 0b \n\t" // Retry on failure.
- : [result]"=&r" (result),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [increment]"IJr" (increment)
- : "memory"
- ); // NOLINT
-
- return result;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- MemoryBarrierInternal();
- Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment);
- MemoryBarrierInternal();
-
- return result;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
-
- return prev;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- MemoryBarrierInternal();
- Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-
- return prev;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- __asm__ __volatile__ ( // NOLINT
- "stlr %w[value], %[ptr] \n\t"
- : [ptr]"=Q" (*ptr)
- : [value]"r" (value)
- : "memory"
- ); // NOLINT
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value;
-
- __asm__ __volatile__ ( // NOLINT
- "ldar %w[value], %[ptr] \n\t"
- : [value]"=r" (value)
- : [ptr]"Q" (*ptr)
- : "memory"
- ); // NOLINT
-
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-// 64-bit versions of the operations.
-// See the 32-bit versions for comments.
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 prev;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %[prev], %[ptr] \n\t"
- "cmp %[prev], %[old_value] \n\t"
- "bne 1f \n\t"
- "stxr %w[temp], %[new_value], %[ptr] \n\t"
- "cbnz %w[temp], 0b \n\t"
- "1: \n\t"
- : [prev]"=&r" (prev),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [old_value]"IJr" (old_value),
- [new_value]"r" (new_value)
- : "cc", "memory"
- ); // NOLINT
-
- return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- Atomic64 result;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %[result], %[ptr] \n\t"
- "stxr %w[temp], %[new_value], %[ptr] \n\t"
- "cbnz %w[temp], 0b \n\t"
- : [result]"=&r" (result),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [new_value]"r" (new_value)
- : "memory"
- ); // NOLINT
-
- return result;
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 result;
- int32_t temp;
-
- __asm__ __volatile__ ( // NOLINT
- "0: \n\t"
- "ldxr %[result], %[ptr] \n\t"
- "add %[result], %[result], %[increment] \n\t"
- "stxr %w[temp], %[result], %[ptr] \n\t"
- "cbnz %w[temp], 0b \n\t"
- : [result]"=&r" (result),
- [temp]"=&r" (temp),
- [ptr]"+Q" (*ptr)
- : [increment]"IJr" (increment)
- : "memory"
- ); // NOLINT
-
- return result;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- MemoryBarrierInternal();
- Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment);
- MemoryBarrierInternal();
-
- return result;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
-
- return prev;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- MemoryBarrierInternal();
- Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-
- return prev;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- __asm__ __volatile__ ( // NOLINT
- "stlr %x[value], %[ptr] \n\t"
- : [ptr]"=Q" (*ptr)
- : [value]"r" (value)
- : "memory"
- ); // NOLINT
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 value;
-
- __asm__ __volatile__ ( // NOLINT
- "ldar %x[value], %[ptr] \n\t"
- : [value]"=r" (value)
- : [ptr]"Q" (*ptr)
- : "memory"
- ); // NOLINT
-
- return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
deleted file mode 100644
index 6e2de67f..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-//
-// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// 0xffff0fc0 is the hard coded address of a function provided by
-// the kernel which implements an atomic compare-exchange. On older
-// ARM architecture revisions (pre-v6) this may be implemented using
-// a syscall. This address is stable, and in active use (hard coded)
-// by at least glibc-2.7 and the Android C library.
-typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
- Atomic32 new_value,
- volatile Atomic32* ptr);
-LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
- (LinuxKernelCmpxchgFunc) 0xffff0fc0;
-
-typedef void (*LinuxKernelMemoryBarrierFunc)(void);
-LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
- (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
-
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev_value = *ptr;
- do {
- if (!pLinuxKernelCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr))) {
- return old_value;
- }
- prev_value = *ptr;
- } while (prev_value == old_value);
- return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- Atomic32 old_value;
- do {
- old_value = *ptr;
- } while (pLinuxKernelCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr)));
- return old_value;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- for (;;) {
- // Atomic exchange the old value with an incremented one.
- Atomic32 old_value = *ptr;
- Atomic32 new_value = old_value + increment;
- if (pLinuxKernelCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr)) == 0) {
- // The exchange took place as expected.
- return new_value;
- }
- // Otherwise, *ptr changed mid-loop and we need to retry.
- }
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void MemoryBarrierInternal() {
- pLinuxKernelMemoryBarrier();
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- MemoryBarrierInternal();
- *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr;
- MemoryBarrierInternal();
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
deleted file mode 100644
index cd97e0c9..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
-
-// For _smp_cmpxchg()
-#include <pthread.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 QNXCmpxchg(Atomic32 old_value,
- Atomic32 new_value,
- volatile Atomic32* ptr) {
- return static_cast<Atomic32>(
- _smp_cmpxchg((volatile unsigned *)ptr,
- (unsigned)old_value,
- (unsigned)new_value));
-}
-
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev_value = *ptr;
- do {
- if (!QNXCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr))) {
- return old_value;
- }
- prev_value = *ptr;
- } while (prev_value == old_value);
- return prev_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- Atomic32 old_value;
- do {
- old_value = *ptr;
- } while (QNXCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr)));
- return old_value;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- for (;;) {
- // Atomic exchange the old value with an incremented one.
- Atomic32 old_value = *ptr;
- Atomic32 new_value = old_value + increment;
- if (QNXCmpxchg(old_value, new_value,
- const_cast<Atomic32*>(ptr)) == 0) {
- // The exchange took place as expected.
- return new_value;
- }
- // Otherwise, *ptr changed mid-loop and we need to retry.
- }
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void MemoryBarrierInternal() {
- __sync_synchronize();
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- MemoryBarrierInternal();
- *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr;
- MemoryBarrierInternal();
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
deleted file mode 100644
index eb198ff5..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
-
-// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
-// which in turn means int. On some LP32 platforms, intptr_t is an int, but
-// on others, it's a long. When AtomicWord and Atomic32 are based on different
-// fundamental types, their pointers are incompatible.
-//
-// This file defines function overloads to allow both AtomicWord and Atomic32
-// data to be used with this interface.
-//
-// On LP64 platforms, AtomicWord and Atomic64 are both always long,
-// so this problem doesn't occur.
-
-#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return NoBarrier_CompareAndSwap(
- reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
-}
-
-inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
- AtomicWord new_value) {
- return NoBarrier_AtomicExchange(
- reinterpret_cast<volatile Atomic32*>(ptr), new_value);
-}
-
-inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return NoBarrier_AtomicIncrement(
- reinterpret_cast<volatile Atomic32*>(ptr), increment);
-}
-
-inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
- AtomicWord increment) {
- return Barrier_AtomicIncrement(
- reinterpret_cast<volatile Atomic32*>(ptr), increment);
-}
-
-inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return Acquire_CompareAndSwap(
- reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
-}
-
-inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
- AtomicWord old_value,
- AtomicWord new_value) {
- return Release_CompareAndSwap(
- reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
- NoBarrier_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
-}
-
-inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
- return Acquire_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
-}
-
-inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
- return Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
-}
-
-inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
- return NoBarrier_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
-}
-
-inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
- return Acquire_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
-}
-
-inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
- return Release_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h b/src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h
deleted file mode 100644
index 44ef9c9e..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_generic_c11_atomic.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
-
-#include <atomic>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// This implementation is transitional and maintains the original API for
-// atomicops.h. This requires casting memory locations to the atomic types, and
-// assumes that the API and the C++11 implementation are layout-compatible,
-// which isn't true for all implementations or hardware platforms. The static
-// assertion should detect this issue, were it to fire then this header
-// shouldn't be used.
-//
-// TODO(jfb) If this header manages to stay committed then the API should be
-// modified, and all call sites updated.
-typedef volatile std::atomic<Atomic32>* AtomicLocation32;
-static_assert(sizeof(*(AtomicLocation32) nullptr) == sizeof(Atomic32),
- "incompatible 32-bit atomic layout");
-
-inline void MemoryBarrierInternal() {
-#if defined(__GLIBCXX__)
- // Work around libstdc++ bug 51038 where atomic_thread_fence was declared but
- // not defined, leading to the linker complaining about undefined references.
- __atomic_thread_fence(std::memory_order_seq_cst);
-#else
- std::atomic_thread_fence(std::memory_order_seq_cst);
-#endif
-}
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- ((AtomicLocation32)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_relaxed,
- std::memory_order_relaxed);
- return old_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- return ((AtomicLocation32)ptr)
- ->exchange(new_value, std::memory_order_relaxed);
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return increment +
- ((AtomicLocation32)ptr)
- ->fetch_add(increment, std::memory_order_relaxed);
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return increment + ((AtomicLocation32)ptr)->fetch_add(increment);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- ((AtomicLocation32)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_acquire,
- std::memory_order_acquire);
- return old_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- ((AtomicLocation32)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_release,
- std::memory_order_relaxed);
- return old_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed);
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed);
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- ((AtomicLocation32)ptr)->store(value, std::memory_order_release);
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed);
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- return ((AtomicLocation32)ptr)->load(std::memory_order_acquire);
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed);
-}
-
-#if defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
-
-typedef volatile std::atomic<Atomic64>* AtomicLocation64;
-static_assert(sizeof(*(AtomicLocation64) nullptr) == sizeof(Atomic64),
- "incompatible 64-bit atomic layout");
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- ((AtomicLocation64)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_relaxed,
- std::memory_order_relaxed);
- return old_value;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- return ((AtomicLocation64)ptr)
- ->exchange(new_value, std::memory_order_relaxed);
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return increment +
- ((AtomicLocation64)ptr)
- ->fetch_add(increment, std::memory_order_relaxed);
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return increment + ((AtomicLocation64)ptr)->fetch_add(increment);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- ((AtomicLocation64)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_acquire,
- std::memory_order_acquire);
- return old_value;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- ((AtomicLocation64)ptr)
- ->compare_exchange_strong(old_value,
- new_value,
- std::memory_order_release,
- std::memory_order_relaxed);
- return old_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed);
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed);
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- ((AtomicLocation64)ptr)->store(value, std::memory_order_release);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- return ((AtomicLocation64)ptr)->load(std::memory_order_acquire);
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- MemoryBarrierInternal();
- return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed);
-}
-
-#endif // defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_C11_ATOMIC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
deleted file mode 100644
index 0b0b06ce..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2013 Red Hat Inc. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Red Hat Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
- __ATOMIC_RELAXED, __ATOMIC_RELAXED);
- return old_value;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
- __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
- return old_value;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
- __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
- return old_value;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
-}
-
-inline void MemoryBarrierInternal() {
- __sync_synchronize();
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST);
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return __atomic_load_n(ptr, __ATOMIC_RELAXED);
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
-}
-
-#ifdef __LP64__
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
- __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
- return old_value;
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- __atomic_compare_exchange_n(ptr, &old_value, new_value, false,
- __ATOMIC_RELAXED, __ATOMIC_RELAXED);
- return old_value;
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return __atomic_load_n(ptr, __ATOMIC_RELAXED);
-}
-
-#endif // defined(__LP64__)
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
deleted file mode 100644
index 6ce6820e..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
+++ /dev/null
@@ -1,313 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// Atomically execute:
-// result = *ptr;
-// if (*ptr == old_value)
-// *ptr = new_value;
-// return result;
-//
-// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
-// Always return the old value of "*ptr"
-//
-// This routine implies no memory barriers.
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev, tmp;
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "ll %0, %5\n" // prev = *ptr
- "bne %0, %3, 2f\n" // if (prev != old_value) goto 2
- "move %2, %4\n" // tmp = new_value
- "sc %2, %1\n" // *ptr = tmp (with atomic check)
- "beqz %2, 1b\n" // start again on atomic error
- "nop\n" // delay slot nop
- "2:\n"
- ".set pop\n"
- : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
- : "r" (old_value), "r" (new_value), "m" (*ptr)
- : "memory");
- return prev;
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr. This routine implies no memory barriers.
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- Atomic32 temp, old;
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "ll %1, %4\n" // old = *ptr
- "move %0, %3\n" // temp = new_value
- "sc %0, %2\n" // *ptr = temp (with atomic check)
- "beqz %0, 1b\n" // start again on atomic error
- "nop\n" // delay slot nop
- ".set pop\n"
- : "=&r" (temp), "=&r" (old), "=m" (*ptr)
- : "r" (new_value), "m" (*ptr)
- : "memory");
-
- return old;
-}
-
-// Atomically increment *ptr by "increment". Returns the new value of
-// *ptr with the increment applied. This routine implies no memory barriers.
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 temp, temp2;
-
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "ll %0, %4\n" // temp = *ptr
- "addu %1, %0, %3\n" // temp2 = temp + increment
- "sc %1, %2\n" // *ptr = temp2 (with atomic check)
- "beqz %1, 1b\n" // start again on atomic error
- "addu %1, %0, %3\n" // temp2 = temp + increment
- ".set pop\n"
- : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
- : "Ir" (increment), "m" (*ptr)
- : "memory");
- // temp2 now holds the final value.
- return temp2;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- ATOMICOPS_COMPILER_BARRIER();
- Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
- ATOMICOPS_COMPILER_BARRIER();
- return res;
-}
-
-// "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation. "Barrier" operations have both "Acquire" and "Release"
-// semantics. A MemoryBarrierInternal() has "Barrier" semantics, but does no
-// memory access.
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- ATOMICOPS_COMPILER_BARRIER();
- Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- ATOMICOPS_COMPILER_BARRIER();
- return res;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- ATOMICOPS_COMPILER_BARRIER();
- Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- ATOMICOPS_COMPILER_BARRIER();
- return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void MemoryBarrierInternal() {
- __asm__ __volatile__("sync" : : : "memory");
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- MemoryBarrierInternal();
- *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr;
- MemoryBarrierInternal();
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-#if defined(__LP64__)
-// 64-bit versions of the atomic ops.
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 prev, tmp;
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "lld %0, %5\n" // prev = *ptr
- "bne %0, %3, 2f\n" // if (prev != old_value) goto 2
- "move %2, %4\n" // tmp = new_value
- "scd %2, %1\n" // *ptr = tmp (with atomic check)
- "beqz %2, 1b\n" // start again on atomic error
- "nop\n" // delay slot nop
- "2:\n"
- ".set pop\n"
- : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
- : "r" (old_value), "r" (new_value), "m" (*ptr)
- : "memory");
- return prev;
-}
-
-// Atomically store new_value into *ptr, returning the previous value held in
-// *ptr. This routine implies no memory barriers.
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- Atomic64 temp, old;
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "lld %1, %4\n" // old = *ptr
- "move %0, %3\n" // temp = new_value
- "scd %0, %2\n" // *ptr = temp (with atomic check)
- "beqz %0, 1b\n" // start again on atomic error
- "nop\n" // delay slot nop
- ".set pop\n"
- : "=&r" (temp), "=&r" (old), "=m" (*ptr)
- : "r" (new_value), "m" (*ptr)
- : "memory");
-
- return old;
-}
-
-// Atomically increment *ptr by "increment". Returns the new value of
-// *ptr with the increment applied. This routine implies no memory barriers.
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 temp, temp2;
-
- __asm__ __volatile__(".set push\n"
- ".set noreorder\n"
- "1:\n"
- "lld %0, %4\n" // temp = *ptr
- "daddu %1, %0, %3\n" // temp2 = temp + increment
- "scd %1, %2\n" // *ptr = temp2 (with atomic check)
- "beqz %1, 1b\n" // start again on atomic error
- "daddu %1, %0, %3\n" // temp2 = temp + increment
- ".set pop\n"
- : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
- : "Ir" (increment), "m" (*ptr)
- : "memory");
- // temp2 now holds the final value.
- return temp2;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- MemoryBarrierInternal();
- Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment);
- MemoryBarrierInternal();
- return res;
-}
-
-// "Acquire" operations
-// ensure that no later memory access can be reordered ahead of the operation.
-// "Release" operations ensure that no previous memory access can be reordered
-// after the operation. "Barrier" operations have both "Acquire" and "Release"
-// semantics. A MemoryBarrierInternal() has "Barrier" semantics, but does no
-// memory access.
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
- return res;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- MemoryBarrierInternal();
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- MemoryBarrierInternal();
- *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 value = *ptr;
- MemoryBarrierInternal();
- return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-#endif
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_power.h b/src/google/protobuf/stubs/atomicops_internals_power.h
deleted file mode 100644
index cad9f1e3..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_power.h
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2014 Bloomberg Finance LP. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Bloomberg Finance LP. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 result;
-
- asm volatile (
- "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpw %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
- " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
- " bne- 1b \n\t"
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- Atomic32 result;
-
- asm volatile (
- "1: lwarx %[res], %[zero], %[obj] \n\t"
- " stwcx. %[val], %[zero], %[obj] \n\t"
- " bne- 1b \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 result;
-
- asm volatile (
- "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " add %[res], %[val], %[res] \n\t" // add the operand
- " stwcx. %[res], %[zero], %[obj] \n\t" // store old value
- // if still reserved
- " bne- 1b \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (increment),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline void MemoryBarrierInternal(void) {
- asm volatile (
- " lwsync \n\t"
- " isync \n\t"
- :
- :
- : "memory");
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " add %[res], %[val], %[res] \n\t" // add the operand
- " stwcx. %[res], %[zero], %[obj] \n\t" // store old value
- // if still reserved
- " bne- 1b \n\t"
- " isync \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (increment),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 result;
-
- asm volatile (
- "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpw %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
- " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
- " bne- 1b \n\t"
-
- " isync \n\t"
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpw %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
- " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
- " bne- 1b \n\t"
-
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- asm volatile (
- " stw %[val], %[obj] \n\t"
- " isync \n\t"
- : [obj] "=m" (*ptr)
- : [val] "b" (value));
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- asm volatile (
- " lwsync \n\t"
- " stw %[val], %[obj] \n\t"
- : [obj] "=m" (*ptr)
- : [val] "b" (value));
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 result;
-
- asm volatile (
- "1: lwz %[res], %[obj] \n\t"
- " cmpw %[res], %[res] \n\t" // create data
- // dependency for
- // load/load ordering
- " bne- 1b \n\t" // never taken
-
- " isync \n\t"
- : [res] "=b" (result)
- : [obj] "m" (*ptr),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- Atomic32 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: lwz %[res], %[obj] \n\t"
- " cmpw %[res], %[res] \n\t" // create data
- // dependency for
- // load/load ordering
- " bne- 1b \n\t" // never taken
- : [res] "=b" (result)
- : [obj] "m" (*ptr),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 result;
-
- asm volatile (
- "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpd %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
-
- " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
- " bne- 1b \n\t"
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- Atomic64 result;
-
- asm volatile (
- "1: ldarx %[res], %[zero], %[obj] \n\t"
- " stdcx. %[val], %[zero], %[obj] \n\t"
- " bne- 1b \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 result;
-
- asm volatile (
- "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " add %[res], %[res], %[val] \n\t" // add the operand
- " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if
- // still reserved
-
- " bne- 1b \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (increment),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
-
- Atomic64 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " add %[res], %[res], %[val] \n\t" // add the operand
- " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if
- // still reserved
-
- " bne- 1b \n\t"
-
- " isync \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [val] "b" (increment),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 result;
-
- asm volatile (
- "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpd %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
-
- " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
- " bne- 1b \n\t"
- " isync \n\t"
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
- " cmpd %[cmp], %[res] \n\t" // compare values
- " bne- 2f \n\t"
-
- " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
- " bne- 1b \n\t"
- "2: \n\t"
- : [res] "=&b" (result)
- : [obj] "b" (ptr),
- [cmp] "b" (old_value),
- [val] "b" (new_value),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- asm volatile (
- " std %[val], %[obj] \n\t"
- " isync \n\t"
- : [obj] "=m" (*ptr)
- : [val] "b" (value));
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- asm volatile (
- " lwsync \n\t"
- " std %[val], %[obj] \n\t"
- : [obj] "=m" (*ptr)
- : [val] "b" (value));
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 result;
-
- asm volatile (
- "1: ld %[res], %[obj] \n\t"
- " cmpd %[res], %[res] \n\t" // create data
- // dependency for
- // load/load ordering
- " bne- 1b \n\t" // never taken
-
- " isync \n\t"
- : [res] "=b" (result)
- : [obj] "m" (*ptr),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- Atomic64 result;
-
- asm volatile (
- " lwsync \n\t"
-
- "1: ld %[res], %[obj] \n\t"
- " cmpd %[res], %[res] \n\t" // create data
- // dependency for
- // load/load ordering
- " bne- 1b \n\t" // never taken
- : [res] "=b" (result)
- : [obj] "m" (*ptr),
- [zero] "i" (0)
- : "cr0", "ctr");
-
- return result;
-}
-#endif
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h b/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h
deleted file mode 100644
index d477dc6d..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2015 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: ogabbay@advaoptical.com (Oded Gabbay)
-// Cleaned up by: bsilver16384@gmail.com (Brian Silverman)
-//
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev;
-
- __asm__ __volatile__(
- "0: \n\t"
- "lwarx %[prev],0,%[ptr] \n\t"
- "cmpw 0,%[prev],%[old_value] \n\t"
- "bne- 1f \n\t"
- "stwcx. %[new_value],0,%[ptr] \n\t"
- "bne- 0b \n\t"
- "1: \n\t"
- : [prev] "=&r"(prev), "+m"(*ptr)
- : [ptr] "r"(ptr), [old_value] "r"(old_value), [new_value] "r"(new_value)
- : "cc", "memory");
-
- return prev;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
- Atomic32 new_value) {
- Atomic32 old;
-
- __asm__ __volatile__(
- "0: \n\t"
- "lwarx %[old],0,%[ptr] \n\t"
- "stwcx. %[new_value],0,%[ptr] \n\t"
- "bne- 0b \n\t"
- : [old] "=&r"(old), "+m"(*ptr)
- : [ptr] "r"(ptr), [new_value] "r"(new_value)
- : "cc", "memory");
-
- return old;
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- Atomic32 temp;
-
- __asm__ __volatile__(
- "0: \n\t"
- "lwarx %[temp],0,%[ptr] \n\t"
- "add %[temp],%[increment],%[temp] \n\t"
- "stwcx. %[temp],0,%[ptr] \n\t"
- "bne- 0b \n\t"
- : [temp] "=&r"(temp)
- : [increment] "r"(increment), [ptr] "r"(ptr)
- : "cc", "memory");
-
- return temp;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- MemoryBarrierInternal();
- Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
- MemoryBarrierInternal();
- return res;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value, Atomic32 new_value) {
- Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
- return res;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value, Atomic32 new_value) {
- MemoryBarrierInternal();
- Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- return res;
-}
-
-inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void MemoryBarrierInternal() { __asm__ __volatile__("sync" : : : "memory"); }
-
-inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
- MemoryBarrierInternal();
- *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) { return *ptr; }
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
- Atomic32 value = *ptr;
- MemoryBarrierInternal();
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_solaris.h b/src/google/protobuf/stubs/atomicops_internals_solaris.h
deleted file mode 100644
index baecb993..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_solaris.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2014 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
-
-#include <atomic.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value);
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value);
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment);
-}
-
-inline void MemoryBarrierInternal(void) {
- membar_producer();
- membar_consumer();
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- MemoryBarrierInternal();
- Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment);
- MemoryBarrierInternal();
-
- return ret;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
-
- return ret;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- MemoryBarrierInternal();
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- membar_producer();
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- membar_consumer();
- *ptr = value;
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 val = *ptr;
- membar_consumer();
- return val;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- membar_producer();
- return *ptr;
-}
-
-#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value);
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) {
- return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value);
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
- return atomic_add_64_nv((volatile uint64_t*)ptr, increment);
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
- MemoryBarrierInternal();
- Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment);
- MemoryBarrierInternal();
- return ret;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- MemoryBarrierInternal();
- return ret;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- MemoryBarrierInternal();
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
- membar_producer();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- membar_consumer();
- *ptr = value;
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 ret = *ptr;
- membar_consumer();
- return ret;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- membar_producer();
- return *ptr;
-}
-#endif
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
-
diff --git a/src/google/protobuf/stubs/atomicops_internals_tsan.h b/src/google/protobuf/stubs/atomicops_internals_tsan.h
deleted file mode 100644
index 676380b1..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_tsan.h
+++ /dev/null
@@ -1,219 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2013 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation for compiler-based
-// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html).
-// Use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-#include <sanitizer/tsan_interface_atomic.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 cmp = old_value;
- __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
- return cmp;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
- Atomic32 new_value) {
- return __tsan_atomic32_exchange(ptr, new_value,
- __tsan_memory_order_relaxed);
-}
-
-inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
- Atomic32 new_value) {
- return __tsan_atomic32_exchange(ptr, new_value,
- __tsan_memory_order_acquire);
-}
-
-inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
- Atomic32 new_value) {
- return __tsan_atomic32_exchange(ptr, new_value,
- __tsan_memory_order_release);
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return increment + __tsan_atomic32_fetch_add(ptr, increment,
- __tsan_memory_order_relaxed);
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
- Atomic32 increment) {
- return increment + __tsan_atomic32_fetch_add(ptr, increment,
- __tsan_memory_order_acq_rel);
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 cmp = old_value;
- __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_acquire, __tsan_memory_order_acquire);
- return cmp;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 cmp = old_value;
- __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_release, __tsan_memory_order_relaxed);
- return cmp;
-}
-
-inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
- __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
-}
-
-inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
- __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
- __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
-}
-
-inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
- __tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
- return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
- return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire);
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
- __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
- return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
-}
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 cmp = old_value;
- __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
- return cmp;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
- Atomic64 new_value) {
- return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed);
-}
-
-inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
- Atomic64 new_value) {
- return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire);
-}
-
-inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
- Atomic64 new_value) {
- return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release);
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return increment + __tsan_atomic64_fetch_add(ptr, increment,
- __tsan_memory_order_relaxed);
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
- Atomic64 increment) {
- return increment + __tsan_atomic64_fetch_add(ptr, increment,
- __tsan_memory_order_acq_rel);
-}
-
-inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
- __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
-}
-
-inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
- __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
- __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
-}
-
-inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
- __tsan_atomic64_store(ptr, value, __tsan_memory_order_release);
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
- return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
- return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire);
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
- __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
- return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 cmp = old_value;
- __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_acquire, __tsan_memory_order_acquire);
- return cmp;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 cmp = old_value;
- __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
- __tsan_memory_order_release, __tsan_memory_order_relaxed);
- return cmp;
-}
-
-inline void MemoryBarrierInternal() {
- __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
-}
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
deleted file mode 100644
index 53c9eae0..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This module gets enough CPU information to optimize the
-// atomicops module on x86.
-
-#include <cstring>
-
-#include <google/protobuf/stubs/atomicops.h>
-
-// This file only makes sense with atomicops_internals_x86_gcc.h -- it
-// depends on structs that are defined in that file. If atomicops.h
-// doesn't sub-include that file, then we aren't needed, and shouldn't
-// try to do anything.
-#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
-
-// Inline cpuid instruction. In PIC compilations, %ebx contains the address
-// of the global offset table. To avoid breaking such executables, this code
-// must preserve that register's value across cpuid instructions.
-#if defined(__i386__)
-#define cpuid(a, b, c, d, inp) \
- asm("mov %%ebx, %%edi\n" \
- "cpuid\n" \
- "xchg %%edi, %%ebx\n" \
- : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#elif defined(__x86_64__)
-#define cpuid(a, b, c, d, inp) \
- asm("mov %%rbx, %%rdi\n" \
- "cpuid\n" \
- "xchg %%rdi, %%rbx\n" \
- : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
-#endif
-
-#if defined(cpuid) // initialize the struct only on x86
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// Set the flags so that code will run correctly and conservatively, so even
-// if we haven't been initialized yet, we're probably single threaded, and our
-// default values should hopefully be pretty safe.
-struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
- false, // bug can't exist before process spawns multiple threads
- false, // no SSE2
-};
-
-namespace {
-
-// Initialize the AtomicOps_Internalx86CPUFeatures struct.
-void AtomicOps_Internalx86CPUFeaturesInit() {
- uint32_t eax;
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
-
- // Get vendor string (issue CPUID with eax = 0)
- cpuid(eax, ebx, ecx, edx, 0);
- char vendor[13];
- memcpy(vendor, &ebx, 4);
- memcpy(vendor + 4, &edx, 4);
- memcpy(vendor + 8, &ecx, 4);
- vendor[12] = 0;
-
- // get feature flags in ecx/edx, and family/model in eax
- cpuid(eax, ebx, ecx, edx, 1);
-
- int family = (eax >> 8) & 0xf; // family and model fields
- int model = (eax >> 4) & 0xf;
- if (family == 0xf) { // use extended family and model fields
- family += (eax >> 20) & 0xff;
- model += ((eax >> 16) & 0xf) << 4;
- }
-
- // Opteron Rev E has a bug in which on very rare occasions a locked
- // instruction doesn't act as a read-acquire barrier if followed by a
- // non-locked read-modify-write instruction. Rev F has this bug in
- // pre-release versions, but not in versions released to customers,
- // so we test only for Rev E, which is family 15, model 32..63 inclusive.
- if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
- family == 15 &&
- 32 <= model && model <= 63) {
- AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
- } else {
- AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
- }
-
- // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
- AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
-}
-
-class AtomicOpsx86Initializer {
- public:
- AtomicOpsx86Initializer() {
- AtomicOps_Internalx86CPUFeaturesInit();
- }
-};
-
-// A global to get use initialized on startup via static initialization :/
-AtomicOpsx86Initializer g_initer;
-
-} // namespace
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // __i386__
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
deleted file mode 100644
index e80121fd..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
+++ /dev/null
@@ -1,293 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// This struct is not part of the public API of this module; clients may not
-// use it.
-// Features of this x86. Values may not be correct before main() is run,
-// but are set conservatively.
-struct AtomicOps_x86CPUFeatureStruct {
- bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
- // after acquire compare-and-swap.
- bool has_sse2; // Processor has SSE2.
-};
-extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
-
-#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
-
-// 32-bit low-level operations on any platform.
-
-inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 prev;
- __asm__ __volatile__("lock; cmpxchgl %1,%2"
- : "=a" (prev)
- : "q" (new_value), "m" (*ptr), "0" (old_value)
- : "memory");
- return prev;
-}
-
-inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
- : "=r" (new_value)
- : "m" (*ptr), "0" (new_value)
- : "memory");
- return new_value; // Now it's the previous value.
-}
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 temp = increment;
- __asm__ __volatile__("lock; xaddl %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now holds the old value of *ptr
- return temp + increment;
-}
-
-inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- Atomic32 temp = increment;
- __asm__ __volatile__("lock; xaddl %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now holds the old value of *ptr
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return temp + increment;
-}
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return x;
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit implementations of memory barrier can be simpler, because it
-// "mfence" is guaranteed to exist.
-inline void MemoryBarrierInternal() {
- __asm__ __volatile__("mfence" : : : "memory");
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-#else
-
-inline void MemoryBarrierInternal() {
- if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
- __asm__ __volatile__("mfence" : : : "memory");
- } else { // mfence is faster but not present on PIII
- Atomic32 x = 0;
- NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII
- }
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
- *ptr = value;
- __asm__ __volatile__("mfence" : : : "memory");
- } else {
- NoBarrier_AtomicExchange(ptr, value);
- // acts as a barrier on PIII
- }
-}
-#endif
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- ATOMICOPS_COMPILER_BARRIER();
- *ptr = value; // An x86 store acts as a release barrier.
- // See comments in Atomic64 version of Release_Store(), below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
- // See comments in Atomic64 version of Release_Store(), below.
- ATOMICOPS_COMPILER_BARRIER();
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-#if defined(__x86_64__)
-
-// 64-bit low-level operations on 64-bit platform.
-
-inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 prev;
- __asm__ __volatile__("lock; cmpxchgq %1,%2"
- : "=a" (prev)
- : "q" (new_value), "m" (*ptr), "0" (old_value)
- : "memory");
- return prev;
-}
-
-inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg.
- : "=r" (new_value)
- : "m" (*ptr), "0" (new_value)
- : "memory");
- return new_value; // Now it's the previous value.
-}
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 temp = increment;
- __asm__ __volatile__("lock; xaddq %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now contains the previous value of *ptr
- return temp + increment;
-}
-
-inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- Atomic64 temp = increment;
- __asm__ __volatile__("lock; xaddq %0,%1"
- : "+r" (temp), "+m" (*ptr)
- : : "memory");
- // temp now contains the previous value of *ptr
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return temp + increment;
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
- MemoryBarrierInternal();
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- ATOMICOPS_COMPILER_BARRIER();
-
- *ptr = value; // An x86 store acts as a release barrier
- // for current AMD/Intel chips as of Jan 2008.
- // See also Acquire_Load(), below.
-
- // When new chips come out, check:
- // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
- // System Programming Guide, Chatper 7: Multiple-processor management,
- // Section 7.2, Memory Ordering.
- // Last seen at:
- // http://developer.intel.com/design/pentium4/manuals/index_new.htm
- //
- // x86 stores/loads fail to act as barriers for a few instructions (clflush
- // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
- // not generated by the compiler, and are rare. Users of these instructions
- // need to know about cache behaviour in any case since all of these involve
- // either flushing cache lines or non-temporal cache hints.
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
- // for current AMD/Intel chips as of Jan 2008.
- // See also Release_Store(), above.
- ATOMICOPS_COMPILER_BARRIER();
- return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
- if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
- __asm__ __volatile__("lfence" : : : "memory");
- }
- return x;
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-#endif // defined(__x86_64__)
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#undef ATOMICOPS_COMPILER_BARRIER
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
deleted file mode 100644
index 74a1bd4e..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The compilation of extension_set.cc fails when windows.h is included.
-// Therefore we move the code depending on windows.h to this separate cc file.
-
-// Don't compile this file for people not concerned about thread safety.
-#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
-#include <google/protobuf/stubs/atomicops.h>
-
-#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
-
-#include <windows.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline void MemoryBarrierInternal() {
- // On ARM this is a define while on x86/x64 this is
- // a function declared in WinNT.h
- MemoryBarrier();
-}
-
-Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- LONG result = InterlockedCompareExchange(
- reinterpret_cast<volatile LONG*>(ptr),
- static_cast<LONG>(new_value),
- static_cast<LONG>(old_value));
- return static_cast<Atomic32>(result);
-}
-
-Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
- Atomic32 new_value) {
- LONG result = InterlockedExchange(
- reinterpret_cast<volatile LONG*>(ptr),
- static_cast<LONG>(new_value));
- return static_cast<Atomic32>(result);
-}
-
-Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return InterlockedExchangeAdd(
- reinterpret_cast<volatile LONG*>(ptr),
- static_cast<LONG>(increment)) + increment;
-}
-
-#if defined(_WIN64)
-
-// 64-bit low-level operations on 64-bit platform.
-
-Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- PVOID result = InterlockedCompareExchangePointer(
- reinterpret_cast<volatile PVOID*>(ptr),
- reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
- return reinterpret_cast<Atomic64>(result);
-}
-
-Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
- Atomic64 new_value) {
- PVOID result = InterlockedExchangePointer(
- reinterpret_cast<volatile PVOID*>(ptr),
- reinterpret_cast<PVOID>(new_value));
- return reinterpret_cast<Atomic64>(result);
-}
-
-Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return InterlockedExchangeAdd64(
- reinterpret_cast<volatile LONGLONG*>(ptr),
- static_cast<LONGLONG>(increment)) + increment;
-}
-
-#endif // defined(_WIN64)
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
-#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
deleted file mode 100644
index 34d60d98..00000000
--- a/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
+++ /dev/null
@@ -1,150 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2012 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This file is an internal atomic implementation, use atomicops.h instead.
-
-#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
-#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
- Atomic32 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
-#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
-#error "We require at least vs2005 for MemoryBarrier"
-#endif
-
-inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
- Atomic32 old_value,
- Atomic32 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
- NoBarrier_AtomicExchange(ptr, value);
- // acts as a barrier in this implementation
-}
-
-inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
- *ptr = value; // works w/o barrier for current Intel chips as of June 2005
- // See comments in Atomic64 version of Release_Store() below.
-}
-
-inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
- return *ptr;
-}
-
-inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
- Atomic32 value = *ptr;
- return value;
-}
-
-inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-#if defined(_WIN64)
-
-// 64-bit low-level operations on 64-bit platform.
-
-inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
- Atomic64 increment) {
- return Barrier_AtomicIncrement(ptr, increment);
-}
-
-inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value;
-}
-
-inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
- NoBarrier_AtomicExchange(ptr, value);
- // acts as a barrier in this implementation
-}
-
-inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
- *ptr = value; // works w/o barrier for current Intel chips as of June 2005
-
- // When new chips come out, check:
- // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
- // System Programming Guide, Chatper 7: Multiple-processor management,
- // Section 7.2, Memory Ordering.
- // Last seen at:
- // http://developer.intel.com/design/pentium4/manuals/index_new.htm
-}
-
-inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
- return *ptr;
-}
-
-inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
- Atomic64 value = *ptr;
- return value;
-}
-
-inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
- MemoryBarrierInternal();
- return *ptr;
-}
-
-inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
- Atomic64 old_value,
- Atomic64 new_value) {
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
-}
-
-#endif // defined(_WIN64)
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h
index 86510d14..cfa19f29 100644
--- a/src/google/protobuf/stubs/bytestream.h
+++ b/src/google/protobuf/stubs/bytestream.h
@@ -57,7 +57,6 @@
#include <google/protobuf/stubs/stringpiece.h>
class CordByteSink;
-class MemBlock;
namespace google {
namespace protobuf {
@@ -162,7 +161,7 @@ class LIBPROTOBUF_EXPORT ByteSource {
class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink {
public:
explicit UncheckedArrayByteSink(char* dest) : dest_(dest) {}
- virtual void Append(const char* data, size_t n);
+ virtual void Append(const char* data, size_t n) override;
// Returns the current output pointer so that a caller can see how many bytes
// were produced.
@@ -190,7 +189,7 @@ class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink {
class LIBPROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink {
public:
CheckedArrayByteSink(char* outbuf, size_t capacity);
- virtual void Append(const char* bytes, size_t n);
+ virtual void Append(const char* bytes, size_t n) override;
// Returns the number of bytes actually written to the sink.
size_t NumberOfBytesWritten() const { return size_; }
@@ -227,7 +226,7 @@ class LIBPROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink {
public:
explicit GrowingArrayByteSink(size_t estimated_size);
virtual ~GrowingArrayByteSink();
- virtual void Append(const char* bytes, size_t n);
+ virtual void Append(const char* bytes, size_t n) override;
// Returns the allocated buffer, and sets nbytes to its size. The caller takes
// ownership of the buffer and must delete it with delete[].
@@ -256,7 +255,7 @@ class LIBPROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink {
class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink {
public:
explicit StringByteSink(string* dest) : dest_(dest) {}
- virtual void Append(const char* data, size_t n);
+ virtual void Append(const char* data, size_t n) override;
private:
string* dest_;
@@ -273,7 +272,7 @@ class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink {
class LIBPROTOBUF_EXPORT NullByteSink : public ByteSink {
public:
NullByteSink() {}
- virtual void Append(const char *data, size_t n) {}
+ virtual void Append(const char *data, size_t n) override {}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NullByteSink);
@@ -296,9 +295,9 @@ class LIBPROTOBUF_EXPORT ArrayByteSource : public ByteSource {
public:
explicit ArrayByteSource(StringPiece s) : input_(s) {}
- virtual size_t Available() const;
- virtual StringPiece Peek();
- virtual void Skip(size_t n);
+ virtual size_t Available() const override;
+ virtual StringPiece Peek() override;
+ virtual void Skip(size_t n) override;
private:
StringPiece input_;
@@ -328,13 +327,13 @@ class LIBPROTOBUF_EXPORT LimitByteSource : public ByteSource {
// Returns at most "limit" bytes from "source".
LimitByteSource(ByteSource* source, size_t limit);
- virtual size_t Available() const;
- virtual StringPiece Peek();
- virtual void Skip(size_t n);
+ virtual size_t Available() const override;
+ virtual StringPiece Peek() override;
+ virtual void Skip(size_t n) override;
// We override CopyTo so that we can forward to the underlying source, in
// case it has an efficient implementation of CopyTo.
- virtual void CopyTo(ByteSink* sink, size_t n);
+ virtual void CopyTo(ByteSink* sink, size_t n) override;
private:
ByteSource* source_;
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index 9ec04979..dae972f2 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -1,8 +1,9 @@
#ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
#define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_
+#include <type_traits>
+
#include <google/protobuf/stubs/macros.h>
-#include <google/protobuf/stubs/type_traits.h>
// ===================================================================
// emulates google3/base/callback.h
@@ -124,7 +125,7 @@ class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
: function_(function), self_deleting_(self_deleting) {}
~FunctionClosure0();
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
function_();
if (needs_delete) delete this;
@@ -144,7 +145,7 @@ class MethodClosure0 : public Closure {
: object_(object), method_(method), self_deleting_(self_deleting) {}
~MethodClosure0() {}
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)();
if (needs_delete) delete this;
@@ -167,7 +168,7 @@ class FunctionClosure1 : public Closure {
arg1_(arg1) {}
~FunctionClosure1() {}
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_);
if (needs_delete) delete this;
@@ -190,7 +191,7 @@ class MethodClosure1 : public Closure {
arg1_(arg1) {}
~MethodClosure1() {}
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_);
if (needs_delete) delete this;
@@ -214,7 +215,7 @@ class FunctionClosure2 : public Closure {
arg1_(arg1), arg2_(arg2) {}
~FunctionClosure2() {}
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
function_(arg1_, arg2_);
if (needs_delete) delete this;
@@ -238,7 +239,7 @@ class MethodClosure2 : public Closure {
arg1_(arg1), arg2_(arg2) {}
~MethodClosure2() {}
- void Run() {
+ void Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
(object_->*method_)(arg1_, arg2_);
if (needs_delete) delete this;
@@ -261,7 +262,7 @@ class FunctionResultCallback_0_0 : public ResultCallback<R> {
: function_(function), self_deleting_(self_deleting) {}
~FunctionResultCallback_0_0() {}
- R Run() {
+ R Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
R result = function_();
if (needs_delete) delete this;
@@ -283,7 +284,7 @@ class FunctionResultCallback_1_0 : public ResultCallback<R> {
: function_(function), self_deleting_(self_deleting), p1_(p1) {}
~FunctionResultCallback_1_0() {}
- R Run() {
+ R Run() override {
bool needs_delete = self_deleting_; // read in case callback deletes
R result = function_(p1_);
if (needs_delete) delete this;
@@ -305,7 +306,7 @@ class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
: function_(function), self_deleting_(self_deleting) {}
~FunctionResultCallback_0_1() {}
- R Run(Arg1 a1) {
+ R Run(Arg1 a1) override {
bool needs_delete = self_deleting_; // read in case callback deletes
R result = function_(a1);
if (needs_delete) delete this;
@@ -327,7 +328,7 @@ class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
: function_(function), self_deleting_(self_deleting), p1_(p1) {}
~FunctionResultCallback_1_1() {}
- R Run(A1 a1) {
+ R Run(A1 a1) override {
bool needs_delete = self_deleting_; // read in case callback deletes
R result = function_(p1_, a1);
if (needs_delete) delete this;
@@ -342,7 +343,7 @@ class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> {
template <typename T>
struct InternalConstRef {
- typedef typename remove_reference<T>::type base_type;
+ typedef typename std::remove_reference<T>::type base_type;
typedef const base_type& type;
};
@@ -386,7 +387,7 @@ class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
p5_(p5) {}
~MethodResultCallback_5_2() {}
- R Run(A1 a1, A2 a2) {
+ R Run(A1 a1, A2 a2) override {
bool needs_delete = self_deleting_;
R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2);
if (needs_delete) delete this;
@@ -397,11 +398,11 @@ class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
T* object_;
MethodType method_;
bool self_deleting_;
- typename remove_reference<P1>::type p1_;
- typename remove_reference<P2>::type p2_;
- typename remove_reference<P3>::type p3_;
- typename remove_reference<P4>::type p4_;
- typename remove_reference<P5>::type p5_;
+ typename std::remove_reference<P1>::type p1_;
+ typename std::remove_reference<P2>::type p2_;
+ typename std::remove_reference<P3>::type p3_;
+ typename std::remove_reference<P4>::type p4_;
+ typename std::remove_reference<P5>::type p5_;
};
} // namespace internal
diff --git a/src/google/protobuf/stubs/casts.h b/src/google/protobuf/stubs/casts.h
index be652849..35e2dba0 100644
--- a/src/google/protobuf/stubs/casts.h
+++ b/src/google/protobuf/stubs/casts.h
@@ -31,8 +31,9 @@
#ifndef GOOGLE_PROTOBUF_CASTS_H__
#define GOOGLE_PROTOBUF_CASTS_H__
+#include <type_traits>
+
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/type_traits.h>
namespace google {
namespace protobuf {
@@ -95,7 +96,7 @@ inline To down_cast(From* f) { // so we only accept pointers
template<typename To, typename From> // use like this: down_cast<T&>(foo);
inline To down_cast(From& f) {
- typedef typename remove_reference<To>::type* ToAsPointer;
+ typedef typename std::remove_reference<To>::type* ToAsPointer;
// Ensures that To is a sub-type of From *. This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 73822168..33d24c57 100755..100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -314,86 +314,6 @@ namespace internal { FunctionClosure0::~FunctionClosure0() {} }
void DoNothing() {}
// ===================================================================
-// emulates google3/base/mutex.cc
-
-#ifdef _WIN32
-
-struct Mutex::Internal {
- CRITICAL_SECTION mutex;
-#ifndef NDEBUG
- // Used only to implement AssertHeld().
- DWORD thread_id;
-#endif
-};
-
-Mutex::Mutex()
- : mInternal(new Internal) {
- InitializeCriticalSection(&mInternal->mutex);
-}
-
-Mutex::~Mutex() {
- DeleteCriticalSection(&mInternal->mutex);
- delete mInternal;
-}
-
-void Mutex::Lock() {
- EnterCriticalSection(&mInternal->mutex);
-#ifndef NDEBUG
- mInternal->thread_id = GetCurrentThreadId();
-#endif
-}
-
-void Mutex::Unlock() {
-#ifndef NDEBUG
- mInternal->thread_id = 0;
-#endif
- LeaveCriticalSection(&mInternal->mutex);
-}
-
-void Mutex::AssertHeld() {
-#ifndef NDEBUG
- GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
-#endif
-}
-
-#elif defined(HAVE_PTHREAD)
-
-struct Mutex::Internal {
- pthread_mutex_t mutex;
-};
-
-Mutex::Mutex()
- : mInternal(new Internal) {
- pthread_mutex_init(&mInternal->mutex, NULL);
-}
-
-Mutex::~Mutex() {
- pthread_mutex_destroy(&mInternal->mutex);
- delete mInternal;
-}
-
-void Mutex::Lock() {
- int result = pthread_mutex_lock(&mInternal->mutex);
- if (result != 0) {
- GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
- }
-}
-
-void Mutex::Unlock() {
- int result = pthread_mutex_unlock(&mInternal->mutex);
- if (result != 0) {
- GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
- }
-}
-
-void Mutex::AssertHeld() {
- // pthreads dosn't provide a way to check which thread holds the mutex.
- // TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
-}
-
-#endif
-
-// ===================================================================
// emulates google3/util/endian/endian.h
//
// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
@@ -430,9 +350,9 @@ struct ShutdownData {
}
}
- vector<void (*)()> functions;
- vector<const std::string*> strings;
- vector<const MessageLite*> messages;
+ std::vector<void (*)()> functions;
+ std::vector<const std::string*> strings;
+ std::vector<const MessageLite*> messages;
Mutex mutex;
};
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index ff363482..5d320764 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -38,6 +38,7 @@
#include <algorithm>
#include <iostream>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -48,7 +49,6 @@
// TODO(liujisi): Remove the following includes after the include clean-up.
#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/callback.h>
@@ -101,27 +101,27 @@ namespace internal {
// The current version, represented as a single integer to make comparison
// easier: major * 10^6 + minor * 10^3 + micro
-#define GOOGLE_PROTOBUF_VERSION 3004000
+#define GOOGLE_PROTOBUF_VERSION 3006000
// A suffix string for alpha, beta or rc releases. Empty for stable releases.
#define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
// The minimum library version which works with the current version of the
// headers.
-#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3004000
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3006000
// The minimum header version which works with the current version of
// the library. This constant should only be used by protoc's C++ code
// generator.
-static const int kMinHeaderVersionForLibrary = 3004000;
+static const int kMinHeaderVersionForLibrary = 3006000;
// The minimum protoc version which works with the current version of the
// headers.
-#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3004000
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3006000
// The minimum header version which works with the current version of
// protoc. This constant should only be used in VerifyVersion().
-static const int kMinHeaderVersionForProtoc = 3004000;
+static const int kMinHeaderVersionForProtoc = 3006000;
// Verifies that the headers and libraries are compatible. Use the macro
// below to call this.
@@ -229,12 +229,7 @@ class FatalException : public std::exception {
// This is at the end of the file instead of the beginning to work around a bug
// in some versions of MSVC.
-// TODO(acozzette): remove these using statements
-using std::istream;
-using std::ostream;
-using std::pair;
using std::string;
-using std::vector;
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
index f9e2cfd4..798a2a27 100644
--- a/src/google/protobuf/stubs/common_unittest.cc
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -75,7 +75,7 @@ TEST(CommonTest, IntMinMaxConstants) {
EXPECT_EQ(0, kuint64max + 1);
}
-vector<string> captured_messages_;
+std::vector<string> captured_messages_;
void CaptureLog(LogLevel level, const char* filename, int line,
const string& message) {
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index 218cd948..fd8ba156 100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -93,7 +93,7 @@
# endif
// GCC <= 4.1 does not define std::tr1::hash for `long long int` or `long long unsigned int`
-# if __GNUC__ == 4 && defined(__GNUC__MINOR__) && __GNUC__MINOR__ <= 1
+# if __GNUC__ == 4 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ <= 1
# undef GOOGLE_PROTOBUF_HAS_TR1
# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
@@ -235,7 +235,8 @@ class hash_set : public std::set<Key, HashFcn> {
HashFcn hash_function() const { return HashFcn(); }
};
-#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
+#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) && \
+ !(defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER >= 11)
template <typename Key>
struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
@@ -408,8 +409,8 @@ struct hash<string> {
};
template <typename First, typename Second>
-struct hash<pair<First, Second> > {
- inline size_t operator()(const pair<First, Second>& key) const {
+struct hash<std::pair<First, Second> > {
+ inline size_t operator()(const std::pair<First, Second>& key) const {
size_t first_hash = hash<First>()(key.first);
size_t second_hash = hash<Second>()(key.second);
@@ -420,8 +421,8 @@ struct hash<pair<First, Second> > {
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
- inline bool operator()(const pair<First, Second>& a,
- const pair<First, Second>& b) const {
+ inline bool operator()(const std::pair<First, Second>& a,
+ const std::pair<First, Second>& b) const {
return a < b;
}
};
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
index a5090801..7b993e8f 100644
--- a/src/google/protobuf/stubs/int128.cc
+++ b/src/google/protobuf/stubs/int128.cc
@@ -76,52 +76,36 @@ static inline int Fls128(uint128 n) {
return Fls64(Uint128Low64(n));
}
-// Long division/modulo for uint128 implemented using the shift-subtract
-// division algorithm adapted from:
-// http://stackoverflow.com/questions/5386377/division-without-using
void uint128::DivModImpl(uint128 dividend, uint128 divisor,
uint128* quotient_ret, uint128* remainder_ret) {
if (divisor == 0) {
GOOGLE_LOG(FATAL) << "Division or mod by zero: dividend.hi=" << dividend.hi_
<< ", lo=" << dividend.lo_;
- }
-
- if (divisor > dividend) {
+ } else if (dividend < divisor) {
*quotient_ret = 0;
*remainder_ret = dividend;
return;
- }
-
- if (divisor == dividend) {
- *quotient_ret = 1;
- *remainder_ret = 0;
- return;
- }
-
- uint128 denominator = divisor;
- uint128 position = 1;
- uint128 quotient = 0;
-
- // Left aligns the MSB of the denominator and the dividend.
- int shift = Fls128(dividend) - Fls128(denominator);
- denominator <<= shift;
- position <<= shift;
-
- // Uses shift-subtract algorithm to divide dividend by denominator. The
- // remainder will be left in dividend.
- while (position > 0) {
- if (dividend >= denominator) {
- dividend -= denominator;
- quotient |= position;
+ } else {
+ int dividend_bit_length = Fls128(dividend);
+ int divisor_bit_length = Fls128(divisor);
+ int difference = dividend_bit_length - divisor_bit_length;
+ uint128 quotient = 0;
+ while (difference >= 0) {
+ quotient <<= 1;
+ uint128 shifted_divisor = divisor << difference;
+ if (shifted_divisor <= dividend) {
+ dividend -= shifted_divisor;
+ quotient += 1;
+ }
+ difference -= 1;
}
- position >>= 1;
- denominator >>= 1;
+ //record the final quotient and remainder
+ *quotient_ret = quotient;
+ *remainder_ret = dividend;
}
-
- *quotient_ret = quotient;
- *remainder_ret = dividend;
}
+
uint128& uint128::operator/=(const uint128& divisor) {
uint128 quotient = 0;
uint128 remainder = 0;
diff --git a/src/google/protobuf/stubs/io_win32.cc b/src/google/protobuf/stubs/io_win32.cc
index 7e1cf785..4407facb 100644
--- a/src/google/protobuf/stubs/io_win32.cc
+++ b/src/google/protobuf/stubs/io_win32.cc
@@ -30,16 +30,17 @@
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
-// Implementation for long-path-aware open/mkdir/etc. on Windows.
+// Implementation for long-path-aware open/mkdir/access/etc. on Windows, as well
+// as for the supporting utility functions.
//
// These functions convert the input path to an absolute Windows path
-// with "\\?\" prefix if necessary, then pass that to _wopen/_wmkdir/etc.
+// with "\\?\" prefix, then pass that to _wopen/_wmkdir/_waccess/etc.
// (declared in <io.h>) respectively. This allows working with files/directories
// whose paths are longer than MAX_PATH (260 chars).
//
// This file is only used on Windows, it's empty on other platforms.
-#if defined(_MSC_VER)
+#if defined(_WIN32)
// Comment this out to fall back to using the ANSI versions (open, mkdir, ...)
// instead of the Unicode ones (_wopen, _wmkdir, ...). Doing so can be useful to
@@ -51,15 +52,14 @@
#include <errno.h>
#include <fcntl.h>
#include <io.h>
+#include <memory>
#include <sys/stat.h>
#include <sys/types.h>
#include <wctype.h>
#include <windows.h>
#include <google/protobuf/stubs/io_win32.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
-#include <cassert>
#include <memory>
#include <sstream>
#include <string>
@@ -89,6 +89,11 @@ struct CharTraits<wchar_t> {
static bool is_alpha(wchar_t ch) { return iswalpha(ch); }
};
+template <typename char_type>
+bool null_or_empty(const char_type* s) {
+ return s == NULL || *s == 0;
+}
+
// Returns true if the path starts with a drive letter, e.g. "c:".
// Note that this won't check for the "\" after the drive letter, so this also
// returns true for "c:foo" (which is "c:\${PWD}\foo").
@@ -121,16 +126,7 @@ bool is_drive_relative(const char_type* path) {
return has_drive_letter(path) && (path[2] == 0 || !is_separator(path[2]));
}
-template <typename char_type>
-void replace_directory_separators(char_type* p) {
- for (; *p; ++p) {
- if (*p == '/') {
- *p = '\\';
- }
- }
-}
-
-string join_paths(const string& path1, const string& path2) {
+wstring join_paths(const wstring& path1, const wstring& path2) {
if (path1.empty() || is_path_absolute(path2.c_str()) ||
has_longpath_prefix(path2.c_str())) {
return path2;
@@ -144,23 +140,24 @@ string join_paths(const string& path1, const string& path2) {
: (path1 + path2);
} else {
return is_separator(path2[0]) ? (path1 + path2)
- : (path1 + '\\' + path2);
+ : (path1 + L'\\' + path2);
}
}
-string normalize(string path) {
+wstring normalize(wstring path) {
if (has_longpath_prefix(path.c_str())) {
path = path.substr(4);
}
- static const string dot(".");
- static const string dotdot("..");
+ static const wstring dot(L".");
+ static const wstring dotdot(L"..");
+ const WCHAR* p = path.c_str();
- std::vector<string> segments;
+ std::vector<wstring> segments;
int segment_start = -1;
// Find the path segments in `path` (separated by "/").
for (int i = 0;; ++i) {
- if (!is_separator(path[i]) && path[i] != '\0') {
+ if (!is_separator(p[i]) && p[i] != L'\0') {
// The current character does not end a segment, so start one unless it's
// already started.
if (segment_start < 0) {
@@ -169,7 +166,7 @@ string normalize(string path) {
} else if (segment_start >= 0 && i > segment_start) {
// The current character is "/" or "\0", so this ends a segment.
// Add that to `segments` if there's anything to add; handle "." and "..".
- string segment(path, segment_start, i - segment_start);
+ wstring segment(p, segment_start, i - segment_start);
segment_start = -1;
if (segment == dotdot) {
if (!segments.empty() &&
@@ -180,7 +177,7 @@ string normalize(string path) {
segments.push_back(segment);
}
}
- if (path[i] == '\0') {
+ if (p[i] == L'\0') {
break;
}
}
@@ -189,64 +186,62 @@ string normalize(string path) {
// form of it, e.g. "c:\..").
if (segments.size() == 1 && segments[0].size() == 2 &&
has_drive_letter(segments[0].c_str())) {
- return segments[0] + '\\';
+ return segments[0] + L'\\';
}
// Join all segments.
bool first = true;
- std::ostringstream result;
+ std::wstringstream result;
for (int i = 0; i < segments.size(); ++i) {
if (!first) {
- result << '\\';
+ result << L'\\';
}
first = false;
result << segments[i];
}
// Preserve trailing separator if the input contained it.
- if (!path.empty() && is_separator(path[path.size() - 1])) {
- result << '\\';
+ if (!path.empty() && is_separator(p[path.size() - 1])) {
+ result << L'\\';
}
return result.str();
}
-WCHAR* as_wstring(const string& s) {
- int len = ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), NULL, 0);
- WCHAR* result = new WCHAR[len + 1];
- ::MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.size(), result, len + 1);
- result[len] = 0;
- return result;
-}
-
-void as_wchar_path(const string& path, wstring* wchar_path) {
- scoped_array<WCHAR> wbuf(as_wstring(path));
- replace_directory_separators(wbuf.get());
- wchar_path->assign(wbuf.get());
-}
-
-bool as_windows_path(const string& path, wstring* result) {
- if (path.empty()) {
+bool as_windows_path(const char* path, wstring* result) {
+ if (null_or_empty(path)) {
result->clear();
return true;
}
- if (is_separator(path[0]) || is_drive_relative(path.c_str())) {
+ wstring wpath;
+ if (!strings::utf8_to_wcs(path, &wpath)) {
+ return false;
+ }
+ if (has_longpath_prefix(wpath.c_str())) {
+ *result = wpath;
+ return true;
+ }
+ if (is_separator(path[0]) || is_drive_relative(path)) {
return false;
}
- string mutable_path = path;
- if (!is_path_absolute(mutable_path.c_str()) &&
- !has_longpath_prefix(mutable_path.c_str())) {
- char cwd[MAX_PATH];
- ::GetCurrentDirectoryA(MAX_PATH, cwd);
- mutable_path = join_paths(cwd, mutable_path);
+
+ if (!is_path_absolute(wpath.c_str())) {
+ int size = ::GetCurrentDirectoryW(0, NULL);
+ if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ return false;
+ }
+ std::unique_ptr<WCHAR[]> wcwd(new WCHAR[size]);
+ ::GetCurrentDirectoryW(size, wcwd.get());
+ wpath = join_paths(wcwd.get(), wpath);
}
- as_wchar_path(normalize(mutable_path), result);
- if (!has_longpath_prefix(result->c_str())) {
+ wpath = normalize(wpath);
+ if (!has_longpath_prefix(wpath.c_str())) {
// Add the "\\?\" prefix unconditionally. This way we prevent the Win32 API
// from processing the path and "helpfully" removing trailing dots from the
// path, for example.
// See https://github.com/bazelbuild/bazel/issues/2935
- *result = wstring(L"\\\\?\\") + *result;
+ wpath = wstring(L"\\\\?\\") + wpath;
}
+ *result = wpath;
return true;
}
@@ -319,13 +314,21 @@ int stat(const char* path, struct _stat* buffer) {
FILE* fopen(const char* path, const char* mode) {
#ifdef SUPPORT_LONGPATHS
+ if (null_or_empty(path)) {
+ errno = EINVAL;
+ return NULL;
+ }
wstring wpath;
if (!as_windows_path(path, &wpath)) {
errno = ENOENT;
return NULL;
}
- scoped_array<WCHAR> wmode(as_wstring(mode));
- return ::_wfopen(wpath.c_str(), wmode.get());
+ wstring wmode;
+ if (!strings::utf8_to_wcs(mode, &wmode)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ return ::_wfopen(wpath.c_str(), wmode.c_str());
#else
return ::fopen(path, mode);
#endif
@@ -347,16 +350,65 @@ int write(int fd, const void* buffer, size_t size) {
return ::_write(fd, buffer, size);
}
-wstring testonly_path_to_winpath(const string& path) {
+wstring testonly_utf8_to_winpath(const char* path) {
wstring wpath;
- as_windows_path(path, &wpath);
- return wpath;
+ return as_windows_path(path, &wpath) ? wpath : wstring();
+}
+
+namespace strings {
+
+bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) {
+ if (null_or_empty(s)) {
+ out->clear();
+ return true;
+ }
+ BOOL usedDefaultChar = FALSE;
+ SetLastError(0);
+ int size = WideCharToMultiByte(
+ outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, NULL, 0, NULL,
+ outUtf8 ? NULL : &usedDefaultChar);
+ if ((size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ || usedDefaultChar) {
+ return false;
+ }
+ std::unique_ptr<CHAR[]> astr(new CHAR[size]);
+ WideCharToMultiByte(
+ outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, NULL, NULL);
+ out->assign(astr.get());
+ return true;
+}
+
+bool mbs_to_wcs(const char* s, wstring* out, bool inUtf8) {
+ if (null_or_empty(s)) {
+ out->clear();
+ return true;
+ }
+
+ SetLastError(0);
+ int size =
+ MultiByteToWideChar(inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, NULL, 0);
+ if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ return false;
+ }
+ std::unique_ptr<WCHAR[]> wstr(new WCHAR[size]);
+ MultiByteToWideChar(
+ inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, wstr.get(), size + 1);
+ out->assign(wstr.get());
+ return true;
}
+bool utf8_to_wcs(const char* input, wstring* out) {
+ return mbs_to_wcs(input, out, true);
+}
+
+bool wcs_to_utf8(const wchar_t* input, string* out) {
+ return wcs_to_mbs(input, out, true);
+}
+
+} // namespace strings
} // namespace win32
} // namespace internal
} // namespace protobuf
} // namespace google
-#endif // defined(_MSC_VER)
-
+#endif // defined(_WIN32)
diff --git a/src/google/protobuf/stubs/io_win32.h b/src/google/protobuf/stubs/io_win32.h
index a20e64c7..9e17d253 100644
--- a/src/google/protobuf/stubs/io_win32.h
+++ b/src/google/protobuf/stubs/io_win32.h
@@ -52,7 +52,6 @@
// Compilers on Windows other than MSVC (e.g. Cygwin, MinGW32) define the
// following functions already, except for mkdir.
-#ifdef _MSC_VER
namespace google {
namespace protobuf {
namespace internal {
@@ -70,16 +69,30 @@ LIBPROTOBUF_EXPORT int read(int fd, void* buffer, size_t size);
LIBPROTOBUF_EXPORT int setmode(int fd, int mode);
LIBPROTOBUF_EXPORT int stat(const char* path, struct _stat* buffer);
LIBPROTOBUF_EXPORT int write(int fd, const void* buffer, size_t size);
-LIBPROTOBUF_EXPORT std::wstring testonly_path_to_winpath(
- const std::string& path);
+LIBPROTOBUF_EXPORT std::wstring testonly_utf8_to_winpath(const char* path);
+
+namespace strings {
+
+// Convert from UTF-16 to Active-Code-Page-encoded or to UTF-8-encoded text.
+LIBPROTOBUF_EXPORT bool wcs_to_mbs(
+ const wchar_t* s, std::string* out, bool outUtf8);
+
+// Convert from Active-Code-Page-encoded or UTF-8-encoded text to UTF-16.
+LIBPROTOBUF_EXPORT bool mbs_to_wcs(
+ const char* s, std::wstring* out, bool inUtf8);
+
+// Convert from UTF-8-encoded text to UTF-16.
+LIBPROTOBUF_EXPORT bool utf8_to_wcs(const char* input, std::wstring* out);
+
+// Convert from UTF-16-encoded text to UTF-8.
+LIBPROTOBUF_EXPORT bool wcs_to_utf8(const wchar_t* input, std::string* out);
+
+} // namespace strings
} // namespace win32
} // namespace internal
} // namespace protobuf
} // namespace google
-#else // _MSC_VER
-#define mkdir(name, mode) mkdir(name)
-#endif // !_MSC_VER
#ifndef W_OK
#define W_OK 02 // not defined by MSVC for whatever reason
@@ -100,5 +113,3 @@ LIBPROTOBUF_EXPORT std::wstring testonly_path_to_winpath(
#endif // defined(_WIN32)
#endif // GOOGLE_PROTOBUF_STUBS_IO_WIN32_H__
-
-
diff --git a/src/google/protobuf/stubs/io_win32_unittest.cc b/src/google/protobuf/stubs/io_win32_unittest.cc
index 288f27ab..c933757c 100644
--- a/src/google/protobuf/stubs/io_win32_unittest.cc
+++ b/src/google/protobuf/stubs/io_win32_unittest.cc
@@ -30,11 +30,12 @@
// Author: laszlocsomor@google.com (Laszlo Csomor)
//
-// Unit tests for long-path-aware open/mkdir/access on Windows.
+// Unit tests for long-path-aware open/mkdir/access/etc. on Windows, as well as
+// for the supporting utility functions.
//
// This file is only used on Windows, it's empty on other platforms.
-#if defined(_MSC_VER)
+#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <errno.h>
@@ -47,8 +48,6 @@
#include <windows.h>
#include <google/protobuf/stubs/io_win32.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
-#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <memory>
@@ -61,6 +60,27 @@ namespace internal {
namespace win32 {
namespace {
+const char kUtf8Text[] = {
+ 'h', 'i', ' ',
+ // utf-8: 11010000 10011111, utf-16: 100 0001 1111 = 0x041F
+ 0xd0, 0x9f,
+ // utf-8: 11010001 10000000, utf-16: 100 0100 0000 = 0x0440
+ 0xd1, 0x80,
+ // utf-8: 11010000 10111000, utf-16: 100 0011 1000 = 0x0438
+ 0xd0, 0xb8,
+ // utf-8: 11010000 10110010, utf-16: 100 0011 0010 = 0x0432
+ 0xd0, 0xb2,
+ // utf-8: 11010000 10110101, utf-16: 100 0011 0101 = 0x0435
+ 0xd0, 0xb5,
+ // utf-8: 11010001 10000010, utf-16: 100 0100 0010 = 0x0442
+ 0xd1, 0x82, 0
+};
+
+const wchar_t kUtf16Text[] = {
+ L'h', L'i', L' ',
+ L'\x41f', L'\x440', L'\x438', L'\x432', L'\x435', L'\x442', 0
+};
+
using std::string;
using std::wstring;
@@ -73,6 +93,7 @@ class IoWin32Test : public ::testing::Test {
bool CreateAllUnder(wstring path);
bool DeleteAllUnder(wstring path);
+ WCHAR working_directory[MAX_PATH];
string test_tmpdir;
wstring wtest_tmpdir;
};
@@ -89,71 +110,88 @@ void StripTrailingSlashes(string* str) {
for (; i >= 0 && ((*str)[i] == '/' || (*str)[i] == '\\'); --i) {}
str->resize(i+1);
}
+
+bool GetEnvVarAsUtf8(const WCHAR* name, string* result) {
+ DWORD size = ::GetEnvironmentVariableW(name, NULL, 0);
+ if (size > 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ std::unique_ptr<WCHAR[]> wcs(new WCHAR[size]);
+ ::GetEnvironmentVariableW(name, wcs.get(), size);
+ // GetEnvironmentVariableA retrieves an Active-Code-Page-encoded text which
+ // we'd first need to convert to UTF-16 then to UTF-8, because there seems
+ // to be no API function to do that conversion directly.
+ // GetEnvironmentVariableW retrieves an UTF-16-encoded text, which we need
+ // to convert to UTF-8.
+ return strings::wcs_to_utf8(wcs.get(), result);
+ } else {
+ return false;
+ }
+}
+
+bool GetCwdAsUtf8(string* result) {
+ DWORD size = ::GetCurrentDirectoryW(0, NULL);
+ if (size > 0) {
+ std::unique_ptr<WCHAR[]> wcs(new WCHAR[size]);
+ ::GetCurrentDirectoryW(size, wcs.get());
+ // GetCurrentDirectoryA retrieves an Active-Code-Page-encoded text which
+ // we'd first need to convert to UTF-16 then to UTF-8, because there seems
+ // to be no API function to do that conversion directly.
+ // GetCurrentDirectoryW retrieves an UTF-16-encoded text, which we need
+ // to convert to UTF-8.
+ return strings::wcs_to_utf8(wcs.get(), result);
+ } else {
+ return false;
+ }
+}
+
} // namespace
void IoWin32Test::SetUp() {
- test_tmpdir = string(TestTempDir());
+ test_tmpdir.clear();
wtest_tmpdir.clear();
- if (test_tmpdir.empty()) {
- const char* test_tmpdir_env = getenv("TEST_TMPDIR");
- if (test_tmpdir_env != NULL && *test_tmpdir_env) {
- test_tmpdir = string(test_tmpdir_env);
- }
-
- // Only Bazel defines TEST_TMPDIR, CMake does not, so look for other
- // suitable environment variables.
- if (test_tmpdir.empty()) {
- static const char* names[] = {"TEMP", "TMP"};
- for (int i = 0; i < sizeof(names)/sizeof(names[0]); ++i) {
- const char* name = names[i];
- test_tmpdir_env = getenv(name);
- if (test_tmpdir_env != NULL && *test_tmpdir_env) {
- test_tmpdir = string(test_tmpdir_env);
- break;
- }
- }
- }
+ EXPECT_GT(::GetCurrentDirectoryW(MAX_PATH, working_directory), 0);
- // No other temp directory was found. Use the current director
- if (test_tmpdir.empty()) {
- char buffer[MAX_PATH];
- // Use GetCurrentDirectoryA instead of GetCurrentDirectoryW, because the
- // current working directory must always be shorter than MAX_PATH, even
- // with
- // "\\?\" prefix (except on Windows 10 version 1607 and beyond, after
- // opting in to long paths by default [1]).
- //
- // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
- DWORD result = ::GetCurrentDirectoryA(MAX_PATH, buffer);
- if (result > 0) {
- test_tmpdir = string(buffer);
- } else {
- // Using assertions in SetUp/TearDown seems to confuse the test
- // framework, so just leave the member variables empty in case of
- // failure.
- GOOGLE_CHECK_OK(false);
- return;
- }
- }
+ string tmp;
+ bool ok = false;
+ if (!ok) {
+ // Bazel sets this environment variable when it runs tests.
+ ok = GetEnvVarAsUtf8(L"TEST_TMPDIR", &tmp);
}
-
- StripTrailingSlashes(&test_tmpdir);
- test_tmpdir += "\\io_win32_unittest.tmp";
-
- // CreateDirectoryA's limit is 248 chars, see MSDN.
- // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
- wtest_tmpdir = testonly_path_to_winpath(test_tmpdir);
- if (!DeleteAllUnder(wtest_tmpdir) || !CreateAllUnder(wtest_tmpdir)) {
- GOOGLE_CHECK_OK(false);
- test_tmpdir.clear();
- wtest_tmpdir.clear();
+ if (!ok) {
+ // Bazel 0.8.0 sets this environment for every build and test action.
+ ok = GetEnvVarAsUtf8(L"TEMP", &tmp);
}
+ if (!ok) {
+ // Bazel 0.8.0 sets this environment for every build and test action.
+ ok = GetEnvVarAsUtf8(L"TMP", &tmp);
+ }
+ if (!ok) {
+ // Fall back to using the current directory.
+ ok = GetCwdAsUtf8(&tmp);
+ }
+ if (!ok || tmp.empty()) {
+ FAIL() << "Cannot find a temp directory.";
+ }
+
+ StripTrailingSlashes(&tmp);
+ std::stringstream result;
+ // Deleting files and directories is asynchronous on Windows, and if TearDown
+ // just deleted the previous temp directory, sometimes we cannot recreate the
+ // same directory.
+ // Use a counter so every test method gets its own temp directory.
+ static unsigned int counter = 0;
+ result << tmp << "\\w32tst" << counter++ << ".tmp";
+ test_tmpdir = result.str();
+ wtest_tmpdir = testonly_utf8_to_winpath(test_tmpdir.c_str());
+ ASSERT_FALSE(wtest_tmpdir.empty());
+ ASSERT_TRUE(DeleteAllUnder(wtest_tmpdir));
+ ASSERT_TRUE(CreateAllUnder(wtest_tmpdir));
}
void IoWin32Test::TearDown() {
if (!wtest_tmpdir.empty()) {
DeleteAllUnder(wtest_tmpdir);
}
+ ::SetCurrentDirectoryW(working_directory);
}
bool IoWin32Test::CreateAllUnder(wstring path) {
@@ -191,8 +229,8 @@ bool IoWin32Test::DeleteAllUnder(wstring path) {
path = wstring(L"\\\\?\\") + path;
}
// Append "\" if necessary.
- if (path[path.size() - 1] != '\\') {
- path.push_back('\\');
+ if (path[path.size() - 1] != L'\\') {
+ path.push_back(L'\\');
}
WIN32_FIND_DATAW metadata;
@@ -309,13 +347,24 @@ TEST_F(IoWin32Test, MkdirTest) {
ASSERT_EQ(errno, ENOENT);
}
+TEST_F(IoWin32Test, MkdirTestNonAscii) {
+ ASSERT_INITIALIZED;
+
+ // Create a non-ASCII path.
+ // Ensure that we can create the directory using SetCurrentDirectoryW.
+ EXPECT_TRUE(CreateDirectoryW((wtest_tmpdir + L"\\1").c_str(), NULL));
+ EXPECT_TRUE(CreateDirectoryW((wtest_tmpdir + L"\\1\\" + kUtf16Text).c_str(), NULL));
+ // Ensure that we can create a very similarly named directory using mkdir.
+ // We don't attemp to delete and recreate the same directory, because on
+ // Windows, deleting files and directories seems to be asynchronous.
+ EXPECT_EQ(mkdir((test_tmpdir + "\\2").c_str(), 0644), 0);
+ EXPECT_EQ(mkdir((test_tmpdir + "\\2\\" + kUtf8Text).c_str(), 0644), 0);
+}
+
TEST_F(IoWin32Test, ChdirTest) {
- char owd[MAX_PATH];
- EXPECT_GT(::GetCurrentDirectoryA(MAX_PATH, owd), 0);
string path("C:\\");
EXPECT_EQ(access(path.c_str(), F_OK), 0);
ASSERT_EQ(chdir(path.c_str()), 0);
- EXPECT_TRUE(::SetCurrentDirectoryA(owd));
// Do not try to chdir into the test_tmpdir, it may already contain directory
// names with trailing dots.
@@ -330,17 +379,37 @@ TEST_F(IoWin32Test, ChdirTest) {
ASSERT_NE(chdir(path.c_str()), 0);
}
+TEST_F(IoWin32Test, ChdirTestNonAscii) {
+ ASSERT_INITIALIZED;
+
+ // Create a directory with a non-ASCII path and ensure we can cd into it.
+ wstring wNonAscii(wtest_tmpdir + L"\\" + kUtf16Text);
+ string nonAscii;
+ EXPECT_TRUE(strings::wcs_to_utf8(wNonAscii.c_str(), &nonAscii));
+ EXPECT_TRUE(CreateDirectoryW(wNonAscii.c_str(), NULL));
+ WCHAR cwd[MAX_PATH];
+ EXPECT_TRUE(GetCurrentDirectoryW(MAX_PATH, cwd));
+ // Ensure that we can cd into the path using SetCurrentDirectoryW.
+ EXPECT_TRUE(SetCurrentDirectoryW(wNonAscii.c_str()));
+ EXPECT_TRUE(SetCurrentDirectoryW(cwd));
+ // Ensure that we can cd into the path using chdir.
+ ASSERT_EQ(chdir(nonAscii.c_str()), 0);
+ // Ensure that the GetCurrentDirectoryW returns the desired path.
+ EXPECT_TRUE(GetCurrentDirectoryW(MAX_PATH, cwd));
+ ASSERT_EQ(wNonAscii, cwd);
+}
+
TEST_F(IoWin32Test, AsWindowsPathTest) {
DWORD size = GetCurrentDirectoryW(0, NULL);
- scoped_array<wchar_t> cwd_str(new wchar_t[size]);
+ std::unique_ptr<wchar_t[]> cwd_str(new wchar_t[size]);
EXPECT_GT(GetCurrentDirectoryW(size, cwd_str.get()), 0);
wstring cwd = wstring(L"\\\\?\\") + cwd_str.get();
- ASSERT_EQ(testonly_path_to_winpath("relative_mkdirtest"),
+ ASSERT_EQ(testonly_utf8_to_winpath("relative_mkdirtest"),
cwd + L"\\relative_mkdirtest");
- ASSERT_EQ(testonly_path_to_winpath("preserve//\\trailing///"),
+ ASSERT_EQ(testonly_utf8_to_winpath("preserve//\\trailing///"),
cwd + L"\\preserve\\trailing\\");
- ASSERT_EQ(testonly_path_to_winpath("./normalize_me\\/../blah"),
+ ASSERT_EQ(testonly_utf8_to_winpath("./normalize_me\\/../blah"),
cwd + L"\\blah");
std::ostringstream relpath;
for (wchar_t* p = cwd_str.get(); *p; ++p) {
@@ -349,18 +418,28 @@ TEST_F(IoWin32Test, AsWindowsPathTest) {
}
}
relpath << ".\\/../\\./beyond-toplevel";
- ASSERT_EQ(testonly_path_to_winpath(relpath.str()),
+ ASSERT_EQ(testonly_utf8_to_winpath(relpath.str().c_str()),
wstring(L"\\\\?\\") + cwd_str.get()[0] + L":\\beyond-toplevel");
// Absolute unix paths lack drive letters, driveless absolute windows paths
// do too. Neither can be converted to a drive-specifying absolute Windows
// path.
- ASSERT_EQ(testonly_path_to_winpath("/absolute/unix/path"), L"");
+ ASSERT_EQ(testonly_utf8_to_winpath("/absolute/unix/path"), L"");
// Though valid on Windows, we also don't support UNC paths (\\UNC\\blah).
- ASSERT_EQ(testonly_path_to_winpath("\\driveless\\absolute"), L"");
+ ASSERT_EQ(testonly_utf8_to_winpath("\\driveless\\absolute"), L"");
// Though valid in cmd.exe, drive-relative paths are not supported.
- ASSERT_EQ(testonly_path_to_winpath("c:foo"), L"");
- ASSERT_EQ(testonly_path_to_winpath("c:/foo"), L"\\\\?\\c:\\foo");
+ ASSERT_EQ(testonly_utf8_to_winpath("c:foo"), L"");
+ ASSERT_EQ(testonly_utf8_to_winpath("c:/foo"), L"\\\\?\\c:\\foo");
+ ASSERT_EQ(testonly_utf8_to_winpath("\\\\?\\C:\\foo"), L"\\\\?\\C:\\foo");
+}
+
+TEST_F(IoWin32Test, Utf8Utf16ConversionTest) {
+ string mbs;
+ wstring wcs;
+ ASSERT_TRUE(strings::utf8_to_wcs(kUtf8Text, &wcs));
+ ASSERT_TRUE(strings::wcs_to_utf8(kUtf16Text, &mbs));
+ ASSERT_EQ(wcs, kUtf16Text);
+ ASSERT_EQ(mbs, kUtf8Text);
}
} // namespace
@@ -369,5 +448,5 @@ TEST_F(IoWin32Test, AsWindowsPathTest) {
} // namespace protobuf
} // namespace google
-#endif // defined(_MSC_VER)
+#endif // defined(_WIN32)
diff --git a/src/google/protobuf/stubs/map_util.h b/src/google/protobuf/stubs/map_util.h
index 887f12a6..3e6d381f 100644
--- a/src/google/protobuf/stubs/map_util.h
+++ b/src/google/protobuf/stubs/map_util.h
@@ -654,7 +654,8 @@ InsertOrReturnExisting(
// delete EraseKeyReturnValuePtr(&my_map, "abc");
//
// Use returned value:
-// scoped_ptr<MyType> value_ptr(EraseKeyReturnValuePtr(&my_map, "abc"));
+// std::unique_ptr<MyType> value_ptr(
+// EraseKeyReturnValuePtr(&my_map, "abc"));
// if (value_ptr.get())
// value_ptr->DoSomething();
//
@@ -708,7 +709,7 @@ void AppendKeysFromMap(const MapContainer& map_container,
// without the complexity of a SFINAE-based solution.)
template <class MapContainer, class KeyType>
void AppendKeysFromMap(const MapContainer& map_container,
- vector<KeyType>* key_container) {
+ std::vector<KeyType>* key_container) {
GOOGLE_CHECK(key_container != NULL);
// We now have the opportunity to call reserve(). Calling reserve() every
// time is a bad idea for some use cases: libstdc++'s implementation of
@@ -752,7 +753,7 @@ void AppendValuesFromMap(const MapContainer& map_container,
// without the complexity of a SFINAE-based solution.)
template <class MapContainer, class ValueType>
void AppendValuesFromMap(const MapContainer& map_container,
- vector<ValueType>* value_container) {
+ std::vector<ValueType>* value_container) {
GOOGLE_CHECK(value_container != NULL);
// See AppendKeysFromMap for why this is done.
if (value_container->empty()) {
diff --git a/src/google/protobuf/stubs/mathlimits.h b/src/google/protobuf/stubs/mathlimits.h
index 2391ac4c..9c9d0e9a 100644
--- a/src/google/protobuf/stubs/mathlimits.h
+++ b/src/google/protobuf/stubs/mathlimits.h
@@ -243,7 +243,7 @@ DECL_UNSIGNED_INT_LIMITS(unsigned long long int)
#endif
// ========================================================================= //
-#ifdef WIN32 // Lacks built-in isnan() and isinf()
+#if WIN32 && !__MINGW32__ // Lacks built-in isnan() and isinf()
#define DECL_FP_LIMIT_FUNCS \
static bool IsFinite(const Type x) { return _finite(x); } \
static bool IsNaN(const Type x) { return _isnan(x); } \
diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h
index 174290f6..47edb7a3 100644
--- a/src/google/protobuf/stubs/mutex.h
+++ b/src/google/protobuf/stubs/mutex.h
@@ -30,46 +30,48 @@
#ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_
#define GOOGLE_PROTOBUF_STUBS_MUTEX_H_
-#ifdef GOOGLE_PROTOBUF_NO_THREADLOCAL
-#include <pthread.h>
-#endif
+#include <mutex>
#include <google/protobuf/stubs/macros.h>
+// Define thread-safety annotations for use below, if we are building with
+// Clang.
+#if defined(__clang__) && !defined(SWIG)
+#define GOOGLE_PROTOBUF_ACQUIRE(...) \
+ __attribute__((acquire_capability(__VA_ARGS__)))
+#define GOOGLE_PROTOBUF_RELEASE(...) \
+ __attribute__((release_capability(__VA_ARGS__)))
+#else
+#define GOOGLE_PROTOBUF_ACQUIRE(...)
+#define GOOGLE_PROTOBUF_RELEASE(...)
+#endif
+
// ===================================================================
// emulates google3/base/mutex.h
namespace google {
namespace protobuf {
namespace internal {
-// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T
-// may hold a mutex at a given time. If T attempts to Lock() the same Mutex
-// while holding it, T will deadlock.
-class LIBPROTOBUF_EXPORT Mutex {
- public:
- // Create a Mutex that is not held by anybody.
- Mutex();
-
- // Destructor
- ~Mutex();
-
- // Block if necessary until this Mutex is free, then acquire it exclusively.
- void Lock();
-
- // Release this Mutex. Caller must hold it exclusively.
- void Unlock();
+#define GOOGLE_PROTOBUF_LINKER_INITIALIZED
+// Mutex is a natural type to wrap. As both google and other organization have
+// specialized mutexes. gRPC also provides an injection mechanism for custom
+// mutexes.
+class LIBPROTOBUF_EXPORT WrappedMutex {
+ public:
+ WrappedMutex() = default;
+ void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
+ void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
// Crash if this Mutex is not held exclusively by this thread.
// May fail to crash when it should; will never crash when it should not.
- void AssertHeld();
+ void AssertHeld() const {}
private:
- struct Internal;
- Internal* mInternal;
-
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex);
+ std::mutex mu_;
};
+using Mutex = WrappedMutex;
+
// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
class LIBPROTOBUF_EXPORT MutexLock {
public:
@@ -133,8 +135,10 @@ using internal::ReaderMutexLock;
using internal::WriterMutexLock;
using internal::MutexLockMaybe;
-
} // namespace protobuf
} // namespace google
+#undef GOOGLE_PROTOBUF_ACQUIRE
+#undef GOOGLE_PROTOBUF_RELEASE
+
#endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_
diff --git a/src/google/protobuf/stubs/once.cc b/src/google/protobuf/stubs/once.cc
deleted file mode 100644
index 889c6476..00000000
--- a/src/google/protobuf/stubs/once.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//
-// emulates google3/base/once.h
-//
-// This header is intended to be included only by internal .cc files and
-// generated .pb.cc files. Users should not use this directly.
-
-#include <google/protobuf/stubs/once.h>
-
-#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sched.h>
-#endif
-
-#include <google/protobuf/stubs/atomicops.h>
-
-namespace google {
-namespace protobuf {
-
-namespace {
-
-void SchedYield() {
-#ifdef _WIN32
- Sleep(0);
-#else // POSIX
- sched_yield();
-#endif
-}
-
-} // namespace
-
-void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
- internal::AtomicWord state = internal::Acquire_Load(once);
- // Fast path. The provided closure was already executed.
- if (state == ONCE_STATE_DONE) {
- return;
- }
- // The closure execution did not complete yet. The once object can be in one
- // of the two following states:
- // - UNINITIALIZED: We are the first thread calling this function.
- // - EXECUTING_CLOSURE: Another thread is already executing the closure.
- //
- // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
- // atomically.
- state = internal::Acquire_CompareAndSwap(
- once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
- if (state == ONCE_STATE_UNINITIALIZED) {
- // We are the first thread to call this function, so we have to call the
- // closure.
- closure->Run();
- internal::Release_Store(once, ONCE_STATE_DONE);
- } else {
- // Another thread has already started executing the closure. We need to
- // wait until it completes the initialization.
- while (state == ONCE_STATE_EXECUTING_CLOSURE) {
- // Note that futex() could be used here on Linux as an improvement.
- SchedYield();
- state = internal::Acquire_Load(once);
- }
- }
-}
-
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h
index 1f082c37..f3835ccd 100644
--- a/src/google/protobuf/stubs/once.h
+++ b/src/google/protobuf/stubs/once.h
@@ -78,88 +78,51 @@
#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
-#include <google/protobuf/stubs/atomicops.h>
-#include <google/protobuf/stubs/callback.h>
-#include <google/protobuf/stubs/common.h>
+#include <mutex>
+#include <utility>
namespace google {
namespace protobuf {
+namespace internal {
-#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
-typedef bool ProtobufOnceType;
-
-#define GOOGLE_PROTOBUF_ONCE_INIT false
-
-inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
- if (!*once) {
- *once = true;
- init_func();
- }
+using once_flag = std::once_flag;
+template <typename... Args>
+void call_once(Args&&... args ) {
+ std::call_once(std::forward<Args>(args)...);
}
-template <typename Arg>
-inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
- Arg arg) {
- if (!*once) {
- *once = true;
- init_func(arg);
- }
-}
+} // namespace internal
-#else
-
-enum {
- ONCE_STATE_UNINITIALIZED = 0,
- ONCE_STATE_EXECUTING_CLOSURE = 1,
- ONCE_STATE_DONE = 2
-};
-
-typedef internal::AtomicWord ProtobufOnceType;
-
-#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
-
-LIBPROTOBUF_EXPORT
-void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
+// TODO(gerbens) remove this once third_party is fully extracted
+using ProtobufOnceType = internal::once_flag;
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
- if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
- internal::FunctionClosure0 func(init_func, false);
- GoogleOnceInitImpl(once, &func);
- }
+ std::call_once(*once, init_func);
}
template <typename Arg>
-inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
- Arg* arg) {
- if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
- internal::FunctionClosure1<Arg*> func(init_func, false, arg);
- GoogleOnceInitImpl(once, &func);
- }
+inline void GoogleOnceInitArg(ProtobufOnceType* once, void (*init_func)(Arg*),
+ Arg* arg) {
+ std::call_once(*once, init_func, arg);
}
-#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
-
class GoogleOnceDynamic {
public:
- GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { }
-
// If this->Init() has not been called before by any thread,
// execute (*func_with_arg)(arg) then return.
// Otherwise, wait until that prior invocation has finished
// executing its function, then return.
template<typename T>
void Init(void (*func_with_arg)(T*), T* arg) {
- GoogleOnceInit<T>(&this->state_,
- func_with_arg,
- arg);
+ GoogleOnceInitArg<T>(&this->state_, func_with_arg, arg);
}
private:
ProtobufOnceType state_;
};
+#define GOOGLE_PROTOBUF_ONCE_TYPE ::google::protobuf::ProtobufOnceType
#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
- ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
+ ::google::protobuf::ProtobufOnceType NAME
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/once_unittest.cc b/src/google/protobuf/stubs/once_unittest.cc
deleted file mode 100644
index d5f7779e..00000000
--- a/src/google/protobuf/stubs/once_unittest.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <unistd.h>
-#include <pthread.h>
-#endif
-
-#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/testing/googletest.h>
-#include <gtest/gtest.h>
-
-namespace google {
-namespace protobuf {
-namespace {
-
-class OnceInitTest : public testing::Test {
- protected:
- void SetUp() {
- state_ = INIT_NOT_STARTED;
- current_test_ = this;
- }
-
- // Since ProtobufOnceType is only allowed to be allocated in static storage,
- // each test must use a different pair of ProtobufOnceType objects which it
- // must declare itself.
- void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) {
- once_ = once;
- recursive_once_ = recursive_once;
- }
-
- void InitOnce() {
- GoogleOnceInit(once_, &InitStatic);
- }
- void InitRecursiveOnce() {
- GoogleOnceInit(recursive_once_, &InitRecursiveStatic);
- }
-
- void BlockInit() { init_blocker_.Lock(); }
- void UnblockInit() { init_blocker_.Unlock(); }
-
- class TestThread {
- public:
- TestThread(Closure* callback)
- : done_(false), joined_(false), callback_(callback) {
-#ifdef _WIN32
- thread_ = CreateThread(NULL, 0, &Start, this, 0, NULL);
-#else
- pthread_create(&thread_, NULL, &Start, this);
-#endif
- }
- ~TestThread() {
- if (!joined_) Join();
- }
-
- bool IsDone() {
- MutexLock lock(&done_mutex_);
- return done_;
- }
- void Join() {
- joined_ = true;
-#ifdef _WIN32
- WaitForSingleObject(thread_, INFINITE);
- CloseHandle(thread_);
-#else
- pthread_join(thread_, NULL);
-#endif
- }
-
- private:
-#ifdef _WIN32
- HANDLE thread_;
-#else
- pthread_t thread_;
-#endif
-
- Mutex done_mutex_;
- bool done_;
- bool joined_;
- Closure* callback_;
-
-#ifdef _WIN32
- static DWORD WINAPI Start(LPVOID arg) {
-#else
- static void* Start(void* arg) {
-#endif
- reinterpret_cast<TestThread*>(arg)->Run();
- return 0;
- }
-
- void Run() {
- callback_->Run();
- MutexLock lock(&done_mutex_);
- done_ = true;
- }
- };
-
- TestThread* RunInitOnceInNewThread() {
- return new TestThread(NewCallback(this, &OnceInitTest::InitOnce));
- }
- TestThread* RunInitRecursiveOnceInNewThread() {
- return new TestThread(
- NewCallback(this, &OnceInitTest::InitRecursiveOnce));
- }
-
- enum State {
- INIT_NOT_STARTED,
- INIT_STARTED,
- INIT_DONE
- };
- State CurrentState() {
- MutexLock lock(&mutex_);
- return state_;
- }
-
- void WaitABit() {
-#ifdef _WIN32
- Sleep(1000);
-#else
- sleep(1);
-#endif
- }
-
- private:
- Mutex mutex_;
- Mutex init_blocker_;
- State state_;
- ProtobufOnceType* once_;
- ProtobufOnceType* recursive_once_;
-
- void Init() {
- MutexLock lock(&mutex_);
- EXPECT_EQ(INIT_NOT_STARTED, state_);
- state_ = INIT_STARTED;
- mutex_.Unlock();
- init_blocker_.Lock();
- init_blocker_.Unlock();
- mutex_.Lock();
- state_ = INIT_DONE;
- }
-
- static OnceInitTest* current_test_;
- static void InitStatic() { current_test_->Init(); }
- static void InitRecursiveStatic() { current_test_->InitOnce(); }
-};
-
-OnceInitTest* OnceInitTest::current_test_ = NULL;
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(simple_once);
-
-TEST_F(OnceInitTest, Simple) {
- SetOnces(&simple_once, NULL);
-
- EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
- InitOnce();
- EXPECT_EQ(INIT_DONE, CurrentState());
-
- // Calling again has no effect.
- InitOnce();
- EXPECT_EQ(INIT_DONE, CurrentState());
-}
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once1);
-GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once2);
-
-TEST_F(OnceInitTest, Recursive) {
- SetOnces(&recursive_once1, &recursive_once2);
-
- EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
- InitRecursiveOnce();
- EXPECT_EQ(INIT_DONE, CurrentState());
-}
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_once);
-
-TEST_F(OnceInitTest, MultipleThreads) {
- SetOnces(&multiple_threads_once, NULL);
-
- scoped_ptr<TestThread> threads[4];
- EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
- for (int i = 0; i < 4; i++) {
- threads[i].reset(RunInitOnceInNewThread());
- }
- for (int i = 0; i < 4; i++) {
- threads[i]->Join();
- }
- EXPECT_EQ(INIT_DONE, CurrentState());
-}
-
-GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once1);
-GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once2);
-
-TEST_F(OnceInitTest, MultipleThreadsBlocked) {
- SetOnces(&multiple_threads_blocked_once1, &multiple_threads_blocked_once2);
-
- scoped_ptr<TestThread> threads[8];
- EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
-
- BlockInit();
- for (int i = 0; i < 4; i++) {
- threads[i].reset(RunInitOnceInNewThread());
- }
- for (int i = 4; i < 8; i++) {
- threads[i].reset(RunInitRecursiveOnceInNewThread());
- }
-
- WaitABit();
-
- // We should now have one thread blocked inside Init(), four blocked waiting
- // for Init() to complete, and three blocked waiting for InitRecursive() to
- // complete.
- EXPECT_EQ(INIT_STARTED, CurrentState());
- UnblockInit();
-
- for (int i = 0; i < 8; i++) {
- threads[i]->Join();
- }
- EXPECT_EQ(INIT_DONE, CurrentState());
-}
-
-} // anonymous namespace
-} // namespace protobuf
-} // namespace google
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index 7a54060d..ce1b1e36 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -50,10 +50,13 @@
#elif defined(_M_ARM) || defined(__ARMEL__)
#define GOOGLE_PROTOBUF_ARCH_ARM 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(_M_ARM64)
+#define GOOGLE_PROTOBUF_ARCH_ARM 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#elif defined(__aarch64__)
#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
-#elif defined(__MIPSEL__)
+#elif defined(__mips__)
#if defined(__LP64__)
#define GOOGLE_PROTOBUF_ARCH_MIPS64 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
@@ -96,6 +99,7 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR
#if defined(__APPLE__)
#define GOOGLE_PROTOBUF_OS_APPLE
+#include <Availability.h>
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define GOOGLE_PROTOBUF_OS_IPHONE
@@ -122,4 +126,9 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR
#define GOOGLE_PROTOBUF_NO_THREADLOCAL
#endif
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+// __thread keyword requires at least 10.7
+#define GOOGLE_PROTOBUF_NO_THREADLOCAL
+#endif
+
#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index cecefdcb..3aa6403b 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -91,9 +91,10 @@
// These #includes are for the byte swap functions declared later on.
#ifdef _MSC_VER
#include <stdlib.h> // NOLINT(build/include)
+#include <intrin.h>
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
-#elif defined(__GLIBC__) || defined(__CYGWIN__)
+#elif defined(__GLIBC__) || defined(__BIONIC__) || defined(__CYGWIN__)
#include <byteswap.h> // IWYU pragma: export
#endif
@@ -209,6 +210,19 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#define GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE GOOGLE_ATTRIBUTE_NOINLINE
+#ifndef GOOGLE_ATTRIBUTE_FUNC_ALIGN
+#if defined(__clang__) || \
+ defined(__GNUC__) && (__GNUC__ > 4 ||(__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+// Function alignment attribute introduced in gcc 4.3
+#define GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__ ((aligned(bytes)))
+#else
+#define GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes)
+#endif
+#endif
+
+#define GOOGLE_PROTOBUF_ATTRIBUTE_FUNC_ALIGN(bytes) \
+ GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes)
+
#ifndef GOOGLE_PREDICT_TRUE
#ifdef __GNUC__
// Provided at least since GCC 3.0.
@@ -227,6 +241,13 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#endif
#endif
+#ifndef GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL
+#ifdef __GNUC__
+#define GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL \
+ __attribute__((returns_nonnull))
+#endif
+#endif
+
// Delimits a block of code which may write to memory which is simultaneously
// written by other threads, but which has been determined to be thread-safe
// (e.g. because it is an idempotent write).
@@ -237,20 +258,6 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#define GOOGLE_SAFE_CONCURRENT_WRITES_END()
#endif
-#if defined(__clang__) && defined(__has_cpp_attribute) \
- && !defined(GOOGLE_PROTOBUF_OS_APPLE)
-# if defined(GOOGLE_PROTOBUF_OS_NACL) || defined(EMSCRIPTEN) || \
- __has_cpp_attribute(clang::fallthrough)
-# define GOOGLE_FALLTHROUGH_INTENDED [[clang::fallthrough]]
-# endif
-#elif defined(__GNUC__) && __GNUC__ > 6
-# define GOOGLE_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
-#endif
-
-#ifndef GOOGLE_FALLTHROUGH_INTENDED
-# define GOOGLE_FALLTHROUGH_INTENDED
-#endif
-
#define GOOGLE_GUARDED_BY(x)
#define GOOGLE_ATTRIBUTE_COLD
@@ -348,6 +355,13 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
}
#endif
+#if defined(GOOGLE_PROTOBUF_OS_NACL) \
+ || (defined(__ANDROID__) && defined(__clang__) \
+ && (__clang_major__ == 3 && __clang_minor__ == 8) \
+ && (__clang_patchlevel__ < 275480))
+# define GOOGLE_PROTOBUF_USE_PORTABLE_LOG2
+#endif
+
#if defined(_MSC_VER)
#define GOOGLE_THREAD_LOCAL __declspec(thread)
#else
@@ -366,12 +380,16 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
-#elif !defined(__GLIBC__) && !defined(__CYGWIN__)
+#elif !defined(__GLIBC__) && !defined(__BIONIC__) && !defined(__CYGWIN__)
+#ifndef bswap_16
static inline uint16 bswap_16(uint16 x) {
return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
}
#define bswap_16(x) bswap_16(x)
+#endif
+
+#ifndef bswap_32
static inline uint32 bswap_32(uint32 x) {
return (((x & 0xFF) << 24) |
((x & 0xFF00) << 8) |
@@ -379,6 +397,9 @@ static inline uint32 bswap_32(uint32 x) {
((x & 0xFF000000) >> 24));
}
#define bswap_32(x) bswap_32(x)
+#endif
+
+#ifndef bswap_64
static inline uint64 bswap_64(uint64 x) {
return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) |
((x & GOOGLE_ULONGLONG(0xFF00)) << 40) |
@@ -390,6 +411,7 @@ static inline uint64 bswap_64(uint64 x) {
((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56));
}
#define bswap_64(x) bswap_64(x)
+#endif
#endif
@@ -401,25 +423,28 @@ class Bits {
static uint32 Log2FloorNonZero(uint32 n) {
#if defined(__GNUC__)
return 31 ^ static_cast<uint32>(__builtin_clz(n));
-#elif defined(COMPILER_MSVC) && defined(_M_IX86)
- _asm {
- bsr ebx, n
- mov n, ebx
- }
- return n;
+#elif defined(_MSC_VER)
+ unsigned long where;
+ _BitScanReverse(&where, n);
+ return where;
#else
return Log2FloorNonZero_Portable(n);
#endif
}
static uint32 Log2FloorNonZero64(uint64 n) {
- // arm-nacl-clang runs into an instruction-selection failure when it
- // encounters __builtin_clzll:
+ // Older versions of clang run into an instruction-selection failure when
+ // it encounters __builtin_clzll:
// https://bugs.chromium.org/p/nativeclient/issues/detail?id=4395
- // To work around this, when we build for NaCl we use the portable
+ // This includes arm-nacl-clang and clang in older Android NDK versions.
+ // To work around this, when we build with those we use the portable
// implementation instead.
-#if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_OS_NACL)
+#if defined(__GNUC__) && !defined(GOOGLE_PROTOBUF_USE_PORTABLE_LOG2)
return 63 ^ static_cast<uint32>(__builtin_clzll(n));
+#elif defined(_MSC_VER) && defined(_M_X64)
+ unsigned long where;
+ _BitScanReverse64(&where, n);
+ return where;
#else
return Log2FloorNonZero64_Portable(n);
#endif
diff --git a/src/google/protobuf/stubs/scoped_ptr.h b/src/google/protobuf/stubs/scoped_ptr.h
deleted file mode 100644
index 4423c118..00000000
--- a/src/google/protobuf/stubs/scoped_ptr.h
+++ /dev/null
@@ -1,236 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_
-#define GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_
-
-#include <google/protobuf/stubs/port.h>
-
-namespace google {
-namespace protobuf {
-
-// ===================================================================
-// from google3/base/scoped_ptr.h
-
-namespace internal {
-
-// This is an implementation designed to match the anticipated future TR2
-// implementation of the scoped_ptr class, and its closely-related brethren,
-// scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
-
-template <class C> class scoped_ptr;
-template <class C> class scoped_array;
-
-// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
-// automatically deletes the pointer it holds (if any).
-// That is, scoped_ptr<T> owns the T object that it points to.
-// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
-//
-// The size of a scoped_ptr is small:
-// sizeof(scoped_ptr<C>) == sizeof(C*)
-template <class C>
-class scoped_ptr {
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized scoped_ptr.
- // The input parameter must be allocated with new.
- explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
-
- // Destructor. If there is a C object, delete it.
- // We don't need to test ptr_ == NULL because C++ does that for us.
- ~scoped_ptr() {
- enum { type_must_be_complete = sizeof(C) };
- delete ptr_;
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (p != ptr_) {
- enum { type_must_be_complete = sizeof(C) };
- delete ptr_;
- ptr_ = p;
- }
- }
-
- // Accessors to get the owned object.
- // operator* and operator-> will assert() if there is no current object.
- C& operator*() const {
- assert(ptr_ != NULL);
- return *ptr_;
- }
- C* operator->() const {
- assert(ptr_ != NULL);
- return ptr_;
- }
- C* get() const { return ptr_; }
-
- // Comparison operators.
- // These return whether two scoped_ptr refer to the same object, not just to
- // two different but equal objects.
- bool operator==(C* p) const { return ptr_ == p; }
- bool operator!=(C* p) const { return ptr_ != p; }
-
- // Swap two scoped pointers.
- void swap(scoped_ptr& p2) {
- C* tmp = ptr_;
- ptr_ = p2.ptr_;
- p2.ptr_ = tmp;
- }
-
- // Release a pointer.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() {
- C* retVal = ptr_;
- ptr_ = NULL;
- return retVal;
- }
-
- private:
- C* ptr_;
-
- // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
- // make sense, and if C2 == C, it still doesn't make sense because you should
- // never have the same object owned by two different scoped_ptrs.
- template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
- template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
-
- // Disallow evil constructors
- scoped_ptr(const scoped_ptr&);
- void operator=(const scoped_ptr&);
-};
-
-// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
-// with new [] and the destructor deletes objects with delete [].
-//
-// As with scoped_ptr<C>, a scoped_array<C> either points to an object
-// or is NULL. A scoped_array<C> owns the object that it points to.
-//
-// Size: sizeof(scoped_array<C>) == sizeof(C*)
-template <class C>
-class scoped_array {
- public:
-
- // The element type
- typedef C element_type;
-
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized scoped_array.
- // The input parameter must be allocated with new [].
- explicit scoped_array(C* p = NULL) : array_(p) { }
-
- // Destructor. If there is a C object, delete it.
- // We don't need to test ptr_ == NULL because C++ does that for us.
- ~scoped_array() {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- }
-
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
- // this->reset(this->get()) works.
- void reset(C* p = NULL) {
- if (p != array_) {
- enum { type_must_be_complete = sizeof(C) };
- delete[] array_;
- array_ = p;
- }
- }
-
- // Get one element of the current object.
- // Will assert() if there is no current object, or index i is negative.
- C& operator[](std::ptrdiff_t i) const {
- assert(i >= 0);
- assert(array_ != NULL);
- return array_[i];
- }
-
- // Get a pointer to the zeroth element of the current object.
- // If there is no current object, return NULL.
- C* get() const {
- return array_;
- }
-
- // Comparison operators.
- // These return whether two scoped_array refer to the same object, not just to
- // two different but equal objects.
- bool operator==(C* p) const { return array_ == p; }
- bool operator!=(C* p) const { return array_ != p; }
-
- // Swap two scoped arrays.
- void swap(scoped_array& p2) {
- C* tmp = array_;
- array_ = p2.array_;
- p2.array_ = tmp;
- }
-
- // Release an array.
- // The return value is the current pointer held by this object.
- // If this object holds a NULL pointer, the return value is NULL.
- // After this operation, this object will hold a NULL pointer,
- // and will not own the object any more.
- C* release() {
- C* retVal = array_;
- array_ = NULL;
- return retVal;
- }
-
- private:
- C* array_;
-
- // Forbid comparison of different scoped_array types.
- template <class C2> bool operator==(scoped_array<C2> const& p2) const;
- template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
-
- // Disallow evil constructors
- scoped_array(const scoped_array&);
- void operator=(const scoped_array&);
-};
-
-} // namespace internal
-
-// We made these internal so that they would show up as such in the docs,
-// but we don't want to stick "internal::" in front of them everywhere.
-using internal::scoped_ptr;
-using internal::scoped_array;
-
-
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_STUBS_SCOPED_PTR_H_
diff --git a/src/google/protobuf/stubs/shared_ptr.h b/src/google/protobuf/stubs/shared_ptr.h
deleted file mode 100644
index 7da114e9..00000000
--- a/src/google/protobuf/stubs/shared_ptr.h
+++ /dev/null
@@ -1,471 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2014 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// from google3/util/gtl/shared_ptr.h
-
-#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
-#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
-
-#include <google/protobuf/stubs/atomicops.h>
-
-#include <algorithm> // for swap
-#include <stddef.h>
-#include <memory>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-// Alias to std::shared_ptr for any C++11 platform,
-// and for any supported MSVC compiler.
-#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
- (defined(COMPILER_MSVC) || defined(LANG_CXX11))
-#define UTIL_GTL_USE_STD_SHARED_PTR 1
-#endif
-
-#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
-
-// These are transitional. They will be going away soon.
-// Please just #include <memory> and just type std::shared_ptr yourself, instead
-// of relying on this file.
-//
-// Migration doc: http://go/std-shared-ptr-lsc
-using std::enable_shared_from_this;
-using std::shared_ptr;
-using std::static_pointer_cast;
-using std::weak_ptr;
-
-#else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
-
-// For everything else there is the google3 implementation.
-inline bool RefCountDec(volatile Atomic32 *ptr) {
- return Barrier_AtomicIncrement(ptr, -1) != 0;
-}
-
-inline void RefCountInc(volatile Atomic32 *ptr) {
- NoBarrier_AtomicIncrement(ptr, 1);
-}
-
-template <typename T> class shared_ptr;
-template <typename T> class weak_ptr;
-
-// This class is an internal implementation detail for shared_ptr. If two
-// shared_ptrs point to the same object, they also share a control block.
-// An "empty" shared_pointer refers to NULL and also has a NULL control block.
-// It contains all of the state that's needed for reference counting or any
-// other kind of resource management. In this implementation the control block
-// happens to consist of two atomic words, the reference count (the number
-// of shared_ptrs that share ownership of the object) and the weak count
-// (the number of weak_ptrs that observe the object, plus 1 if the
-// refcount is nonzero).
-//
-// The "plus 1" is to prevent a race condition in the shared_ptr and
-// weak_ptr destructors. We need to make sure the control block is
-// only deleted once, so we need to make sure that at most one
-// object sees the weak count decremented from 1 to 0.
-class SharedPtrControlBlock {
- template <typename T> friend class shared_ptr;
- template <typename T> friend class weak_ptr;
- private:
- SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
- Atomic32 refcount_;
- Atomic32 weak_count_;
-};
-
-// Forward declaration. The class is defined below.
-template <typename T> class enable_shared_from_this;
-
-template <typename T>
-class shared_ptr {
- template <typename U> friend class weak_ptr;
- public:
- typedef T element_type;
-
- shared_ptr() : ptr_(NULL), control_block_(NULL) {}
-
- explicit shared_ptr(T* ptr)
- : ptr_(ptr),
- control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) {
- // If p is non-null and T inherits from enable_shared_from_this, we
- // set up the data that shared_from_this needs.
- MaybeSetupWeakThis(ptr);
- }
-
- // Copy constructor: makes this object a copy of ptr, and increments
- // the reference count.
- template <typename U>
- shared_ptr(const shared_ptr<U>& ptr)
- : ptr_(NULL),
- control_block_(NULL) {
- Initialize(ptr);
- }
- // Need non-templated version to prevent the compiler-generated default
- shared_ptr(const shared_ptr<T>& ptr)
- : ptr_(NULL),
- control_block_(NULL) {
- Initialize(ptr);
- }
-
- // Assignment operator. Replaces the existing shared_ptr with ptr.
- // Increment ptr's reference count and decrement the one being replaced.
- template <typename U>
- shared_ptr<T>& operator=(const shared_ptr<U>& ptr) {
- if (ptr_ != ptr.ptr_) {
- shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
- swap(me);
- }
- return *this;
- }
-
- // Need non-templated version to prevent the compiler-generated default
- shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
- if (ptr_ != ptr.ptr_) {
- shared_ptr<T> me(ptr); // will hold our previous state to be destroyed.
- swap(me);
- }
- return *this;
- }
-
- // TODO(austern): Consider providing this constructor. The draft C++ standard
- // (20.8.10.2.1) includes it. However, it says that this constructor throws
- // a bad_weak_ptr exception when ptr is expired. Is it better to provide this
- // constructor and make it do something else, like fail with a CHECK, or to
- // leave this constructor out entirely?
- //
- // template <typename U>
- // shared_ptr(const weak_ptr<U>& ptr);
-
- ~shared_ptr() {
- if (ptr_ != NULL) {
- if (!RefCountDec(&control_block_->refcount_)) {
- delete ptr_;
-
- // weak_count_ is defined as the number of weak_ptrs that observe
- // ptr_, plus 1 if refcount_ is nonzero.
- if (!RefCountDec(&control_block_->weak_count_)) {
- delete control_block_;
- }
- }
- }
- }
-
- // Replaces underlying raw pointer with the one passed in. The reference
- // count is set to one (or zero if the pointer is NULL) for the pointer
- // being passed in and decremented for the one being replaced.
- //
- // If you have a compilation error with this code, make sure you aren't
- // passing NULL, nullptr, or 0 to this function. Call reset without an
- // argument to reset to a null ptr.
- template <typename Y>
- void reset(Y* p) {
- if (p != ptr_) {
- shared_ptr<T> tmp(p);
- tmp.swap(*this);
- }
- }
-
- void reset() {
- reset(static_cast<T*>(NULL));
- }
-
- // Exchanges the contents of this with the contents of r. This function
- // supports more efficient swapping since it eliminates the need for a
- // temporary shared_ptr object.
- void swap(shared_ptr<T>& r) {
- using std::swap; // http://go/using-std-swap
- swap(ptr_, r.ptr_);
- swap(control_block_, r.control_block_);
- }
-
- // The following function is useful for gaining access to the underlying
- // pointer when a shared_ptr remains in scope so the reference-count is
- // known to be > 0 (e.g. for parameter passing).
- T* get() const {
- return ptr_;
- }
-
- T& operator*() const {
- return *ptr_;
- }
-
- T* operator->() const {
- return ptr_;
- }
-
- long use_count() const {
- return control_block_ ? control_block_->refcount_ : 1;
- }
-
- bool unique() const {
- return use_count() == 1;
- }
-
- private:
- // If r is non-empty, initialize *this to share ownership with r,
- // increasing the underlying reference count.
- // If r is empty, *this remains empty.
- // Requires: this is empty, namely this->ptr_ == NULL.
- template <typename U>
- void Initialize(const shared_ptr<U>& r) {
- // This performs a static_cast on r.ptr_ to U*, which is a no-op since it
- // is already a U*. So initialization here requires that r.ptr_ is
- // implicitly convertible to T*.
- InitializeWithStaticCast<U>(r);
- }
-
- // Initializes *this as described in Initialize, but additionally performs a
- // static_cast from r.ptr_ (V*) to U*.
- // NOTE(gfc): We'd need a more general form to support const_pointer_cast and
- // dynamic_pointer_cast, but those operations are sufficiently discouraged
- // that supporting static_pointer_cast is sufficient.
- template <typename U, typename V>
- void InitializeWithStaticCast(const shared_ptr<V>& r) {
- if (r.control_block_ != NULL) {
- RefCountInc(&r.control_block_->refcount_);
-
- ptr_ = static_cast<U*>(r.ptr_);
- control_block_ = r.control_block_;
- }
- }
-
- // Helper function for the constructor that takes a raw pointer. If T
- // doesn't inherit from enable_shared_from_this<T> then we have nothing to
- // do, so this function is trivial and inline. The other version is declared
- // out of line, after the class definition of enable_shared_from_this.
- void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr);
- void MaybeSetupWeakThis(...) { }
-
- T* ptr_;
- SharedPtrControlBlock* control_block_;
-
-#ifndef SWIG
- template <typename U>
- friend class shared_ptr;
-
- template <typename U, typename V>
- friend shared_ptr<U> static_pointer_cast(const shared_ptr<V>& rhs);
-#endif
-};
-
-// Matches the interface of std::swap as an aid to generic programming.
-template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) {
- r.swap(s);
-}
-
-template <typename T, typename U>
-shared_ptr<T> static_pointer_cast(const shared_ptr<U>& rhs) {
- shared_ptr<T> lhs;
- lhs.template InitializeWithStaticCast<T>(rhs);
- return lhs;
-}
-
-// See comments at the top of the file for a description of why this
-// class exists, and the draft C++ standard (as of July 2009 the
-// latest draft is N2914) for the detailed specification.
-template <typename T>
-class weak_ptr {
- template <typename U> friend class weak_ptr;
- public:
- typedef T element_type;
-
- // Create an empty (i.e. already expired) weak_ptr.
- weak_ptr() : ptr_(NULL), control_block_(NULL) { }
-
- // Create a weak_ptr that observes the same object that ptr points
- // to. Note that there is no race condition here: we know that the
- // control block can't disappear while we're looking at it because
- // it is owned by at least one shared_ptr, ptr.
- template <typename U> weak_ptr(const shared_ptr<U>& ptr) {
- CopyFrom(ptr.ptr_, ptr.control_block_);
- }
-
- // Copy a weak_ptr. The object it points to might disappear, but we
- // don't care: we're only working with the control block, and it can't
- // disappear while we're looking at because it's owned by at least one
- // weak_ptr, ptr.
- template <typename U> weak_ptr(const weak_ptr<U>& ptr) {
- CopyFrom(ptr.ptr_, ptr.control_block_);
- }
-
- // Need non-templated version to prevent default copy constructor
- weak_ptr(const weak_ptr& ptr) {
- CopyFrom(ptr.ptr_, ptr.control_block_);
- }
-
- // Destroy the weak_ptr. If no shared_ptr owns the control block, and if
- // we are the last weak_ptr to own it, then it can be deleted. Note that
- // weak_count_ is defined as the number of weak_ptrs sharing this control
- // block, plus 1 if there are any shared_ptrs. We therefore know that it's
- // safe to delete the control block when weak_count_ reaches 0, without
- // having to perform any additional tests.
- ~weak_ptr() {
- if (control_block_ != NULL &&
- !RefCountDec(&control_block_->weak_count_)) {
- delete control_block_;
- }
- }
-
- weak_ptr& operator=(const weak_ptr& ptr) {
- if (&ptr != this) {
- weak_ptr tmp(ptr);
- tmp.swap(*this);
- }
- return *this;
- }
- template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) {
- weak_ptr tmp(ptr);
- tmp.swap(*this);
- return *this;
- }
- template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) {
- weak_ptr tmp(ptr);
- tmp.swap(*this);
- return *this;
- }
-
- void swap(weak_ptr& ptr) {
- using std::swap; // http://go/using-std-swap
- swap(ptr_, ptr.ptr_);
- swap(control_block_, ptr.control_block_);
- }
-
- void reset() {
- weak_ptr tmp;
- tmp.swap(*this);
- }
-
- // Return the number of shared_ptrs that own the object we are observing.
- // Note that this number can be 0 (if this pointer has expired).
- long use_count() const {
- return control_block_ != NULL ? control_block_->refcount_ : 0;
- }
-
- bool expired() const { return use_count() == 0; }
-
- // Return a shared_ptr that owns the object we are observing. If we
- // have expired, the shared_ptr will be empty. We have to be careful
- // about concurrency, though, since some other thread might be
- // destroying the last owning shared_ptr while we're in this
- // function. We want to increment the refcount only if it's nonzero
- // and get the new value, and we want that whole operation to be
- // atomic.
- shared_ptr<T> lock() const {
- shared_ptr<T> result;
- if (control_block_ != NULL) {
- Atomic32 old_refcount;
- do {
- old_refcount = control_block_->refcount_;
- if (old_refcount == 0)
- break;
- } while (old_refcount !=
- NoBarrier_CompareAndSwap(
- &control_block_->refcount_, old_refcount,
- old_refcount + 1));
- if (old_refcount > 0) {
- result.ptr_ = ptr_;
- result.control_block_ = control_block_;
- }
- }
-
- return result;
- }
-
- private:
- void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
- ptr_ = ptr;
- control_block_ = control_block;
- if (control_block_ != NULL)
- RefCountInc(&control_block_->weak_count_);
- }
-
- private:
- element_type* ptr_;
- SharedPtrControlBlock* control_block_;
-};
-
-template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) {
- r.swap(s);
-}
-
-// See comments at the top of the file for a description of why this class
-// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
-// the latest draft is N2914) for the detailed specification.
-template <typename T>
-class enable_shared_from_this {
- friend class shared_ptr<T>;
- public:
- // Precondition: there must be a shared_ptr that owns *this and that was
- // created, directly or indirectly, from a raw pointer of type T*. (The
- // latter part of the condition is technical but not quite redundant; it
- // rules out some complicated uses involving inheritance hierarchies.)
- shared_ptr<T> shared_from_this() {
- // Behavior is undefined if the precondition isn't satisfied; we choose
- // to die with a CHECK failure.
- GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
- return weak_this_.lock();
- }
- shared_ptr<const T> shared_from_this() const {
- GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
- return weak_this_.lock();
- }
-
- protected:
- enable_shared_from_this() { }
- enable_shared_from_this(const enable_shared_from_this& other) { }
- enable_shared_from_this& operator=(const enable_shared_from_this& other) {
- return *this;
- }
- ~enable_shared_from_this() { }
-
- private:
- weak_ptr<T> weak_this_;
-};
-
-// This is a helper function called by shared_ptr's constructor from a raw
-// pointer. If T inherits from enable_shared_from_this<T>, it sets up
-// weak_this_ so that shared_from_this works correctly. If T does not inherit
-// from weak_this we get a different overload, defined inline, which does
-// nothing.
-template<typename T>
-void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) {
- if (ptr) {
- GOOGLE_CHECK(ptr->weak_this_.expired())
- << "Object already owned by a shared_ptr";
- ptr->weak_this_ = *this;
- }
-}
-
-#endif // UTIL_GTL_USE_STD_SHARED_PTR
-
-} // internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
diff --git a/src/google/protobuf/stubs/singleton.h b/src/google/protobuf/stubs/singleton.h
index 9301f549..2e6ccbdb 100644
--- a/src/google/protobuf/stubs/singleton.h
+++ b/src/google/protobuf/stubs/singleton.h
@@ -30,7 +30,6 @@
#ifndef GOOGLE_PROTOBUF_STUBS_SINGLETON_H__
#define GOOGLE_PROTOBUF_STUBS_SINGLETON_H__
-#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc
index dd1bd614..2bfbe0b4 100644
--- a/src/google/protobuf/stubs/status.cc
+++ b/src/google/protobuf/stubs/status.cc
@@ -124,7 +124,7 @@ string Status::ToString() const {
}
}
-ostream& operator<<(ostream& os, const Status& x) {
+std::ostream& operator<<(std::ostream& os, const Status& x) {
os << x.ToString();
return os;
}
diff --git a/src/google/protobuf/stubs/status.h b/src/google/protobuf/stubs/status.h
index 614ab994..c5d38f0b 100644
--- a/src/google/protobuf/stubs/status.h
+++ b/src/google/protobuf/stubs/status.h
@@ -106,7 +106,7 @@ class LIBPROTOBUF_EXPORT Status {
};
// Prints a human-readable representation of 'x' to 'os'.
-LIBPROTOBUF_EXPORT ostream& operator<<(ostream& os, const Status& x);
+LIBPROTOBUF_EXPORT std::ostream& operator<<(std::ostream& os, const Status& x);
#define EXPECT_OK(value) EXPECT_TRUE((value).ok())
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
index 83fdfe45..d98b9b87 100644
--- a/src/google/protobuf/stubs/stringprintf.cc
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -137,7 +137,7 @@ const int kStringPrintfVectorMaxArgs = 32;
// and we can fix the problem or protect against an attack.
static const char string_printf_empty_block[256] = { '\0' };
-string StringPrintfVector(const char* format, const vector<string>& v) {
+string StringPrintfVector(const char* format, const std::vector<string>& v) {
GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
<< "StringPrintfVector currently only supports up to "
<< kStringPrintfVectorMaxArgs << " arguments. "
diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h
index ab1ab558..7183ec6a 100644
--- a/src/google/protobuf/stubs/stringprintf.h
+++ b/src/google/protobuf/stubs/stringprintf.h
@@ -68,7 +68,7 @@ LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs;
// You can use this version when all your arguments are strings, but
// you don't know how many arguments you'll have at compile time.
// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
-LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector<string>& v);
+LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const std::vector<string>& v);
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc
index d79a6ee4..b2239682 100644
--- a/src/google/protobuf/stubs/structurally_valid.cc
+++ b/src/google/protobuf/stubs/structurally_valid.cc
@@ -1,4 +1,33 @@
-// Copyright 2005-2008 Google Inc. All Rights Reserved.
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
// Author: jrm@google.com (Jim Meehan)
#include <google/protobuf/stubs/common.h>
diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc
index 90888885..eec07a87 100644
--- a/src/google/protobuf/stubs/structurally_valid_unittest.cc
+++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc
@@ -1,3 +1,33 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
// Copyright 2008 Google Inc. All Rights Reserved.
// Author: xpeng@google.com (Peter Peng)
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 1a4d71c8..552d416f 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -226,8 +226,8 @@ void SplitStringToIteratorUsing(const string& full,
void SplitStringUsing(const string& full,
const char* delim,
- vector<string>* result) {
- std::back_insert_iterator< vector<string> > it(*result);
+ std::vector<string>* result) {
+ std::back_insert_iterator< std::vector<string> > it(*result);
SplitStringToIteratorUsing(full, delim, it);
}
@@ -264,8 +264,8 @@ void SplitStringToIteratorAllowEmpty(const StringType& full,
}
void SplitStringAllowEmpty(const string& full, const char* delim,
- vector<string>* result) {
- std::back_insert_iterator<vector<string> > it(*result);
+ std::vector<string>* result) {
+ std::back_insert_iterator<std::vector<string> > it(*result);
SplitStringToIteratorAllowEmpty(full, delim, 0, it);
}
@@ -303,7 +303,7 @@ static void JoinStringsIterator(const ITERATOR& start,
}
}
-void JoinStrings(const vector<string>& components,
+void JoinStrings(const std::vector<string>& components,
const char* delim,
string * result) {
JoinStringsIterator(components.begin(), components.end(), delim, result);
@@ -332,7 +332,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest) {
}
int UnescapeCEscapeSequences(const char* source, char* dest,
- vector<string> *errors) {
+ std::vector<string> *errors) {
GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented.";
char* d = dest;
@@ -468,8 +468,8 @@ int UnescapeCEscapeString(const string& src, string* dest) {
}
int UnescapeCEscapeString(const string& src, string* dest,
- vector<string> *errors) {
- scoped_array<char> unescaped(new char[src.size() + 1]);
+ std::vector<string> *errors) {
+ std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
GOOGLE_CHECK(dest);
dest->assign(unescaped.get(), len);
@@ -477,7 +477,7 @@ int UnescapeCEscapeString(const string& src, string* dest,
}
string UnescapeCEscapeString(const string& src) {
- scoped_array<char> unescaped(new char[src.size() + 1]);
+ std::unique_ptr<char[]> unescaped(new char[src.size() + 1]);
int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL);
return string(unescaped.get(), len);
}
@@ -620,7 +620,7 @@ namespace strings {
string Utf8SafeCEscape(const string& src) {
const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
- scoped_array<char> dest(new char[dest_length]);
+ std::unique_ptr<char[]> dest(new char[dest_length]);
const int len = CEscapeInternal(src.data(), src.size(),
dest.get(), dest_length, false, true);
GOOGLE_DCHECK_GE(len, 0);
@@ -629,7 +629,7 @@ string Utf8SafeCEscape(const string& src) {
string CHexEscape(const string& src) {
const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
- scoped_array<char> dest(new char[dest_length]);
+ std::unique_ptr<char[]> dest(new char[dest_length]);
const int len = CEscapeInternal(src.data(), src.size(),
dest.get(), dest_length, true, false);
GOOGLE_DCHECK_GE(len, 0);
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index df28c94d..a839b8b3 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -213,7 +213,7 @@ LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
// over all of them.
// ----------------------------------------------------------------------
LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
- vector<string>* res);
+ std::vector<string>* res);
// Split a string using one or more byte delimiters, presented
// as a nul-terminated c string. Append the components to 'result'.
@@ -225,15 +225,15 @@ LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
// ----------------------------------------------------------------------
LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full,
const char* delim,
- vector<string>* result);
+ std::vector<string>* result);
// ----------------------------------------------------------------------
// Split()
// Split a string using a character delimiter.
// ----------------------------------------------------------------------
-inline vector<string> Split(
+inline std::vector<string> Split(
const string& full, const char* delim, bool skip_empty = true) {
- vector<string> result;
+ std::vector<string> result;
if (skip_empty) {
SplitStringUsing(full, delim, &result);
} else {
@@ -250,10 +250,10 @@ inline vector<string> Split(
// another takes a pointer to the target string. In the latter case the
// target string is cleared and overwritten.
// ----------------------------------------------------------------------
-LIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components,
+LIBPROTOBUF_EXPORT void JoinStrings(const std::vector<string>& components,
const char* delim, string* result);
-inline string JoinStrings(const vector<string>& components,
+inline string JoinStrings(const std::vector<string>& components,
const char* delim) {
string result;
JoinStrings(components, delim, &result);
@@ -285,15 +285,15 @@ inline string JoinStrings(const vector<string>& components,
//
// Errors: In the first form of the call, errors are reported with
// LOG(ERROR). The same is true for the second form of the call if
-// the pointer to the string vector is NULL; otherwise, error
-// messages are stored in the vector. In either case, the effect on
+// the pointer to the string std::vector is NULL; otherwise, error
+// messages are stored in the std::vector. In either case, the effect on
// the dest array is not defined, but rest of the source will be
// processed.
// ----------------------------------------------------------------------
LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
- vector<string> *errors);
+ std::vector<string> *errors);
// ----------------------------------------------------------------------
// UnescapeCEscapeString()
@@ -312,7 +312,7 @@ LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
- vector<string> *errors);
+ std::vector<string> *errors);
LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
// ----------------------------------------------------------------------
diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc
index 5d62fc4a..6bf0f598 100644
--- a/src/google/protobuf/stubs/strutil_unittest.cc
+++ b/src/google/protobuf/stubs/strutil_unittest.cc
@@ -782,7 +782,7 @@ TEST(Base64, EscapeAndUnescape) {
reinterpret_cast<const unsigned char*>(base64_strings[i].plaintext);
int plain_length = strlen(base64_strings[i].plaintext);
int cypher_length = strlen(base64_strings[i].cyphertext);
- vector<char> buffer(cypher_length+1);
+ std::vector<char> buffer(cypher_length+1);
int encode_length = WebSafeBase64Escape(unsigned_plaintext,
plain_length,
&buffer[0],
diff --git a/src/google/protobuf/stubs/time.cc b/src/google/protobuf/stubs/time.cc
index 49c0412c..6def637e 100644
--- a/src/google/protobuf/stubs/time.cc
+++ b/src/google/protobuf/stubs/time.cc
@@ -80,9 +80,9 @@ bool ValidateDateTime(const DateTime& time) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
- return time.month <= kDaysInMonth[time.month] + 1;
+ return time.day <= kDaysInMonth[time.month] + 1;
} else {
- return time.month <= kDaysInMonth[time.month];
+ return time.day <= kDaysInMonth[time.month];
}
}
diff --git a/src/google/protobuf/stubs/time_test.cc b/src/google/protobuf/stubs/time_test.cc
index 59e9d1c7..53da9480 100644
--- a/src/google/protobuf/stubs/time_test.cc
+++ b/src/google/protobuf/stubs/time_test.cc
@@ -149,6 +149,59 @@ TEST(DateTimeTest, LeapYear) {
CreateTimestamp(2400, 3, 1) - CreateTimestamp(2400, 2, 29));
}
+TEST(DateTimeTest, WrongDays) {
+ int64 seconds;
+ DateTime time;
+ time.hour = 0;
+ time.minute = 0;
+ time.second = 0;
+ time.month = 2;
+
+ // Non-leap year.
+ time.year = 2015;
+ time.day = 29;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Leap year.
+ time.year = 2016;
+ time.day = 29;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 30;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Non-leap year.
+ time.year = 2100;
+ time.day = 29;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Leap year.
+ time.year = 2400;
+ time.day = 29;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 30;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Non-february
+ time.year = 2015;
+ time.month = 1;
+ time.day = 0;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+ time.day = 1;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 31;
+ ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
+ time.day = 32;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+
+ // Bad month
+ time.year = 2015;
+ time.month = 0;
+ time.day = 1;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+ time.month = 13;
+ ASSERT_FALSE(DateTimeToSeconds(time, &seconds));
+}
+
TEST(DateTimeTest, StringFormat) {
DateTime start, end;
start.year = 1;
diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h
deleted file mode 100644
index 3ab5ea7d..00000000
--- a/src/google/protobuf/stubs/type_traits.h
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ----
-// Author: Matt Austern
-//
-// This code is compiled directly on many platforms, including client
-// platforms like Windows, Mac, and embedded systems. Before making
-// any changes here, make sure that you're not breaking any platforms.
-//
-// Define a small subset of tr1 type traits. The traits we define are:
-// enable_if
-// is_integral
-// is_floating_point
-// is_pointer
-// is_enum
-// is_reference
-// is_pod
-// has_trivial_constructor
-// has_trivial_copy
-// has_trivial_assign
-// has_trivial_destructor
-// remove_const
-// remove_volatile
-// remove_cv
-// remove_reference
-// add_reference
-// remove_pointer
-// is_same
-// is_convertible
-// We can add more type traits as required.
-
-#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
-#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
-
-#include <cstddef> // for NULL
-#include <utility> // For pair
-
-#include <google/protobuf/stubs/template_util.h> // For true_type and false_type
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-template<typename B, typename D>
-struct is_base_of {
- typedef char (&yes)[1];
- typedef char (&no)[2];
-
- // BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac.
- #undef check
- // END GOOGLE LOCAL MODIFICATION
-
- static yes check(const B*);
- static no check(const void*);
-
- enum {
- value = sizeof(check(static_cast<const D*>(NULL))) == sizeof(yes),
- };
-};
-
-template <bool cond, class T = void> struct enable_if;
-template <class T> struct is_integral;
-template <class T> struct is_floating_point;
-template <class T> struct is_pointer;
-// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-// is_enum uses is_convertible, which is not available on MSVC.
-template <class T> struct is_enum;
-#endif
-template <class T> struct is_reference;
-template <class T> struct is_pod;
-template <class T> struct has_trivial_constructor;
-template <class T> struct has_trivial_copy;
-template <class T> struct has_trivial_assign;
-template <class T> struct has_trivial_destructor;
-template <class T> struct remove_const;
-template <class T> struct remove_volatile;
-template <class T> struct remove_cv;
-template <class T> struct remove_reference;
-template <class T> struct add_reference;
-template <class T> struct remove_pointer;
-template <class T, class U> struct is_same;
-#if !(defined(__GNUC__) && __GNUC__ <= 3)
-template <class From, class To> struct is_convertible;
-#endif
-
-// enable_if, equivalent semantics to c++11 std::enable_if, specifically:
-// "If B is true, the member typedef type shall equal T; otherwise, there
-// shall be no member typedef type."
-// Specified by 20.9.7.6 [Other transformations]
-
-template<bool cond, class T> struct enable_if { typedef T type; };
-template<class T> struct enable_if<false, T> {};
-// is_integral is false except for the built-in integer types. A
-// cv-qualified type is integral if and only if the underlying type is.
-template <class T> struct is_integral : false_type { };
-template<> struct is_integral<bool> : true_type { };
-template<> struct is_integral<char> : true_type { };
-template<> struct is_integral<unsigned char> : true_type { };
-template<> struct is_integral<signed char> : true_type { };
-#if defined(_MSC_VER)
-// wchar_t is not by default a distinct type from unsigned short in
-// Microsoft C.
-// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
-template<> struct is_integral<__wchar_t> : true_type { };
-#else
-template<> struct is_integral<wchar_t> : true_type { };
-#endif
-template<> struct is_integral<short> : true_type { };
-template<> struct is_integral<unsigned short> : true_type { };
-template<> struct is_integral<int> : true_type { };
-template<> struct is_integral<unsigned int> : true_type { };
-template<> struct is_integral<long> : true_type { };
-template<> struct is_integral<unsigned long> : true_type { };
-#if defined(HAVE_LONG_LONG) || defined(_MSC_VER)
-template<> struct is_integral<long long> : true_type { };
-template<> struct is_integral<unsigned long long> : true_type { };
-#endif
-template <class T> struct is_integral<const T> : is_integral<T> { };
-template <class T> struct is_integral<volatile T> : is_integral<T> { };
-template <class T> struct is_integral<const volatile T> : is_integral<T> { };
-
-// is_floating_point is false except for the built-in floating-point types.
-// A cv-qualified type is integral if and only if the underlying type is.
-template <class T> struct is_floating_point : false_type { };
-template<> struct is_floating_point<float> : true_type { };
-template<> struct is_floating_point<double> : true_type { };
-template<> struct is_floating_point<long double> : true_type { };
-template <class T> struct is_floating_point<const T>
- : is_floating_point<T> { };
-template <class T> struct is_floating_point<volatile T>
- : is_floating_point<T> { };
-template <class T> struct is_floating_point<const volatile T>
- : is_floating_point<T> { };
-
-// is_pointer is false except for pointer types. A cv-qualified type (e.g.
-// "int* const", as opposed to "int const*") is cv-qualified if and only if
-// the underlying type is.
-template <class T> struct is_pointer : false_type { };
-template <class T> struct is_pointer<T*> : true_type { };
-template <class T> struct is_pointer<const T> : is_pointer<T> { };
-template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
-template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
-
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
-
-namespace type_traits_internal {
-
-template <class T> struct is_class_or_union {
- template <class U> static small_ tester(void (U::*)());
- template <class U> static big_ tester(...);
- static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
-};
-
-// is_convertible chokes if the first argument is an array. That's why
-// we use add_reference here.
-template <bool NotUnum, class T> struct is_enum_impl
- : is_convertible<typename add_reference<T>::type, int> { };
-
-template <class T> struct is_enum_impl<true, T> : false_type { };
-
-} // namespace type_traits_internal
-
-// Specified by TR1 [4.5.1] primary type categories.
-
-// Implementation note:
-//
-// Each type is either void, integral, floating point, array, pointer,
-// reference, member object pointer, member function pointer, enum,
-// union or class. Out of these, only integral, floating point, reference,
-// class and enum types are potentially convertible to int. Therefore,
-// if a type is not a reference, integral, floating point or class and
-// is convertible to int, it's a enum. Adding cv-qualification to a type
-// does not change whether it's an enum.
-//
-// Is-convertible-to-int check is done only if all other checks pass,
-// because it can't be used with some types (e.g. void or classes with
-// inaccessible conversion operators).
-template <class T> struct is_enum
- : type_traits_internal::is_enum_impl<
- is_same<T, void>::value ||
- is_integral<T>::value ||
- is_floating_point<T>::value ||
- is_reference<T>::value ||
- type_traits_internal::is_class_or_union<T>::value,
- T> { };
-
-template <class T> struct is_enum<const T> : is_enum<T> { };
-template <class T> struct is_enum<volatile T> : is_enum<T> { };
-template <class T> struct is_enum<const volatile T> : is_enum<T> { };
-
-#endif
-
-// is_reference is false except for reference types.
-template<typename T> struct is_reference : false_type {};
-template<typename T> struct is_reference<T&> : true_type {};
-
-
-// We can't get is_pod right without compiler help, so fail conservatively.
-// We will assume it's false except for arithmetic types, enumerations,
-// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
-// is not a POD even if T and U are PODs.
-template <class T> struct is_pod
- : integral_constant<bool, (is_integral<T>::value ||
- is_floating_point<T>::value ||
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
- // is_enum is not available on MSVC.
- is_enum<T>::value ||
-#endif
- is_pointer<T>::value)> { };
-template <class T> struct is_pod<const T> : is_pod<T> { };
-template <class T> struct is_pod<volatile T> : is_pod<T> { };
-template <class T> struct is_pod<const volatile T> : is_pod<T> { };
-
-
-// We can't get has_trivial_constructor right without compiler help, so
-// fail conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial
-// constructors. (3) array of a type with a trivial constructor.
-// (4) const versions thereof.
-template <class T> struct has_trivial_constructor : is_pod<T> { };
-template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
- : integral_constant<bool,
- (has_trivial_constructor<T>::value &&
- has_trivial_constructor<U>::value)> { };
-template <class A, int N> struct has_trivial_constructor<A[N]>
- : has_trivial_constructor<A> { };
-template <class T> struct has_trivial_constructor<const T>
- : has_trivial_constructor<T> { };
-
-// We can't get has_trivial_copy right without compiler help, so fail
-// conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial copy
-// constructors. (3) array of a type with a trivial copy constructor.
-// (4) const versions thereof.
-template <class T> struct has_trivial_copy : is_pod<T> { };
-template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
- : integral_constant<bool,
- (has_trivial_copy<T>::value &&
- has_trivial_copy<U>::value)> { };
-template <class A, int N> struct has_trivial_copy<A[N]>
- : has_trivial_copy<A> { };
-template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
-
-// We can't get has_trivial_assign right without compiler help, so fail
-// conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial copy
-// constructors. (3) array of a type with a trivial assign constructor.
-template <class T> struct has_trivial_assign : is_pod<T> { };
-template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
- : integral_constant<bool,
- (has_trivial_assign<T>::value &&
- has_trivial_assign<U>::value)> { };
-template <class A, int N> struct has_trivial_assign<A[N]>
- : has_trivial_assign<A> { };
-
-// We can't get has_trivial_destructor right without compiler help, so
-// fail conservatively. We will assume it's false except for: (1) types
-// for which is_pod is true. (2) std::pair of types with trivial
-// destructors. (3) array of a type with a trivial destructor.
-// (4) const versions thereof.
-template <class T> struct has_trivial_destructor : is_pod<T> { };
-template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
- : integral_constant<bool,
- (has_trivial_destructor<T>::value &&
- has_trivial_destructor<U>::value)> { };
-template <class A, int N> struct has_trivial_destructor<A[N]>
- : has_trivial_destructor<A> { };
-template <class T> struct has_trivial_destructor<const T>
- : has_trivial_destructor<T> { };
-
-// Specified by TR1 [4.7.1]
-template<typename T> struct remove_const { typedef T type; };
-template<typename T> struct remove_const<T const> { typedef T type; };
-template<typename T> struct remove_volatile { typedef T type; };
-template<typename T> struct remove_volatile<T volatile> { typedef T type; };
-template<typename T> struct remove_cv {
- typedef typename remove_const<typename remove_volatile<T>::type>::type type;
-};
-
-
-// Specified by TR1 [4.7.2] Reference modifications.
-template<typename T> struct remove_reference { typedef T type; };
-template<typename T> struct remove_reference<T&> { typedef T type; };
-
-template <typename T> struct add_reference { typedef T& type; };
-template <typename T> struct add_reference<T&> { typedef T& type; };
-
-// Specified by TR1 [4.7.4] Pointer modifications.
-template<typename T> struct remove_pointer { typedef T type; };
-template<typename T> struct remove_pointer<T*> { typedef T type; };
-template<typename T> struct remove_pointer<T* const> { typedef T type; };
-template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
-template<typename T> struct remove_pointer<T* const volatile> {
- typedef T type; };
-
-// Specified by TR1 [4.6] Relationships between types
-template<typename T, typename U> struct is_same : public false_type { };
-template<typename T> struct is_same<T, T> : public true_type { };
-
-// Specified by TR1 [4.6] Relationships between types
-#if !(defined(__GNUC__) && __GNUC__ <= 3)
-namespace type_traits_internal {
-
-// This class is an implementation detail for is_convertible, and you
-// don't need to know how it works to use is_convertible. For those
-// who care: we declare two different functions, one whose argument is
-// of type To and one with a variadic argument list. We give them
-// return types of different size, so we can use sizeof to trick the
-// compiler into telling us which function it would have chosen if we
-// had called it with an argument of type From. See Alexandrescu's
-// _Modern C++ Design_ for more details on this sort of trick.
-
-template <typename From, typename To>
-struct ConvertHelper {
- static small_ Test(To);
- static big_ Test(...);
- static From Create();
- enum {
- value = sizeof(Test(Create())) == sizeof(small_)
- };
-};
-} // namespace type_traits_internal
-
-// Inherits from true_type if From is convertible to To, false_type otherwise.
-template <typename From, typename To>
-struct is_convertible
- : integral_constant<bool,
- type_traits_internal::ConvertHelper<From, To>::value> {
-};
-#endif
-
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_
diff --git a/src/google/protobuf/stubs/type_traits_unittest.cc b/src/google/protobuf/stubs/type_traits_unittest.cc
deleted file mode 100644
index 49c10ace..00000000
--- a/src/google/protobuf/stubs/type_traits_unittest.cc
+++ /dev/null
@@ -1,631 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ----
-// Author: Matt Austern
-
-#include <google/protobuf/stubs/type_traits.h>
-
-#include <stdlib.h> // for exit()
-#include <stdio.h>
-#include <string>
-#include <vector>
-
-#include <google/protobuf/testing/googletest.h>
-#include <gtest/gtest.h>
-
-typedef int int32;
-// IBM AIX typedefs `int64` in `sys/inttypes.h`, included transitively above.
-#ifndef _AIX
-typedef long int64;
-#endif
-
-using std::string;
-using std::vector;
-using std::pair;
-
-
-// This assertion produces errors like "error: invalid use of
-// incomplete type 'struct <unnamed>::AssertTypesEq<const int, int>'"
-// when it fails.
-template<typename T, typename U> struct AssertTypesEq;
-template<typename T> struct AssertTypesEq<T, T> {};
-#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast<void>(AssertTypesEq<T, U>())
-
-// A user-defined POD type.
-struct A {
- int n_;
-};
-
-// A user-defined non-POD type with a trivial copy constructor.
-class B {
- public:
- explicit B(int n) : n_(n) { }
- private:
- int n_;
-};
-
-// Another user-defined non-POD type with a trivial copy constructor.
-// We will explicitly declare C to have a trivial copy constructor
-// by specializing has_trivial_copy.
-class C {
- public:
- explicit C(int n) : n_(n) { }
- private:
- int n_;
-};
-
-namespace google {
-namespace protobuf {
-namespace internal {
-template<> struct has_trivial_copy<C> : true_type { };
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-// Another user-defined non-POD type with a trivial assignment operator.
-// We will explicitly declare C to have a trivial assignment operator
-// by specializing has_trivial_assign.
-class D {
- public:
- explicit D(int n) : n_(n) { }
- private:
- int n_;
-};
-
-namespace google {
-namespace protobuf {
-namespace internal {
-template<> struct has_trivial_assign<D> : true_type { };
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-// Another user-defined non-POD type with a trivial constructor.
-// We will explicitly declare E to have a trivial constructor
-// by specializing has_trivial_constructor.
-class E {
- public:
- int n_;
-};
-
-namespace google {
-namespace protobuf {
-namespace internal {
-template<> struct has_trivial_constructor<E> : true_type { };
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-// Another user-defined non-POD type with a trivial destructor.
-// We will explicitly declare E to have a trivial destructor
-// by specializing has_trivial_destructor.
-class F {
- public:
- explicit F(int n) : n_(n) { }
- private:
- int n_;
-};
-
-namespace google {
-namespace protobuf {
-namespace internal {
-template<> struct has_trivial_destructor<F> : true_type { };
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-
-enum G {};
-
-union H {};
-
-class I {
- public:
- operator int() const;
-};
-
-class J {
- private:
- operator int() const;
-};
-
-namespace google {
-namespace protobuf {
-namespace internal {
-namespace {
-
-// A base class and a derived class that inherits from it, used for
-// testing conversion type traits.
-class Base {
- public:
- virtual ~Base() { }
-};
-
-class Derived : public Base {
-};
-
-TEST(TypeTraitsTest, TestIsInteger) {
- // Verify that is_integral is true for all integer types.
- EXPECT_TRUE(is_integral<bool>::value);
- EXPECT_TRUE(is_integral<char>::value);
- EXPECT_TRUE(is_integral<unsigned char>::value);
- EXPECT_TRUE(is_integral<signed char>::value);
- EXPECT_TRUE(is_integral<wchar_t>::value);
- EXPECT_TRUE(is_integral<int>::value);
- EXPECT_TRUE(is_integral<unsigned int>::value);
- EXPECT_TRUE(is_integral<short>::value);
- EXPECT_TRUE(is_integral<unsigned short>::value);
- EXPECT_TRUE(is_integral<long>::value);
- EXPECT_TRUE(is_integral<unsigned long>::value);
-
- // Verify that is_integral is false for a few non-integer types.
- EXPECT_FALSE(is_integral<void>::value);
- EXPECT_FALSE(is_integral<float>::value);
- EXPECT_FALSE(is_integral<string>::value);
- EXPECT_FALSE(is_integral<int*>::value);
- EXPECT_FALSE(is_integral<A>::value);
- EXPECT_FALSE((is_integral<pair<int, int> >::value));
-
- // Verify that cv-qualified integral types are still integral, and
- // cv-qualified non-integral types are still non-integral.
- EXPECT_TRUE(is_integral<const char>::value);
- EXPECT_TRUE(is_integral<volatile bool>::value);
- EXPECT_TRUE(is_integral<const volatile unsigned int>::value);
- EXPECT_FALSE(is_integral<const float>::value);
- EXPECT_FALSE(is_integral<int* volatile>::value);
- EXPECT_FALSE(is_integral<const volatile string>::value);
-}
-
-TEST(TypeTraitsTest, TestIsFloating) {
- // Verify that is_floating_point is true for all floating-point types.
- EXPECT_TRUE(is_floating_point<float>::value);
- EXPECT_TRUE(is_floating_point<double>::value);
- EXPECT_TRUE(is_floating_point<long double>::value);
-
- // Verify that is_floating_point is false for a few non-float types.
- EXPECT_FALSE(is_floating_point<void>::value);
- EXPECT_FALSE(is_floating_point<long>::value);
- EXPECT_FALSE(is_floating_point<string>::value);
- EXPECT_FALSE(is_floating_point<float*>::value);
- EXPECT_FALSE(is_floating_point<A>::value);
- EXPECT_FALSE((is_floating_point<pair<int, int> >::value));
-
- // Verify that cv-qualified floating point types are still floating, and
- // cv-qualified non-floating types are still non-floating.
- EXPECT_TRUE(is_floating_point<const float>::value);
- EXPECT_TRUE(is_floating_point<volatile double>::value);
- EXPECT_TRUE(is_floating_point<const volatile long double>::value);
- EXPECT_FALSE(is_floating_point<const int>::value);
- EXPECT_FALSE(is_floating_point<volatile string>::value);
- EXPECT_FALSE(is_floating_point<const volatile char>::value);
-}
-
-TEST(TypeTraitsTest, TestIsPointer) {
- // Verify that is_pointer is true for some pointer types.
- EXPECT_TRUE(is_pointer<int*>::value);
- EXPECT_TRUE(is_pointer<void*>::value);
- EXPECT_TRUE(is_pointer<string*>::value);
- EXPECT_TRUE(is_pointer<const void*>::value);
- EXPECT_TRUE(is_pointer<volatile float* const*>::value);
-
- // Verify that is_pointer is false for some non-pointer types.
- EXPECT_FALSE(is_pointer<void>::value);
- EXPECT_FALSE(is_pointer<float&>::value);
- EXPECT_FALSE(is_pointer<long>::value);
- EXPECT_FALSE(is_pointer<vector<int*> >::value);
- EXPECT_FALSE(is_pointer<int[5]>::value);
-
- // A function pointer is a pointer, but a function type, or a function
- // reference type, is not.
- EXPECT_TRUE(is_pointer<int (*)(int x)>::value);
- EXPECT_FALSE(is_pointer<void(char x)>::value);
- EXPECT_FALSE(is_pointer<double (&)(string x)>::value);
-
- // Verify that is_pointer<T> is true for some cv-qualified pointer types,
- // and false for some cv-qualified non-pointer types.
- EXPECT_TRUE(is_pointer<int* const>::value);
- EXPECT_TRUE(is_pointer<const void* volatile>::value);
- EXPECT_TRUE(is_pointer<char** const volatile>::value);
- EXPECT_FALSE(is_pointer<const int>::value);
- EXPECT_FALSE(is_pointer<volatile vector<int*> >::value);
- EXPECT_FALSE(is_pointer<const volatile double>::value);
-}
-
-TEST(TypeTraitsTest, TestIsEnum) {
-// is_enum isn't supported on MSVC or gcc 3.x
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
- // Verify that is_enum is true for enum types.
- EXPECT_TRUE(is_enum<G>::value);
- EXPECT_TRUE(is_enum<const G>::value);
- EXPECT_TRUE(is_enum<volatile G>::value);
- EXPECT_TRUE(is_enum<const volatile G>::value);
-
- // Verify that is_enum is false for a few non-enum types.
- EXPECT_FALSE(is_enum<void>::value);
- EXPECT_FALSE(is_enum<G&>::value);
- EXPECT_FALSE(is_enum<G[1]>::value);
- EXPECT_FALSE(is_enum<const G[1]>::value);
- EXPECT_FALSE(is_enum<G[]>::value);
- EXPECT_FALSE(is_enum<int>::value);
- EXPECT_FALSE(is_enum<float>::value);
- EXPECT_FALSE(is_enum<A>::value);
- EXPECT_FALSE(is_enum<A*>::value);
- EXPECT_FALSE(is_enum<const A>::value);
- EXPECT_FALSE(is_enum<H>::value);
- EXPECT_FALSE(is_enum<I>::value);
- EXPECT_FALSE(is_enum<J>::value);
- EXPECT_FALSE(is_enum<void()>::value);
- EXPECT_FALSE(is_enum<void(*)()>::value);
- EXPECT_FALSE(is_enum<int A::*>::value);
- EXPECT_FALSE(is_enum<void (A::*)()>::value);
-#endif
-}
-
-TEST(TypeTraitsTest, TestIsReference) {
- // Verifies that is_reference is true for all reference types.
- typedef float& RefFloat;
- EXPECT_TRUE(is_reference<float&>::value);
- EXPECT_TRUE(is_reference<const int&>::value);
- EXPECT_TRUE(is_reference<const int*&>::value);
- EXPECT_TRUE(is_reference<int (&)(bool)>::value);
- EXPECT_TRUE(is_reference<RefFloat>::value);
- EXPECT_TRUE(is_reference<const RefFloat>::value);
- EXPECT_TRUE(is_reference<volatile RefFloat>::value);
- EXPECT_TRUE(is_reference<const volatile RefFloat>::value);
-
-
- // Verifies that is_reference is false for all non-reference types.
- EXPECT_FALSE(is_reference<float>::value);
- EXPECT_FALSE(is_reference<const float>::value);
- EXPECT_FALSE(is_reference<volatile float>::value);
- EXPECT_FALSE(is_reference<const volatile float>::value);
- EXPECT_FALSE(is_reference<const int*>::value);
- EXPECT_FALSE(is_reference<int()>::value);
- EXPECT_FALSE(is_reference<void(*)(const char&)>::value);
-}
-
-TEST(TypeTraitsTest, TestAddReference) {
- COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int>::type);
- COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int>::type);
- COMPILE_ASSERT_TYPES_EQ(volatile int&,
- add_reference<volatile int>::type);
- COMPILE_ASSERT_TYPES_EQ(const volatile int&,
- add_reference<const volatile int>::type);
- COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int&>::type);
- COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int&>::type);
- COMPILE_ASSERT_TYPES_EQ(volatile int&,
- add_reference<volatile int&>::type);
- COMPILE_ASSERT_TYPES_EQ(const volatile int&,
- add_reference<const volatile int&>::type);
-}
-
-TEST(TypeTraitsTest, TestIsPod) {
- // Verify that arithmetic types and pointers are marked as PODs.
- EXPECT_TRUE(is_pod<bool>::value);
- EXPECT_TRUE(is_pod<char>::value);
- EXPECT_TRUE(is_pod<unsigned char>::value);
- EXPECT_TRUE(is_pod<signed char>::value);
- EXPECT_TRUE(is_pod<wchar_t>::value);
- EXPECT_TRUE(is_pod<int>::value);
- EXPECT_TRUE(is_pod<unsigned int>::value);
- EXPECT_TRUE(is_pod<short>::value);
- EXPECT_TRUE(is_pod<unsigned short>::value);
- EXPECT_TRUE(is_pod<long>::value);
- EXPECT_TRUE(is_pod<unsigned long>::value);
- EXPECT_TRUE(is_pod<float>::value);
- EXPECT_TRUE(is_pod<double>::value);
- EXPECT_TRUE(is_pod<long double>::value);
- EXPECT_TRUE(is_pod<string*>::value);
- EXPECT_TRUE(is_pod<A*>::value);
- EXPECT_TRUE(is_pod<const B*>::value);
- EXPECT_TRUE(is_pod<C**>::value);
- EXPECT_TRUE(is_pod<const int>::value);
- EXPECT_TRUE(is_pod<char* volatile>::value);
- EXPECT_TRUE(is_pod<const volatile double>::value);
-#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
- EXPECT_TRUE(is_pod<G>::value);
- EXPECT_TRUE(is_pod<const G>::value);
- EXPECT_TRUE(is_pod<volatile G>::value);
- EXPECT_TRUE(is_pod<const volatile G>::value);
-#endif
-
- // Verify that some non-POD types are not marked as PODs.
- EXPECT_FALSE(is_pod<void>::value);
- EXPECT_FALSE(is_pod<string>::value);
- EXPECT_FALSE((is_pod<pair<int, int> >::value));
- EXPECT_FALSE(is_pod<A>::value);
- EXPECT_FALSE(is_pod<B>::value);
- EXPECT_FALSE(is_pod<C>::value);
- EXPECT_FALSE(is_pod<const string>::value);
- EXPECT_FALSE(is_pod<volatile A>::value);
- EXPECT_FALSE(is_pod<const volatile B>::value);
-}
-
-TEST(TypeTraitsTest, TestHasTrivialConstructor) {
- // Verify that arithmetic types and pointers have trivial constructors.
- EXPECT_TRUE(has_trivial_constructor<bool>::value);
- EXPECT_TRUE(has_trivial_constructor<char>::value);
- EXPECT_TRUE(has_trivial_constructor<unsigned char>::value);
- EXPECT_TRUE(has_trivial_constructor<signed char>::value);
- EXPECT_TRUE(has_trivial_constructor<wchar_t>::value);
- EXPECT_TRUE(has_trivial_constructor<int>::value);
- EXPECT_TRUE(has_trivial_constructor<unsigned int>::value);
- EXPECT_TRUE(has_trivial_constructor<short>::value);
- EXPECT_TRUE(has_trivial_constructor<unsigned short>::value);
- EXPECT_TRUE(has_trivial_constructor<long>::value);
- EXPECT_TRUE(has_trivial_constructor<unsigned long>::value);
- EXPECT_TRUE(has_trivial_constructor<float>::value);
- EXPECT_TRUE(has_trivial_constructor<double>::value);
- EXPECT_TRUE(has_trivial_constructor<long double>::value);
- EXPECT_TRUE(has_trivial_constructor<string*>::value);
- EXPECT_TRUE(has_trivial_constructor<A*>::value);
- EXPECT_TRUE(has_trivial_constructor<const B*>::value);
- EXPECT_TRUE(has_trivial_constructor<C**>::value);
-
- // Verify that pairs and arrays of such types have trivial
- // constructors.
- typedef int int10[10];
- EXPECT_TRUE((has_trivial_constructor<pair<int, char*> >::value));
- EXPECT_TRUE(has_trivial_constructor<int10>::value);
-
- // Verify that pairs of types without trivial constructors
- // are not marked as trivial.
- EXPECT_FALSE((has_trivial_constructor<pair<int, string> >::value));
- EXPECT_FALSE((has_trivial_constructor<pair<string, int> >::value));
-
- // Verify that types without trivial constructors are
- // correctly marked as such.
- EXPECT_FALSE(has_trivial_constructor<string>::value);
- EXPECT_FALSE(has_trivial_constructor<vector<int> >::value);
-
- // Verify that E, which we have declared to have a trivial
- // constructor, is correctly marked as such.
- EXPECT_TRUE(has_trivial_constructor<E>::value);
-}
-
-TEST(TypeTraitsTest, TestHasTrivialCopy) {
- // Verify that arithmetic types and pointers have trivial copy
- // constructors.
- EXPECT_TRUE(has_trivial_copy<bool>::value);
- EXPECT_TRUE(has_trivial_copy<char>::value);
- EXPECT_TRUE(has_trivial_copy<unsigned char>::value);
- EXPECT_TRUE(has_trivial_copy<signed char>::value);
- EXPECT_TRUE(has_trivial_copy<wchar_t>::value);
- EXPECT_TRUE(has_trivial_copy<int>::value);
- EXPECT_TRUE(has_trivial_copy<unsigned int>::value);
- EXPECT_TRUE(has_trivial_copy<short>::value);
- EXPECT_TRUE(has_trivial_copy<unsigned short>::value);
- EXPECT_TRUE(has_trivial_copy<long>::value);
- EXPECT_TRUE(has_trivial_copy<unsigned long>::value);
- EXPECT_TRUE(has_trivial_copy<float>::value);
- EXPECT_TRUE(has_trivial_copy<double>::value);
- EXPECT_TRUE(has_trivial_copy<long double>::value);
- EXPECT_TRUE(has_trivial_copy<string*>::value);
- EXPECT_TRUE(has_trivial_copy<A*>::value);
- EXPECT_TRUE(has_trivial_copy<const B*>::value);
- EXPECT_TRUE(has_trivial_copy<C**>::value);
-
- // Verify that pairs and arrays of such types have trivial
- // copy constructors.
- typedef int int10[10];
- EXPECT_TRUE((has_trivial_copy<pair<int, char*> >::value));
- EXPECT_TRUE(has_trivial_copy<int10>::value);
-
- // Verify that pairs of types without trivial copy constructors
- // are not marked as trivial.
- EXPECT_FALSE((has_trivial_copy<pair<int, string> >::value));
- EXPECT_FALSE((has_trivial_copy<pair<string, int> >::value));
-
- // Verify that types without trivial copy constructors are
- // correctly marked as such.
- EXPECT_FALSE(has_trivial_copy<string>::value);
- EXPECT_FALSE(has_trivial_copy<vector<int> >::value);
-
- // Verify that C, which we have declared to have a trivial
- // copy constructor, is correctly marked as such.
- EXPECT_TRUE(has_trivial_copy<C>::value);
-}
-
-TEST(TypeTraitsTest, TestHasTrivialAssign) {
- // Verify that arithmetic types and pointers have trivial assignment
- // operators.
- EXPECT_TRUE(has_trivial_assign<bool>::value);
- EXPECT_TRUE(has_trivial_assign<char>::value);
- EXPECT_TRUE(has_trivial_assign<unsigned char>::value);
- EXPECT_TRUE(has_trivial_assign<signed char>::value);
- EXPECT_TRUE(has_trivial_assign<wchar_t>::value);
- EXPECT_TRUE(has_trivial_assign<int>::value);
- EXPECT_TRUE(has_trivial_assign<unsigned int>::value);
- EXPECT_TRUE(has_trivial_assign<short>::value);
- EXPECT_TRUE(has_trivial_assign<unsigned short>::value);
- EXPECT_TRUE(has_trivial_assign<long>::value);
- EXPECT_TRUE(has_trivial_assign<unsigned long>::value);
- EXPECT_TRUE(has_trivial_assign<float>::value);
- EXPECT_TRUE(has_trivial_assign<double>::value);
- EXPECT_TRUE(has_trivial_assign<long double>::value);
- EXPECT_TRUE(has_trivial_assign<string*>::value);
- EXPECT_TRUE(has_trivial_assign<A*>::value);
- EXPECT_TRUE(has_trivial_assign<const B*>::value);
- EXPECT_TRUE(has_trivial_assign<C**>::value);
-
- // Verify that pairs and arrays of such types have trivial
- // assignment operators.
- typedef int int10[10];
- EXPECT_TRUE((has_trivial_assign<pair<int, char*> >::value));
- EXPECT_TRUE(has_trivial_assign<int10>::value);
-
- // Verify that pairs of types without trivial assignment operators
- // are not marked as trivial.
- EXPECT_FALSE((has_trivial_assign<pair<int, string> >::value));
- EXPECT_FALSE((has_trivial_assign<pair<string, int> >::value));
-
- // Verify that types without trivial assignment operators are
- // correctly marked as such.
- EXPECT_FALSE(has_trivial_assign<string>::value);
- EXPECT_FALSE(has_trivial_assign<vector<int> >::value);
-
- // Verify that D, which we have declared to have a trivial
- // assignment operator, is correctly marked as such.
- EXPECT_TRUE(has_trivial_assign<D>::value);
-}
-
-TEST(TypeTraitsTest, TestHasTrivialDestructor) {
- // Verify that arithmetic types and pointers have trivial destructors.
- EXPECT_TRUE(has_trivial_destructor<bool>::value);
- EXPECT_TRUE(has_trivial_destructor<char>::value);
- EXPECT_TRUE(has_trivial_destructor<unsigned char>::value);
- EXPECT_TRUE(has_trivial_destructor<signed char>::value);
- EXPECT_TRUE(has_trivial_destructor<wchar_t>::value);
- EXPECT_TRUE(has_trivial_destructor<int>::value);
- EXPECT_TRUE(has_trivial_destructor<unsigned int>::value);
- EXPECT_TRUE(has_trivial_destructor<short>::value);
- EXPECT_TRUE(has_trivial_destructor<unsigned short>::value);
- EXPECT_TRUE(has_trivial_destructor<long>::value);
- EXPECT_TRUE(has_trivial_destructor<unsigned long>::value);
- EXPECT_TRUE(has_trivial_destructor<float>::value);
- EXPECT_TRUE(has_trivial_destructor<double>::value);
- EXPECT_TRUE(has_trivial_destructor<long double>::value);
- EXPECT_TRUE(has_trivial_destructor<string*>::value);
- EXPECT_TRUE(has_trivial_destructor<A*>::value);
- EXPECT_TRUE(has_trivial_destructor<const B*>::value);
- EXPECT_TRUE(has_trivial_destructor<C**>::value);
-
- // Verify that pairs and arrays of such types have trivial
- // destructors.
- typedef int int10[10];
- EXPECT_TRUE((has_trivial_destructor<pair<int, char*> >::value));
- EXPECT_TRUE(has_trivial_destructor<int10>::value);
-
- // Verify that pairs of types without trivial destructors
- // are not marked as trivial.
- EXPECT_FALSE((has_trivial_destructor<pair<int, string> >::value));
- EXPECT_FALSE((has_trivial_destructor<pair<string, int> >::value));
-
- // Verify that types without trivial destructors are
- // correctly marked as such.
- EXPECT_FALSE(has_trivial_destructor<string>::value);
- EXPECT_FALSE(has_trivial_destructor<vector<int> >::value);
-
- // Verify that F, which we have declared to have a trivial
- // destructor, is correctly marked as such.
- EXPECT_TRUE(has_trivial_destructor<F>::value);
-}
-
-// Tests remove_pointer.
-TEST(TypeTraitsTest, TestRemovePointer) {
- COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int*>::type);
- COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer<const int*>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* const>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* volatile>::type);
-}
-
-TEST(TypeTraitsTest, TestRemoveConst) {
- COMPILE_ASSERT_TYPES_EQ(int, remove_const<int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_const<const int>::type);
- COMPILE_ASSERT_TYPES_EQ(int *, remove_const<int * const>::type);
- // TR1 examples.
- COMPILE_ASSERT_TYPES_EQ(const int *, remove_const<const int *>::type);
- COMPILE_ASSERT_TYPES_EQ(volatile int,
- remove_const<const volatile int>::type);
-}
-
-TEST(TypeTraitsTest, TestRemoveVolatile) {
- COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<volatile int>::type);
- COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile<int * volatile>::type);
- // TR1 examples.
- COMPILE_ASSERT_TYPES_EQ(volatile int *,
- remove_volatile<volatile int *>::type);
- COMPILE_ASSERT_TYPES_EQ(const int,
- remove_volatile<const volatile int>::type);
-}
-
-TEST(TypeTraitsTest, TestRemoveCV) {
- COMPILE_ASSERT_TYPES_EQ(int, remove_cv<int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_cv<volatile int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_cv<const int>::type);
- COMPILE_ASSERT_TYPES_EQ(int *, remove_cv<int * const volatile>::type);
- // TR1 examples.
- COMPILE_ASSERT_TYPES_EQ(const volatile int *,
- remove_cv<const volatile int *>::type);
- COMPILE_ASSERT_TYPES_EQ(int,
- remove_cv<const volatile int>::type);
-}
-
-TEST(TypeTraitsTest, TestRemoveReference) {
- COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int>::type);
- COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int&>::type);
- COMPILE_ASSERT_TYPES_EQ(const int, remove_reference<const int&>::type);
- COMPILE_ASSERT_TYPES_EQ(int*, remove_reference<int * &>::type);
-}
-
-TEST(TypeTraitsTest, TestIsSame) {
- EXPECT_TRUE((is_same<int32, int32>::value));
- EXPECT_FALSE((is_same<int32, int64>::value));
- EXPECT_FALSE((is_same<int64, int32>::value));
- EXPECT_FALSE((is_same<int, const int>::value));
-
- EXPECT_TRUE((is_same<void, void>::value));
- EXPECT_FALSE((is_same<void, int>::value));
- EXPECT_FALSE((is_same<int, void>::value));
-
- EXPECT_TRUE((is_same<int*, int*>::value));
- EXPECT_TRUE((is_same<void*, void*>::value));
- EXPECT_FALSE((is_same<int*, void*>::value));
- EXPECT_FALSE((is_same<void*, int*>::value));
- EXPECT_FALSE((is_same<void*, const void*>::value));
- EXPECT_FALSE((is_same<void*, void* const>::value));
-
- EXPECT_TRUE((is_same<Base*, Base*>::value));
- EXPECT_TRUE((is_same<Derived*, Derived*>::value));
- EXPECT_FALSE((is_same<Base*, Derived*>::value));
- EXPECT_FALSE((is_same<Derived*, Base*>::value));
-}
-
-TEST(TypeTraitsTest, TestConvertible) {
-#if !(defined(__GNUC__) && __GNUC__ <= 3)
- EXPECT_TRUE((is_convertible<int, int>::value));
- EXPECT_TRUE((is_convertible<int, long>::value));
- EXPECT_TRUE((is_convertible<long, int>::value));
-
- EXPECT_TRUE((is_convertible<int*, void*>::value));
- EXPECT_FALSE((is_convertible<void*, int*>::value));
-
- EXPECT_TRUE((is_convertible<Derived*, Base*>::value));
- EXPECT_FALSE((is_convertible<Base*, Derived*>::value));
- EXPECT_TRUE((is_convertible<Derived*, const Base*>::value));
- EXPECT_FALSE((is_convertible<const Derived*, Base*>::value));
-#endif
-}
-
-} // anonymous namespace
-} // namespace internal
-} // namespace protobuf
-} // namespace google