pw_polyfill, pw_minimal_cpp_stdlib: Fix namespace

- Clang / libc++ require standard library names to be defined in a
  special namespace. If they are simply declared in namespace std,
  strange errors can occur. This caused problems with std::span. Update
  pw_polyfill to add a macro that provides the std namespace
  declaration.
- Update pw_polyfill and pw_minimal_cpp_stdlib to use the new std
  namespace macro.
- Fully isolate the pw_minimal_cpp_stdlib library tests from the rest of
  Pigweed, since Pigweed builds with the standard library. This prevents
  isolates potentially conflicting standard library defintions.

Change-Id: I1a095e8ac879757ffba6796239e70785cc328cd7
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/13240
Reviewed-by: Rob Mohr <mohrr@google.com>
Reviewed-by: David Rogers <davidrogers@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_kvs/key_value_store_map_test.cc b/pw_kvs/key_value_store_map_test.cc
index 9919cae..b1de093 100644
--- a/pw_kvs/key_value_store_map_test.cc
+++ b/pw_kvs/key_value_store_map_test.cc
@@ -13,6 +13,7 @@
 // the License.
 
 #include <cstdlib>
+#include <random>
 #include <set>
 #include <span>
 #include <string>
@@ -20,18 +21,6 @@
 #include <unordered_map>
 #include <unordered_set>
 
-// TODO(hepler): Clang 11 fails to compile this file if <random> is included
-// before <span>. It seems to miss the definition of std::span. This compiles
-// correctly in GCC 9.
-//
-//   In file included from ../pw_kvs/key_value_store_map_test.cc:33:
-//   In file included from ../pw_unit_test/public_overrides/gtest/gtest.h:20:
-//   In file included from ../pw_unit_test/public/pw_unit_test/framework.h:32:
-//   ../pw_string/public/pw_string/string_builder.h:267:25: error:
-//       implicit instantiation of undefined template
-//       'std::span<char, 18446744073709551615>'
-#include <random>
-
 #define DUMP_KVS_CONTENTS 0
 
 #if DUMP_KVS_CONTENTS
diff --git a/pw_minimal_cpp_stdlib/BUILD b/pw_minimal_cpp_stdlib/BUILD
index 96aca6d..01d6276 100644
--- a/pw_minimal_cpp_stdlib/BUILD
+++ b/pw_minimal_cpp_stdlib/BUILD
@@ -66,14 +66,23 @@
     includes = ["public"],
 )
 
+pw_cc_library(
+    name = "minimal_cpp_stdlib_isolated_test",
+    srcs = ["isolated_test.cc"],
+    copts = ["-nostdinc++"],
+    deps = [
+        ":pw_minimal_cpp_stdlib",
+        "//pw_preprocessor",
+    ],
+)
+
 pw_cc_test(
     name = "test",
     srcs = [
         "test.cc",
     ],
-    copts = ["-nostdinc++"],
     deps = [
-        ":pw_minimal_cpp_stdlib",
+        ":pw_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 541541d..5f3a6ad 100644
--- a/pw_minimal_cpp_stdlib/BUILD.gn
+++ b/pw_minimal_cpp_stdlib/BUILD.gn
@@ -76,14 +76,26 @@
   ]
 }
 
