pw_minimal_cpp_stdlib: initializer_list

Change-Id: I9123859000705469ae5cb1f9b20c83b90bfeeedb
diff --git a/pw_minimal_cpp_stdlib/BUILD b/pw_minimal_cpp_stdlib/BUILD
index 3e39d7b..906ac44 100644
--- a/pw_minimal_cpp_stdlib/BUILD
+++ b/pw_minimal_cpp_stdlib/BUILD
@@ -30,6 +30,7 @@
         "public/internal/cstdint.h",
         "public/internal/cstdio.h",
         "public/internal/cstring.h",
+        "public/internal/initializer_list.h",
         "public/internal/iterator.h",
         "public/internal/limits.h",
         "public/internal/new.h",
@@ -47,6 +48,7 @@
         "public/cstdint",
         "public/cstdio",
         "public/cstring",
+        "public/initializer_list",
         "public/iterator",
         "public/limits",
         "public/new",
diff --git a/pw_minimal_cpp_stdlib/BUILD.gn b/pw_minimal_cpp_stdlib/BUILD.gn
index d9ac40f..533dbbd 100644
--- a/pw_minimal_cpp_stdlib/BUILD.gn
+++ b/pw_minimal_cpp_stdlib/BUILD.gn
@@ -36,6 +36,7 @@
     "public/cstdint",
     "public/cstdio",
     "public/cstring",
+    "public/initializer_list",
     "public/iterator",
     "public/limits",
     "public/new",
@@ -53,6 +54,7 @@
     "public/internal/cstdint.h",
     "public/internal/cstdio.h",
     "public/internal/cstring.h",
+    "public/internal/initializer_list.h",
     "public/internal/iterator.h",
     "public/internal/limits.h",
     "public/internal/new.h",
diff --git a/pw_minimal_cpp_stdlib/public/initializer_list b/pw_minimal_cpp_stdlib/public/initializer_list
new file mode 120000
index 0000000..cdccec8
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/initializer_list
@@ -0,0 +1 @@
+internal/initializer_list.h
\ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/internal/initializer_list.h b/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
new file mode 100644
index 0000000..fe8651e
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
@@ -0,0 +1,42 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+namespace std {
+
+template <typename T>
+class initializer_list {
+ public:
+  using value_type = T;
+  using reference = const T&;
+  using const_reference = const T&;
+  using size_type = decltype(sizeof(0));
+  using iterator = const T*;
+  using const_iterator = const T*;
+
+  constexpr initializer_list() : begin_(nullptr), size_(0) {}
+
+  size_type size() const { return size_; }
+
+  iterator begin() const { return begin_; }
+  iterator end() const { return begin_ + size_; }
+
+ private:
+  // The order of these members must stay the same. The compiler makes
+  // assumptions about this class, and reordering these breaks things.
+  const T* begin_;
+  size_type size_;
+};
+
+}  // namespace std
diff --git a/pw_minimal_cpp_stdlib/test.cc b/pw_minimal_cpp_stdlib/test.cc
index 1d9c6c3..2fc9b01 100644
--- a/pw_minimal_cpp_stdlib/test.cc
+++ b/pw_minimal_cpp_stdlib/test.cc
@@ -22,6 +22,7 @@
 #include <cstdint>
 #include <cstdio>
 #include <cstring>
+#include <initializer_list>
 #include <iterator>
 #include <limits>
 #include <new>
@@ -82,6 +83,32 @@
   EXPECT_EQ(foo[2], 99);
 }
 
+template <typename T>
+int SumFromInitializerList(std::initializer_list<T> values) {
+  int sum = 0;
+  for (auto value : values) {
+    sum += value;
+  }
+  return sum;
+}
+TEST(InitializerList, Empty) {
+  std::initializer_list<int> mt;
+  EXPECT_EQ(0, SumFromInitializerList(mt));
+
+  EXPECT_EQ(0, SumFromInitializerList<float>({}));
+}
+
+TEST(InitializerList, Declared) {
+  std::initializer_list<char> list{'\3', '\3', '\4'};
+  EXPECT_EQ(10, SumFromInitializerList(list));
+}
+
+TEST(InitializerList, Inline) {
+  EXPECT_EQ(42, SumFromInitializerList<long>({42}));
+  EXPECT_EQ(2, SumFromInitializerList<bool>({true, false, true}));
+  EXPECT_EQ(15, SumFromInitializerList({1, 2, 3, 4, 5}));
+}
+
 TEST(Limits, Basic) {
   static_assert(std::numeric_limits<unsigned char>::is_specialized);
   static_assert(std::numeric_limits<unsigned char>::is_integer);