summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_audio/resampler/push_resampler.cc4
-rw-r--r--common_audio/resampler/push_sinc_resampler.cc5
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c12
-rw-r--r--modules/audio_coding/codecs/isac/fix/source/pitch_filter.c16
-rw-r--r--modules/audio_coding/main/acm2/audio_coding_module_impl.cc1
-rw-r--r--modules/audio_coding/main/source/audio_coding_module_impl.cc1
-rw-r--r--modules/audio_coding/neteq4/neteq_impl.cc11
-rw-r--r--modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc5
-rw-r--r--modules/audio_processing/aecm/aecm_core.c2
-rw-r--r--modules/audio_processing/utility/delay_estimator_wrapper.c2
-rw-r--r--modules/desktop_capture/win/cursor.cc3
-rw-r--r--modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc69
-rw-r--r--modules/video_coding/main/test/rtp_player.cc1
-rw-r--r--system_wrappers/interface/asm_defines.h2
-rw-r--r--system_wrappers/interface/compile_assert.h71
-rw-r--r--system_wrappers/interface/compile_assert_c.h22
-rw-r--r--system_wrappers/interface/move.h215
-rw-r--r--system_wrappers/interface/scoped_ptr.h610
-rw-r--r--system_wrappers/interface/template_util.h114
-rw-r--r--system_wrappers/source/atomic32_win.cc5
-rw-r--r--test/test_suite.cc3
-rw-r--r--typedefs.h9
-rw-r--r--video_engine/test/common/frame_generator_capturer.cc1
-rw-r--r--video_engine/vie_channel.cc1
-rw-r--r--video_engine/vie_encoder.cc1
-rw-r--r--voice_engine/channel.cc1
-rw-r--r--voice_engine/shared_data.cc1
27 files changed, 1009 insertions, 179 deletions
diff --git a/common_audio/resampler/push_resampler.cc b/common_audio/resampler/push_resampler.cc
index 92775afb..29944187 100644
--- a/common_audio/resampler/push_resampler.cc
+++ b/common_audio/resampler/push_resampler.cc
@@ -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),
diff --git a/common_audio/resampler/push_sinc_resampler.cc b/common_audio/resampler/push_sinc_resampler.cc
index 886d7633..1fb72dc7 100644
--- a/common_audio/resampler/push_sinc_resampler.cc
+++ b/common_audio/resampler/push_sinc_resampler.cc
@@ -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() {
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
index a1dced98..9c4e5875 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_estimator.c
@@ -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] = {
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c b/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
index df961a7a..c3db01c6 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_filter.c
@@ -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;
diff --git a/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
index 911605e8..59d5727a 100644
--- a/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
+++ b/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
@@ -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) {
diff --git a/modules/audio_coding/main/source/audio_coding_module_impl.cc b/modules/audio_coding/main/source/audio_coding_module_impl.cc
index 62a13c57..38027338 100644
--- a/modules/audio_coding/main/source/audio_coding_module_impl.cc
+++ b/modules/audio_coding/main/source/audio_coding_module_impl.cc
@@ -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),
diff --git a/modules/audio_coding/neteq4/neteq_impl.cc b/modules/audio_coding/neteq4/neteq_impl.cc
index 4ed39764..a5c45ff7 100644
--- a/modules/audio_coding/neteq4/neteq_impl.cc
+++ b/modules/audio_coding/neteq4/neteq_impl.cc
@@ -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),
diff --git a/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc b/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc
index da16814d..c5cf137f 100644
--- a/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc
+++ b/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc
@@ -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()
diff --git a/modules/audio_processing/aecm/aecm_core.c b/modules/audio_processing/aecm/aecm_core.c
index a44ce08d..2c0a40f0 100644
--- a/modules/audio_processing/aecm/aecm_core.c
+++ b/modules/audio_processing/aecm/aecm_core.c
@@ -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"
diff --git a/modules/audio_processing/utility/delay_estimator_wrapper.c b/modules/audio_processing/utility/delay_estimator_wrapper.c
index c358f138..b72b8ffa 100644
--- a/modules/audio_processing/utility/delay_estimator_wrapper.c
+++ b/modules/audio_processing/utility/delay_estimator_wrapper.c
@@ -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.
diff --git a/modules/desktop_capture/win/cursor.cc b/modules/desktop_capture/win/cursor.cc
index 6e0fd4eb..11bb2dbb 100644
--- a/modules/desktop_capture/win/cursor.cc
+++ b/modules/desktop_capture/win/cursor.cc
@@ -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);
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
index bcd1d10c..1d8b2be3 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
@@ -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);
diff --git a/modules/video_coding/main/test/rtp_player.cc b/modules/video_coding/main/test/rtp_player.cc
index 6af43893..99651431 100644
--- a/modules/video_coding/main/test/rtp_player.cc
+++ b/modules/video_coding/main/test/rtp_player.cc
@@ -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),
diff --git a/system_wrappers/interface/asm_defines.h b/system_wrappers/interface/asm_defines.h
index c432ec0e..4b839a95 100644
--- a/system_wrappers/interface/asm_defines.h
+++ b/system_wrappers/interface/asm_defines.h
@@ -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_
diff --git a/system_wrappers/interface/compile_assert.h b/system_wrappers/interface/compile_assert.h
index 4feda86c..0c8776d2 100644
--- a/system_wrappers/interface/compile_assert.h
+++ b/system_wrappers/interface/compile_assert.h
@@ -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_
diff --git a/system_wrappers/interface/compile_assert_c.h b/system_wrappers/interface/compile_assert_c.h
new file mode 100644
index 00000000..d9ba8660
--- /dev/null
+++ b/system_wrappers/interface/compile_assert_c.h
@@ -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_
diff --git a/system_wrappers/interface/move.h b/system_wrappers/interface/move.h
new file mode 100644
index 00000000..d828c32a
--- /dev/null
+++ b/system_wrappers/interface/move.h
@@ -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_
diff --git a/system_wrappers/interface/scoped_ptr.h b/system_wrappers/interface/scoped_ptr.h
index cfaf5cbe..a2a1b44e 100644
--- a/system_wrappers/interface/scoped_ptr.h
+++ b/system_wrappers/interface/scoped_ptr.h
@@ -1,118 +1,581 @@
-// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
-// Copyright (c) 2001, 2002 Peter Dimov
+/*
+ * 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/memory/scoped_ptr.h.
+
+// 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[].
//
-// 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.
+// Example usage (scoped_ptr<T>):
+// {
+// scoped_ptr<Foo> foo(new Foo("wee"));
+// } // foo goes out of scope, releasing the pointer with it.
//
-// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
+// {
+// 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.
-// 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.
-
-// 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.
-
-// 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).
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
-#ifdef _WIN32
-namespace std { using ::ptrdiff_t; };
-#endif // _WIN32
+#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 {
+// 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;
+ }
+};
+
+// 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;
+};
- T* ptr;
+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);
+};
- scoped_ptr(scoped_ptr const &);
- scoped_ptr & operator=(scoped_ptr const &);
+// 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.
+ }
- typedef T element_type;
+ 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();
+ }
- explicit scoped_ptr(T* p = NULL): ptr(p) {}
+ ~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);
+ }
+ }
- ~scoped_ptr() {
- typedef char type_must_be_complete[sizeof(T)];
- delete 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;
}
- void reset(T* p = NULL) {
- typedef char type_must_be_complete[sizeof(T)];
+ T* get() const { return data_.ptr; }
- if (ptr != p) {
- T* obj = ptr;
- ptr = p;
- // Delete last, in case obj destructor indirectly results in ~scoped_ptr
- delete obj;
- }
+ 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& operator*() const {
- assert(ptr != NULL);
- return *ptr;
+ T* release() {
+ T* old_ptr = data_.ptr;
+ data_.ptr = NULL;
+ return old_ptr;
}
- T* operator->() const {
- assert(ptr != NULL);
- return 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);
}
- T* get() const {
- return ptr;
+ // 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;
}
- void swap(scoped_ptr & b) {
- T* tmp = b.ptr;
- b.ptr = ptr;
- ptr = tmp;
+ // 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;
- T* release() {
- T* tmp = ptr;
- ptr = NULL;
- return tmp;
+ 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_);
}
- T** accept() {
- if (ptr) {
- delete ptr;
- ptr = NULL;
- }
- return &ptr;
+ // 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();
}
- T** use() {
- return &ptr;
+ // 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<typename T> inline
-void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
- a.swap(b);
+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_
diff --git a/system_wrappers/interface/template_util.h b/system_wrappers/interface/template_util.h
new file mode 100644
index 00000000..5ae415b5
--- /dev/null
+++ b/system_wrappers/interface/template_util.h
@@ -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_
diff --git a/system_wrappers/source/atomic32_win.cc b/system_wrappers/source/atomic32_win.cc
index 5dd07092..7c70376f 100644
--- a/system_wrappers/source/atomic32_win.cc
+++ b/system_wrappers/source/atomic32_win.cc
@@ -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());
}
diff --git a/test/test_suite.cc b/test/test_suite.cc
index c8ff742c..7cfb856f 100644
--- a/test/test_suite.cc
+++ b/test/test_suite.cc
@@ -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
diff --git a/typedefs.h b/typedefs.h
index e15bb1b3..dc206f29 100644
--- a/typedefs.h
+++ b/typedefs.h
@@ -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_
diff --git a/video_engine/test/common/frame_generator_capturer.cc b/video_engine/test/common/frame_generator_capturer.cc
index 02b4a31d..08b3d298 100644
--- a/video_engine/test/common/frame_generator_capturer.cc
+++ b/video_engine/test/common/frame_generator_capturer.cc
@@ -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);
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index 10f46eb2..dabccefa 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -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),
diff --git a/video_engine/vie_encoder.cc b/video_engine/vie_encoder.cc
index a3023f9a..6295920a 100644
--- a/video_engine/vie_encoder.cc
+++ b/video_engine/vie_encoder.cc
@@ -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),
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index af89d5cd..9e616a35 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -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),
diff --git a/voice_engine/shared_data.cc b/voice_engine/shared_data.cc
index 712bb66a..21878447 100644
--- a/voice_engine/shared_data.cc
+++ b/voice_engine/shared_data.cc
@@ -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)