-pw_test("minimal_cpp_stdlib_test") {
+pw_source_set("minimal_cpp_stdlib_isolated_test") {
   configs = [ ":no_cpp_includes" ]
-  deps = [ ":pw_minimal_cpp_stdlib" ]
+  deps = [
+    ":pw_minimal_cpp_stdlib",
+    dir_pw_preprocessor,
+  ]
+  sources = [ "isolated_test.cc" ]
+  visibility = [ ":*" ]
+}
+
+pw_test("minimal_cpp_stdlib_test") {
+  deps = [ ":minimal_cpp_stdlib_isolated_test" ]
   sources = [ "test.cc" ]
 }
 
 pw_test("standard_library_test") {
-  sources = [ "test.cc" ]
+  sources = [
+    "isolated_test.cc",
+    "test.cc",
+  ]
 }
 
 pw_doc_group("docs") {
diff --git a/pw_minimal_cpp_stdlib/CMakeLists.txt b/pw_minimal_cpp_stdlib/CMakeLists.txt
index 90f96cd..5ab9ffe 100644
--- a/pw_minimal_cpp_stdlib/CMakeLists.txt
+++ b/pw_minimal_cpp_stdlib/CMakeLists.txt
@@ -12,4 +12,5 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
-pw_auto_add_simple_module(pw_minimal_cpp_stdlib)
+add_library(pw_minimal_cpp_stdlib INTERFACE)
+target_include_directories(pw_minimal_cpp_stdlib INTERFACE public)
diff --git a/pw_minimal_cpp_stdlib/isolated_test.cc b/pw_minimal_cpp_stdlib/isolated_test.cc
new file mode 100644
index 0000000..4f90a82
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/isolated_test.cc
@@ -0,0 +1,333 @@
+// Copyright 2019 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.
+
+// Include all of the provided headers, even if they aren't tested.
+#include <algorithm>
+#include <array>
+#include <cinttypes>
+#include <cmath>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <initializer_list>
+#include <iterator>
+#include <limits>
+#include <new>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+#include "pw_preprocessor/compiler.h"
+
+namespace {
+
+// In order to test this file without dependencies on the C++ standard library,
+// this file needs to be fully isolated from the regular Pigweed testing
+// infrastructure. pw_unit_test's dependencies do compile with the C++ standard
+// library, which could conflict with pw_minimal_cpp_stdlib.
+//
+// SimpleTest provides the basic features of pw_unit_test without dependencies.
+class SimpleTest {
+ public:
+  virtual ~SimpleTest() = default;
+
+  static bool RunAllTests() {
+    for (SimpleTest* test = all_tests; test != nullptr; test = test->next_) {
+      test->Run();
+      if (!test->passed_) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+ protected:
+  SimpleTest() : next_(all_tests) { all_tests = this; }
+
+  void RecordTestFailure() { passed_ = false; }
+
+ private:
+  virtual void Run() = 0;
+
+  static SimpleTest* all_tests;
+
+  bool passed_ = true;
+  SimpleTest* next_;
+};
+
+SimpleTest* SimpleTest::all_tests = nullptr;
+
+#define EXPECT_EQ(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)
+
+#define TEST(suite, name)                                 \
+  class SimpleTest_##suite##_##name : public SimpleTest { \
+    void Run() override;                                  \
+  } test_##suite##_##name;                                \
+                                                          \
+  void SimpleTest_##suite##_##name::Run()
+
+TEST(Algorithm, Basic) {
+  static_assert(std::min(1, 2) == 1);
+  static_assert(std::max(1, 2) == 2);
+
+  EXPECT_EQ(std::forward<int>(2), 2);
+}
+
+TEST(Algorithm, Copy) {
+  constexpr size_t kCopyOffset = 1;
+  std::array<int, 3> foo{3, 2, 1};
+  std::array<int, 5> bar{0};
+
+  // Ensure zero-element iterator doesn't modify the destination object when
+  // copied.
+  int temp = foo[0];
+  std::copy(foo.end(), foo.end(), bar.begin());
+  EXPECT_EQ(foo[0], temp);
+
+  // Copy a single element.
+  std::array<int, 1> one{-101};
+  std::copy(one.begin(), one.end(), foo.begin());
+  EXPECT_EQ(foo[0], -101);
+
+  auto copy_end = std::copy(foo.begin(), foo.end(), bar.begin() + kCopyOffset);
+  // Verify the iterator points to the end of the copied region.
+  EXPECT_EQ(copy_end, bar.begin() + foo.size() + kCopyOffset);
+
+  // Verify all the values were properly copied from foo to bar.
+  {
+    size_t i = 0;
+    for (auto it = bar.begin() + kCopyOffset; it != copy_end; ++it) {
+      EXPECT_EQ(*it, foo[i++]);
+    }
+  }
+}
+
+TEST(Algorithm, Find) {
+  std::array<int, 5> foo{3, 2, 1, 42, 17};
+  // Ensure a value in the middle of the array is properly found.
+  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 42), 42);
+
+  // Ensure the iterator returned by find() matches the expected location of the
+  // element.
+  EXPECT_EQ(std::find(std::begin(foo), std::end(foo), 42), std::begin(foo) + 3);
+
+  // Ensure an element at the beginning of an array is found.
+  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 3), foo[0]);
+
+  // Ensure an element at the end of an array is found.
+  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 17),
+            foo[foo.size() - 1]);
+}
+
+TEST(Algorithm, NotFound) {
+  std::array<int, 3> foo{3, 2, 1};
+
+  // Ensure that if an element is not found, an iterator matching foo.end() is
+  // returned.
+  EXPECT_EQ(std::find(std::begin(foo), std::end(foo), -99), std::end(foo));
+
+  // Ensure that a zero-element iterator range returns the end iterator passed
+  // to std::find().
+  EXPECT_EQ(std::find(std::end(foo), std::end(foo), 3), std::end(foo));
+}
+
+TEST(Array, Basic) {
+  constexpr std::array<int, 4> array{0, 1, 2, 3};
+
+  static_assert(array[2] == 2);
+
+  for (int i = 0; i < static_cast<int>(array.size()); ++i) {
+    EXPECT_EQ(i, array[i]);
+  }
+}
+
+TEST(Cmath, Basic) PW_NO_SANITIZE("float-divide-by-zero") {
+  EXPECT_EQ(std::abs(-1), 1);
+  EXPECT_EQ(std::abs(1), 1);
+
+  // Although Clang/LLVM do not fully support __STDC_IEC_559__, they do have the
+  // necessary IEEE 754 support for floating point division by zero.
+  EXPECT_TRUE(std::isfinite(1.0));
+  EXPECT_FALSE(std::isfinite(1.0 / 0.0));
+
+  EXPECT_FALSE(std::isnan(1.0));
+  EXPECT_TRUE(std::isnan(0.0 / 0.0));
+
+  EXPECT_FALSE(std::signbit(1.0));
+  EXPECT_TRUE(std::signbit(-1.0));
+}
+
+TEST(Cstddef, Basic) {
+  using std::byte;
+  byte foo = byte{12};
+  EXPECT_EQ(foo, byte{12});
+}
+
+TEST(Iterator, Basic) {
+  std::array<int, 3> foo{3, 2, 1};
+
+  EXPECT_EQ(std::data(foo), foo.data());
+  EXPECT_EQ(std::size(foo), foo.size());
+
+  EXPECT_EQ(*std::begin(foo), foo[0]);
+  EXPECT_EQ(std::end(foo), std::begin(foo) + foo.size());
+
+  foo.fill(99);
+  EXPECT_EQ(foo[0], 99);
+  EXPECT_EQ(foo[1], 99);
+  EXPECT_EQ(foo[2], 99);
+}
+
+template <typename T>
+int SumFromInitializerList(std::initializer_list<T> values) {
+  int sum = 0;
+  for (auto value : values) {
+    sum += value;
+  }
+  return sum;
+}
+TEST(InitializerList, Empty) {
+  std::initializer_list<int> mt;
+  EXPECT_EQ(0, SumFromInitializerList(mt));
+
+  EXPECT_EQ(0, SumFromInitializerList<float>({}));
+}
+
+TEST(InitializerList, Declared) {
+  std::initializer_list<char> list{'\3', '\3', '\4'};
+  EXPECT_EQ(10, SumFromInitializerList(list));
+}
+
+TEST(InitializerList, Inline) {
+  EXPECT_EQ(42, SumFromInitializerList<long>({42}));
+  EXPECT_EQ(2, SumFromInitializerList<bool>({true, false, true}));
+  EXPECT_EQ(15, SumFromInitializerList({1, 2, 3, 4, 5}));
+}
+
+TEST(Limits, Basic) {
+  static_assert(std::numeric_limits<unsigned char>::is_specialized);
+  static_assert(std::numeric_limits<unsigned char>::is_integer);
+  static_assert(std::numeric_limits<unsigned char>::min() == 0u);
+  static_assert(std::numeric_limits<unsigned char>::max() == 255u);
+
+  static_assert(std::numeric_limits<signed char>::is_specialized);
+  static_assert(std::numeric_limits<signed char>::is_integer);
+  static_assert(std::numeric_limits<signed char>::min() == -128);
+  static_assert(std::numeric_limits<signed char>::max() == 127);
+
+  // Assume 64-bit long long
+  static_assert(std::numeric_limits<long long>::is_specialized);
+  static_assert(std::numeric_limits<long long>::is_integer);
+  static_assert(std::numeric_limits<long long>::min() ==
+                (-9223372036854775807ll - 1));
+  static_assert(std::numeric_limits<long long>::max() == 9223372036854775807ll);
+
+  static_assert(std::numeric_limits<unsigned long long>::is_specialized);
+  static_assert(std::numeric_limits<unsigned long long>::is_integer);
+  static_assert(std::numeric_limits<unsigned long long>::min() == 0u);
+  static_assert(std::numeric_limits<unsigned long long>::max() ==
+                18446744073709551615ull);
+}
+
+TEST(New, PlacementNew) {
+  unsigned char value[4];
+  new (value) int(1234);
+
+  int int_value;
+  std::memcpy(&int_value, value, sizeof(int_value));
+  EXPECT_EQ(1234, int_value);
+}
+
+TEST(New, Launder) {
+  unsigned char value[4];
+  int* int_ptr = std::launder(reinterpret_cast<int*>(value));
+  EXPECT_EQ(static_cast<void*>(int_ptr), static_cast<void*>(value));
+}
+
+TEST(StringView, Basic) {
+  constexpr std::string_view value("1234567890");
+  static_assert(value.size() == 10);
+  static_assert(value[1] == '2');
+
+  char buffer[] = "!!!!!";
+  constexpr size_t buffer_size = sizeof(buffer) - 1;  // always keep the \0
+
+  value.copy(buffer, buffer_size, 10);
+  EXPECT_STREQ(buffer, "!!!!!");
+
+  value.copy(buffer, buffer_size, 9);
+  EXPECT_STREQ(buffer, "0!!!!");
+
+  value.copy(buffer, buffer_size, 2);
+  EXPECT_STREQ(buffer, "34567");
+
+  value.copy(buffer, buffer_size);
+  EXPECT_STREQ(buffer, "12345");
+}
+
+TEST(TypeTraits, Basic) {
+  static_assert(std::is_integral_v<bool>);
+  static_assert(!std::is_integral_v<float>);
+
+  static_assert(std::is_floating_point_v<float>);
+  static_assert(!std::is_floating_point_v<bool>);
+
+  static_assert(std::is_same_v<float, float>);
+  static_assert(!std::is_same_v<char, unsigned char>);
+}
+
+struct MoveTester {
+  MoveTester(int value) : magic_value(value), moved(false) {}
+
+  MoveTester(const MoveTester&) = default;
+
+  MoveTester(MoveTester&& other) : magic_value(other.magic_value), moved(true) {
+    other.magic_value = 0xffff;
+  }
+
+  int magic_value;
+  bool moved;
+};
+
+TEST(Utility, Move) {
+  MoveTester test(123);
+
+  MoveTester copied(test);
+  EXPECT_EQ(copied.magic_value, 123);
+  EXPECT_FALSE(copied.moved);
+
+  MoveTester moved(std::move(copied));
+  EXPECT_EQ(123, moved.magic_value);
+  EXPECT_EQ(0xffff, copied.magic_value);
+  EXPECT_TRUE(moved.moved);
+}
+
+}  // namespace
+
+namespace pw::minimal_cpp_stdlib {
+
+bool RunAllTests() { return SimpleTest::RunAllTests(); }
+
+}  // namespace pw::minimal_cpp_stdlib
diff --git a/pw_minimal_cpp_stdlib/public/__config b/pw_minimal_cpp_stdlib/public/__config
new file mode 100644
index 0000000..1dd808a
--- /dev/null
+++ b/pw_minimal_cpp_stdlib/public/__config
@@ -0,0 +1,29 @@
+// 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.
+
+// This is a fake version of Clang / libc++'s <__config> header. The <__config>
+// header provides various _LIBCPP defines used internally by libc++.
+//
+// In particular, pw_polyfill and pw_minimal_cpp_stdlib need the macros that
+// provide the namespace to use for standard library definitions. This header
+// provides _LIBCPP_BEGIN_NAMESPACE_STD and _LIBCPP_END_NAMESPACE_STD.
+#pragma once
+
+#define _LIBCPP_BEGIN_NAMESPACE_STD \
+  namespace std {                   \
+  inline namespace __pw_minimal_cpp_stdlib {
+
+#define _LIBCPP_END_NAMESPACE_STD \
+  }                               \
+  }
diff --git a/pw_minimal_cpp_stdlib/public/internal/algorithm.h b/pw_minimal_cpp_stdlib/public/internal/algorithm.h
index 6ad7179..aa2993f 100644
--- a/pw_minimal_cpp_stdlib/public/internal/algorithm.h
+++ b/pw_minimal_cpp_stdlib/public/internal/algorithm.h
@@ -15,7 +15,9 @@
 
 #include <type_traits>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <class InputIterator, class OutputIterator>
 constexpr OutputIterator copy(InputIterator first,
@@ -93,4 +95,4 @@
   return (first_l == last_l) && (first_r != last_r);
 }
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/array.h b/pw_minimal_cpp_stdlib/public/internal/array.h
index 80aeeca..8a26e69 100644
--- a/pw_minimal_cpp_stdlib/public/internal/array.h
+++ b/pw_minimal_cpp_stdlib/public/internal/array.h
@@ -15,7 +15,9 @@
 
 #include <iterator>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T, decltype(sizeof(0)) kSize>
 struct array {
@@ -100,4 +102,4 @@
 
 // NOT IMPLEMENTED: comparison operators, get, swap, tuple specializations
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/cmath.h b/pw_minimal_cpp_stdlib/public/internal/cmath.h
index cec4a7e..2cf754c 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cmath.h
+++ b/pw_minimal_cpp_stdlib/public/internal/cmath.h
@@ -15,7 +15,9 @@
 
 #include <math.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 // The integer overloads of these functions are not provided.
 
@@ -52,4 +54,4 @@
 
 using ::round;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdarg.h b/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
index 8d31c67..129a0d3 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
+++ b/pw_minimal_cpp_stdlib/public/internal/cstdarg.h
@@ -15,8 +15,10 @@
 
 #include <stdarg.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 using ::va_list;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstddef.h b/pw_minimal_cpp_stdlib/public/internal/cstddef.h
index bcb7bb2..c6fd87a 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstddef.h
+++ b/pw_minimal_cpp_stdlib/public/internal/cstddef.h
@@ -15,7 +15,9 @@
 
 #include <stddef.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 using ::ptrdiff_t;
 using ::size_t;
@@ -71,4 +73,4 @@
   return b = b >> shift;
 }
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstdio.h b/pw_minimal_cpp_stdlib/public/internal/cstdio.h
index 0a4bae6..725c1d5 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstdio.h
+++ b/pw_minimal_cpp_stdlib/public/internal/cstdio.h
@@ -15,7 +15,9 @@
 
 #include <stdio.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 using ::size_t;
 
