Upgrade scoped_ptr to Chromium's latest version.

Analogous to the recent libjingle change: http://cl/54929753-p10.
This supports scoped_ptr<T[]> and scoped_ptr<C, FreeDeleter> rather
than scoped_array and scoped_ptr_malloc respectively.

- Add Chromium's template-based COMPILE_ASSERT. We didn't have this
previously in order to support the macro in C. Instead, move the
existing macro to compile_assert_c.h.
- Additionally copy the move.h and template_util.h depedencies and add
the WARN_UNUSED_RESULT macro.
- Leave scoped_array and scoped_ptr_malloc for now, but mark as
deprecated.
- Remove scoped_ptr foo(NULL) use. The default constructor handles it.
- Remove the now redundant COMPILE_ASSERT from peerconnection_jni.cc.
- Add a CHECK_ARRAY_SIZE macro to rtp_format_vp8_unittest.cc to remove
some repeated code.

TESTED=trybots
R=pbos@webrtc.org, tommi@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2449005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5015 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org 2013-10-22 12:50:00 +00:00
parent 06b60c07b7
commit 31628aae7e
28 changed files with 1035 additions and 210 deletions

View File

@ -72,6 +72,7 @@
#include "talk/media/devices/videorendererfactory.h"
#include "talk/media/webrtc/webrtcvideocapturer.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/video_engine/include/vie_base.h"
#include "webrtc/voice_engine/include/voe_base.h"
@ -135,12 +136,6 @@ using webrtc::VideoTrackVector;
CHECK(!count, "Unexpected refcount"); \
} while (0)
// Lifted from chromium's base/basictypes.h.
template <bool>
struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) \
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
namespace {
static JavaVM* g_jvm = NULL; // Set in JNI_OnLoad().

View File

@ -19,9 +19,7 @@
namespace webrtc {
PushResampler::PushResampler()
: sinc_resampler_(NULL),
sinc_resampler_right_(NULL),
src_sample_rate_hz_(0),
: src_sample_rate_hz_(0),
dst_sample_rate_hz_(0),
num_channels_(0),
src_left_(NULL),

View File

@ -17,14 +17,13 @@ namespace webrtc {
PushSincResampler::PushSincResampler(int source_frames,
int destination_frames)
: resampler_(NULL),
: resampler_(new SincResampler(source_frames * 1.0 / destination_frames,
source_frames, this)),
float_buffer_(new float[destination_frames]),
source_ptr_(NULL),
destination_frames_(destination_frames),
first_pass_(true),
source_available_(0) {
resampler_.reset(new SincResampler(source_frames * 1.0 / destination_frames,
source_frames, this));
}
PushSincResampler::~PushSincResampler() {

View File

@ -8,20 +8,14 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* pitch_estimator.c
*
* Pitch filter functions
*
*/
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
#ifdef WEBRTC_ARCH_ARM_NEON
#include <arm_neon.h>
#endif
#include "pitch_estimator.h"
#include "signal_processing_library.h"
#include "system_wrappers/interface/compile_assert.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/system_wrappers/interface/compile_assert_c.h"
/* log2[0.2, 0.5, 0.98] in Q8 */
static const int16_t kLogLagWinQ8[3] = {

View File

@ -8,18 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* pitch_filter.c
*
* Pitch filter functions
*
*/
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_coding/codecs/isac/fix/source/pitch_estimator.h"
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
#include "modules/audio_coding/codecs/isac/fix/source/structs.h"
#include "system_wrappers/interface/compile_assert.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/settings.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"
#include "webrtc/system_wrappers/interface/compile_assert_c.h"
// Number of segments in a pitch subframe.
static const int kSegments = 5;

View File

@ -140,7 +140,6 @@ AudioCodingModuleImpl::AudioCodingModuleImpl(int id)
receiver_initialized_(false),
callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
secondary_send_codec_inst_(),
secondary_encoder_(NULL),
codec_timestamp_(expected_codec_ts_),
first_10ms_data_(false) {

View File

@ -154,7 +154,6 @@ AudioCodingModuleImpl::AudioCodingModuleImpl(const int32_t id, Clock* clock)
last_detected_tone_(kACMToneEnd),
callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
secondary_send_codec_inst_(),
secondary_encoder_(NULL),
initial_delay_ms_(0),
num_packets_accumulated_(0),
num_bytes_accumulated_(0),

View File

@ -59,8 +59,7 @@ NetEqImpl::NetEqImpl(int fs,
PacketBuffer* packet_buffer,
PayloadSplitter* payload_splitter,
TimestampScaler* timestamp_scaler)
: background_noise_(NULL),
buffer_level_filter_(buffer_level_filter),
: buffer_level_filter_(buffer_level_filter),
decoder_database_(decoder_database),
delay_manager_(delay_manager),
delay_peak_detector_(delay_peak_detector),
@ -70,14 +69,6 @@ NetEqImpl::NetEqImpl(int fs,
payload_splitter_(payload_splitter),
timestamp_scaler_(timestamp_scaler),
vad_(new PostDecodeVad()),
algorithm_buffer_(NULL),
sync_buffer_(NULL),
expand_(NULL),
normal_(NULL),
merge_(NULL),
accelerate_(NULL),
preemptive_expand_(NULL),
comfort_noise_(NULL),
last_mode_(kModeNormal),
mute_factor_array_(NULL),
decoded_buffer_length_(kMaxFrameSize),

View File

@ -124,8 +124,6 @@ AudioConferenceMixerImpl::AudioConferenceMixerImpl(int id)
_scratchMixedParticipants(),
_scratchVadPositiveParticipantsAmount(0),
_scratchVadPositiveParticipants(),
_crit(NULL),
_cbCrit(NULL),
_id(id),
_minimumMixingFreq(kLowestPossible),
_mixReceiver(NULL),
@ -142,8 +140,7 @@ AudioConferenceMixerImpl::AudioConferenceMixerImpl(int id)
_timeStamp(0),
_timeScheduler(kProcessPeriodicityInMs),
_mixedAudioLevel(),
_processCalls(0),
_limiter(NULL)
_processCalls(0)
{}
bool AudioConferenceMixerImpl::Init()

View File

@ -18,7 +18,7 @@
#include "webrtc/modules/audio_processing/aecm/include/echo_control_mobile.h"
#include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
#include "webrtc/modules/audio_processing/utility/ring_buffer.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/compile_assert_c.h"
#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
#include "webrtc/typedefs.h"

View File

@ -16,7 +16,7 @@
#include "webrtc/modules/audio_processing/utility/delay_estimator.h"
#include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/compile_assert_c.h"
// Only bit |kBandFirst| through bit |kBandLast| are processed and
// |kBandFirst| - |kBandLast| must be < 32.

View File

@ -78,7 +78,8 @@ void AddCursorOutline(int width, int height, uint32_t* data) {
// Premultiplies RGB components of the pixel data in the given image by
// the corresponding alpha components.
void AlphaMul(uint32_t* data, int width, int height) {
COMPILE_ASSERT(sizeof(uint32_t) == kBytesPerPixel);
COMPILE_ASSERT(sizeof(uint32_t) == kBytesPerPixel,
size_of_uint32_should_be_the_bytes_per_pixel);
for (uint32_t* data_end = data + width * height; data != data_end; ++data) {
RGBQUAD* from = reinterpret_cast<RGBQUAD*>(data);

View File

@ -8,19 +8,20 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* This file includes unit tests for the VP8 packetizer.
*/
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/typedefs.h"
#define CHECK_ARRAY_SIZE(expected_size, array) \
COMPILE_ASSERT(expected_size == sizeof(array) / sizeof(array[0]), \
check_array_size);
namespace webrtc {
class RtpFormatVp8Test : public ::testing::Test {
@ -63,10 +64,8 @@ TEST_F(RtpFormatVp8Test, TestStrictMode) {
const bool kExpectedFragStart[] =
{true, false, true, true, false, false, false};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -91,10 +90,8 @@ TEST_F(RtpFormatVp8Test, TestAggregateMode) {
const int kExpectedPart[] = {0, 0, 0, 1};
const bool kExpectedFragStart[] = {true, false, false, true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -119,10 +116,8 @@ TEST_F(RtpFormatVp8Test, TestAggregateModeManyPartitions1) {
const int kExpectedPart[] = {0, 0, 1, 5};
const bool kExpectedFragStart[] = {true, false, true, true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -147,10 +142,8 @@ TEST_F(RtpFormatVp8Test, TestAggregateModeManyPartitions2) {
const int kExpectedPart[] = {0, 0, 1, 4, 4, 5};
const bool kExpectedFragStart[] = {true, false, true, true, false, true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -175,10 +168,8 @@ TEST_F(RtpFormatVp8Test, TestAggregateModeTwoLargePartitions) {
const int kExpectedPart[] = {0, 0, 1, 1};
const bool kExpectedFragStart[] = {true, false, true, false};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -203,10 +194,8 @@ TEST_F(RtpFormatVp8Test, TestEqualSizeModeFallback) {
// Frag start only true for first packet in equal size mode.
const bool kExpectedFragStart[] = {true, false, false, false};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->set_sloppy_partitioning(true);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
@ -232,10 +221,8 @@ TEST_F(RtpFormatVp8Test, TestNonReferenceBit) {
// Frag start only true for first packet in equal size mode.
const bool kExpectedFragStart[] = {true, false};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->set_sloppy_partitioning(true);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
@ -265,10 +252,8 @@ TEST_F(RtpFormatVp8Test, TestTl0PicIdxAndTID) {
const int kExpectedPart[1] = {0}; // Packet starts with partition 0.
const bool kExpectedFragStart[1] = {true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -295,10 +280,8 @@ TEST_F(RtpFormatVp8Test, TestKeyIdx) {
const int kExpectedPart[1] = {0}; // Packet starts with partition 0.
const bool kExpectedFragStart[1] = {true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);
@ -326,10 +309,8 @@ TEST_F(RtpFormatVp8Test, TestTIDAndKeyIdx) {
const int kExpectedPart[1] = {0}; // Packet starts with partition 0.
const bool kExpectedFragStart[1] = {true};
const int kExpectedNum = sizeof(kExpectedSizes) / sizeof(kExpectedSizes[0]);
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedPart) / sizeof(kExpectedPart[0]));
COMPILE_ASSERT(kExpectedNum ==
sizeof(kExpectedFragStart) / sizeof(kExpectedFragStart[0]));
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedPart);
CHECK_ARRAY_SIZE(kExpectedNum, kExpectedFragStart);
helper_->GetAllPacketsAndCheck(&packetizer, kExpectedSizes, kExpectedPart,
kExpectedFragStart, kExpectedNum);

View File

@ -326,7 +326,6 @@ class RtpPlayerImpl : public RtpPlayerInterface {
float loss_rate, uint32_t rtt_ms, bool reordering)
: ssrc_handlers_(payload_sink_factory, payload_types),
clock_(clock),
packet_source_(NULL),
next_rtp_time_(0),
first_packet_(true),
first_packet_rtp_time_(0),

View File

@ -56,4 +56,4 @@ strheq \reg1, \reg2, \num
.text
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_ASM_DEFINES_H_

View File

@ -8,14 +8,73 @@
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/basictypes.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
/* Use this macro to verify at compile time that certain restrictions are met.
* The argument is the boolean expression to evaluate.
* Example:
* COMPILE_ASSERT(sizeof(foo) < 128);
*/
#define COMPILE_ASSERT(expression) switch(0){case 0: case expression:;}
// The COMPILE_ASSERT macro can be used to verify that a compile time
// expression is true. For example, you could use it to verify the
// size of a static array:
//
// COMPILE_ASSERT(ARRAYSIZE_UNSAFE(content_type_names) == CONTENT_NUM_TYPES,
// content_type_names_incorrect_size);
//
// or to make sure a struct is smaller than a certain size:
//
// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
//
// The second argument to the macro is the name of the variable. If
// the expression is false, most compilers will issue a warning/error
// containing the name of the variable.
template <bool>
struct CompileAssert {
};
#undef COMPILE_ASSERT
#define COMPILE_ASSERT(expr, msg) \
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
// Implementation details of COMPILE_ASSERT:
//
// - COMPILE_ASSERT works by defining an array type that has -1
// elements (and thus is invalid) when the expression is false.
//
// - The simpler definition
//
// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
//
// does not work, as gcc supports variable-length arrays whose sizes
// are determined at run-time (this is gcc's extension and not part
// of the C++ standard). As a result, gcc fails to reject the
// following code with the simple definition:
//
// int foo;
// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
// // not a compile-time constant.
//
// - By using the type CompileAssert<(bool(expr))>, we ensures that
// expr is a compile-time constant. (Template arguments must be
// determined at compile-time.)
//
// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
//
// CompileAssert<bool(expr)>
//
// instead, these compilers will refuse to compile
//
// COMPILE_ASSERT(5 > 0, some_message);
//
// (They seem to think the ">" in "5 > 0" marks the end of the
// template argument list.)
//
// - The array size is (bool(expr) ? 1 : -1), instead of simply
//
// ((expr) ? 1 : -1).
//
// This is to avoid running into a bug in MS VC 7.1, which
// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_
// Only use this for C files. For C++, use compile_assert.h.
//
// Use this macro to verify at compile time that certain restrictions are met.
// The argument is the boolean expression to evaluate.
// Example:
// COMPILE_ASSERT(sizeof(foo) < 128);
#define COMPILE_ASSERT(expression) switch (0) {case 0: case expression:;}
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_COMPILE_ASSERT_H_

View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/move.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_
// Macro with the boilerplate that makes a type move-only in C++03.
//
// USAGE
//
// This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create
// a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be
// the first line in a class declaration.
//
// A class using this macro must call .Pass() (or somehow be an r-value already)
// before it can be:
//
// * Passed as a function argument
// * Used as the right-hand side of an assignment
// * Returned from a function
//
// Each class will still need to define their own "move constructor" and "move
// operator=" to make this useful. Here's an example of the macro, the move
// constructor, and the move operator= from the scoped_ptr class:
//
// template <typename T>
// class scoped_ptr {
// MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
// public:
// scoped_ptr(RValue& other) : ptr_(other.release()) { }
// scoped_ptr& operator=(RValue& other) {
// swap(other);
// return *this;
// }
// };
//
// Note that the constructor must NOT be marked explicit.
//
// For consistency, the second parameter to the macro should always be RValue
// unless you have a strong reason to do otherwise. It is only exposed as a
// macro parameter so that the move constructor and move operator= don't look
// like they're using a phantom type.
//
//
// HOW THIS WORKS
//
// For a thorough explanation of this technique, see:
//
// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
//
// The summary is that we take advantage of 2 properties:
//
// 1) non-const references will not bind to r-values.
// 2) C++ can apply one user-defined conversion when initializing a
// variable.
//
// The first lets us disable the copy constructor and assignment operator
// by declaring private version of them with a non-const reference parameter.
//
// For l-values, direct initialization still fails like in
// DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment
// operators are private.
//
// For r-values, the situation is different. The copy constructor and
// assignment operator are not viable due to (1), so we are trying to call
// a non-existent constructor and non-existing operator= rather than a private
// one. Since we have not committed an error quite yet, we can provide an
// alternate conversion sequence and a constructor. We add
//
// * a private struct named "RValue"
// * a user-defined conversion "operator RValue()"
// * a "move constructor" and "move operator=" that take the RValue& as
// their sole parameter.
//
// Only r-values will trigger this sequence and execute our "move constructor"
// or "move operator=." L-values will match the private copy constructor and
// operator= first giving a "private in this context" error. This combination
// gives us a move-only type.
//
// For signaling a destructive transfer of data from an l-value, we provide a
// method named Pass() which creates an r-value for the current instance
// triggering the move constructor or move operator=.
//
// Other ways to get r-values is to use the result of an expression like a
// function call.
//
// Here's an example with comments explaining what gets triggered where:
//
// class Foo {
// MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue);
//
// public:
// ... API ...
// Foo(RValue other); // Move constructor.
// Foo& operator=(RValue rhs); // Move operator=
// };
//
// Foo MakeFoo(); // Function that returns a Foo.
//
// Foo f;
// Foo f_copy(f); // ERROR: Foo(Foo&) is private in this context.
// Foo f_assign;
// f_assign = f; // ERROR: operator=(Foo&) is private in this context.
//
//
// Foo f(MakeFoo()); // R-value so alternate conversion executed.
// Foo f_copy(f.Pass()); // R-value so alternate conversion executed.
// f = f_copy.Pass(); // R-value so alternate conversion executed.
//
//
// IMPLEMENTATION SUBTLETIES WITH RValue
//
// The RValue struct is just a container for a pointer back to the original
// object. It should only ever be created as a temporary, and no external
// class should ever declare it or use it in a parameter.
//
// It is tempting to want to use the RValue type in function parameters, but
// excluding the limited usage here for the move constructor and move
// operator=, doing so would mean that the function could take both r-values
// and l-values equially which is unexpected. See COMPARED To Boost.Move for
// more details.
//
// An alternate, and incorrect, implementation of the RValue class used by
// Boost.Move makes RValue a fieldless child of the move-only type. RValue&
// is then used in place of RValue in the various operators. The RValue& is
// "created" by doing *reinterpret_cast<RValue*>(this). This has the appeal
// of never creating a temporary RValue struct even with optimizations
// disabled. Also, by virtue of inheritance you can treat the RValue
// reference as if it were the move-only type itself. Unfortunately,
// using the result of this reinterpret_cast<> is actually undefined behavior
// due to C++98 5.2.10.7. In certain compilers (e.g., NaCl) the optimizer
// will generate non-working code.
//
// In optimized builds, both implementations generate the same assembly so we
// choose the one that adheres to the standard.
//
//
// COMPARED TO C++11
//
// In C++11, you would implement this functionality using an r-value reference
// and our .Pass() method would be replaced with a call to std::move().
//
// This emulation also has a deficiency where it uses up the single
// user-defined conversion allowed by C++ during initialization. This can
// cause problems in some API edge cases. For instance, in scoped_ptr, it is
// impossible to make a function "void Foo(scoped_ptr<Parent> p)" accept a
// value of type scoped_ptr<Child> even if you add a constructor to
// scoped_ptr<> that would make it look like it should work. C++11 does not
// have this deficiency.
//
//
// COMPARED TO Boost.Move
//
// Our implementation similar to Boost.Move, but we keep the RValue struct
// private to the move-only type, and we don't use the reinterpret_cast<> hack.
//
// In Boost.Move, RValue is the boost::rv<> template. This type can be used
// when writing APIs like:
//
// void MyFunc(boost::rv<Foo>& f)
//
// that can take advantage of rv<> to avoid extra copies of a type. However you
// would still be able to call this version of MyFunc with an l-value:
//
// Foo f;
// MyFunc(f); // Uh oh, we probably just destroyed |f| w/o calling Pass().
//
// unless someone is very careful to also declare a parallel override like:
//
// void MyFunc(const Foo& f)
//
// that would catch the l-values first. This was declared unsafe in C++11 and
// a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot
// ensure this in C++03.
//
// Since we have no need for writing such APIs yet, our implementation keeps
// RValue private and uses a .Pass() method to do the conversion instead of
// trying to write a version of "std::move()." Writing an API like std::move()
// would require the RValue struct to be public.
//
//
// CAVEATS
//
// If you include a move-only type as a field inside a class that does not
// explicitly declare a copy constructor, the containing class's implicit
// copy constructor will change from Containing(const Containing&) to
// Containing(Containing&). This can cause some unexpected errors.
//
// http://llvm.org/bugs/show_bug.cgi?id=11528
//
// The workaround is to explicitly declare your copy constructor.
//
#define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
private: \
struct rvalue_type { \
explicit rvalue_type(type* object) : object(object) {} \
type* object; \
}; \
type(type&); \
void operator=(type&); \
public: \
operator rvalue_type() { return rvalue_type(this); } \
type Pass() { return type(rvalue_type(this)); } \
private:
#endif // WEBRTC_SYSTEM_WRAPPERS_INTEFACE_MOVE_H_

View File

@ -1,118 +1,581 @@
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
//
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// scoped_ptr mimics a built-in pointer except that it guarantees deletion
// of the object pointed to, either on destruction of the scoped_ptr or via
// an explicit reset(). scoped_ptr is a simple solution for simple needs;
// use shared_ptr or std::auto_ptr if your needs are more complex.
// Borrowed from Chromium's src/base/memory/scoped_ptr.h.
// scoped_ptr_malloc added in by Google. When one of
// these goes out of scope, instead of doing a delete or delete[], it
// calls free(). scoped_ptr_malloc<char> is likely to see much more
// use than any other specializations.
// Scopers help you manage ownership of a pointer, helping you easily manage the
// a pointer within a scope, and automatically destroying the pointer at the
// end of a scope. There are two main classes you will use, which correspond
// to the operators new/delete and new[]/delete[].
//
// Example usage (scoped_ptr<T>):
// {
// scoped_ptr<Foo> foo(new Foo("wee"));
// } // foo goes out of scope, releasing the pointer with it.
//
// {
// scoped_ptr<Foo> foo; // No pointer managed.
// foo.reset(new Foo("wee")); // Now a pointer is managed.
// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed.
// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed.
// foo->Method(); // Foo::Method() called.
// foo.get()->Method(); // Foo::Method() called.
// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer
// // manages a pointer.
// foo.reset(new Foo("wee4")); // foo manages a pointer again.
// foo.reset(); // Foo("wee4") destroyed, foo no longer
// // manages a pointer.
// } // foo wasn't managing a pointer, so nothing was destroyed.
//
// Example usage (scoped_ptr<T[]>):
// {
// scoped_ptr<Foo[]> foo(new Foo[100]);
// foo.get()->Method(); // Foo::Method on the 0th element.
// foo[10].Method(); // Foo::Method on the 10th element.
// }
//
// These scopers also implement part of the functionality of C++11 unique_ptr
// in that they are "movable but not copyable." You can use the scopers in
// the parameter and return types of functions to signify ownership transfer
// in to and out of a function. When calling a function that has a scoper
// as the argument type, it must be called with the result of an analogous
// scoper's Pass() function or another function that generates a temporary;
// passing by copy will NOT work. Here is an example using scoped_ptr:
//
// void TakesOwnership(scoped_ptr<Foo> arg) {
// // Do something with arg
// }
// scoped_ptr<Foo> CreateFoo() {
// // No need for calling Pass() because we are constructing a temporary
// // for the return value.
// return scoped_ptr<Foo>(new Foo("new"));
// }
// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
// return arg.Pass();
// }
//
// {
// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay").
// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL.
// }
//
// Notice that if you do not call Pass() when returning from PassThru(), or
// when invoking TakesOwnership(), the code will not compile because scopers
// are not copyable; they only implement move semantics which require calling
// the Pass() function to signify a destructive transfer of state. CreateFoo()
// is different though because we are constructing a temporary on the return
// line and thus can avoid needing to call Pass().
//
// Pass() properly handles upcast in initialization, i.e. you can use a
// scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
//
// scoped_ptr<Foo> foo(new Foo());
// scoped_ptr<FooParent> parent(foo.Pass());
//
// PassAs<>() should be used to upcast return value in return statement:
//
// scoped_ptr<Foo> CreateFoo() {
// scoped_ptr<FooChild> result(new FooChild());
// return result.PassAs<Foo>();
// }
//
// Note that PassAs<>() is implemented only for scoped_ptr<T>, but not for
// scoped_ptr<T[]>. This is because casting array pointers may not be safe.
// release() added in by Google. Use this to conditionally
// transfer ownership of a heap-allocated object to the caller, usually on
// method success.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
#include <assert.h> // for assert
#include <stddef.h> // for ptrdiff_t
#include <stdlib.h> // for free() decl
// This is an implementation designed to match the anticipated future TR2
// implementation of the scoped_ptr class and scoped_ptr_malloc (deprecated).
#ifdef _WIN32
namespace std { using ::ptrdiff_t; };
#endif // _WIN32
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <algorithm> // For std::swap().
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/constructor_magic.h"
#include "webrtc/system_wrappers/interface/move.h"
#include "webrtc/system_wrappers/interface/template_util.h"
#include "webrtc/typedefs.h"
namespace webrtc {
template <typename T>
class scoped_ptr {
private:
T* ptr;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
public:
typedef T element_type;
explicit scoped_ptr(T* p = NULL): ptr(p) {}
~scoped_ptr() {
typedef char type_must_be_complete[sizeof(T)];
// Function object which deletes its parameter, which must be a pointer.
// If C is an array type, invokes 'delete[]' on the parameter; otherwise,
// invokes 'delete'. The default deleter for scoped_ptr<T>.
template <class T>
struct DefaultDeleter {
DefaultDeleter() {}
template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
// IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
// if U* is implicitly convertible to T* and U is not an array type.
//
// Correct implementation should use SFINAE to disable this
// constructor. However, since there are no other 1-argument constructors,
// using a COMPILE_ASSERT() based on is_convertible<> and requiring
// complete types is simpler and will cause compile failures for equivalent
// misuses.
//
// Note, the is_convertible<U*, T*> check also ensures that U is not an
// array. T is guaranteed to be a non-array, so any U* where U is an array
// cannot convert to T*.
enum { T_must_be_complete = sizeof(T) };
enum { U_must_be_complete = sizeof(U) };
COMPILE_ASSERT((webrtc::is_convertible<U*, T*>::value),
U_ptr_must_implicitly_convert_to_T_ptr);
}
inline void operator()(T* ptr) const {
enum { type_must_be_complete = sizeof(T) };
delete ptr;
}
void reset(T* p = NULL) {
typedef char type_must_be_complete[sizeof(T)];
if (ptr != p) {
T* obj = ptr;
ptr = p;
// Delete last, in case obj destructor indirectly results in ~scoped_ptr
delete obj;
}
}
T& operator*() const {
assert(ptr != NULL);
return *ptr;
}
T* operator->() const {
assert(ptr != NULL);
return ptr;
}
T* get() const {
return ptr;
}
void swap(scoped_ptr & b) {
T* tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
T* release() {
T* tmp = ptr;
ptr = NULL;
return tmp;
}
T** accept() {
if (ptr) {
delete ptr;
ptr = NULL;
}
return &ptr;
}
T** use() {
return &ptr;
}
};
template<typename T> inline
void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
a.swap(b);
// Specialization of DefaultDeleter for array types.
template <class T>
struct DefaultDeleter<T[]> {
inline void operator()(T* ptr) const {
enum { type_must_be_complete = sizeof(T) };
delete[] ptr;
}
private:
// Disable this operator for any U != T because it is undefined to execute
// an array delete when the static type of the array mismatches the dynamic
// type.
//
// References:
// C++98 [expr.delete]p3
// http://cplusplus.github.com/LWG/lwg-defects.html#938
template <typename U> void operator()(U* array) const;
};
template <class T, int n>
struct DefaultDeleter<T[n]> {
// Never allow someone to declare something like scoped_ptr<int[10]>.
COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
};
// Function object which invokes 'free' on its parameter, which must be
// a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
//
// scoped_ptr<int, webrtc::FreeDeleter> foo_ptr(
// static_cast<int*>(malloc(sizeof(int))));
struct FreeDeleter {
inline void operator()(void* ptr) const {
free(ptr);
}
};
namespace internal {
// Minimal implementation of the core logic of scoped_ptr, suitable for
// reuse in both scoped_ptr and its specializations.
template <class T, class D>
class scoped_ptr_impl {
public:
explicit scoped_ptr_impl(T* p) : data_(p) { }
// Initializer for deleters that have data parameters.
scoped_ptr_impl(T* p, const D& d) : data_(p, d) {}
// Templated constructor that destructively takes the value from another
// scoped_ptr_impl.
template <typename U, typename V>
scoped_ptr_impl(scoped_ptr_impl<U, V>* other)
: data_(other->release(), other->get_deleter()) {
// We do not support move-only deleters. We could modify our move
// emulation to have webrtc::subtle::move() and webrtc::subtle::forward()
// functions that are imperfect emulations of their C++11 equivalents,
// but until there's a requirement, just assume deleters are copyable.
}
template <typename U, typename V>
void TakeState(scoped_ptr_impl<U, V>* other) {
// See comment in templated constructor above regarding lack of support
// for move-only deleters.
reset(other->release());
get_deleter() = other->get_deleter();
}
~scoped_ptr_impl() {
if (data_.ptr != NULL) {
// Not using get_deleter() saves one function call in non-optimized
// builds.
static_cast<D&>(data_)(data_.ptr);
}
}
void reset(T* p) {
// This is a self-reset, which is no longer allowed: http://crbug.com/162971
if (p != NULL && p == data_.ptr)
abort();
// Note that running data_.ptr = p can lead to undefined behavior if
// get_deleter()(get()) deletes this. In order to pevent this, reset()
// should update the stored pointer before deleting its old value.
//
// However, changing reset() to use that behavior may cause current code to
// break in unexpected ways. If the destruction of the owned object
// dereferences the scoped_ptr when it is destroyed by a call to reset(),
// then it will incorrectly dispatch calls to |p| rather than the original
// value of |data_.ptr|.
//
// During the transition period, set the stored pointer to NULL while
// deleting the object. Eventually, this safety check will be removed to
// prevent the scenario initially described from occuring and
// http://crbug.com/176091 can be closed.
T* old = data_.ptr;
data_.ptr = NULL;
if (old != NULL)
static_cast<D&>(data_)(old);
data_.ptr = p;
}
T* get() const { return data_.ptr; }
D& get_deleter() { return data_; }
const D& get_deleter() const { return data_; }
void swap(scoped_ptr_impl& p2) {
// Standard swap idiom: 'using std::swap' ensures that std::swap is
// present in the overload set, but we call swap unqualified so that
// any more-specific overloads can be used, if available.
using std::swap;
swap(static_cast<D&>(data_), static_cast<D&>(p2.data_));
swap(data_.ptr, p2.data_.ptr);
}
T* release() {
T* old_ptr = data_.ptr;
data_.ptr = NULL;
return old_ptr;
}
private:
// Needed to allow type-converting constructor.
template <typename U, typename V> friend class scoped_ptr_impl;
// Use the empty base class optimization to allow us to have a D
// member, while avoiding any space overhead for it when D is an
// empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good
// discussion of this technique.
struct Data : public D {
explicit Data(T* ptr_in) : ptr(ptr_in) {}
Data(T* ptr_in, const D& other) : D(other), ptr(ptr_in) {}
T* ptr;
};
Data data_;
DISALLOW_COPY_AND_ASSIGN(scoped_ptr_impl);
};
} // namespace internal
// 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.
// Also like T*, scoped_ptr<T> is thread-compatible, and once you
// dereference it, you get the thread safety guarantees of T.
//
// The size of scoped_ptr is small. On most compilers, when using the
// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
// increase the size proportional to whatever state they need to have. See
// comments inside scoped_ptr_impl<> for details.
//
// Current implementation targets having a strict subset of C++11's
// unique_ptr<> features. Known deficiencies include not supporting move-only
// deleteres, function pointers as deleters, and deleters with reference
// types.
template <class T, class D = webrtc::DefaultDeleter<T> >
class scoped_ptr {
MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
// Constructor. Defaults to initializing with NULL.
scoped_ptr() : impl_(NULL) { }
// Constructor. Takes ownership of p.
explicit scoped_ptr(element_type* p) : impl_(p) { }
// Constructor. Allows initialization of a stateful deleter.
scoped_ptr(element_type* p, const D& d) : impl_(p, d) { }
// Constructor. Allows construction from a scoped_ptr rvalue for a
// convertible type and deleter.
//
// IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
// from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
// has different post-conditions if D is a reference type. Since this
// implementation does not support deleters with reference type,
// we do not need a separate move constructor allowing us to avoid one
// use of SFINAE. You only need to care about this if you modify the
// implementation of scoped_ptr.
template <typename U, typename V>
scoped_ptr(scoped_ptr<U, V> other) : impl_(&other.impl_) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
}
// Constructor. Move constructor for C++03 move emulation of this type.
scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
// operator=. Allows assignment from a scoped_ptr rvalue for a convertible
// type and deleter.
//
// IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
// the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
// form has different requirements on for move-only Deleters. Since this
// implementation does not support move-only Deleters, we do not need a
// separate move assignment operator allowing us to avoid one use of SFINAE.
// You only need to care about this if you modify the implementation of
// scoped_ptr.
template <typename U, typename V>
scoped_ptr& operator=(scoped_ptr<U, V> rhs) {
COMPILE_ASSERT(!webrtc::is_array<U>::value, U_cannot_be_an_array);
impl_.TakeState(&rhs.impl_);
return *this;
}
// Reset. Deletes the currently owned object, if any.
// Then takes ownership of a new object, if given.
void reset(element_type* p = NULL) { impl_.reset(p); }
// Accessors to get the owned object.
// operator* and operator-> will assert() if there is no current object.
element_type& operator*() const {
assert(impl_.get() != NULL);
return *impl_.get();
}
element_type* operator->() const {
assert(impl_.get() != NULL);
return impl_.get();
}
element_type* get() const { return impl_.get(); }
// Access to the deleter.
deleter_type& get_deleter() { return impl_.get_deleter(); }
const deleter_type& get_deleter() const { return impl_.get_deleter(); }
// Allow scoped_ptr<element_type> to be used in boolean expressions, but not
// implicitly convertible to a real bool (which is dangerous).
//
// Note that this trick is only safe when the == and != operators
// are declared explicitly, as otherwise "scoped_ptr1 ==
// scoped_ptr2" will compile but do the wrong thing (i.e., convert
// to Testable and then do the comparison).
private:
typedef webrtc::internal::scoped_ptr_impl<element_type, deleter_type>
scoped_ptr::*Testable;
public:
operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
// two different but equal objects.
bool operator==(const element_type* p) const { return impl_.get() == p; }
bool operator!=(const element_type* p) const { return impl_.get() != p; }
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
}
// 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.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
// C++98 doesn't support functions templates with default parameters which
// makes it hard to write a PassAs() that understands converting the deleter
// while preserving simple calling semantics.
//
// Until there is a use case for PassAs() with custom deleters, just ignore
// the custom deleter.
template <typename PassAsType>
scoped_ptr<PassAsType> PassAs() {
return scoped_ptr<PassAsType>(Pass());
}
private:
// Needed to reach into |impl_| in the constructor.
template <typename U, typename V> friend class scoped_ptr;
webrtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
// Forbidden for API compatibility with std::unique_ptr.
explicit scoped_ptr(int disallow_construction_from_null);
// Forbid comparison of scoped_ptr types. If U != T, it totally
// doesn't make sense, and if U == T, it still doesn't make sense
// because you should never have the same object owned by two different
// scoped_ptrs.
template <class U> bool operator==(scoped_ptr<U> const& p2) const;
template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
template <class T, class D>
class scoped_ptr<T[], D> {
MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
public:
// The element and deleter types.
typedef T element_type;
typedef D deleter_type;
// Constructor. Defaults to initializing with NULL.
scoped_ptr() : impl_(NULL) { }
// Constructor. Stores the given array. Note that the argument's type
// must exactly match T*. In particular:
// - it cannot be a pointer to a type derived from T, because it is
// inherently unsafe in the general case to access an array through a
// pointer whose dynamic type does not match its static type (eg., if
// T and the derived types had different sizes access would be
// incorrectly calculated). Deletion is also always undefined
// (C++98 [expr.delete]p3). If you're doing this, fix your code.
// - it cannot be NULL, because NULL is an integral expression, not a
// pointer to T. Use the no-argument version instead of explicitly
// passing NULL.
// - it cannot be const-qualified differently from T per unique_ptr spec
// (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
// to work around this may use implicit_cast<const T*>().
// However, because of the first bullet in this comment, users MUST
// NOT use implicit_cast<Base*>() to upcast the static type of the array.
explicit scoped_ptr(element_type* array) : impl_(array) { }
// Constructor. Move constructor for C++03 move emulation of this type.
scoped_ptr(RValue rvalue) : impl_(&rvalue.object->impl_) { }
// operator=. Move operator= for C++03 move emulation of this type.
scoped_ptr& operator=(RValue rhs) {
impl_.TakeState(&rhs.object->impl_);
return *this;
}
// Reset. Deletes the currently owned array, if any.
// Then takes ownership of a new object, if given.
void reset(element_type* array = NULL) { impl_.reset(array); }
// Accessors to get the owned array.
element_type& operator[](size_t i) const {
assert(impl_.get() != NULL);
return impl_.get()[i];
}
element_type* get() const { return impl_.get(); }
// Access to the deleter.
deleter_type& get_deleter() { return impl_.get_deleter(); }
const deleter_type& get_deleter() const { return impl_.get_deleter(); }
// Allow scoped_ptr<element_type> to be used in boolean expressions, but not
// implicitly convertible to a real bool (which is dangerous).
private:
typedef webrtc::internal::scoped_ptr_impl<element_type, deleter_type>
scoped_ptr::*Testable;
public:
operator Testable() const { return impl_.get() ? &scoped_ptr::impl_ : NULL; }
// Comparison operators.
// These return whether two scoped_ptr refer to the same object, not just to
// two different but equal objects.
bool operator==(element_type* array) const { return impl_.get() == array; }
bool operator!=(element_type* array) const { return impl_.get() != array; }
// Swap two scoped pointers.
void swap(scoped_ptr& p2) {
impl_.swap(p2.impl_);
}
// 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.
element_type* release() WARN_UNUSED_RESULT {
return impl_.release();
}
private:
// Force element_type to be a complete type.
enum { type_must_be_complete = sizeof(element_type) };
// Actually hold the data.
webrtc::internal::scoped_ptr_impl<element_type, deleter_type> impl_;
// Disable initialization from any type other than element_type*, by
// providing a constructor that matches such an initialization, but is
// private and has no definition. This is disabled because it is not safe to
// call delete[] on an array whose static type does not match its dynamic
// type.
template <typename U> explicit scoped_ptr(U* array);
explicit scoped_ptr(int disallow_construction_from_null);
// Disable reset() from any type other than element_type*, for the same
// reasons as the constructor above.
template <typename U> void reset(U* array);
void reset(int disallow_reset_from_null);
// Forbid comparison of scoped_ptr types. If U != T, it totally
// doesn't make sense, and if U == T, it still doesn't make sense
// because you should never have the same object owned by two different
// scoped_ptrs.
template <class U> bool operator==(scoped_ptr<U> const& p2) const;
template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
};
} // namespace webrtc
// Free functions
template <class T, class D>
void swap(webrtc::scoped_ptr<T, D>& p1, webrtc::scoped_ptr<T, D>& p2) {
p1.swap(p2);
}
template <class T, class D>
bool operator==(T* p1, const webrtc::scoped_ptr<T, D>& p2) {
return p1 == p2.get();
}
template <class T, class D>
bool operator!=(T* p1, const webrtc::scoped_ptr<T, D>& p2) {
return p1 != p2.get();
}
// A function to convert T* into webrtc::scoped_ptr<T>
// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for webrtc::scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
webrtc::scoped_ptr<T> make_scoped_ptr(T* ptr) {
return webrtc::scoped_ptr<T>(ptr);
}
namespace webrtc {
// DEPRECATED: Use scoped_ptr<T[]> instead.
// TODO(ajm): Remove scoped_array.
//
// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
// is guaranteed, either on destruction of the scoped_array or via an explicit
// reset(). Use shared_array or std::vector if your needs are more complex.
@ -184,6 +647,9 @@ void swap(scoped_array<T>& a, scoped_array<T>& b) {
a.swap(b);
}
// DEPRECATED: Use scoped_ptr<C, webrtc::FreeDeleter> instead.
// TODO(ajm): Remove scoped_ptr_malloc.
//
// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
// second template argument, the function used to free the object.
@ -254,4 +720,4 @@ void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
} // namespace webrtc
#endif // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Borrowed from Chromium's src/base/template_util.h.
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_
#include <cstddef> // For size_t.
namespace webrtc {
// Template definitions from tr1.
template<class T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
};
template <class T, T v> const T integral_constant<T, v>::value;
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
template <class T> struct is_pointer : false_type {};
template <class T> struct is_pointer<T*> : true_type {};
template <class T, class U> struct is_same : public false_type {};
template <class T> struct is_same<T, T> : true_type {};
template<class> struct is_array : public false_type {};
template<class T, size_t n> struct is_array<T[n]> : public true_type {};
template<class T> struct is_array<T[]> : public true_type {};
template <class T> struct is_non_const_reference : false_type {};
template <class T> struct is_non_const_reference<T&> : true_type {};
template <class T> struct is_non_const_reference<const T&> : false_type {};
template <class T> struct is_void : false_type {};
template <> struct is_void<void> : true_type {};
namespace internal {
// Types YesType and NoType are guaranteed such that sizeof(YesType) <
// sizeof(NoType).
typedef char YesType;
struct NoType {
YesType dummy[2];
};
// This class is an implementation detail for is_convertible, and you
// don't need to know how it works to use is_convertible. For those
// who care: we declare two different functions, one whose argument is
// of type To and one with a variadic argument list. We give them
// return types of different size, so we can use sizeof to trick the
// compiler into telling us which function it would have chosen if we
// had called it with an argument of type From. See Alexandrescu's
// _Modern C++ Design_ for more details on this sort of trick.
struct ConvertHelper {
template <typename To>
static YesType Test(To);
template <typename To>
static NoType Test(...);
template <typename From>
static From& Create();
};
// Used to determine if a type is a struct/union/class. Inspired by Boost's
// is_class type_trait implementation.
struct IsClassHelper {
template <typename C>
static YesType Test(void(C::*)(void));
template <typename C>
static NoType Test(...);
};
} // namespace internal
// Inherits from true_type if From is convertible to To, false_type otherwise.
//
// Note that if the type is convertible, this will be a true_type REGARDLESS
// of whether or not the conversion would emit a warning.
template <typename From, typename To>
struct is_convertible
: integral_constant<bool,
sizeof(internal::ConvertHelper::Test<To>(
internal::ConvertHelper::Create<From>())) ==
sizeof(internal::YesType)> {
};
template <typename T>
struct is_class
: integral_constant<bool,
sizeof(internal::IsClassHelper::Test<T>(0)) ==
sizeof(internal::YesType)> {
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_TEMPLATE_UTIL_H_

View File

@ -20,9 +20,8 @@ namespace webrtc {
Atomic32::Atomic32(int32_t initial_value)
: value_(initial_value) {
// Make sure that the counter variable we're using is of the same size
// as what the API expects.
COMPILE_ASSERT(sizeof(value_) == sizeof(LONG));
COMPILE_ASSERT(sizeof(value_) == sizeof(LONG),
counter_variable_is_the_expected_size);
assert(Is32bitAligned());
}

View File

@ -21,8 +21,7 @@ DEFINE_bool(logs, false, "print logs to stderr");
namespace webrtc {
namespace test {
TestSuite::TestSuite(int argc, char** argv)
: trace_to_stderr_(NULL) {
TestSuite::TestSuite(int argc, char** argv) {
SetExecutablePath(argv[0]);
testing::InitGoogleMock(&argc, argv); // Runs InitGoogleTest() internally.
// AllowCommandLineParsing allows us to ignore flags passed on to us by

View File

@ -92,4 +92,13 @@ typedef unsigned __int64 uint64_t;
#define OVERRIDE
#endif
// Annotate a function indicating the caller must examine the return value.
// Use like:
// int foo() WARN_UNUSED_RESULT;
#if defined(__GNUC__)
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#endif // WEBRTC_TYPEDEFS_H_

View File

@ -66,7 +66,6 @@ FrameGeneratorCapturer::FrameGeneratorCapturer(Clock* clock,
sending_(false),
tick_(EventWrapper::Create()),
lock_(CriticalSectionWrapper::CreateCriticalSection()),
thread_(NULL),
frame_generator_(frame_generator),
target_fps_(target_fps) {
assert(input != NULL);

View File

@ -74,7 +74,6 @@ ViEChannel::ViEChannel(int32_t channel_id,
callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
default_rtp_rtcp_(default_rtp_rtcp),
rtp_rtcp_(NULL),
vcm_(*VideoCodingModule::Create(ViEModuleId(engine_id, channel_id))),
vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator, this),
vie_sender_(channel_id),

View File

@ -141,7 +141,6 @@ ViEEncoder::ViEEncoder(int32_t engine_id,
channel_id))),
vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(engine_id,
channel_id))),
default_rtp_rtcp_(NULL),
callback_cs_(CriticalSectionWrapper::CreateCriticalSection()),
data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
bitrate_controller_(bitrate_controller),

View File

@ -919,7 +919,6 @@ Channel::Channel(int32_t channelId,
_callbackCritSectPtr(NULL),
_transportPtr(NULL),
_encryptionPtr(NULL),
rtp_audioproc_(NULL),
rx_audioproc_(AudioProcessing::Create(VoEModuleId(instanceId, channelId))),
_rxVadObserverPtr(NULL),
_oldVadDecision(-1),

View File

@ -29,7 +29,6 @@ SharedData::SharedData(const Config& config) :
_channelManager(_gInstanceCounter, config),
_engineStatistics(_gInstanceCounter),
_audioDevicePtr(NULL),
audioproc_(NULL),
_moduleProcessThreadPtr(ProcessThread::CreateProcessThread()),
_externalRecording(false),
_externalPlayout(false)