aboutsummaryrefslogtreecommitdiff
path: root/pw_minimal_cpp_stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'pw_minimal_cpp_stdlib')
-rw-r--r--pw_minimal_cpp_stdlib/BUILD.bazel44
-rw-r--r--pw_minimal_cpp_stdlib/BUILD.gn52
-rw-r--r--pw_minimal_cpp_stdlib/CMakeLists.txt4
-rw-r--r--pw_minimal_cpp_stdlib/Kconfig23
-rw-r--r--pw_minimal_cpp_stdlib/docs.rst42
-rw-r--r--pw_minimal_cpp_stdlib/isolated_test.cc54
l---------pw_minimal_cpp_stdlib/public/algorithm2
l---------pw_minimal_cpp_stdlib/public/array2
l---------pw_minimal_cpp_stdlib/public/cinttypes2
l---------pw_minimal_cpp_stdlib/public/climits2
l---------pw_minimal_cpp_stdlib/public/cmath2
l---------pw_minimal_cpp_stdlib/public/cstdarg2
l---------pw_minimal_cpp_stdlib/public/cstddef2
l---------pw_minimal_cpp_stdlib/public/cstdint2
l---------pw_minimal_cpp_stdlib/public/cstdio2
l---------pw_minimal_cpp_stdlib/public/cstring2
l---------pw_minimal_cpp_stdlib/public/functional1
l---------pw_minimal_cpp_stdlib/public/initializer_list2
l---------pw_minimal_cpp_stdlib/public/iterator2
l---------pw_minimal_cpp_stdlib/public/limits2
l---------pw_minimal_cpp_stdlib/public/memory1
l---------pw_minimal_cpp_stdlib/public/new2
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/algorithm.h (renamed from pw_minimal_cpp_stdlib/public/internal/algorithm.h)12
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/array.h (renamed from pw_minimal_cpp_stdlib/public/internal/array.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cinttypes.h (renamed from pw_minimal_cpp_stdlib/public/internal/cinttypes.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/climits.h (renamed from pw_minimal_cpp_stdlib/public/internal/climits.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cmath.h (renamed from pw_minimal_cpp_stdlib/public/internal/cmath.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdarg.h (renamed from pw_minimal_cpp_stdlib/public/internal/cstdarg.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstddef.h (renamed from pw_minimal_cpp_stdlib/public/internal/cstddef.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdint.h (renamed from pw_minimal_cpp_stdlib/public/internal/cstdint.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdio.h (renamed from pw_minimal_cpp_stdlib/public/internal/cstdio.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstring.h (renamed from pw_minimal_cpp_stdlib/public/internal/cstring.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/functional.h39
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/initializer_list.h (renamed from pw_minimal_cpp_stdlib/public/internal/initializer_list.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/iterator.h (renamed from pw_minimal_cpp_stdlib/public/internal/iterator.h)6
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/limits.h (renamed from pw_minimal_cpp_stdlib/public/internal/limits.h)47
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/memory.h39
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/new.h (renamed from pw_minimal_cpp_stdlib/public/internal/new.h)0
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string.h73
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string_view.h (renamed from pw_minimal_cpp_stdlib/public/internal/string_view.h)4
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/type_traits.h (renamed from pw_minimal_cpp_stdlib/public/internal/type_traits.h)149
-rw-r--r--pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/utility.h (renamed from pw_minimal_cpp_stdlib/public/internal/utility.h)20
l---------pw_minimal_cpp_stdlib/public/string1
l---------pw_minimal_cpp_stdlib/public/string_view2
l---------pw_minimal_cpp_stdlib/public/type_traits2
l---------pw_minimal_cpp_stdlib/public/utility2
46 files changed, 508 insertions, 137 deletions
diff --git a/pw_minimal_cpp_stdlib/BUILD.bazel b/pw_minimal_cpp_stdlib/BUILD.bazel
index 8dd4536a8..7e8968e30 100644
--- a/pw_minimal_cpp_stdlib/BUILD.bazel
+++ b/pw_minimal_cpp_stdlib/BUILD.bazel
@@ -25,23 +25,26 @@ licenses(["notice"])
pw_cc_library(
name = "pw_minimal_cpp_stdlib",
srcs = [
- "public/internal/algorithm.h",
- "public/internal/array.h",
- "public/internal/cinttypes.h",
- "public/internal/climits.h",
- "public/internal/cmath.h",
- "public/internal/cstdarg.h",
- "public/internal/cstddef.h",
- "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",
- "public/internal/string_view.h",
- "public/internal/type_traits.h",
- "public/internal/utility.h",
+ "public/pw_minimal_cpp_stdlib/internal/algorithm.h",
+ "public/pw_minimal_cpp_stdlib/internal/array.h",
+ "public/pw_minimal_cpp_stdlib/internal/cinttypes.h",
+ "public/pw_minimal_cpp_stdlib/internal/climits.h",
+ "public/pw_minimal_cpp_stdlib/internal/cmath.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdarg.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstddef.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdint.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdio.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstring.h",
+ "public/pw_minimal_cpp_stdlib/internal/functional.h",
+ "public/pw_minimal_cpp_stdlib/internal/initializer_list.h",
+ "public/pw_minimal_cpp_stdlib/internal/iterator.h",
+ "public/pw_minimal_cpp_stdlib/internal/limits.h",
+ "public/pw_minimal_cpp_stdlib/internal/memory.h",
+ "public/pw_minimal_cpp_stdlib/internal/new.h",
+ "public/pw_minimal_cpp_stdlib/internal/string.h",
+ "public/pw_minimal_cpp_stdlib/internal/string_view.h",
+ "public/pw_minimal_cpp_stdlib/internal/type_traits.h",
+ "public/pw_minimal_cpp_stdlib/internal/utility.h",
],
hdrs = [
"public/algorithm",
@@ -54,10 +57,13 @@ pw_cc_library(
"public/cstdint",
"public/cstdio",
"public/cstring",
+ "public/functional",
"public/initializer_list",
"public/iterator",
"public/limits",
+ "public/memory",
"public/new",
+ "public/string",
"public/string_view",
"public/type_traits",
"public/utility",
@@ -73,7 +79,7 @@ pw_cc_library(
name = "minimal_cpp_stdlib_isolated_test",
srcs = ["isolated_test.cc"],
copts = ["-nostdinc++"],
- tags = ["manual"], # TODO(b/257529911): Fix build failures.
+ tags = ["manual"], # TODO: b/257529911 - Fix build failures.
deps = [
":pw_minimal_cpp_stdlib",
"//pw_polyfill",
@@ -86,7 +92,7 @@ pw_cc_test(
srcs = [
"test.cc",
],
- tags = ["manual"], # TODO(b/257529911): Fix build failures.
+ tags = ["manual"], # TODO: b/257529911 - Fix build failures.
deps = [
":minimal_cpp_stdlib_isolated_test",
"//pw_unit_test",
diff --git a/pw_minimal_cpp_stdlib/BUILD.gn b/pw_minimal_cpp_stdlib/BUILD.gn
index 779029cd2..7fcf11b01 100644
--- a/pw_minimal_cpp_stdlib/BUILD.gn
+++ b/pw_minimal_cpp_stdlib/BUILD.gn
@@ -27,16 +27,11 @@ config("no_cpp_includes") {
cflags = [ "-nostdinc++" ]
}
-config("use_minimal_cpp_stdlib") {
- configs = [
+pw_source_set("pw_minimal_cpp_stdlib") {
+ public_configs = [
":public_include_path",
":no_cpp_includes",
]
-}
-
-pw_source_set("pw_minimal_cpp_stdlib") {
- public_configs = [ ":public_include_path" ]
- configs = [ ":no_cpp_includes" ]
public = [
"public/algorithm",
"public/array",
@@ -48,34 +43,41 @@ pw_source_set("pw_minimal_cpp_stdlib") {
"public/cstdint",
"public/cstdio",
"public/cstring",
+ "public/functional",
"public/initializer_list",
"public/iterator",
"public/limits",
+ "public/memory",
"public/new",
+ "public/string",
"public/string_view",
"public/type_traits",
"public/utility",
]
sources = [
- "public/internal/algorithm.h",
- "public/internal/array.h",
- "public/internal/cinttypes.h",
- "public/internal/climits.h",
- "public/internal/cmath.h",
- "public/internal/cstdarg.h",
- "public/internal/cstddef.h",
- "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",
- "public/internal/string_view.h",
- "public/internal/type_traits.h",
- "public/internal/utility.h",
+ "public/pw_minimal_cpp_stdlib/internal/algorithm.h",
+ "public/pw_minimal_cpp_stdlib/internal/array.h",
+ "public/pw_minimal_cpp_stdlib/internal/cinttypes.h",
+ "public/pw_minimal_cpp_stdlib/internal/climits.h",
+ "public/pw_minimal_cpp_stdlib/internal/cmath.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdarg.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstddef.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdint.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstdio.h",
+ "public/pw_minimal_cpp_stdlib/internal/cstring.h",
+ "public/pw_minimal_cpp_stdlib/internal/functional.h",
+ "public/pw_minimal_cpp_stdlib/internal/initializer_list.h",
+ "public/pw_minimal_cpp_stdlib/internal/iterator.h",
+ "public/pw_minimal_cpp_stdlib/internal/limits.h",
+ "public/pw_minimal_cpp_stdlib/internal/memory.h",
+ "public/pw_minimal_cpp_stdlib/internal/new.h",
+ "public/pw_minimal_cpp_stdlib/internal/string.h",
+ "public/pw_minimal_cpp_stdlib/internal/string_view.h",
+ "public/pw_minimal_cpp_stdlib/internal/type_traits.h",
+ "public/pw_minimal_cpp_stdlib/internal/utility.h",
]
- public_deps = [ dir_pw_polyfill ]
+ public_deps = [ "$dir_pw_polyfill:standard_library" ]
+ remove_public_deps = [ "$dir_pw_minimal_cpp_stdlib" ]
}
pw_test_group("tests") {
diff --git a/pw_minimal_cpp_stdlib/CMakeLists.txt b/pw_minimal_cpp_stdlib/CMakeLists.txt
index 5ab9ffeee..af027fe61 100644
--- a/pw_minimal_cpp_stdlib/CMakeLists.txt
+++ b/pw_minimal_cpp_stdlib/CMakeLists.txt
@@ -14,3 +14,7 @@
add_library(pw_minimal_cpp_stdlib INTERFACE)
target_include_directories(pw_minimal_cpp_stdlib INTERFACE public)
+target_link_libraries(pw_minimal_cpp_stdlib
+ INTERFACE
+ pw_polyfill._standard_library_public
+)
diff --git a/pw_minimal_cpp_stdlib/Kconfig b/pw_minimal_cpp_stdlib/Kconfig
new file mode 100644
index 000000000..8b9faf915
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/Kconfig
@@ -0,0 +1,23 @@
+# Copyright 2023 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.
+
+config PIGWEED_MINIMAL_CPP_STDLIB
+ bool "Link pw_minimal_cpp_stdlib"
+ depends on STD_CPP17 || STD_CPP2A || STD_CPP20 || STD_CPP2B
+ help
+ Uses the pw_minimal_cpp_stdlib C++ standard library implementation.
+ The build must set `-nostdinc++` to exclude the toolchain's standard
+ library. This is NOT a full standard library implementation and may
+ only be used to build pw_tokenizer.
+ see :ref:'module-pw_minimal_cpp_stdlib' for module details.
diff --git a/pw_minimal_cpp_stdlib/docs.rst b/pw_minimal_cpp_stdlib/docs.rst
index d48629b93..7742cd71e 100644
--- a/pw_minimal_cpp_stdlib/docs.rst
+++ b/pw_minimal_cpp_stdlib/docs.rst
@@ -3,20 +3,37 @@
=====================
pw_minimal_cpp_stdlib
=====================
-The ``pw_minimal_cpp_stdlib`` module provides an extremely limited
-implementation of the C++ Standard Library. This module falls far, far short of
-providing a complete C++ Standard Library and should only be used for testing
-and development when compiling with C++17 or newer without a C++ Standard
-Library. Production code should use a real C++ Standard Library implementation,
-such as `libc++ <https://libcxx.llvm.org/>`_ or
-`libstdc++ <https://gcc.gnu.org/onlinedocs/libstdc++/>`_.
+.. admonition:: 🛑 Stop 🛑
+
+ **Do not use this module** unless you have consulted with the Pigweed team.
+
+The ``pw_minimal_cpp_stdlib`` module provides an extremely limited, incomplete
+implementation of the C++ Standard Library. This module is only intended for
+testing and development when compiling with C++17 or newer, but without access
+to the C++ Standard Library (``-nostdinc++``).
+
+Production code should use a real C++ Standard Library implementation, such as
+`libc++ <https://libcxx.llvm.org/>`_ or `libstdc++
+<https://gcc.gnu.org/onlinedocs/libstdc++/>`_.
.. warning::
``pw_minimal_cpp_stdlib`` was created for a very specific purpose. It is NOT a
general purpose C++ Standard Library implementation and should not be used as
- one. Many features are missing, some features non-functioning stubs, and some
- features may not match the C++ standard.
+ one.
+
+ - Many library features are **missing**.
+ - Many features are **non-functioning stubs**.
+ - Some features **do not match the C++ standard**.
+ - Test coverage is **extremely limited**.
+
+-----------------
+Build integration
+-----------------
+The top-level ``build_with_minimal_cpp_stdlib`` GN group builds a few supported
+modules with ``pw_minimal_cpp_stdlib`` swapped in for the C++ library at the
+toolchain level. Notably, ``pw_minimal_cpp_stdlib`` does not support
+``pw_unit_test``, so this group does NOT run any tests.
-----------
Code layout
@@ -32,12 +49,7 @@ defined in ``public/``. These files are symlinks to their implementations in
.. code-block:: bash
- for f in $(ls internal/); do ln -s internal/$f ${f%.h}; done
-
-The top-level ``build_with_minimal_cpp_stdlib`` GN group builds a few supported
-modules with ``pw_minimal_cpp_stdlib`` swapped in for the C++ library at the
-toolchain level. Notably, ``pw_minimal_cpp_stdlib`` does not support
-``pw_unit_test``, so this group does not run any tests.
+ for f in $(ls pw_minimal_cpp_stdlib/internal/); do ln -s pw_minimal_cpp_stdlib/internal/$f ${f%.h}; done
------------
Requirements
diff --git a/pw_minimal_cpp_stdlib/isolated_test.cc b/pw_minimal_cpp_stdlib/isolated_test.cc
index 8fb13b113..6620dc960 100644
--- a/pw_minimal_cpp_stdlib/isolated_test.cc
+++ b/pw_minimal_cpp_stdlib/isolated_test.cc
@@ -22,10 +22,13 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
+#include <functional>
#include <initializer_list>
#include <iterator>
#include <limits>
+#include <memory>
#include <new>
+#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
@@ -78,6 +81,27 @@ SimpleTest* SimpleTest::all_tests = nullptr;
} \
} while (0)
+#define EXPECT_NE(lhs, rhs) \
+ do { \
+ if ((lhs) == (rhs)) { \
+ RecordTestFailure(); \
+ } \
+ } while (0)
+
+#define EXPECT_LT(lhs, rhs) \
+ do { \
+ if ((lhs) < (rhs)) { \
+ RecordTestFailure(); \
+ } \
+ } while (0)
+
+#define EXPECT_GT(lhs, rhs) \
+ do { \
+ if ((lhs) > (rhs)) { \
+ RecordTestFailure(); \
+ } \
+ } while (0)
+
#define EXPECT_TRUE(expr) EXPECT_EQ(true, expr)
#define EXPECT_FALSE(expr) EXPECT_EQ(false, expr)
#define EXPECT_STREQ(lhs, rhs) EXPECT_EQ(std::strcmp((lhs), (rhs)), 0)
@@ -297,6 +321,9 @@ TEST(TypeTraits, Basic) {
static_assert(std::is_same_v<float, float>);
static_assert(!std::is_same_v<char, unsigned char>);
+ static_assert(std::is_same_v<const int, std::add_const_t<int>>);
+ static_assert(std::is_same_v<const int, std::add_const_t<const int>>);
+ static_assert(!std::is_same_v<int, std::add_const_t<int>>);
}
TEST(TypeTraits, LogicalTraits) {
@@ -318,6 +345,16 @@ TEST(TypeTraits, LogicalTraits) {
static_assert(!std::negation_v<std::true_type>);
}
+TEST(TypeTraits, AlignmentOf) {
+ struct Foo {
+ char x;
+ double y;
+ };
+
+ static_assert(std::alignment_of_v<int> == alignof(int));
+ static_assert(std::alignment_of_v<Foo> == alignof(Foo));
+}
+
struct MoveTester {
MoveTester(int value) : magic_value(value), moved(false) {}
@@ -389,10 +426,19 @@ TEST(Iterator, Tags) {
#endif // PW_CXX_STANDARD_IS_SUPPORTED(20)
}
-TEST(TypeTrait, Basic) {
- static_assert(std::is_same_v<const int, std::add_const_t<int>>);
- static_assert(std::is_same_v<const int, std::add_const_t<const int>>);
- static_assert(!std::is_same_v<int, std::add_const_t<int>>);
+TEST(Memory, AddressOf) {
+ struct Foo {
+ Foo** operator&() { return nullptr; } // NOLINT
+ } nullptr_address;
+
+ EXPECT_EQ(&nullptr_address, nullptr);
+ EXPECT_NE(std::addressof(nullptr_address), nullptr);
+}
+
+TEST(String, CharTraits) {
+ static_assert(std::char_traits<char>::compare("1234a", "1234z", 4) == 0);
+ static_assert(std::char_traits<char>::compare("1234a", "1234z", 5) < 0);
+ static_assert(std::char_traits<char>::compare("1234z", "1234a", 5) > 0);
}
} // namespace
diff --git a/pw_minimal_cpp_stdlib/public/algorithm b/pw_minimal_cpp_stdlib/public/algorithm
index 81f8692fe..3f8358712 120000
--- a/pw_minimal_cpp_stdlib/public/algorithm
+++ b/pw_minimal_cpp_stdlib/public/algorithm
@@ -1 +1 @@
-internal/algorithm.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/algorithm.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/array b/pw_minimal_cpp_stdlib/public/array
index e9f7bca46..92fbb6693 120000
--- a/pw_minimal_cpp_stdlib/public/array
+++ b/pw_minimal_cpp_stdlib/public/array
@@ -1 +1 @@
-internal/array.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/array.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cinttypes b/pw_minimal_cpp_stdlib/public/cinttypes
index 8b251e577..cb0246276 120000
--- a/pw_minimal_cpp_stdlib/public/cinttypes
+++ b/pw_minimal_cpp_stdlib/public/cinttypes
@@ -1 +1 @@
-internal/cinttypes.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cinttypes.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/climits b/pw_minimal_cpp_stdlib/public/climits
index e098495d9..4b8f33a15 120000
--- a/pw_minimal_cpp_stdlib/public/climits
+++ b/pw_minimal_cpp_stdlib/public/climits
@@ -1 +1 @@
-internal/climits.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/climits.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cmath b/pw_minimal_cpp_stdlib/public/cmath
index caf50544e..b1204c53e 120000
--- a/pw_minimal_cpp_stdlib/public/cmath
+++ b/pw_minimal_cpp_stdlib/public/cmath
@@ -1 +1 @@
-internal/cmath.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cmath.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cstdarg b/pw_minimal_cpp_stdlib/public/cstdarg
index 5d649b59a..1c1caed54 120000
--- a/pw_minimal_cpp_stdlib/public/cstdarg
+++ b/pw_minimal_cpp_stdlib/public/cstdarg
@@ -1 +1 @@
-internal/cstdarg.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cstdarg.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cstddef b/pw_minimal_cpp_stdlib/public/cstddef
index c35111420..89a6b029f 120000
--- a/pw_minimal_cpp_stdlib/public/cstddef
+++ b/pw_minimal_cpp_stdlib/public/cstddef
@@ -1 +1 @@
-internal/cstddef.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cstddef.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cstdint b/pw_minimal_cpp_stdlib/public/cstdint
index 749150fa7..6b961cda6 120000
--- a/pw_minimal_cpp_stdlib/public/cstdint
+++ b/pw_minimal_cpp_stdlib/public/cstdint
@@ -1 +1 @@
-internal/cstdint.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cstdint.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cstdio b/pw_minimal_cpp_stdlib/public/cstdio
index 12ae70578..ffc679fa5 120000
--- a/pw_minimal_cpp_stdlib/public/cstdio
+++ b/pw_minimal_cpp_stdlib/public/cstdio
@@ -1 +1 @@
-internal/cstdio.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cstdio.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cstring b/pw_minimal_cpp_stdlib/public/cstring
index 429e0263c..90047efff 120000
--- a/pw_minimal_cpp_stdlib/public/cstring
+++ b/pw_minimal_cpp_stdlib/public/cstring
@@ -1 +1 @@
-internal/cstring.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/cstring.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/functional b/pw_minimal_cpp_stdlib/public/functional
new file mode 120000
index 000000000..a9a97d3e2
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/functional
@@ -0,0 +1 @@
+pw_minimal_cpp_stdlib/internal/functional.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/initializer_list b/pw_minimal_cpp_stdlib/public/initializer_list
index cdccec8ce..60ec51ec8 120000
--- a/pw_minimal_cpp_stdlib/public/initializer_list
+++ b/pw_minimal_cpp_stdlib/public/initializer_list
@@ -1 +1 @@
-internal/initializer_list.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/initializer_list.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/iterator b/pw_minimal_cpp_stdlib/public/iterator
index 4703aa88c..beb633d31 120000
--- a/pw_minimal_cpp_stdlib/public/iterator
+++ b/pw_minimal_cpp_stdlib/public/iterator
@@ -1 +1 @@
-internal/iterator.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/iterator.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/limits b/pw_minimal_cpp_stdlib/public/limits
index 8309de0da..cee7e6a96 120000
--- a/pw_minimal_cpp_stdlib/public/limits
+++ b/pw_minimal_cpp_stdlib/public/limits
@@ -1 +1 @@
-internal/limits.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/limits.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/memory b/pw_minimal_cpp_stdlib/public/memory
new file mode 120000
index 000000000..89e025306
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/memory
@@ -0,0 +1 @@
+pw_minimal_cpp_stdlib/internal/memory.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/new b/pw_minimal_cpp_stdlib/public/new
index ed0129c94..8f3c1a0dc 120000
--- a/pw_minimal_cpp_stdlib/public/new
+++ b/pw_minimal_cpp_stdlib/public/new
@@ -1 +1 @@
-internal/new.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/new.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/internal/algorithm.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/algorithm.h
index aa2993f3e..66cf2bf87 100644
--- a/pw_minimal_cpp_stdlib/public/internal/algorithm.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/algorithm.h
@@ -13,8 +13,6 @@
// the License.
#pragma once
-#include <type_traits>
-
#include "pw_polyfill/standard_library/namespace.h"
_PW_POLYFILL_BEGIN_NAMESPACE_STD
@@ -51,16 +49,6 @@ constexpr InputIterator find(InputIterator first,
return last;
}
-template <typename T>
-constexpr T&& forward(remove_reference_t<T>& value) {
- return static_cast<T&&>(value);
-}
-
-template <typename T>
-constexpr T&& forward(remove_reference_t<T>&& value) {
- return static_cast<T&&>(value);
-}
-
template <class LhsIterator, class RhsIterator>
constexpr bool equal(LhsIterator first_l,
LhsIterator last_l,
diff --git a/pw_minimal_cpp_stdlib/public/internal/array.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/array.h
index 8a26e69bb..8a26e69bb 100644
--- a/pw_minimal_cpp_stdlib/public/internal/array.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/array.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cinttypes.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cinttypes.h
index 5141862e0..5141862e0 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cinttypes.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cinttypes.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/climits.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/climits.h
index 6acdaeac6..6acdaeac6 100644
--- a/pw_minimal_cpp_stdlib/public/internal/climits.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/climits.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cmath.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cmath.h
index 2cf754c80..2cf754c80 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cmath.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cmath.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdarg.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdarg.h
index 129a0d33c..129a0d33c 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdarg.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstddef.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstddef.h
index c6fd87a5b..c6fd87a5b 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstddef.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstddef.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdint.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdint.h
index abe9e04fc..abe9e04fc 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstdint.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdint.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdio.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdio.h
index 725c1d561..725c1d561 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstdio.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstdio.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstring.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstring.h
index ed24ecb73..ed24ecb73 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstring.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/cstring.h
diff --git a/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/functional.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/functional.h
new file mode 100644
index 000000000..1f55a6736
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/functional.h
@@ -0,0 +1,39 @@
+// Copyright 2023 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
+
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
+
+template <typename T>
+class reference_wrapper {
+ public:
+ using type = T;
+
+ // This constructor is incomplete / incorrect!
+ constexpr reference_wrapper(T& reference) : pointer_(&reference) {}
+
+ constexpr reference_wrapper(const reference_wrapper&) noexcept = default;
+ constexpr reference_wrapper& operator=(const reference_wrapper&) noexcept =
+ default;
+
+ constexpr T& get() const noexcept { return *pointer_; }
+ constexpr operator T&() const noexcept { return *pointer_; }
+
+ private:
+ T* pointer_;
+};
+
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/initializer_list.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/initializer_list.h
index 44da38d20..44da38d20 100644
--- a/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/initializer_list.h
diff --git a/pw_minimal_cpp_stdlib/public/internal/iterator.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/iterator.h
index 4828cc5c3..23704ccd0 100644
--- a/pw_minimal_cpp_stdlib/public/internal/iterator.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/iterator.h
@@ -42,7 +42,7 @@ constexpr auto data(const C& container) -> decltype(container.data()) {
return container.data();
}
-template <typename T, decltype(sizeof(int)) kSize>
+template <typename T, decltype(sizeof(0)) kSize>
constexpr T* data(T (&array)[kSize]) noexcept {
return array;
}
@@ -62,8 +62,8 @@ constexpr auto size(const C& container) -> decltype(container.size()) {
return container.size();
}
-template <typename T, decltype(sizeof(int)) kSize>
-constexpr decltype(sizeof(int)) size(const T (&)[kSize]) noexcept {
+template <typename T, decltype(sizeof(0)) kSize>
+constexpr decltype(sizeof(0)) size(const T (&)[kSize]) noexcept {
return kSize;
}
diff --git a/pw_minimal_cpp_stdlib/public/internal/limits.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/limits.h
index 85b4d59f7..5ce61ae4d 100644
--- a/pw_minimal_cpp_stdlib/public/internal/limits.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/limits.h
@@ -22,29 +22,42 @@ _PW_POLYFILL_BEGIN_NAMESPACE_STD
template <typename T>
struct numeric_limits {
static constexpr bool is_specialized = false;
+ static constexpr int digits = 0;
};
// Only a few of the numeric_limits methods are implemented.
-#define _PW_LIMITS_SPECIALIZATION( \
- type, val_signed, val_int, min_value, max_value) \
- template <> \
- struct numeric_limits<type> { \
- static constexpr bool is_specialized = true; \
- \
- static constexpr bool is_signed = (val_signed); \
- static constexpr bool is_integer = (val_int); \
- \
- static constexpr type min() noexcept { return (min_value); } \
- static constexpr type max() noexcept { return (max_value); } \
+#define _PW_LIMITS_SPECIALIZATION( \
+ type, val_signed, val_int, min_value, max_value, digits_value) \
+ template <> \
+ struct numeric_limits<type> { \
+ static constexpr bool is_specialized = true; \
+ \
+ static constexpr bool is_signed = (val_signed); \
+ static constexpr bool is_integer = (val_int); \
+ \
+ static constexpr int digits = (digits_value); \
+ \
+ static constexpr type min() noexcept { return (min_value); } \
+ static constexpr type max() noexcept { return (max_value); } \
}
-#define _PW_INTEGRAL_LIMIT(type, sname, uname) \
- _PW_LIMITS_SPECIALIZATION( \
- signed type, true, true, sname##_MIN, sname##_MAX); \
- _PW_LIMITS_SPECIALIZATION(unsigned type, false, true, 0u, uname##_MAX)
+#define _PW_INTEGRAL_LIMIT(type, sname, uname) \
+ _PW_LIMITS_SPECIALIZATION(signed type, \
+ true, \
+ true, \
+ sname##_MIN, \
+ sname##_MAX, \
+ CHAR_BIT * sizeof(type)); \
+ _PW_LIMITS_SPECIALIZATION(unsigned type, \
+ false, \
+ true, \
+ 0u, \
+ uname##_MAX, \
+ CHAR_BIT * sizeof(type) - 1)
-_PW_LIMITS_SPECIALIZATION(bool, false, true, false, true);
-_PW_LIMITS_SPECIALIZATION(char, char(-1) < char(0), true, CHAR_MIN, CHAR_MAX);
+_PW_LIMITS_SPECIALIZATION(bool, false, true, false, true, 1);
+_PW_LIMITS_SPECIALIZATION(
+ char, char(-1) < char(0), true, CHAR_MIN, CHAR_MAX, 1);
_PW_INTEGRAL_LIMIT(char, SCHAR, UCHAR);
_PW_INTEGRAL_LIMIT(short, SHRT, USHRT);
diff --git a/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/memory.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/memory.h
new file mode 100644
index 000000000..500db85e9
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/memory.h
@@ -0,0 +1,39 @@
+// Copyright 2023 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
+
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
+
+template <typename T>
+T* addressof(T& arg) noexcept {
+ return reinterpret_cast<T*>(
+ const_cast<char*>(reinterpret_cast<const volatile char*>(&arg)));
+}
+
+template <typename T>
+T* addressof(T&& arg) = delete;
+
+template <typename T>
+struct pointer_traits;
+
+template <typename T>
+struct pointer_traits<T*> {
+ using pointer = T*;
+ using element_type = T;
+ using difference_type = decltype((const char*)1 - (const char*)1);
+};
+
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/new.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/new.h
index 38fc8b5f0..38fc8b5f0 100644
--- a/pw_minimal_cpp_stdlib/public/internal/new.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/new.h
diff --git a/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string.h
new file mode 100644
index 000000000..a89125117
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string.h
@@ -0,0 +1,73 @@
+// Copyright 2023 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
+
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
+
+// NOT IMPLEMENTED: Some functions and overloads are missing.
+template <typename T>
+class char_traits {
+ public:
+ static constexpr void assign(T& dest, const T& source) noexcept {
+ dest = source;
+ }
+
+ static constexpr T* assign(T* dest, decltype(sizeof(0)) count, T value) {
+ for (decltype(sizeof(0)) i = 0; i < count; ++i) {
+ dest[i] = value;
+ }
+ return dest;
+ }
+
+ static constexpr bool eq(T lhs, T rhs) noexcept { return lhs == rhs; }
+
+ static constexpr bool lt(T lhs, T rhs) noexcept { return lhs < rhs; }
+
+ static constexpr T* move(T* dest,
+ const T* source,
+ decltype(sizeof(0)) count) {
+ if (dest < source) {
+ copy(dest, source, count);
+ } else if (source < dest) {
+ for (decltype(sizeof(0)) i = count; i != 0; --i) {
+ assign(dest[i - 1], source[i - 1]);
+ }
+ }
+ return dest;
+ }
+
+ static constexpr T* copy(T* dest,
+ const T* source,
+ decltype(sizeof(0)) count) {
+ for (decltype(sizeof(0)) i = 0; i < count; ++i) {
+ char_traits<T>::assign(dest[i], source[i]);
+ }
+ return dest;
+ }
+
+ static constexpr int compare(const T* lhs,
+ const T* rhs,
+ decltype(sizeof(0)) count) {
+ for (decltype(sizeof(0)) i = 0; i < count; ++i) {
+ if (!eq(lhs[i], rhs[i])) {
+ return lt(lhs[i], rhs[i]) ? -1 : 1;
+ }
+ }
+ return 0;
+ }
+};
+
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/string_view.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string_view.h
index 6fbffa08c..5eafb8d38 100644
--- a/pw_minimal_cpp_stdlib/public/internal/string_view.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/string_view.h
@@ -36,7 +36,7 @@ class basic_string_view {
using iterator = const_iterator;
using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
- using size_type = size_t;
+ using size_type = decltype(sizeof(0));
using difference_type = ptrdiff_t;
static constexpr size_type npos = size_type(-1);
@@ -80,7 +80,7 @@ class basic_string_view {
constexpr size_type size() const noexcept { return size_; }
constexpr size_type length() const noexcept { return size(); }
- constexpr size_type max_size() const noexcept { return ~size_t{0}; }
+ constexpr size_type max_size() const noexcept { return ~size_type{0}; }
[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0u; }
diff --git a/pw_minimal_cpp_stdlib/public/internal/type_traits.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/type_traits.h
index d228f853d..5d518be2e 100644
--- a/pw_minimal_cpp_stdlib/public/internal/type_traits.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/type_traits.h
@@ -55,29 +55,40 @@ using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
template <typename T>
-struct is_array : false_type {};
+struct is_aggregate : bool_constant<__is_aggregate(T)> {};
template <typename T>
-struct is_array<T[]> : true_type {};
+static constexpr bool is_aggregate_v = is_aggregate<T>::value;
-template <typename T, decltype(sizeof(int)) kSize>
+template <typename T>
+struct is_array : false_type {};
+template <typename T>
+struct is_array<T[]> : true_type {};
+template <typename T, decltype(sizeof(0)) kSize>
struct is_array<T[kSize]> : true_type {};
-
template <typename T>
inline constexpr bool is_array_v = is_array<T>::value;
template <typename T>
struct is_const : false_type {};
-
template <typename T>
struct is_const<const T> : true_type {};
+template <typename T>
+inline constexpr bool is_const_v = is_const<T>::value;
-// NOT IMPLEMENTED: is_enum requires compiler builtins.
template <typename T>
-struct is_enum : false_type {};
+struct is_lvalue_reference : false_type {};
+template <typename T>
+struct is_lvalue_reference<T&> : true_type {};
+template <typename T>
+inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
template <typename T>
-inline constexpr bool is_enum_v = is_enum<T>::value;
+struct is_rvalue_reference : false_type {};
+template <typename T>
+struct is_rvalue_reference<T&&> : true_type {};
+template <typename T>
+inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
template <typename T>
struct remove_cv; // Forward declaration
@@ -395,7 +406,7 @@ struct type_identity {
template <typename T>
using type_identity_t = typename type_identity<T>::type;
-#define __cpp_lib_void_t void_t 201411L
+#define __cpp_lib_void_t 201411L
template <typename...>
using void_t = void;
@@ -514,27 +525,129 @@ struct is_convertible
template <typename T, typename U>
inline constexpr bool is_convertible_v = is_convertible<T, U>::value;
+template <typename T>
+struct alignment_of : integral_constant<decltype(sizeof(0)), alignof(T)> {};
+template <typename T>
+inline constexpr decltype(sizeof(0)) alignment_of_v = alignment_of<T>::value;
+
+#define PW_STDLIB_UNIMPLEMENTED(name) \
+ [[deprecated(#name " is NOT IMPLEMENTED in pw_minimal_cpp_stdlib!")]]
+
// NOT IMPLEMENTED: Stubs are provided for these traits classes, but they do not
// return useful values. Many of these would require compiler builtins.
+#define PW_BOOLEAN_TRAIT_NOT_SUPPORTED(name) \
+ template <typename T> \
+ struct name : false_type {}; \
+ template <typename T> \
+ PW_STDLIB_UNIMPLEMENTED(name) \
+ inline constexpr bool name##_v = name<T>::value
+
+#define PW_BOOLEAN_TRAIT_NOT_SUPPORTED_2(name) \
+ template <typename T, typename U> \
+ struct name : false_type {}; \
+ template <typename T, typename U> \
+ PW_STDLIB_UNIMPLEMENTED(name) \
+ inline constexpr bool name##_v = name<T, U>::value
+
+#define PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(name) \
+ template <typename T, typename... Args> \
+ struct name : false_type {}; \
+ template <typename T, typename... Args> \
+ PW_STDLIB_UNIMPLEMENTED(name) \
+ inline constexpr bool name##_v = name<T, Args...>::value
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_class);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_enum);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_function);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_member_function_pointer);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_member_object_pointer);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_union);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_compound);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_fundamental);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_member_pointer);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_object);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_reference);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_scalar);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_abstract);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_empty);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_final);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_pod);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_polymorphic);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_standard_layout);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_trivial);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_trivially_copyable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_volatile);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_constructible);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_default_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_default_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_default_constructible);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_copy_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_copy_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_copy_constructible);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_move_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_move_constructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_move_constructible);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_assignable);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_copy_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_copy_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_copy_assignable);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_move_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_nothrow_move_assignable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS(is_trivially_move_assignable);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_destructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_nothrow_destructible);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_trivially_destructible);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(has_virtual_destructor);
+
template <typename T>
-struct is_function : false_type {};
+struct extent : integral_constant<decltype(sizeof(0)), 1> {};
template <typename T>
-struct is_trivially_copyable : true_type {};
+PW_STDLIB_UNIMPLEMENTED(extent)
+inline constexpr decltype(sizeof(0)) extent_v = extent<T>::value;
+
template <typename T>
-struct is_polymorphic : false_type {};
-template <typename T, typename U>
-struct is_base_of : false_type {};
+struct rank : integral_constant<decltype(sizeof(0)), 1> {};
+template <typename T>
+PW_STDLIB_UNIMPLEMENTED(rank)
+inline constexpr decltype(sizeof(0)) rank_v = extent<T>::value;
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED_2(is_base_of);
+
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_invocable_r);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_invocable);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_nothrow_invocable_r);
+PW_BOOLEAN_TRAIT_NOT_SUPPORTED(is_nothrow_invocable);
+
template <typename T>
-struct extent : integral_constant<decltype(sizeof(int)), 1> {};
+struct invoke_result {};
template <typename T>
-inline constexpr bool extent_v = extent<T>::value;
+using invoke_result_t = typename invoke_result<T>::type;
+
template <typename T>
struct underlying_type {
using type = T;
};
template <typename T>
using underlying_type_t = typename underlying_type<T>::type;
-template <typename T>
-inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
+
+#undef PW_BOOLEAN_TRAIT_NOT_SUPPORTED
+#undef PW_BOOLEAN_TRAIT_NOT_SUPPORTED_2
+#undef PW_BOOLEAN_TRAIT_NOT_SUPPORTED_VARARGS
+#undef PW_STDLIB_UNIMPLEMENTED
_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/utility.h b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/utility.h
index 31a704b41..a5a65343e 100644
--- a/pw_minimal_cpp_stdlib/public/internal/utility.h
+++ b/pw_minimal_cpp_stdlib/public/pw_minimal_cpp_stdlib/internal/utility.h
@@ -21,7 +21,17 @@ _PW_POLYFILL_BEGIN_NAMESPACE_STD
template <typename T>
constexpr remove_reference_t<T>&& move(T&& object) {
- return (remove_reference_t<T> &&) object;
+ return (remove_reference_t<T>&&)object;
+}
+
+template <typename T>
+constexpr T&& forward(remove_reference_t<T>& value) {
+ return static_cast<T&&>(value);
+}
+
+template <typename T>
+constexpr T&& forward(remove_reference_t<T>&& value) {
+ return static_cast<T&&>(value);
}
// Forward declare these classes, which are specialized in other headers.
@@ -34,8 +44,8 @@ struct tuple_size;
template <typename T, T... kSequence>
class integer_sequence;
-template <size_t... kSequence>
-using index_sequence = integer_sequence<decltype(sizeof(int)), kSequence...>;
+template <decltype(sizeof(0))... kSequence>
+using index_sequence = integer_sequence<decltype(sizeof(0)), kSequence...>;
template <typename T, T kEnd>
#if __has_builtin(__make_integer_seq)
@@ -44,8 +54,8 @@ using make_integer_sequence = __make_integer_seq<integer_sequence, T, kEnd>;
using make_integer_sequence = integer_sequence<T, __integer_pack(kEnd)...>;
#endif // make_integer_sequence
-template <size_t kEnd>
-using make_index_sequence = make_integer_sequence<size_t, kEnd>;
+template <decltype(sizeof(0)) kEnd>
+using make_index_sequence = make_integer_sequence<decltype(sizeof(0)), kEnd>;
struct in_place_t {
explicit constexpr in_place_t() = default;
diff --git a/pw_minimal_cpp_stdlib/public/string b/pw_minimal_cpp_stdlib/public/string
new file mode 120000
index 000000000..02144e675
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/string
@@ -0,0 +1 @@
+pw_minimal_cpp_stdlib/internal/string.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/string_view b/pw_minimal_cpp_stdlib/public/string_view
index 8e1be6701..ea0385498 120000
--- a/pw_minimal_cpp_stdlib/public/string_view
+++ b/pw_minimal_cpp_stdlib/public/string_view
@@ -1 +1 @@
-internal/string_view.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/string_view.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/type_traits b/pw_minimal_cpp_stdlib/public/type_traits
index 71b1217ca..fae63ce86 120000
--- a/pw_minimal_cpp_stdlib/public/type_traits
+++ b/pw_minimal_cpp_stdlib/public/type_traits
@@ -1 +1 @@
-internal/type_traits.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/type_traits.h \ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/utility b/pw_minimal_cpp_stdlib/public/utility
index 58c32f231..1d13fc8c8 120000
--- a/pw_minimal_cpp_stdlib/public/utility
+++ b/pw_minimal_cpp_stdlib/public/utility
@@ -1 +1 @@
-internal/utility.h \ No newline at end of file
+pw_minimal_cpp_stdlib/internal/utility.h \ No newline at end of file