@@ -29,4 +31,4 @@
 using ::getchar;
 using ::sscanf;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/cstring.h b/pw_minimal_cpp_stdlib/public/internal/cstring.h
index 4d0a815..ed24ecb 100644
--- a/pw_minimal_cpp_stdlib/public/internal/cstring.h
+++ b/pw_minimal_cpp_stdlib/public/internal/cstring.h
@@ -15,7 +15,9 @@
 
 #include <string.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 using ::size_t;
 
@@ -35,4 +37,4 @@
 using ::strlen;
 using ::strncmp;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/initializer_list.h b/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
index fe8651e..44da38d 100644
--- a/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
+++ b/pw_minimal_cpp_stdlib/public/internal/initializer_list.h
@@ -13,7 +13,9 @@
 // the License.
 #pragma once
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T>
 class initializer_list {
@@ -39,4 +41,4 @@
   size_type size_;
 };
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/iterator.h b/pw_minimal_cpp_stdlib/public/internal/iterator.h
index e3010be..09b0c70 100644
--- a/pw_minimal_cpp_stdlib/public/internal/iterator.h
+++ b/pw_minimal_cpp_stdlib/public/internal/iterator.h
@@ -15,7 +15,9 @@
 
 #include <cstddef>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 #define __cpp_lib_nonmember_container_access 201411L
 
