diff options
Diffstat (limited to 'pw_minimal_cpp_stdlib')
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 |