pw_minimal_cpp_stdlib: Extremely limited C++ lib
pw_minimal_cpp_stdlib is an extremely limited, non-standard
implementation of the C++ Standard Library. It requires C++17 and a C
standard library.
Change-Id: I2d0b8d6cf49730e2c746eddf2c4a23308af1eb6a
diff --git a/pw_minimal_cpp_stdlib/public/algorithm b/pw_minimal_cpp_stdlib/public/algorithm
new file mode 120000
index 0000000..81f8692
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/algorithm
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..e9f7bca
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/array
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..8b251e5
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cinttypes
@@ -0,0 +1 @@
+internal/cinttypes.h
\ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/cmath b/pw_minimal_cpp_stdlib/public/cmath
new file mode 120000
index 0000000..caf5054
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cmath
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..5d649b5
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cstdarg
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..c351114
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cstddef
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..749150f
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cstdint
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..12ae705
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cstdio
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..429e026
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/cstring
@@ -0,0 +1 @@
+internal/cstring.h
\ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/internal/algorithm.h b/pw_minimal_cpp_stdlib/public/internal/algorithm.h
new file mode 100644
index 0000000..2556702
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/algorithm.h
@@ -0,0 +1,40 @@
+// 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
+
+#include <type_traits>
+
+namespace std {
+
+template <typename T>
+constexpr const T& min(const T& lhs, const T& rhs) {
+ return (rhs < lhs) ? rhs : lhs;
+}
+
+template <typename T>
+constexpr const T& max(const T& lhs, const T& rhs) {
+ return (lhs < rhs) ? rhs : lhs;
+}
+
+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);
+}
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/array.h b/pw_minimal_cpp_stdlib/public/internal/array.h
new file mode 100644
index 0000000..80aeeca
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/array.h
@@ -0,0 +1,103 @@
+// 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
+
+#include <iterator>
+
+namespace std {
+
+template <typename T, decltype(sizeof(0)) kSize>
+struct array {
+ using value_type = T;
+ using size_type = decltype(kSize);
+ using difference_type =
+ decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
+ using reference = value_type&;
+ using const_reference = const value_type&;
+ using pointer = value_type*;
+ using const_pointer = const value_type*;
+ using iterator = T*;
+ using const_iterator = const T*;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ // NOT IMPLEMENTED: at() does not bounds checking.
+ constexpr reference at(size_type index) { return data()[index]; }
+ constexpr const_reference at(size_type index) const { return data()[index]; }
+
+ constexpr reference operator[](size_type index) { return data()[index]; }
+ constexpr const_reference operator[](size_type index) const {
+ return data()[index];
+ }
+
+ constexpr reference front() { return data()[0]; }
+ constexpr const_reference front() const { return data()[0]; }
+
+ constexpr reference back() {
+ static_assert(kSize > 0);
+ return data()[size() - 1];
+ }
+ constexpr const_reference back() const {
+ static_assert(kSize > 0);
+ return data()[size() - 1];
+ }
+
+ constexpr pointer data() noexcept {
+ static_assert(kSize > 0);
+ return __data;
+ }
+ constexpr const_pointer data() const noexcept {
+ static_assert(kSize > 0);
+ return __data;
+ }
+
+ constexpr iterator begin() noexcept { return data(); }
+ constexpr const_iterator begin() const noexcept { return data(); }
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
+
+ constexpr iterator end() noexcept { return data() + kSize; }
+ constexpr const_iterator end() const noexcept { return data() + kSize; }
+ constexpr const_iterator cend() const noexcept { return end(); }
+
+ // NOT IMPLEMENTED
+ constexpr reverse_iterator rbegin() noexcept;
+ constexpr const_reverse_iterator rbegin() const noexcept;
+ constexpr const_reverse_iterator crbegin() const noexcept;
+
+ // NOT IMPLEMENTED
+ constexpr reverse_iterator rend() noexcept;
+ constexpr const_reverse_iterator rend() const noexcept;
+ constexpr const_reverse_iterator crend() const noexcept;
+
+ [[nodiscard]] constexpr bool empty() const noexcept { return kSize == 0u; }
+
+ constexpr size_type size() const noexcept { return kSize; }
+
+ constexpr size_type max_size() const noexcept { return size(); }
+
+ constexpr void fill(const T& value) {
+ for (T& array_value : __data) {
+ array_value = value;
+ }
+ }
+
+ // NOT IMPLEMENTED
+ constexpr void swap(array& other) noexcept;
+
+ T __data[kSize];
+};
+
+// NOT IMPLEMENTED: comparison operators, get, swap, tuple specializations
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/cinttypes.h b/pw_minimal_cpp_stdlib/public/internal/cinttypes.h
new file mode 100644
index 0000000..5141862
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cinttypes.h
@@ -0,0 +1,16 @@
+// 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
+
+#include "inttypes.h"
diff --git a/pw_minimal_cpp_stdlib/public/internal/cmath.h b/pw_minimal_cpp_stdlib/public/internal/cmath.h
new file mode 100644
index 0000000..cec4a7e
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cmath.h
@@ -0,0 +1,55 @@
+// 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
+
+#include <math.h>
+
+namespace std {
+
+// The integer overloads of these functions are not provided.
+
+// This is not technically correct, but avoids ambiguous calls to an overloaded
+// abs function.
+template <typename T>
+inline T abs(T value) {
+ return value < 0 ? -value : value;
+}
+
+#ifdef isfinite
+#undef isfinite
+#endif // isfinite
+
+inline bool isfinite(float value) { return __builtin_isfinite(value); }
+inline bool isfinite(double value) { return __builtin_isfinite(value); }
+inline bool isfinite(long double value) { return __builtin_isfinite(value); }
+
+#ifdef isnan
+#undef isnan
+#endif // isnan
+
+inline bool isnan(float value) { return __builtin_isnan(value); }
+inline bool isnan(double value) { return __builtin_isnan(value); }
+inline bool isnan(long double value) { return __builtin_isnan(value); }
+
+#ifdef signbit
+#undef signbit
+#endif // signbit
+
+inline bool signbit(float value) { return __builtin_signbit(value); }
+inline bool signbit(double value) { return __builtin_signbit(value); }
+inline bool signbit(long double value) { return __builtin_signbit(value); }
+
+using ::round;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdarg.h b/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
new file mode 100644
index 0000000..8d31c67
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
@@ -0,0 +1,22 @@
+// 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
+
+#include <stdarg.h>
+
+namespace std {
+
+using ::va_list;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstddef.h b/pw_minimal_cpp_stdlib/public/internal/cstddef.h
new file mode 100644
index 0000000..bcb7bb2
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cstddef.h
@@ -0,0 +1,74 @@
+// 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
+
+#include <stddef.h>
+
+namespace std {
+
+using ::ptrdiff_t;
+using ::size_t;
+using nullptr_t = decltype(nullptr);
+using ::max_align_t;
+
+#define __cpp_lib_byte 201603L
+
+enum class byte : unsigned char {};
+
+template <typename I>
+constexpr I to_integer(byte b) noexcept {
+ return I(b);
+}
+
+constexpr byte operator|(byte l, byte r) noexcept {
+ return byte(static_cast<unsigned int>(l) | static_cast<unsigned int>(r));
+}
+
+constexpr byte operator&(byte l, byte r) noexcept {
+ return byte(static_cast<unsigned int>(l) & static_cast<unsigned int>(r));
+}
+
+constexpr byte operator^(byte l, byte r) noexcept {
+ return byte(static_cast<unsigned int>(l) ^ static_cast<unsigned int>(r));
+}
+
+constexpr byte operator~(byte b) noexcept {
+ return byte(~static_cast<unsigned int>(b));
+}
+
+template <typename I>
+constexpr byte operator<<(byte b, I shift) noexcept {
+ return byte(static_cast<unsigned int>(b) << shift);
+}
+
+template <typename I>
+constexpr byte operator>>(byte b, I shift) noexcept {
+ return byte(static_cast<unsigned int>(b) >> shift);
+}
+
+constexpr byte& operator|=(byte& l, byte r) noexcept { return l = l | r; }
+constexpr byte& operator&=(byte& l, byte r) noexcept { return l = l & r; }
+constexpr byte& operator^=(byte& l, byte r) noexcept { return l = l ^ r; }
+
+template <typename I>
+inline byte& operator<<=(byte& b, I shift) noexcept {
+ return b = b << shift;
+}
+
+template <typename I>
+inline byte& operator>>=(byte& b, I shift) noexcept {
+ return b = b >> shift;
+}
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdint.h b/pw_minimal_cpp_stdlib/public/internal/cstdint.h
new file mode 100644
index 0000000..abe9e04
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cstdint.h
@@ -0,0 +1,16 @@
+// 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
+
+#include "stdint.h"
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdio.h b/pw_minimal_cpp_stdlib/public/internal/cstdio.h
new file mode 100644
index 0000000..0a4bae6
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cstdio.h
@@ -0,0 +1,32 @@
+// 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
+
+#include <stdio.h>
+
+namespace std {
+
+using ::size_t;
+
+// Only a small subset of functions are exposed here.
+
+using ::putchar;
+using ::puts;
+using ::snprintf;
+using ::vsnprintf;
+
+using ::getchar;
+using ::sscanf;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstring.h b/pw_minimal_cpp_stdlib/public/internal/cstring.h
new file mode 100644
index 0000000..b2f08ad
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/cstring.h
@@ -0,0 +1,39 @@
+// 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
+
+#include <string.h>
+
+namespace std {
+
+using ::size_t;
+
+// Only a small subset of functions are exposed here.
+
+using ::memchr;
+using ::memcmp;
+using ::memcpy;
+using ::memmove;
+using ::memset;
+
+using ::strcat;
+using ::strcpy;
+using ::strncat;
+using ::strncpy;
+
+using ::strcmp;
+using ::strlen;
+using ::strncmp;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/iterator.h b/pw_minimal_cpp_stdlib/public/internal/iterator.h
new file mode 100644
index 0000000..9c5e9ad
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/iterator.h
@@ -0,0 +1,51 @@
+// 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
+
+#include <cstddef>
+
+namespace std {
+
+#define __cpp_lib_nonmember_container_access 201411L
+
+template <typename C>
+constexpr auto data(C& container) -> decltype(container.data()) {
+ return container.data();
+}
+
+template <typename C>
+constexpr auto data(const C& container) -> decltype(container.data()) {
+ return container.data();
+}
+
+template <typename T, decltype(sizeof(int)) kSize>
+constexpr T* data(T (&array)[kSize]) noexcept {
+ return array;
+}
+
+template <typename C>
+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 {
+ return kSize;
+}
+
+// NOT IMPLEMENTED: Reverse iterators are not implemented.
+template <typename>
+struct reverse_iterator;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/limits.h b/pw_minimal_cpp_stdlib/public/internal/limits.h
new file mode 100644
index 0000000..6c14180
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/limits.h
@@ -0,0 +1,65 @@
+// 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
+
+#include <limits.h>
+
+namespace std {
+
+template <typename T>
+struct numeric_limits {
+ static constexpr bool is_specialized = false;
+};
+
+// 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_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)
+
+_PW_LIMITS_SPECIALIZATION(bool, false, true, false, true);
+_PW_LIMITS_SPECIALIZATION(char, char(-1) < char(0), true, CHAR_MIN, CHAR_MAX);
+
+_PW_INTEGRAL_LIMIT(char, SCHAR, UCHAR);
+_PW_INTEGRAL_LIMIT(short, SHRT, USHRT);
+_PW_INTEGRAL_LIMIT(int, INT, UINT);
+_PW_INTEGRAL_LIMIT(long, LONG, ULONG);
+
+#ifndef LLONG_MIN
+#define LLONG_MIN ((long long)(~0ull ^ (~0ull >> 1)))
+#define LLONG_MAX ((long long)(~0ull >> 1))
+
+#define ULLONG_MIN (0ull)
+#define ULLONG_MAX (~0ull)
+#endif // LLONG_MIN
+
+_PW_INTEGRAL_LIMIT(long long, LLONG, ULLONG);
+
+#undef _PW_LIMITS_SPECIALIZATION
+#undef _PW_INTEGRAL_LIMIT
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/new.h b/pw_minimal_cpp_stdlib/public/internal/new.h
new file mode 100644
index 0000000..d21d991
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/new.h
@@ -0,0 +1,17 @@
+// 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
+
+// Placement new
+inline void* operator new(decltype(sizeof(0)), void* ptr) { return ptr; }
diff --git a/pw_minimal_cpp_stdlib/public/internal/string_view.h b/pw_minimal_cpp_stdlib/public/internal/string_view.h
new file mode 100644
index 0000000..65ee858
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/string_view.h
@@ -0,0 +1,174 @@
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+
+#define __cpp_lib_string_view 201606L
+
+namespace std {
+
+template <typename T>
+class basic_string_view {
+ public:
+ using traits_type = void; // No traits object is used.
+ using value_type = T;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using reference = T&;
+ using const_reference = const T&;
+ using const_iterator = const T*;
+ 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 difference_type = ptrdiff_t;
+
+ static constexpr size_type npos = size_type(-1);
+
+ constexpr basic_string_view() noexcept : string_(nullptr), size_(0) {}
+ constexpr basic_string_view(const basic_string_view&) noexcept = default;
+ constexpr basic_string_view(const T* string, size_type count)
+ : string_(string), size_(count) {}
+ constexpr basic_string_view(const T* string)
+ : string_(string), size_(CStringLength(string)) {}
+
+ constexpr basic_string_view& operator=(const basic_string_view&) noexcept =
+ default;
+
+ constexpr const_iterator begin() const noexcept { return string_; }
+ constexpr const_iterator cbegin() const noexcept { return begin(); }
+
+ constexpr const_iterator end() const noexcept { return string_ + size_; }
+ constexpr const_iterator cend() const noexcept { return end(); }
+
+ // NOT IMPLEMENTED: Reverse iterators not supported.
+ constexpr const_reverse_iterator rbegin() const noexcept;
+ constexpr const_reverse_iterator crbegin() const noexcept;
+
+ constexpr const_reverse_iterator rend() const noexcept;
+ constexpr const_reverse_iterator crend() const noexcept;
+
+ constexpr const_reference operator[](size_type pos) const {
+ return data()[pos];
+ }
+
+ // NOT IMPLEMENTED: at() has no bounds checking.
+ constexpr const_reference at(size_type pos) const { return data()[pos]; }
+
+ constexpr const_reference front() const { return data()[0]; }
+
+ constexpr const_reference back() const { return data()[size() - 1]; }
+
+ constexpr const_pointer data() const noexcept { return string_; }
+
+ 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}; }
+
+ [[nodiscard]] constexpr bool empty() const noexcept { return size() == 0u; }
+
+ constexpr void remove_prefix(size_type characters) {
+ string_ += characters;
+ size_ -= characters;
+ }
+
+ constexpr void remove_suffix(size_type characters) { size_ -= characters; }
+
+ constexpr void swap(basic_string_view& other) noexcept {
+ pointer temp_string = string_;
+ string_ = other.string_;
+ other.string_ = temp_string;
+
+ size_type temp_size = size_;
+ size_ = other.size_;
+ other.size_ = temp_size;
+ }
+
+ // NOT IMPLEMENTED: copy does no bounds checking.
+ constexpr size_type copy(T* dest, size_type count, size_type pos = 0) const {
+ const size_type to_copy = min(count, size() - pos);
+ for (size_type i = pos; i < pos + to_copy; ++i) {
+ *dest++ = string_[i];
+ }
+ return to_copy;
+ }
+
+ constexpr basic_string_view substr(size_type pos = 0,
+ size_type count = npos) const {
+ return basic_string_view(string_ + pos, min(count, size() - pos));
+ }
+
+ // NOT IMPLEMENTED: These functions and their overloads are not defined.
+ constexpr int compare(basic_string_view view) const noexcept;
+ constexpr bool starts_with(basic_string_view view) const noexcept;
+ constexpr bool ends_with(basic_string_view view) const noexcept;
+ constexpr size_type find(basic_string_view view,
+ size_type pos = 0) const noexcept;
+ constexpr size_type rfind(basic_string_view view,
+ size_type pos = npos) const noexcept;
+ constexpr size_type find_first_of(basic_string_view view,
+ size_type pos = 0) const noexcept;
+ constexpr size_type find_last_of(basic_string_view view,
+ size_type pos = npos) const noexcept;
+ constexpr size_type find_first_not_of(basic_string_view view,
+ size_type pos = 0) const noexcept;
+ constexpr size_type find_last_not_of(basic_string_view view,
+ size_type pos = npos) const noexcept;
+
+ private:
+ static constexpr size_type CStringLength(const T* string) {
+ size_type length = 0;
+ while (string[length] != T()) {
+ length += 1;
+ }
+ return length;
+ }
+
+ const_pointer string_;
+ size_type size_;
+};
+
+template <typename T>
+constexpr bool operator==(basic_string_view<T> lhs, basic_string_view<T> rhs) {
+ if (lhs.size() != rhs.size()) {
+ return false;
+ }
+ for (typename basic_string_view<T>::size_type i = 0; i < lhs.size(); ++i) {
+ if (lhs[i] != rhs[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <typename T>
+constexpr bool operator!=(basic_string_view<T> lhs, basic_string_view<T> rhs) {
+ return !(lhs == rhs);
+}
+
+// NOT IMPLEMENTED: Other comparison operators are not defined.
+
+using string_view = basic_string_view<char>;
+using wstring_view = basic_string_view<wchar_t>;
+using u16string_view = basic_string_view<char16_t>;
+using u32string_view = basic_string_view<char32_t>;
+
+// NOT IMPLEMENTED: string_view literals cannot be implemented since they do not
+// start with _.
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/type_traits.h b/pw_minimal_cpp_stdlib/public/internal/type_traits.h
new file mode 100644
index 0000000..422b2df
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/type_traits.h
@@ -0,0 +1,425 @@
+// 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 {
+
+#define __cpp_lib_transformation_trait_aliases 201304L
+#define __cpp_lib_type_trait_variable_templates 201510L
+
+template <decltype(sizeof(0)) kLength,
+ decltype(sizeof(0)) kAlignment> // no default
+struct aligned_storage {
+ struct type {
+ alignas(kAlignment) unsigned char __data[kLength];
+ };
+};
+
+template <decltype(sizeof(0)) kLength,
+ decltype(sizeof(0)) kAlignment> // no default
+using aligned_storage_t = typename aligned_storage<kLength, kAlignment>::type;
+
+#define __cpp_lib_integral_constant_callable 201304L
+
+template <typename T, T kValue>
+struct integral_constant {
+ using value_type = T;
+ using type = integral_constant;
+
+ static constexpr T value = kValue;
+
+ constexpr operator value_type() const noexcept { return value; }
+
+ constexpr value_type operator()() const noexcept { return value; }
+};
+
+#define __cpp_lib_bool_constant 201505L
+
+template <bool kValue>
+using bool_constant = integral_constant<bool, kValue>;
+
+using true_type = bool_constant<true>;
+using false_type = bool_constant<false>;
+
+template <typename T>
+struct is_array : false_type {};
+
+template <typename T>
+struct is_array<T[]> : true_type {};
+
+template <typename T, decltype(sizeof(int)) 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 {};
+
+// NOT IMPLEMENTED: is_enum requires compiler builtins.
+template <typename T>
+struct is_enum : false_type {};
+
+template <typename T>
+inline constexpr bool is_enum_v = is_enum<T>::value;
+
+template <typename T>
+struct remove_cv; // Forward declaration
+
+namespace impl {
+
+template <typename T>
+struct is_floating_point : false_type {};
+
+template <>
+struct is_floating_point<float> : true_type {};
+template <>
+struct is_floating_point<double> : true_type {};
+template <>
+struct is_floating_point<long double> : true_type {};
+
+} // namespace impl
+
+template <typename T>
+struct is_floating_point
+ : impl::is_floating_point<typename remove_cv<T>::type> {};
+
+template <typename T>
+inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
+
+namespace impl {
+
+template <typename T>
+struct is_integral : false_type {};
+
+template <>
+struct is_integral<bool> : true_type {};
+template <>
+struct is_integral<char> : true_type {};
+template <>
+struct is_integral<char16_t> : true_type {};
+template <>
+struct is_integral<char32_t> : true_type {};
+template <>
+struct is_integral<wchar_t> : true_type {};
+
+template <>
+struct is_integral<short> : true_type {};
+template <>
+struct is_integral<unsigned short> : true_type {};
+template <>
+struct is_integral<int> : true_type {};
+template <>
+struct is_integral<unsigned int> : true_type {};
+template <>
+struct is_integral<long> : true_type {};
+template <>
+struct is_integral<unsigned long> : true_type {};
+template <>
+struct is_integral<long long> : true_type {};
+template <>
+struct is_integral<unsigned long long> : true_type {};
+
+} // namespace impl
+
+template <typename T>
+struct is_integral : impl::is_integral<typename remove_cv<T>::type> {};
+
+template <typename T>
+inline constexpr bool is_integral_v = is_integral<T>::value;
+
+template <typename T>
+struct is_arithmetic
+ : bool_constant<is_integral_v<T> || is_floating_point_v<T>> {};
+
+template <typename T>
+inline constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
+
+#define __cpp_lib_is_null_pointer 201309L
+
+template <typename T>
+struct is_null_pointer : false_type {};
+
+template <>
+struct is_null_pointer<decltype(nullptr)> : true_type {};
+
+template <typename T>
+inline constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
+
+template <typename T>
+struct is_pointer : false_type {};
+
+template <typename T>
+struct is_pointer<T*> : true_type {};
+
+template <typename T>
+inline constexpr bool is_pointer_v = is_pointer<T>::value;
+
+template <typename T, typename U>
+struct is_same : false_type {};
+
+template <typename T>
+struct is_same<T, T> : true_type {};
+
+template <typename T, typename U>
+inline constexpr bool is_same_v = is_same<T, U>::value;
+
+namespace impl {
+
+template <typename T, bool = is_arithmetic<T>::value>
+struct is_signed : integral_constant<bool, T(-1) < T(0)> {};
+
+template <typename T>
+struct is_signed<T, false> : false_type {};
+
+} // namespace impl
+
+template <typename T>
+struct is_signed : impl::is_signed<T>::type {};
+
+template <typename T>
+inline constexpr bool is_signed_v = is_signed<T>::value;
+
+template <typename T>
+struct is_unsigned : bool_constant<!is_signed_v<T>> {};
+
+template <typename T>
+inline constexpr bool is_unsigned_v = is_unsigned<T>::value;
+
+template <typename T>
+struct is_void : is_same<void, typename remove_cv<T>::type> {};
+
+template <typename T>
+inline constexpr bool is_void_v = is_void<T>::value;
+
+template <bool kBool, typename TrueType, typename FalseType>
+struct conditional {
+ using type = TrueType;
+};
+
+template <typename TrueType, typename FalseType>
+struct conditional<false, TrueType, FalseType> {
+ using type = FalseType;
+};
+
+template <bool kBool, typename TrueType, typename FalseType>
+using conditional_t = typename conditional<kBool, TrueType, FalseType>::type;
+
+template <bool kEnable, typename T = void>
+struct enable_if {
+ using type = T;
+};
+
+template <typename T>
+struct enable_if<false, T> {};
+
+template <bool kEnable, typename T = void>
+using enable_if_t = typename enable_if<kEnable, T>::type;
+
+template <typename T>
+struct remove_const {
+ using type = T;
+};
+
+template <typename T>
+struct remove_const<const T> {
+ using type = T;
+};
+
+template <typename T>
+using remove_const_t = typename remove_const<T>::type;
+
+template <typename T>
+struct remove_volatile {
+ using type = T;
+};
+
+template <typename T>
+struct remove_volatile<volatile T> {
+ using type = T;
+};
+
+template <typename T>
+using remove_volatile_t = typename remove_volatile<T>::type;
+
+template <typename T>
+struct remove_cv {
+ using type = remove_volatile_t<remove_const_t<T>>;
+};
+
+template <typename T>
+using remove_cv_t = typename remove_cv<T>::type;
+
+template <typename T>
+struct remove_extent {
+ using type = T;
+};
+
+template <typename T>
+struct remove_extent<T[]> {
+ using type = T;
+};
+
+template <typename T, decltype(sizeof(0)) kSize>
+struct remove_extent<T[kSize]> {
+ using type = T;
+};
+
+template <typename T>
+using remove_extent_t = typename remove_extent<T>::type;
+
+template <typename T>
+struct remove_pointer {
+ using type = T;
+};
+
+template <typename T>
+struct remove_pointer<T*> {
+ using type = T;
+};
+
+template <typename T>
+struct remove_pointer<T* const> {
+ using type = T;
+};
+
+template <typename T>
+struct remove_pointer<T* volatile> {
+ using type = T;
+};
+
+template <typename T>
+struct remove_pointer<T* const volatile> {
+ using type = T;
+};
+
+template <typename T>
+using remove_pointer_t = typename remove_pointer<T>::type;
+
+template <typename T>
+struct remove_reference {
+ using type = T;
+};
+
+template <typename T>
+struct remove_reference<T&> {
+ using type = T;
+};
+
+template <typename T>
+struct remove_reference<T&&> {
+ using type = T;
+};
+
+template <typename T>
+using remove_reference_t = typename remove_reference<T>::type;
+
+// NOT IMPLEMENTED: This implementation is INCOMPLETE, as it does not cover
+// function types.
+template <typename T>
+struct decay {
+ private:
+ using U = remove_reference_t<T>;
+
+ public:
+ using type =
+ conditional_t<is_array<U>::value, remove_extent_t<U>*, remove_cv_t<U>>;
+};
+
+template <typename T>
+using decay_t = typename decay<T>::type;
+
+#define __cpp_lib_type_identity 201806
+
+template <class T>
+struct type_identity {
+ using type = T;
+};
+
+template <typename T>
+using type_identity_t = typename type_identity<T>::type;
+
+#define __cpp_lib_void_t void_t 201411L
+
+template <typename...>
+using void_t = void;
+
+// NOT IMPLEMENTED: add_rvalue_refernce does work with reference types.
+template <typename T>
+struct add_rvalue_reference {
+ using type = T&&;
+};
+
+template <typename T>
+using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
+
+template <typename T>
+add_rvalue_reference_t<T> declval() noexcept;
+
+namespace impl {
+
+template <typename>
+using templated_true = true_type;
+
+template <typename T>
+auto returnable(int) -> templated_true<T()>;
+
+template <typename>
+auto returnable(...) -> false_type;
+
+template <typename From, typename To>
+auto convertible(int)
+ -> templated_true<decltype(declval<void (&)(To)>()(declval<From>()))>;
+
+template <typename, typename>
+auto convertible(...) -> false_type;
+
+} // namespace impl
+
+template <typename From, typename To>
+struct is_convertible
+ : bool_constant<(decltype(impl::returnable<To>(0))() &&
+ decltype(impl::convertible<From, To>(0))()) ||
+ (is_void_v<From> && is_void_v<To>)> {};
+
+template <typename T, typename U>
+inline constexpr bool is_convertible_v = is_convertible<T, U>::value;
+
+// NOT IMPLEMENTED: Stubs are provided for these traits classes, but they do not
+// return useful values. Many of these would require compiler builtins.
+template <typename T>
+struct is_function : false_type {};
+template <typename T>
+struct is_trivially_copyable : true_type {};
+template <typename T>
+struct is_polymorphic : false_type {};
+template <typename T, typename U>
+struct is_base_of : false_type {};
+template <typename T>
+struct extent : integral_constant<decltype(sizeof(int)), 1> {};
+template <typename T>
+inline constexpr bool extent_v = extent<T>::value;
+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;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/internal/utility.h b/pw_minimal_cpp_stdlib/public/internal/utility.h
new file mode 100644
index 0000000..6d238f7
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/internal/utility.h
@@ -0,0 +1,25 @@
+// 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 {
+
+// Forward declare these classes, which are specialized in other headers.
+template <decltype(sizeof(0)), typename>
+struct tuple_element;
+
+template <typename>
+struct tuple_size;
+
+} // namespace std
diff --git a/pw_minimal_cpp_stdlib/public/iterator b/pw_minimal_cpp_stdlib/public/iterator
new file mode 120000
index 0000000..4703aa8
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/iterator
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..8309de0
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/limits
@@ -0,0 +1 @@
+internal/limits.h
\ No newline at end of file
diff --git a/pw_minimal_cpp_stdlib/public/new b/pw_minimal_cpp_stdlib/public/new
new file mode 120000
index 0000000..ed0129c
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/new
@@ -0,0 +1 @@
+internal/new.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
new file mode 120000
index 0000000..8e1be67
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/string_view
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..71b1217
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/type_traits
@@ -0,0 +1 @@
+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
new file mode 120000
index 0000000..58c32f2
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/utility
@@ -0,0 +1 @@
+internal/utility.h
\ No newline at end of file