@@ -72,4 +74,4 @@
 template <typename>
 struct reverse_iterator;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/limits.h b/pw_minimal_cpp_stdlib/public/internal/limits.h
index 6c14180..85b4d59 100644
--- a/pw_minimal_cpp_stdlib/public/internal/limits.h
+++ b/pw_minimal_cpp_stdlib/public/internal/limits.h
@@ -15,7 +15,9 @@
 
 #include <limits.h>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T>
 struct numeric_limits {
@@ -62,4 +64,4 @@
 #undef _PW_LIMITS_SPECIALIZATION
 #undef _PW_INTEGRAL_LIMIT
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/new.h b/pw_minimal_cpp_stdlib/public/internal/new.h
index b7a583c..38fc8b5 100644
--- a/pw_minimal_cpp_stdlib/public/internal/new.h
+++ b/pw_minimal_cpp_stdlib/public/internal/new.h
@@ -13,16 +13,18 @@
 // the License.
 #pragma once
 
+#include "pw_polyfill/standard_library/namespace.h"
+
 // Placement new
 inline void* operator new(decltype(sizeof(0)), void* ptr) { return ptr; }
 
 #define __cpp_lib_launder 201606L
 
-namespace std {
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T>
 [[nodiscard]] constexpr T* launder(T* pointer) noexcept {
   return __builtin_launder(pointer);
 }
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/string_view.h b/pw_minimal_cpp_stdlib/public/internal/string_view.h
index 65ee858..6fbffa0 100644
--- a/pw_minimal_cpp_stdlib/public/internal/string_view.h
+++ b/pw_minimal_cpp_stdlib/public/internal/string_view.h
@@ -17,9 +17,11 @@
 #include <cstddef>
 #include <iterator>
 
+#include "pw_polyfill/standard_library/namespace.h"
+
 #define __cpp_lib_string_view 201606L
 
-namespace std {
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T>
 class basic_string_view {
@@ -171,4 +173,4 @@
 // NOT IMPLEMENTED: string_view literals cannot be implemented since they do not
 //                  start with _.
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/type_traits.h b/pw_minimal_cpp_stdlib/public/internal/type_traits.h
index 366f568..6630e3b 100644
--- a/pw_minimal_cpp_stdlib/public/internal/type_traits.h
+++ b/pw_minimal_cpp_stdlib/public/internal/type_traits.h
@@ -13,7 +13,9 @@
 // the License.
 #pragma once
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 #define __cpp_lib_transformation_trait_aliases 201304L
 #define __cpp_lib_type_trait_variable_templates 201510L
@@ -447,4 +449,4 @@
 template <typename T>
 inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/public/internal/utility.h b/pw_minimal_cpp_stdlib/public/internal/utility.h
index ccfdf69..c3862a7 100644
--- a/pw_minimal_cpp_stdlib/public/internal/utility.h
+++ b/pw_minimal_cpp_stdlib/public/internal/utility.h
@@ -15,7 +15,9 @@
 
 #include <type_traits>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename T>
 constexpr remove_reference_t<T>&& move(T&& object) {
@@ -29,4 +31,4 @@
 template <typename>
 struct tuple_size;
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_minimal_cpp_stdlib/test.cc b/pw_minimal_cpp_stdlib/test.cc
index c0badd1..1bba833 100644
--- a/pw_minimal_cpp_stdlib/test.cc
+++ b/pw_minimal_cpp_stdlib/test.cc
@@ -13,261 +13,13 @@
 // the License.
 
 // Include all of the provided headers, even if they aren't tested.
-#include <algorithm>
-#include <array>
-#include <cinttypes>
-#include <cmath>
-#include <cstdarg>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <cstring>
-#include <initializer_list>
-#include <iterator>
-#include <limits>
-#include <new>
-#include <string_view>
-#include <type_traits>
-#include <utility>
 
 #include "gtest/gtest.h"
 
-namespace {
+namespace pw::minimal_cpp_stdlib {
 
-TEST(Algorithm, Basic) {
-  static_assert(std::min(1, 2) == 1);
-  static_assert(std::max(1, 2) == 2);
+bool RunAllTests();
 
-  EXPECT_EQ(std::forward<int>(2), 2);
-}
+TEST(MinimalCppStdlib, AllTests) { EXPECT_TRUE(RunAllTests()); }
 
-TEST(Algorithm, Copy) {
-  constexpr size_t kCopyOffset = 1;
-  std::array<int, 3> foo{3, 2, 1};
-  std::array<int, 5> bar{0};
-
-  // Ensure zero-element iterator doesn't modify the destination object when
-  // copied.
-  int temp = foo[0];
-  std::copy(foo.end(), foo.end(), bar.begin());
-  EXPECT_EQ(foo[0], temp);
-
-  // Copy a single element.
-  std::array<int, 1> one{-101};
-  std::copy(one.begin(), one.end(), foo.begin());
-  EXPECT_EQ(foo[0], -101);
-
-  auto copy_end = std::copy(foo.begin(), foo.end(), bar.begin() + kCopyOffset);
-  // Verify the iterator points to the end of the copied region.
-  EXPECT_EQ(copy_end, bar.begin() + foo.size() + kCopyOffset);
-
-  // Verify all the values were properly copied from foo to bar.
-  {
-    size_t i = 0;
-    for (auto it = bar.begin() + kCopyOffset; it != copy_end; ++it) {
-      EXPECT_EQ(*it, foo[i++]);
-    }
-  }
-}
-
-TEST(Algorithm, Find) {
-  std::array<int, 5> foo{3, 2, 1, 42, 17};
-  // Ensure a value in the middle of the array is properly found.
-  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 42), 42);
-
-  // Ensure the iterator returned by find() matches the expected location of the
-  // element.
-  EXPECT_EQ(std::find(std::begin(foo), std::end(foo), 42), std::begin(foo) + 3);
-
-  // Ensure an element at the beginning of an array is found.
-  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 3), foo[0]);
-
-  // Ensure an element at the end of an array is found.
-  EXPECT_EQ(*std::find(std::begin(foo), std::end(foo), 17),
-            foo[foo.size() - 1]);
-}
-
-TEST(Algorithm, NotFound) {
-  std::array<int, 3> foo{3, 2, 1};
-
-  // Ensure that if an element is not found, an iterator matching foo.end() is
-  // returned.
-  EXPECT_EQ(std::find(std::begin(foo), std::end(foo), -99), std::end(foo));
-
-  // Ensure that a zero-element iterator range returns the end iterator passed
-  // to std::find().
-  EXPECT_EQ(std::find(std::end(foo), std::end(foo), 3), std::end(foo));
-}
-
-TEST(Array, Basic) {
-  constexpr std::array<int, 4> array{0, 1, 2, 3};
-
-  static_assert(array[2] == 2);
-
-  for (int i = 0; i < static_cast<int>(array.size()); ++i) {
-    EXPECT_EQ(i, array[i]);
-  }
-}
-
-TEST(Cmath, Basic) PW_NO_SANITIZE("float-divide-by-zero") {
-  EXPECT_EQ(std::abs(-1), 1);
-  EXPECT_EQ(std::abs(1), 1);
-
-  // Although Clang/LLVM do not fully support __STDC_IEC_559__, they do have the
-  // necessary IEEE 754 support for floating point division by zero.
-  EXPECT_TRUE(std::isfinite(1.0));
-  EXPECT_FALSE(std::isfinite(1.0 / 0.0));
-
-  EXPECT_FALSE(std::isnan(1.0));
-  EXPECT_TRUE(std::isnan(0.0 / 0.0));
-
-  EXPECT_FALSE(std::signbit(1.0));
-  EXPECT_TRUE(std::signbit(-1.0));
-}
-
-TEST(Cstddef, Basic) {
-  using std::byte;
-  byte foo = byte{12};
-  EXPECT_EQ(foo, byte{12});
-}
-
-TEST(Iterator, Basic) {
-  std::array<int, 3> foo{3, 2, 1};
-
-  EXPECT_EQ(std::data(foo), foo.data());
-  EXPECT_EQ(std::size(foo), foo.size());
-
-  EXPECT_EQ(*std::begin(foo), foo[0]);
-  EXPECT_EQ(std::end(foo), std::begin(foo) + foo.size());
-
-  foo.fill(99);
-  EXPECT_EQ(foo[0], 99);
-  EXPECT_EQ(foo[1], 99);
-  EXPECT_EQ(foo[2], 99);
-}
-
-template <typename T>
-int SumFromInitializerList(std::initializer_list<T> values) {
-  int sum = 0;
-  for (auto value : values) {
-    sum += value;
-  }
-  return sum;
-}
-TEST(InitializerList, Empty) {
-  std::initializer_list<int> mt;
-  EXPECT_EQ(0, SumFromInitializerList(mt));
-
-  EXPECT_EQ(0, SumFromInitializerList<float>({}));
-}
-
-TEST(InitializerList, Declared) {
-  std::initializer_list<char> list{'\3', '\3', '\4'};
-  EXPECT_EQ(10, SumFromInitializerList(list));
-}
-
-TEST(InitializerList, Inline) {
-  EXPECT_EQ(42, SumFromInitializerList<long>({42}));
-  EXPECT_EQ(2, SumFromInitializerList<bool>({true, false, true}));
-  EXPECT_EQ(15, SumFromInitializerList({1, 2, 3, 4, 5}));
-}
-
-TEST(Limits, Basic) {
-  static_assert(std::numeric_limits<unsigned char>::is_specialized);
-  static_assert(std::numeric_limits<unsigned char>::is_integer);
-  static_assert(std::numeric_limits<unsigned char>::min() == 0u);
-  static_assert(std::numeric_limits<unsigned char>::max() == 255u);
-
-  static_assert(std::numeric_limits<signed char>::is_specialized);
-  static_assert(std::numeric_limits<signed char>::is_integer);
-  static_assert(std::numeric_limits<signed char>::min() == -128);
-  static_assert(std::numeric_limits<signed char>::max() == 127);
-
-  // Assume 64-bit long long
-  static_assert(std::numeric_limits<long long>::is_specialized);
-  static_assert(std::numeric_limits<long long>::is_integer);
-  static_assert(std::numeric_limits<long long>::min() ==
-                (-9223372036854775807ll - 1));
-  static_assert(std::numeric_limits<long long>::max() == 9223372036854775807ll);
-
-  static_assert(std::numeric_limits<unsigned long long>::is_specialized);
-  static_assert(std::numeric_limits<unsigned long long>::is_integer);
-  static_assert(std::numeric_limits<unsigned long long>::min() == 0u);
-  static_assert(std::numeric_limits<unsigned long long>::max() ==
-                18446744073709551615ull);
-}
-
-TEST(New, PlacementNew) {
-  unsigned char value[4];
-  new (value) int(1234);
-
-  int int_value;
-  std::memcpy(&int_value, value, sizeof(int_value));
-  EXPECT_EQ(1234, int_value);
-}
-
-TEST(New, Launder) {
-  unsigned char value[4];
-  int* int_ptr = std::launder(reinterpret_cast<int*>(value));
-  EXPECT_EQ(static_cast<void*>(int_ptr), static_cast<void*>(value));
-}
-
-TEST(StringView, Basic) {
-  constexpr std::string_view value("1234567890");
-  static_assert(value.size() == 10);
-  static_assert(value[1] == '2');
-
-  char buffer[] = "!!!!!";
-  constexpr size_t buffer_size = sizeof(buffer) - 1;  // always keep the \0
-
-  value.copy(buffer, buffer_size, 10);
-  EXPECT_STREQ(buffer, "!!!!!");
-
-  value.copy(buffer, buffer_size, 9);
-  EXPECT_STREQ(buffer, "0!!!!");
-
-  value.copy(buffer, buffer_size, 2);
-  EXPECT_STREQ(buffer, "34567");
-
-  value.copy(buffer, buffer_size);
-  EXPECT_STREQ(buffer, "12345");
-}
-
-TEST(TypeTraits, Basic) {
-  static_assert(std::is_integral_v<bool>);
-  static_assert(!std::is_integral_v<float>);
-
-  static_assert(std::is_floating_point_v<float>);
-  static_assert(!std::is_floating_point_v<bool>);
-
-  static_assert(std::is_same_v<float, float>);
-  static_assert(!std::is_same_v<char, unsigned char>);
-}
-
-struct MoveTester {
-  MoveTester(int value) : magic_value(value), moved(false) {}
-
-  MoveTester(const MoveTester&) = default;
-
-  MoveTester(MoveTester&& other) : magic_value(other.magic_value), moved(true) {
-    other.magic_value = 0xffff;
-  }
-
-  int magic_value;
-  bool moved;
-};
-
-TEST(Utility, Move) {
-  MoveTester test(123);
-
-  MoveTester copied(test);
-  EXPECT_EQ(copied.magic_value, 123);
-  EXPECT_FALSE(copied.moved);
-
-  MoveTester moved(std::move(copied));
-  EXPECT_EQ(123, moved.magic_value);
-  EXPECT_EQ(0xffff, copied.magic_value);
-  EXPECT_TRUE(moved.moved);
-}
-
-}  // namespace
+}  // namespace pw::minimal_cpp_stdlib
diff --git a/pw_polyfill/BUILD b/pw_polyfill/BUILD
index 12fdbd1..36affb2 100644
--- a/pw_polyfill/BUILD
+++ b/pw_polyfill/BUILD
@@ -50,6 +50,7 @@
         "standard_library_public/pw_polyfill/standard_library/assert.h",
         "standard_library_public/pw_polyfill/standard_library/cstddef.h",
         "standard_library_public/pw_polyfill/standard_library/iterator.h",
+        "standard_library_public/pw_polyfill/standard_library/namespace.h",
         "standard_library_public/pw_polyfill/standard_library/type_traits.h",
     ],
     includes = ["standard_library_public"],
