From 5fe8c4e5449568387f659b7708f44faf3d3bb4a5 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 1 Dec 2015 20:43:17 -0500 Subject: [PATCH] Bug 1228641. Add a polyfill of std::initializer_list. r=froydnj --- config/stl-headers | 1 + config/system-headers | 1 + mfbt/InitializerList.h | 62 ++++++++++++++++++++++++++++++ mfbt/moz.build | 1 + mfbt/tests/TestInitializerList.cpp | 24 ++++++++++++ mfbt/tests/moz.build | 1 + testing/cppunittest.ini | 1 + 7 files changed, 91 insertions(+) create mode 100644 mfbt/InitializerList.h create mode 100644 mfbt/tests/TestInitializerList.cpp diff --git a/config/stl-headers b/config/stl-headers index a1f77ac5ba6..1e4922df664 100644 --- a/config/stl-headers +++ b/config/stl-headers @@ -20,6 +20,7 @@ new algorithm atomic deque +initializer_list ios iosfwd iostream diff --git a/config/system-headers b/config/system-headers index cde1cad17b8..b2b7d9c2ba0 100644 --- a/config/system-headers +++ b/config/system-headers @@ -548,6 +548,7 @@ image.h imagehlp.h imm.h initguid.h +initializer_list InterfaceDefs.h InternetConfig.h IntlResources.h diff --git a/mfbt/InitializerList.h b/mfbt/InitializerList.h new file mode 100644 index 00000000000..0f324253275 --- /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 +#include +#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 +#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 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 */ diff --git a/mfbt/moz.build b/mfbt/moz.build index 67c276df3d6..4eefdf9e29c 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -44,6 +44,7 @@ EXPORTS.mozilla = [ 'GuardObjects.h', 'HashFunctions.h', 'IndexSequence.h', + 'InitializerList.h', 'IntegerPrintfMacros.h', 'IntegerRange.h', 'IntegerTypeTraits.h', diff --git a/mfbt/tests/TestInitializerList.cpp b/mfbt/tests/TestInitializerList.cpp new file mode 100644 index 00000000000..03bc60bca45 --- /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 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; +} diff --git a/mfbt/tests/moz.build b/mfbt/tests/moz.build index 850254b57e0..c75ee8eec15 100644 --- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -19,6 +19,7 @@ CppUnitTests([ 'TestFastBernoulliTrial', 'TestFloatingPoint', 'TestFunction', + 'TestInitializerList', 'TestIntegerPrintfMacros', 'TestIntegerRange', 'TestJSONWriter', diff --git a/testing/cppunittest.ini b/testing/cppunittest.ini index 57b967c17de..05899358c4b 100644 --- a/testing/cppunittest.ini +++ b/testing/cppunittest.ini @@ -38,6 +38,7 @@ skip-if = os != 'win' [TestGetURL] [TestHashtables] [TestID] +[TestInitializerList] [TestIntegerPrintfMacros] [TestIntegerRange] [TestJSONWriter]