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