diff --git a/pw_polyfill/BUILD.gn b/pw_polyfill/BUILD.gn
index 737551c..e3d40f2 100644
--- a/pw_polyfill/BUILD.gn
+++ b/pw_polyfill/BUILD.gn
@@ -60,6 +60,7 @@
     "standard_library_public/pw_polyfill/standard_library/assert.h",
     "standard_library_public/pw_polyfill/standard_library/cstddef.h",
     "standard_library_public/pw_polyfill/standard_library/iterator.h",
+    "standard_library_public/pw_polyfill/standard_library/namespace.h",
     "standard_library_public/pw_polyfill/standard_library/type_traits.h",
   ]
   sources = public
diff --git a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/cstddef.h b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/cstddef.h
index a41c2b9..4f086b5 100644
--- a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/cstddef.h
+++ b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/cstddef.h
@@ -15,10 +15,12 @@
 
 #include <cstddef>
 
+#include "pw_polyfill/standard_library/namespace.h"
+
 // Defines the std::byte type if it is not present.
 #ifndef __cpp_lib_byte
 
-namespace std {
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 enum class byte : unsigned char {};
 
@@ -77,6 +79,6 @@
   return b = b >> shift;
 }
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
 
 #endif  // __cpp_lib_byte
diff --git a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/iterator.h b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/iterator.h
index 7c97675..027ddf9 100644
--- a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/iterator.h
+++ b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/iterator.h
@@ -15,12 +15,14 @@
 
 #include <iterator>
 
