Bug 1228641. Add a polyfill of std::initializer_list. r=froydnj
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Tue, 01 Dec 2015 20:43:17 -0500
changeset 278912 bedd35d9ebe637a9a06e6c3f1499f3b3a724f1c3
parent 278911 d0a231612fd057dfc86c21da07434d459eb0ce2d
child 278913 fc20ecea0409c0434ef50f24cbd28d2ed55d48f3
push id29860
push usercbook@mozilla.com
push dateThu, 07 Jan 2016 10:51:20 +0000
treeherdermozilla-central@e0bcd16e1d4b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1228641
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1228641. Add a polyfill of std::initializer_list. r=froydnj
config/stl-headers
config/system-headers
mfbt/InitializerList.h
mfbt/moz.build
mfbt/tests/TestInitializerList.cpp
mfbt/tests/moz.build
testing/cppunittest.ini
--- a/config/stl-headers
+++ b/config/stl-headers
@@ -15,16 +15,17 @@
 new
 
 # FIXME: these headers haven't been reviewed yet, but we use them
 # unsafely in Gecko, so we might as well prevent them from
 # throwing exceptions
 algorithm
 atomic
 deque
+initializer_list
 ios
 iosfwd
 iostream
 iterator
 limits
 list
 map
 memory
--- a/config/system-headers
+++ b/config/system-headers
@@ -543,16 +543,17 @@ ia64/sys/inline.h
 Icons.h
 iconv.h
 ieeefp.h
 ifaddrs.h
 image.h
 imagehlp.h
 imm.h
 initguid.h
+initializer_list
 InterfaceDefs.h
 InternetConfig.h
 IntlResources.h
 ints.h
 intshcut.h
 inttypes.h
 iodef.h
 io.h
new file mode 100644
--- /dev/null
+++ b/mfbt/InitializerList.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ *  * License, v. 2.0. If a copy of the MPL was not distributed with this
+ *   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* A polyfill for std::initializer_list if it doesn't exist */
+
+#ifndef mozilla_InitializerList_h
+#define mozilla_InitializerList_h
+
+#include <mozilla/Compiler.h>
+#include <mozilla/Attributes.h>
+#if MOZ_USING_LIBCXX
+#  define MOZ_HAVE_INITIALIZER_LIST
+#elif MOZ_USING_LIBSTDCXX && __GLIBCXX__ >= 20090421 // GCC 4.4.0
+#  define MOZ_HAVE_INITIALIZER_LIST
+#elif _MSC_VER
+#  define MOZ_HAVE_INITIALIZER_LIST
+#elif defined(MOZ_USING_STLPORT)
+#else
+#  error "Unknown standard library situation"
+#endif
+
+#ifdef MOZ_HAVE_INITIALIZER_LIST
+#  include <initializer_list>
+#else
+/* Normally we would put things in mozilla:: however, std::initializer_list is a
+ * magic name used by the compiler and so we need to name it that way.
+ */
+namespace std
+{
+
+template<class T>
+class initializer_list
+{
+    /* This matches the representation used by GCC and Clang which
+     * are the only compilers we need to polyfill */
+    const T* mBegin;
+    size_t   mSize;
+
+    /* This constructor is called directly by the compiler */
+    initializer_list(const T* begin, size_t size) : mBegin(begin), mSize(size) {}
+public:
+
+    MOZ_CONSTEXPR initializer_list() : mBegin(nullptr), mSize(0) {}
+
+    typedef T value_type;
+    typedef const T& reference;
+    typedef const T& const_reference;
+    typedef size_t size_type;
+    typedef const T* iterator;
+    typedef const T* const_iterator;
+
+    size_t size() const { return mSize; }
+    const T* begin() const { return mBegin; }
+    const T* end() const { return mBegin + mSize; }
+};
+
+}
+#endif /* MOZ_HAS_INITIALIZER_LIST */
+#endif /* mozilla_InitializerList_h */
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -39,16 +39,17 @@ EXPORTS.mozilla = [
     'EnumeratedRange.h',
     'EnumSet.h',
     'FastBernoulliTrial.h',
     'FloatingPoint.h',
     'Function.h',
     'GuardObjects.h',
     'HashFunctions.h',
     'IndexSequence.h',
+    'InitializerList.h',
     'IntegerPrintfMacros.h',
     'IntegerRange.h',
     'IntegerTypeTraits.h',
     'JSONWriter.h',
     'Likely.h',
     'LinkedList.h',
     'MacroArgs.h',
     'MacroForEach.h',
new file mode 100644
--- /dev/null
+++ b/mfbt/tests/TestInitializerList.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Assertions.h"
+#include "mozilla/InitializerList.h"
+
+int sum(std::initializer_list<int> p)
+{
+  int result = 0;
+  for (auto i : p) {
+    result += i;
+  }
+  return result;
+}
+
+int
+main()
+{
+  MOZ_RELEASE_ASSERT(sum({1, 2, 3, 4, 5, 6}) == 7 * 3);
+  return 0;
+}
--- a/mfbt/tests/moz.build
+++ b/mfbt/tests/moz.build
@@ -14,16 +14,17 @@ CppUnitTests([
     'TestCheckedInt',
     'TestCountPopulation',
     'TestCountZeroes',
     'TestEndian',
     'TestEnumSet',
     'TestFastBernoulliTrial',
     'TestFloatingPoint',
     'TestFunction',
+    'TestInitializerList',
     'TestIntegerPrintfMacros',
     'TestIntegerRange',
     'TestJSONWriter',
     'TestLinkedList',
     'TestMacroArgs',
     'TestMacroForEach',
     'TestMathAlgorithms',
     'TestMaybe',
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -33,16 +33,17 @@ skip-if = os == 'b2g' || (os == 'android
 skip-if = os != 'win'
 [TestEndian]
 [TestEnumSet]
 [TestFile]
 [TestFloatingPoint]
 [TestGetURL]
 [TestHashtables]
 [TestID]
+[TestInitializerList]
 [TestIntegerPrintfMacros]
 [TestIntegerRange]
 [TestJSONWriter]
 [TestJemalloc]
 [TestLineBreak]
 [TestMD4]
 [TestMacroArgs]
 [TestMacroForEach]