Add arraysize() macro from Chromium, and make use of it in a few places.

This not only shortens some test code, it makes it more robust against changing
the lengths of the arrays later and forgetting to update the length constants
(which bit me).

BUG=none
TEST=none
R=hta@webrtc.org, tommi@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8191}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8191 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvideoengine2_unittest.cc b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
index 116949e..061126d 100644
--- a/talk/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/talk/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -37,6 +37,7 @@
 #include "talk/media/webrtc/webrtcvideoengine2.h"
 #include "talk/media/webrtc/webrtcvideoengine2_unittest.h"
 #include "talk/media/webrtc/webrtcvoiceengine.h"
+#include "webrtc/base/arraysize.h"
 #include "webrtc/base/gunit.h"
 #include "webrtc/base/stringutils.h"
 #include "webrtc/video_encoder.h"
@@ -1213,9 +1214,8 @@
 }
 
 TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
-  const size_t kNumIncorrectIds = 4;
-  const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
-  for (size_t i = 0; i < kNumIncorrectIds; ++i) {
+  const int kIncorrectIds[] = {-2, -1, 15, 16};
+  for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
     std::vector<cricket::RtpHeaderExtension> extensions;
     extensions.push_back(cricket::RtpHeaderExtension(
         webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
@@ -1225,9 +1225,8 @@
 }
 
 TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
-  const size_t kNumIncorrectIds = 4;
-  const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
-  for (size_t i = 0; i < kNumIncorrectIds; ++i) {
+  const int kIncorrectIds[] = {-2, -1, 15, 16};
+  for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
     std::vector<cricket::RtpHeaderExtension> extensions;
     extensions.push_back(cricket::RtpHeaderExtension(
         webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
@@ -1815,12 +1814,10 @@
 
 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
   // TODO(pbos): Should we only allow the dynamic range?
-  static const size_t kNumIncorrectPayloads = 4;
-  static const int kIncorrectPayloads[kNumIncorrectPayloads] = {
-      -2, -1, 128, 129};
+  static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
   std::vector<cricket::VideoCodec> codecs;
   codecs.push_back(kVp8Codec);
-  for (size_t i = 0; i < kNumIncorrectPayloads; ++i) {
+  for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
     int payload_type = kIncorrectPayloads[i];
     codecs[0].id = payload_type;
     EXPECT_FALSE(channel_->SetSendCodecs(codecs))
diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn
index 670e42c..e758d86 100644
--- a/webrtc/base/BUILD.gn
+++ b/webrtc/base/BUILD.gn
@@ -153,6 +153,7 @@
   ]
 
   sources = [
+    "arraysize.h",
     "asyncfile.cc",
     "asyncfile.h",
     "asynchttprequest.cc",
diff --git a/webrtc/base/arraysize.h b/webrtc/base/arraysize.h
new file mode 100644
index 0000000..93ea0f6
--- /dev/null
+++ b/webrtc/base/arraysize.h
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2015 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_BASE_ARRAYSIZE_H_
+#define WEBRTC_BASE_ARRAYSIZE_H_
+
+// This file defines the arraysize() macro and is derived from Chromium's
+// base/macros.h.
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.  If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+// That gcc wants both of these prototypes seems mysterious. VC, for
+// its part, can't decide which to use (another mystery). Matching of
+// template overloads: the final frontier.
+#ifndef _MSC_VER
+template <typename T, size_t N>
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
+#endif  // WEBRTC_BASE_ARRAYSIZE_H_
diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp
index 16437be..74ba76a 100644
--- a/webrtc/base/base.gyp
+++ b/webrtc/base/base.gyp
@@ -65,6 +65,7 @@
         'USE_WEBRTC_DEV_BRANCH',
       ],
       'sources': [
+        'arraysize.h',
         'asyncfile.cc',
         'asyncfile.h',
         'asynchttprequest.cc',
diff --git a/webrtc/examples/android/media_demo/jni/jni_helpers.h b/webrtc/examples/android/media_demo/jni/jni_helpers.h
index 25706db..a4d4d96 100644
--- a/webrtc/examples/android/media_demo/jni/jni_helpers.h
+++ b/webrtc/examples/android/media_demo/jni/jni_helpers.h
@@ -44,9 +44,6 @@
     }                             \
   }
 
-#define ARRAYSIZE(instance)                                     \
-  static_cast<int>(sizeof(instance) / sizeof(instance[0]))
-
 // JNIEnv-helper methods that CHECK success: no Java exception thrown and found
 // object/class/method/field is non-null.
 jmethodID GetMethodID(JNIEnv* jni, jclass c, const std::string& name,
diff --git a/webrtc/examples/android/media_demo/jni/video_engine_jni.cc b/webrtc/examples/android/media_demo/jni/video_engine_jni.cc
index d9e6312..d389cda 100644
--- a/webrtc/examples/android/media_demo/jni/video_engine_jni.cc
+++ b/webrtc/examples/android/media_demo/jni/video_engine_jni.cc
@@ -16,6 +16,7 @@
 #include <map>
 #include <string>
 
+#include "webrtc/base/arraysize.h"
 #include "webrtc/common_types.h"
 #include "webrtc/examples/android/media_demo/jni/jni_helpers.h"
 #include "webrtc/examples/android/media_demo/jni/media_codec_video_decoder.h"
@@ -330,7 +331,7 @@
   webrtc::AttachThreadScoped ats(g_vm);
   JNIEnv* jni = ats.env();
   g_class_reference_holder = new ClassReferenceHolder(
-      jni, g_classes, ARRAYSIZE(g_classes));
+      jni, g_classes, arraysize(g_classes));
 }
 
 void ClearVieDeviceObjects() {
diff --git a/webrtc/examples/android/media_demo/jni/voice_engine_jni.cc b/webrtc/examples/android/media_demo/jni/voice_engine_jni.cc
index 72df498..85ad84f 100644
--- a/webrtc/examples/android/media_demo/jni/voice_engine_jni.cc
+++ b/webrtc/examples/android/media_demo/jni/voice_engine_jni.cc
@@ -16,6 +16,7 @@
 #include <map>
 #include <string>
 
+#include "webrtc/base/arraysize.h"
 #include "webrtc/examples/android/media_demo/jni/jni_helpers.h"
 #include "webrtc/modules/utility/interface/helpers_android.h"
 #include "webrtc/test/channel_transport/include/channel_transport.h"
@@ -164,7 +165,7 @@
   webrtc::AttachThreadScoped ats(g_vm);
   JNIEnv* jni = ats.env();
   g_class_reference_holder = new ClassReferenceHolder(
-      jni, g_classes, ARRAYSIZE(g_classes));
+      jni, g_classes, arraysize(g_classes));
 }
 
 void ClearVoeDeviceObjects() {