+#include "pw_polyfill/standard_library/namespace.h"
+
 // Define std::data and std::size.
 #ifndef __cpp_lib_nonmember_container_access
 
 #include <cstddef>
 
-namespace std {
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 template <typename C>
 constexpr auto data(C& container) -> decltype(container.data()) {
@@ -47,6 +49,6 @@
   return kSize;
 }
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
 
 #endif  // __cpp_lib_nonmember_container_access
diff --git a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/namespace.h b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/namespace.h
new file mode 100644
index 0000000..abaab09
--- /dev/null
+++ b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/namespace.h
@@ -0,0 +1,48 @@
+// 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
+
+// Clang uses a special namespace for standard library headers. Use this
+// namespace via the defines in <__config>.
+#if defined(__clang__) && __has_include(<__config>)
+
+#include <__config>
+
+#define _PW_POLYFILL_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD
+#define _PW_POLYFILL_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
+
+#else  // Directly use the std namespace in GCC.
+
+#define _PW_POLYFILL_BEGIN_NAMESPACE_STD namespace std {
+#define _PW_POLYFILL_END_NAMESPACE_STD }  // namespace std
+
+// Cannot compile with Clang / libc++ without the <__config> header.
+#ifdef __clang__
+static_assert(
+    false,
+    "Compiling with Clang, but the <__config> header is not available. "
+    "The <__config> header provides various _LIBCPP defines used internally "
+    "by libc++. pw_polyfill needs this header for the "
+    "_LIBCPP_BEGIN_NAMESPACE_STD and _LIBCPP_END_NAMESPACE_STD macros, which "
+    "specify the namespace to use for the standard library. "
+    ""
+    "If you see this message, you may be compiling with Clang, but without "
+    "libc++, in which case a fake <__config> header should be provided. "
+    "Alternately, libc++ may have been updated and no longer provides "
+    "<__config>, in which this file should be updated to properly "
+    "set _PW_POLYFILL_BEGIN_NAMESPACE_STD and _PW_POLYFILL_END_NAMESPACE_STD.");
+
+#endif  // __clang__
+
+#endif  // defined(__clang__) && __has_include(<__config>)
diff --git a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/type_traits.h b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/type_traits.h
index 9385028..e91e5ae 100644
--- a/pw_polyfill/standard_library_public/pw_polyfill/standard_library/type_traits.h
+++ b/pw_polyfill/standard_library_public/pw_polyfill/standard_library/type_traits.h
@@ -15,7 +15,9 @@
 
 #include <type_traits>
 
-namespace std {
+#include "pw_polyfill/standard_library/namespace.h"
+
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 // Defines std:foo_t aliases for typename foo::type. This is a small subset of
 // <type_traits> which may be expanded as needed.
@@ -61,4 +63,4 @@
 
 #endif  // __cpp_lib_is_null_pointer
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
diff --git a/pw_span/public/pw_span/internal/span.h b/pw_span/public/pw_span/internal/span.h
index f3ac9be..a39859b 100644
--- a/pw_span/public/pw_span/internal/span.h
+++ b/pw_span/public/pw_span/internal/span.h
@@ -44,11 +44,12 @@
 #include <utility>
 
 #include "pw_polyfill/language_features.h"
+#include "pw_polyfill/standard_library/namespace.h"
 
 // Pigweed: Disable the asserts from Chromium for now.
 #define _PW_SPAN_ASSERT(arg)
 
-namespace std {
+_PW_POLYFILL_BEGIN_NAMESPACE_STD
 
 // [views.constants]
 constexpr size_t dynamic_extent = std::numeric_limits<size_t>::max();
@@ -466,6 +467,6 @@
 
 #endif  // __cpp_deduction_guides
 
-}  // namespace std
+_PW_POLYFILL_END_NAMESPACE_STD
 
 #undef _PW_SPAN_ASSERT