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);