Implement C++17 <variant>. Patch from Michael Park!

This patch was reviewed as https://reviews.llvm.org/D23263.


git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@288547 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/std/utilities/variant/lit.local.cfg b/test/std/utilities/variant/lit.local.cfg
deleted file mode 100644
index 43671e2..0000000
--- a/test/std/utilities/variant/lit.local.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-# FIXME: Libc++ does not yet implement variant but other STLs benefit from
-# having our tests in-tree. This must be removed when <variant> is added.
-if 'libc++' in config.available_features:
-  config.unsupported = True
diff --git a/test/std/utilities/variant/variant.get/get_if_index.pass.cpp b/test/std/utilities/variant/variant.get/get_if_index.pass.cpp
index 2ea88e3..94cc080 100644
--- a/test/std/utilities/variant/variant.get/get_if_index.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_if_index.pass.cpp
@@ -32,17 +32,17 @@
     static_assert(std::get_if<0>(v) == nullptr, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42);
     ASSERT_NOEXCEPT(std::get_if<0>(&v));
-    ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), int const *);
+    ASSERT_SAME_TYPE(decltype(std::get_if<0>(&v)), const int *);
     static_assert(*std::get_if<0>(&v) == 42, "");
     static_assert(std::get_if<1>(&v) == nullptr, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), long const *);
+    ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), const long *);
     static_assert(*std::get_if<1>(&v) == 42, "");
     static_assert(std::get_if<0>(&v) == nullptr, "");
   }
@@ -87,9 +87,9 @@
     assert(std::get_if<1>(&v) == nullptr);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), long *);
+    ASSERT_SAME_TYPE(decltype(std::get_if<1>(&v)), const long *);
     assert(*std::get_if<1>(&v) == 42);
     assert(std::get_if<0>(&v) == nullptr);
   }
diff --git a/test/std/utilities/variant/variant.get/get_if_type.pass.cpp b/test/std/utilities/variant/variant.get/get_if_type.pass.cpp
index 59ddef3..a8cc664 100644
--- a/test/std/utilities/variant/variant.get/get_if_type.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_if_type.pass.cpp
@@ -30,18 +30,18 @@
     static_assert(std::get_if<int>(v) == nullptr, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42);
     ASSERT_NOEXCEPT(std::get_if<int>(&v));
-    ASSERT_SAME_TYPE(decltype(std::get_if<int>(&v)), int const *);
+    ASSERT_SAME_TYPE(decltype(std::get_if<int>(&v)), const int *);
     static_assert(*std::get_if<int>(&v) == 42, "");
-    static_assert(std::get_if<long>(&v) == nullptr, "");
+    static_assert(std::get_if<const long>(&v) == nullptr, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get_if<long>(&v)), long const *);
-    static_assert(*std::get_if<long>(&v) == 42, "");
+    ASSERT_SAME_TYPE(decltype(std::get_if<const long>(&v)), const long *);
+    static_assert(*std::get_if<const long>(&v) == 42, "");
     static_assert(std::get_if<int>(&v) == nullptr, "");
   }
 // FIXME: Remove these once reference support is reinstated
@@ -77,18 +77,18 @@
     assert(std::get_if<int>(v) == nullptr);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42);
     ASSERT_NOEXCEPT(std::get_if<int>(&v));
     ASSERT_SAME_TYPE(decltype(std::get_if<int>(&v)), int *);
     assert(*std::get_if<int>(&v) == 42);
-    assert(std::get_if<long>(&v) == nullptr);
+    assert(std::get_if<const long>(&v) == nullptr);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get_if<long>(&v)), long *);
-    assert(*std::get_if<long>(&v) == 42);
+    ASSERT_SAME_TYPE(decltype(std::get_if<const long>(&v)), const long *);
+    assert(*std::get_if<const long>(&v) == 42);
     assert(std::get_if<int>(&v) == nullptr);
   }
 // FIXME: Remove these once reference support is reinstated
diff --git a/test/std/utilities/variant/variant.get/get_index.pass.cpp b/test/std/utilities/variant/variant.get/get_index.pass.cpp
index 657db9b..669da53 100644
--- a/test/std/utilities/variant/variant.get/get_index.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_index.pass.cpp
@@ -34,16 +34,16 @@
 
 void test_const_lvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     constexpr V v(42);
-    // ASSERT_NOT_NOEXCEPT(std::get<0>(v));
-    ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int const &);
+    ASSERT_NOT_NOEXCEPT(std::get<0>(v));
+    ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
     static_assert(std::get<0>(v) == 42, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<1>(v)), long const &);
+    ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
     static_assert(std::get<1>(v) == 42, "");
   }
 // FIXME: Remove these once reference support is reinstated
@@ -74,16 +74,16 @@
 
 void test_lvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<0>(v));
     ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int &);
     assert(std::get<0>(v) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<1>(v)), long &);
+    ASSERT_SAME_TYPE(decltype(std::get<1>(v)), const long &);
     assert(std::get<1>(v) == 42);
   }
 // FIXME: Remove these once reference support is reinstated
@@ -121,16 +121,16 @@
 
 void test_rvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
     ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), int &&);
     assert(std::get<0>(std::move(v)) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), long &&);
+    ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
     assert(std::get<1>(std::move(v)) == 42);
   }
 // FIXME: Remove these once reference support is reinstated
@@ -170,14 +170,14 @@
 
 void test_const_rvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     const V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<0>(std::move(v)));
     ASSERT_SAME_TYPE(decltype(std::get<0>(std::move(v))), const int &&);
     assert(std::get<0>(std::move(v)) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     const V v(42l);
     ASSERT_SAME_TYPE(decltype(std::get<1>(std::move(v))), const long &&);
     assert(std::get<1>(std::move(v)) == 42);
@@ -234,7 +234,7 @@
     using Idx = decltype(idx);
     try {
       std::get<Idx::value>(std::forward<decltype(v)>(v));
-    } catch (std::bad_variant_access const &) {
+    } catch (const std::bad_variant_access &) {
       return true;
     } catch (...) { /* ... */
     }
diff --git a/test/std/utilities/variant/variant.get/get_type.pass.cpp b/test/std/utilities/variant/variant.get/get_type.pass.cpp
index 11991dc..497f004 100644
--- a/test/std/utilities/variant/variant.get/get_type.pass.cpp
+++ b/test/std/utilities/variant/variant.get/get_type.pass.cpp
@@ -28,17 +28,17 @@
 
 void test_const_lvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     constexpr V v(42);
-    // ASSERT_NOT_NOEXCEPT(std::get<int>(v));
-    ASSERT_SAME_TYPE(decltype(std::get<0>(v)), int const &);
+    ASSERT_NOT_NOEXCEPT(std::get<int>(v));
+    ASSERT_SAME_TYPE(decltype(std::get<0>(v)), const int &);
     static_assert(std::get<int>(v) == 42, "");
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     constexpr V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<long>(v)), long const &);
-    static_assert(std::get<long>(v) == 42, "");
+    ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
+    static_assert(std::get<const long>(v) == 42, "");
   }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
@@ -68,17 +68,17 @@
 
 void test_lvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<int>(v));
     ASSERT_SAME_TYPE(decltype(std::get<int>(v)), int &);
     assert(std::get<int>(v) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<long>(v)), long &);
-    assert(std::get<long>(v) == 42);
+    ASSERT_SAME_TYPE(decltype(std::get<const long>(v)), const long &);
+    assert(std::get<const long>(v) == 42);
   }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
@@ -115,17 +115,18 @@
 
 void test_rvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<int>(std::move(v)));
     ASSERT_SAME_TYPE(decltype(std::get<int>(std::move(v))), int &&);
     assert(std::get<int>(std::move(v)) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<long>(std::move(v))), long &&);
-    assert(std::get<long>(std::move(v)) == 42);
+    ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
+                     const long &&);
+    assert(std::get<const long>(std::move(v)) == 42);
   }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
@@ -166,17 +167,18 @@
 
 void test_const_rvalue_get() {
   {
-    using V = std::variant<int>;
+    using V = std::variant<int, const long>;
     const V v(42);
     ASSERT_NOT_NOEXCEPT(std::get<int>(std::move(v)));
     ASSERT_SAME_TYPE(decltype(std::get<int>(std::move(v))), const int &&);
     assert(std::get<int>(std::move(v)) == 42);
   }
   {
-    using V = std::variant<int, long>;
+    using V = std::variant<int, const long>;
     const V v(42l);
-    ASSERT_SAME_TYPE(decltype(std::get<long>(std::move(v))), const long &&);
-    assert(std::get<long>(std::move(v)) == 42);
+    ASSERT_SAME_TYPE(decltype(std::get<const long>(std::move(v))),
+                     const long &&);
+    assert(std::get<const long>(std::move(v)) == 42);
   }
 // FIXME: Remove these once reference support is reinstated
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
@@ -232,7 +234,7 @@
     using Idx = decltype(idx);
     try {
       std::get<typename Idx::type>(std::forward<decltype(v)>(v));
-    } catch (std::bad_variant_access const &) {
+    } catch (const std::bad_variant_access &) {
       return true;
     } catch (...) { /* ... */
     }
diff --git a/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp b/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp
index 3484386..103b049 100644
--- a/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp
+++ b/test/std/utilities/variant/variant.get/holds_alternative.pass.cpp
@@ -15,6 +15,7 @@
 // template <class T, class... Types>
 // constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
 
+#include "test_macros.h"
 #include <variant>
 
 int main() {
@@ -32,6 +33,6 @@
   { // noexcept test
     using V = std::variant<int>;
     const V v;
-    static_assert(noexcept(std::holds_alternative<int>(v)), "must be noexcept");
+    ASSERT_NOEXCEPT(std::holds_alternative<int>(v));
   }
 }
diff --git a/test/std/utilities/variant/variant.hash/hash.pass.cpp b/test/std/utilities/variant/variant.hash/hash.pass.cpp
index df63989..1745508 100644
--- a/test/std/utilities/variant/variant.hash/hash.pass.cpp
+++ b/test/std/utilities/variant/variant.hash/hash.pass.cpp
@@ -25,7 +25,7 @@
 #ifndef TEST_HAS_NO_EXCEPTIONS
 namespace std {
 template <> struct hash<::MakeEmptyT> {
-  size_t operator()(::MakeEmptyT const &) const {
+  size_t operator()(const ::MakeEmptyT &) const {
     assert(false);
     return 0;
   }
@@ -40,7 +40,6 @@
     const V v(std::in_place_index<0>, 42);
     const V v_copy = v;
     V v2(std::in_place_index<0>, 100);
-    const V v3(std::in_place_index<2>, 42);
     const H h{};
     assert(h(v) == h(v));
     assert(h(v) != h(v2));
diff --git a/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp b/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp
index 1871c10..84689a0 100644
--- a/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp
+++ b/test/std/utilities/variant/variant.helpers/variant_alternative.pass.cpp
@@ -66,10 +66,10 @@
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
-    using V = std::variant<int, int &, int const &, int &&, long double>;
+    using V = std::variant<int, int &, const int &, int &&, long double>;
     test<V, 0, int>();
     test<V, 1, int &>();
-    test<V, 2, int const &>();
+    test<V, 2, const int &>();
     test<V, 3, int &&>();
     test<V, 4, long double>();
   }
diff --git a/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp b/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp
index f430a66..49abba2 100644
--- a/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp
+++ b/test/std/utilities/variant/variant.monostate.relops/relops.pass.cpp
@@ -19,6 +19,7 @@
 // constexpr bool operator==(monostate, monostate) noexcept { return true; }
 // constexpr bool operator!=(monostate, monostate) noexcept { return false; }
 
+#include "test_macros.h"
 #include <cassert>
 #include <type_traits>
 #include <variant>
@@ -29,26 +30,26 @@
   constexpr M m2{};
   {
     static_assert((m1 < m2) == false, "");
-    static_assert(noexcept(m1 < m2), "");
+    ASSERT_NOEXCEPT(m1 < m2);
   }
   {
     static_assert((m1 > m2) == false, "");
-    static_assert(noexcept(m1 > m2), "");
+    ASSERT_NOEXCEPT(m1 > m2);
   }
   {
     static_assert((m1 <= m2) == true, "");
-    static_assert(noexcept(m1 <= m2), "");
+    ASSERT_NOEXCEPT(m1 <= m2);
   }
   {
     static_assert((m1 >= m2) == true, "");
-    static_assert(noexcept(m1 >= m2), "");
+    ASSERT_NOEXCEPT(m1 >= m2);
   }
   {
     static_assert((m1 == m2) == true, "");
-    static_assert(noexcept(m1 == m2), "");
+    ASSERT_NOEXCEPT(m1 == m2);
   }
   {
     static_assert((m1 != m2) == false, "");
-    static_assert(noexcept(m1 != m2), "");
+    ASSERT_NOEXCEPT(m1 != m2);
   }
 }
diff --git a/test/std/utilities/variant/variant.relops/relops.pass.cpp b/test/std/utilities/variant/variant.relops/relops.pass.cpp
index 51712ff..4337b4b 100644
--- a/test/std/utilities/variant/variant.relops/relops.pass.cpp
+++ b/test/std/utilities/variant/variant.relops/relops.pass.cpp
@@ -49,27 +49,27 @@
   MakeEmptyT(MakeEmptyT &&) { throw 42; }
   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
 };
-inline bool operator==(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator==(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
-inline bool operator!=(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator!=(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
-inline bool operator<(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator<(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
-inline bool operator<=(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator<=(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
-inline bool operator>(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator>(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
-inline bool operator>=(MakeEmptyT const &, MakeEmptyT const &) {
+inline bool operator>=(const MakeEmptyT &, const MakeEmptyT &) {
   assert(false);
   return false;
 }
@@ -158,7 +158,7 @@
 }
 
 template <class Var>
-constexpr bool test_less(Var const &l, Var const &r, bool expect_less,
+constexpr bool test_less(const Var &l, const Var &r, bool expect_less,
                          bool expect_greater) {
   return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&
          ((l > r) == expect_greater) && (!(l <= r) == expect_greater);
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
index 0a1d3c9..10022b1 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp
@@ -116,7 +116,7 @@
     static_assert(!std::is_assignable<V, int>::value, "ambiguous");
   }
   {
-    using V = std::variant<int, int const &>;
+    using V = std::variant<int, const int &>;
     static_assert(!std::is_assignable<V, int>::value, "ambiguous");
   }
 #endif
@@ -149,9 +149,9 @@
     v = std::move(x);
     assert(v.index() == 1);
     assert(&std::get<1>(v) == &x);
-    // 'long' is selected by FUN(int const&) since 'int const&' cannot bind
+    // 'long' is selected by FUN(const int &) since 'const int &' cannot bind
     // to 'int&'.
-    int const &cx = x;
+    const int &cx = x;
     v = cx;
     assert(v.index() == 2);
     assert(std::get<2>(v) == 42);
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
index 65c2052..0e1a0cd 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
@@ -24,32 +24,32 @@
 #include "test_macros.h"
 
 struct NoCopy {
-  NoCopy(NoCopy const &) = delete;
-  NoCopy &operator=(NoCopy const &) = default;
+  NoCopy(const NoCopy &) = delete;
+  NoCopy &operator=(const NoCopy &) = default;
 };
 
 struct NothrowCopy {
-  NothrowCopy(NothrowCopy const &) noexcept = default;
-  NothrowCopy &operator=(NothrowCopy const &) noexcept = default;
+  NothrowCopy(const NothrowCopy &) noexcept = default;
+  NothrowCopy &operator=(const NothrowCopy &) noexcept = default;
 };
 
 struct CopyOnly {
-  CopyOnly(CopyOnly const &) = default;
+  CopyOnly(const CopyOnly &) = default;
   CopyOnly(CopyOnly &&) = delete;
-  CopyOnly &operator=(CopyOnly const &) = default;
+  CopyOnly &operator=(const CopyOnly &) = default;
   CopyOnly &operator=(CopyOnly &&) = delete;
 };
 
 struct MoveOnly {
-  MoveOnly(MoveOnly const &) = delete;
+  MoveOnly(const MoveOnly &) = delete;
   MoveOnly(MoveOnly &&) = default;
-  MoveOnly &operator=(MoveOnly const &) = default;
+  MoveOnly &operator=(const MoveOnly &) = default;
 };
 
 struct MoveOnlyNT {
-  MoveOnlyNT(MoveOnlyNT const &) = delete;
+  MoveOnlyNT(const MoveOnlyNT &) = delete;
   MoveOnlyNT(MoveOnlyNT &&) {}
-  MoveOnlyNT &operator=(MoveOnlyNT const &) = default;
+  MoveOnlyNT &operator=(const MoveOnlyNT &) = default;
 };
 
 struct CopyAssign {
@@ -62,7 +62,7 @@
     copy_construct = copy_assign = move_construct = move_assign = alive = 0;
   }
   CopyAssign(int v) : value(v) { ++alive; }
-  CopyAssign(CopyAssign const &o) : value(o.value) {
+  CopyAssign(const CopyAssign &o) : value(o.value) {
     ++alive;
     ++copy_construct;
   }
@@ -71,7 +71,7 @@
     ++alive;
     ++move_construct;
   }
-  CopyAssign &operator=(CopyAssign const &o) {
+  CopyAssign &operator=(const CopyAssign &o) {
     value = o.value;
     ++copy_assign;
     return *this;
@@ -93,27 +93,27 @@
 int CopyAssign::move_assign = 0;
 
 struct CopyMaybeThrows {
-  CopyMaybeThrows(CopyMaybeThrows const &);
-  CopyMaybeThrows &operator=(CopyMaybeThrows const &);
+  CopyMaybeThrows(const CopyMaybeThrows &);
+  CopyMaybeThrows &operator=(const CopyMaybeThrows &);
 };
 struct CopyDoesThrow {
-  CopyDoesThrow(CopyDoesThrow const &) noexcept(false);
-  CopyDoesThrow &operator=(CopyDoesThrow const &) noexcept(false);
+  CopyDoesThrow(const CopyDoesThrow &) noexcept(false);
+  CopyDoesThrow &operator=(const CopyDoesThrow &) noexcept(false);
 };
 
 #ifndef TEST_HAS_NO_EXCEPTIONS
 struct CopyThrows {
   CopyThrows() = default;
-  CopyThrows(CopyThrows const &) { throw 42; }
-  CopyThrows &operator=(CopyThrows const &) { throw 42; }
+  CopyThrows(const CopyThrows &) { throw 42; }
+  CopyThrows &operator=(const CopyThrows &) { throw 42; }
 };
 
 struct MoveThrows {
   static int alive;
   MoveThrows() { ++alive; }
-  MoveThrows(MoveThrows const &) { ++alive; }
+  MoveThrows(const MoveThrows &) { ++alive; }
   MoveThrows(MoveThrows &&) { throw 42; }
-  MoveThrows &operator=(MoveThrows const &) { return *this; }
+  MoveThrows &operator=(const MoveThrows &) { return *this; }
   MoveThrows &operator=(MoveThrows &&) { throw 42; }
   ~MoveThrows() { --alive; }
 };
@@ -123,13 +123,13 @@
 struct MakeEmptyT {
   static int alive;
   MakeEmptyT() { ++alive; }
-  MakeEmptyT(MakeEmptyT const &) {
+  MakeEmptyT(const MakeEmptyT &) {
     ++alive;
     // Don't throw from the copy constructor since variant's assignment
     // operator performs a copy before committing to the assignment.
   }
   MakeEmptyT(MakeEmptyT &&) { throw 42; }
-  MakeEmptyT &operator=(MakeEmptyT const &) { throw 42; }
+  MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
   ~MakeEmptyT() { --alive; }
 };
@@ -164,7 +164,7 @@
     static_assert(std::is_copy_assignable<V>::value, "");
   }
   {
-    // variant only provides copy assignment when beth the copy and move
+    // variant only provides copy assignment when both the copy and move
     // constructors are well formed
     using V = std::variant<int, CopyOnly>;
     static_assert(!std::is_copy_assignable<V>::value, "");
diff --git a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
index 0e07d13..f3dc815 100644
--- a/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
@@ -26,36 +26,36 @@
 #include "variant_test_helpers.hpp"
 
 struct NoCopy {
-  NoCopy(NoCopy const &) = delete;
-  NoCopy &operator=(NoCopy const &) = default;
+  NoCopy(const NoCopy &) = delete;
+  NoCopy &operator=(const NoCopy &) = default;
 };
 
 struct CopyOnly {
-  CopyOnly(CopyOnly const &) = default;
+  CopyOnly(const CopyOnly &) = default;
   CopyOnly(CopyOnly &&) = delete;
-  CopyOnly &operator=(CopyOnly const &) = default;
+  CopyOnly &operator=(const CopyOnly &) = default;
   CopyOnly &operator=(CopyOnly &&) = delete;
 };
 
 struct MoveOnly {
-  MoveOnly(MoveOnly const &) = delete;
+  MoveOnly(const MoveOnly &) = delete;
   MoveOnly(MoveOnly &&) = default;
-  MoveOnly &operator=(MoveOnly const &) = delete;
+  MoveOnly &operator=(const MoveOnly &) = delete;
   MoveOnly &operator=(MoveOnly &&) = default;
 };
 
 struct MoveOnlyNT {
-  MoveOnlyNT(MoveOnlyNT const &) = delete;
+  MoveOnlyNT(const MoveOnlyNT &) = delete;
   MoveOnlyNT(MoveOnlyNT &&) {}
-  MoveOnlyNT &operator=(MoveOnlyNT const &) = delete;
+  MoveOnlyNT &operator=(const MoveOnlyNT &) = delete;
   MoveOnlyNT &operator=(MoveOnlyNT &&) = default;
 };
 
 struct MoveOnlyOddNothrow {
   MoveOnlyOddNothrow(MoveOnlyOddNothrow &&) noexcept(false) {}
-  MoveOnlyOddNothrow(MoveOnlyOddNothrow const &) = delete;
+  MoveOnlyOddNothrow(const MoveOnlyOddNothrow &) = delete;
   MoveOnlyOddNothrow &operator=(MoveOnlyOddNothrow &&) noexcept = default;
-  MoveOnlyOddNothrow &operator=(MoveOnlyOddNothrow const &) = delete;
+  MoveOnlyOddNothrow &operator=(const MoveOnlyOddNothrow &) = delete;
 };
 
 struct MoveAssignOnly {
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
index b9ea610..d33ea0b 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp
@@ -68,7 +68,7 @@
     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
   }
   {
-    using V = std::variant<int, int const &>;
+    using V = std::variant<int, const int &>;
     static_assert(!std::is_constructible<V, int>::value, "ambiguous");
   }
 #endif
@@ -87,7 +87,7 @@
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
-    using V = std::variant<int const &, int &&, long>;
+    using V = std::variant<const int &, int &&, long>;
     static_assert(std::is_convertible<int &, V>::value, "must be implicit");
     int x = 42;
     V v(x);
@@ -95,7 +95,7 @@
     assert(&std::get<0>(v) == &x);
   }
   {
-    using V = std::variant<int const &, int &&, long>;
+    using V = std::variant<const int &, int &&, long>;
     static_assert(std::is_convertible<int, V>::value, "must be implicit");
     int x = 42;
     V v(std::move(x));
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
index 78fab62..18216c6 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
@@ -24,22 +24,22 @@
 
 struct NonT {
   NonT(int v) : value(v) {}
-  NonT(NonT const &o) : value(o.value) {}
+  NonT(const NonT &o) : value(o.value) {}
   int value;
 };
 static_assert(!std::is_trivially_copy_constructible<NonT>::value, "");
 
 struct NoCopy {
-  NoCopy(NoCopy const &) = delete;
+  NoCopy(const NoCopy &) = delete;
 };
 
 struct MoveOnly {
-  MoveOnly(MoveOnly const &) = delete;
+  MoveOnly(const MoveOnly &) = delete;
   MoveOnly(MoveOnly &&) = default;
 };
 
 struct MoveOnlyNT {
-  MoveOnlyNT(MoveOnlyNT const &) = delete;
+  MoveOnlyNT(const MoveOnlyNT &) = delete;
   MoveOnlyNT(MoveOnlyNT &&) {}
 };
 
@@ -47,13 +47,13 @@
 struct MakeEmptyT {
   static int alive;
   MakeEmptyT() { ++alive; }
-  MakeEmptyT(MakeEmptyT const &) {
+  MakeEmptyT(const MakeEmptyT &) {
     ++alive;
     // Don't throw from the copy constructor since variant's assignment
     // operator performs a copy before committing to the assignment.
   }
   MakeEmptyT(MakeEmptyT &&) { throw 42; }
-  MakeEmptyT &operator=(MakeEmptyT const &) { throw 42; }
+  MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
   ~MakeEmptyT() { --alive; }
 };
@@ -124,7 +124,7 @@
   using V = std::variant<int, MakeEmptyT>;
   V v1;
   makeEmpty(v1);
-  V const &cv1 = v1;
+  const V &cv1 = v1;
   V v(cv1);
   assert(v.valueless_by_exception());
 #endif
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
index 124260b..a4a86ff 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/default.pass.cpp
@@ -71,7 +71,7 @@
   try {
     V v;
     assert(false);
-  } catch (int const &ex) {
+  } catch (const int &ex) {
     assert(ex == 42);
   } catch (...) {
     assert(false);
diff --git a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
index 2a87f32..66f67fe 100644
--- a/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp
@@ -28,20 +28,20 @@
 };
 
 struct NoCopy {
-  NoCopy(NoCopy const &) = delete;
+  NoCopy(const NoCopy &) = delete;
 };
 
 struct MoveOnly {
   int value;
   MoveOnly(int v) : value(v) {}
-  MoveOnly(MoveOnly const &) = delete;
+  MoveOnly(const MoveOnly &) = delete;
   MoveOnly(MoveOnly &&) = default;
 };
 
 struct MoveOnlyNT {
   int value;
   MoveOnlyNT(int v) : value(v) {}
-  MoveOnlyNT(MoveOnlyNT const &) = delete;
+  MoveOnlyNT(const MoveOnlyNT &) = delete;
   MoveOnlyNT(MoveOnlyNT &&other) : value(other.value) { other.value = -1; }
 };
 
@@ -49,13 +49,13 @@
 struct MakeEmptyT {
   static int alive;
   MakeEmptyT() { ++alive; }
-  MakeEmptyT(MakeEmptyT const &) {
+  MakeEmptyT(const MakeEmptyT &) {
     ++alive;
     // Don't throw from the copy constructor since variant's assignment
     // operator performs a copy before committing to the assignment.
   }
   MakeEmptyT(MakeEmptyT &&) { throw 42; }
-  MakeEmptyT &operator=(MakeEmptyT const &) { throw 42; }
+  MakeEmptyT &operator=(const MakeEmptyT &) { throw 42; }
   MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }
   ~MakeEmptyT() { --alive; }
 };
diff --git a/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp b/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp
index 8e36a8a..7299394 100644
--- a/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.dtor/dtor.pass.cpp
@@ -39,7 +39,7 @@
 static_assert(!std::is_trivially_destructible<NonTDtor1>::value, "");
 
 struct TDtor {
-  TDtor(TDtor const &) {} // non-trivial copy
+  TDtor(const TDtor &) {} // non-trivial copy
   ~TDtor() = default;
 };
 static_assert(!std::is_trivially_copy_constructible<TDtor>::value, "");
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
index 4dae324..8f694cf 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_index_args.pass.cpp
@@ -58,14 +58,14 @@
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
-    using V = std::variant<int, int &, int const &, int &&, TestTypes::NoCtors>;
+    using V = std::variant<int, int &, const int &, int &&, TestTypes::NoCtors>;
     static_assert(emplace_exists<V, 0>(), "");
     static_assert(emplace_exists<V, 0, int>(), "");
     static_assert(emplace_exists<V, 0, long long>(), "");
     static_assert(!emplace_exists<V, 0, int, int>(), "too many args");
     static_assert(emplace_exists<V, 1, int &>(), "");
     static_assert(!emplace_exists<V, 1>(), "cannot default construct ref");
-    static_assert(!emplace_exists<V, 1, int const &>(), "cannot bind ref");
+    static_assert(!emplace_exists<V, 1, const int &>(), "cannot bind ref");
     static_assert(!emplace_exists<V, 1, int &&>(), "cannot bind ref");
     static_assert(emplace_exists<V, 2, int &>(), "");
     static_assert(emplace_exists<V, 2, const int &>(), "");
@@ -74,8 +74,8 @@
                   "not constructible from void*");
     static_assert(emplace_exists<V, 3, int>(), "");
     static_assert(!emplace_exists<V, 3, int &>(), "cannot bind ref");
-    static_assert(!emplace_exists<V, 3, int const &>(), "cannot bind ref");
-    static_assert(!emplace_exists<V, 3, int const &&>(), "cannot bind ref");
+    static_assert(!emplace_exists<V, 3, const int &>(), "cannot bind ref");
+    static_assert(!emplace_exists<V, 3, const int &&>(), "cannot bind ref");
     static_assert(!emplace_exists<V, 4>(), "no ctors");
   }
 #endif
@@ -106,7 +106,7 @@
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
-    using V = std::variant<int, long, int const &, int &&, TestTypes::NoCtors,
+    using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
                            std::string>;
     const int x = 100;
     int y = 42;
diff --git a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
index 53a030d..4ca2cc4 100644
--- a/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.mod/emplace_type_args.pass.cpp
@@ -52,12 +52,12 @@
     static_assert(!emplace_exists<V, void *, int>(), "cannot construct");
     static_assert(emplace_exists<V, void *, int *>(), "");
     static_assert(!emplace_exists<V, void *, const int *>(), "");
-    static_assert(emplace_exists<V, void const *, const int *>(), "");
-    static_assert(emplace_exists<V, void const *, int *>(), "");
+    static_assert(emplace_exists<V, const void *, const int *>(), "");
+    static_assert(emplace_exists<V, const void *, int *>(), "");
     static_assert(!emplace_exists<V, TestTypes::NoCtors>(), "cannot construct");
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
-  using V = std::variant<int, int &, int const &, int &&, long, long,
+  using V = std::variant<int, int &, const int &, int &&, long, long,
                          TestTypes::NoCtors>;
   static_assert(emplace_exists<V, int>(), "");
   static_assert(emplace_exists<V, int, int>(), "");
@@ -65,17 +65,17 @@
   static_assert(!emplace_exists<V, int, int, int>(), "too many args");
   static_assert(emplace_exists<V, int &, int &>(), "");
   static_assert(!emplace_exists<V, int &>(), "cannot default construct ref");
-  static_assert(!emplace_exists<V, int &, int const &>(), "cannot bind ref");
+  static_assert(!emplace_exists<V, int &, const int &>(), "cannot bind ref");
   static_assert(!emplace_exists<V, int &, int &&>(), "cannot bind ref");
-  static_assert(emplace_exists<V, int const &, int &>(), "");
-  static_assert(emplace_exists<V, int const &, const int &>(), "");
-  static_assert(emplace_exists<V, int const &, int &&>(), "");
-  static_assert(!emplace_exists<V, int const &, void *>(),
+  static_assert(emplace_exists<V, const int &, int &>(), "");
+  static_assert(emplace_exists<V, const int &, const int &>(), "");
+  static_assert(emplace_exists<V, const int &, int &&>(), "");
+  static_assert(!emplace_exists<V, const int &, void *>(),
                 "not constructible from void*");
   static_assert(emplace_exists<V, int &&, int>(), "");
   static_assert(!emplace_exists<V, int &&, int &>(), "cannot bind ref");
-  static_assert(!emplace_exists<V, int &&, int const &>(), "cannot bind ref");
-  static_assert(!emplace_exists<V, int &&, int const &&>(), "cannot bind ref");
+  static_assert(!emplace_exists<V, int &&, const int &>(), "cannot bind ref");
+  static_assert(!emplace_exists<V, int &&, const int &&>(), "cannot bind ref");
   static_assert(!emplace_exists<V, long, long>(), "ambiguous");
   static_assert(!emplace_exists<V, TestTypes::NoCtors>(),
                 "cannot construct void");
@@ -107,7 +107,7 @@
   }
 #if !defined(TEST_VARIANT_HAS_NO_REFERENCES)
   {
-    using V = std::variant<int, long, int const &, int &&, TestTypes::NoCtors,
+    using V = std::variant<int, long, const int &, int &&, TestTypes::NoCtors,
                            std::string>;
     const int x = 100;
     int y = 42;
@@ -117,8 +117,8 @@
     v.emplace<long>();
     assert(std::get<long>(v) == 0);
     // emplace a reference
-    v.emplace<int const &>(x);
-    assert(&std::get<int const &>(v) == &x);
+    v.emplace<const int &>(x);
+    assert(&std::get<const int &>(v) == &x);
     // emplace an rvalue reference
     v.emplace<int &&>(std::move(y));
     assert(&std::get<int &&>(v) == &y);
diff --git a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
index 1fb5c72..416c6b4 100644
--- a/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
+++ b/test/std/utilities/variant/variant.variant/variant.swap/swap.pass.cpp
@@ -30,14 +30,14 @@
 
 struct NotCopyable {
   NotCopyable() = default;
-  NotCopyable(NotCopyable const &) = delete;
-  NotCopyable &operator=(NotCopyable const &) = delete;
+  NotCopyable(const NotCopyable &) = delete;
+  NotCopyable &operator=(const NotCopyable &) = delete;
 };
 
 struct NotCopyableWithSwap {
   NotCopyableWithSwap() = default;
-  NotCopyableWithSwap(NotCopyableWithSwap const &) = delete;
-  NotCopyableWithSwap &operator=(NotCopyableWithSwap const &) = delete;
+  NotCopyableWithSwap(const NotCopyableWithSwap &) = delete;
+  NotCopyableWithSwap &operator=(const NotCopyableWithSwap &) = delete;
 };
 void swap(NotCopyableWithSwap &, NotCopyableWithSwap) {}
 
@@ -73,7 +73,7 @@
   static void reset() { move_called = move_assign_called = swap_called = 0; }
   NothrowTypeImp() = default;
   explicit NothrowTypeImp(int v) : value(v) {}
-  NothrowTypeImp(NothrowTypeImp const &o) noexcept(NT_Copy) : value(o.value) {
+  NothrowTypeImp(const NothrowTypeImp &o) noexcept(NT_Copy) : value(o.value) {
     assert(false);
   } // never called by test
   NothrowTypeImp(NothrowTypeImp &&o) noexcept(NT_Move) : value(o.value) {
@@ -81,7 +81,7 @@
     do_throw<!NT_Move>();
     o.value = -1;
   }
-  NothrowTypeImp &operator=(NothrowTypeImp const &) noexcept(NT_CopyAssign) {
+  NothrowTypeImp &operator=(const NothrowTypeImp &) noexcept(NT_CopyAssign) {
     assert(false);
     return *this;
   } // never called by the tests
diff --git a/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp b/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp
index 1e5b927..bda27f0 100644
--- a/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp
+++ b/test/std/utilities/variant/variant.variant/variant_reference.fail.cpp
@@ -23,6 +23,6 @@
 {
     // expected-error@variant:* 3 {{static_assert failed}}
     std::variant<int, int&> v; // expected-note {{requested here}}
-    std::variant<int, int const&> v2; // expected-note {{requested here}}
+    std::variant<int, const int &> v2; // expected-note {{requested here}}
     std::variant<int, int&&> v3; // expected-note {{requested here}}
 }
diff --git a/test/std/utilities/variant/variant.visit/visit.pass.cpp b/test/std/utilities/variant/variant.visit/visit.pass.cpp
index 1783fe9..46d2258 100644
--- a/test/std/utilities/variant/variant.visit/visit.pass.cpp
+++ b/test/std/utilities/variant/variant.visit/visit.pass.cpp
@@ -77,16 +77,16 @@
   }
 
   static CallType last_call_type;
-  static TypeID const *last_call_args;
+  static const TypeID *last_call_args;
 };
 
 CallType ForwardingCallObject::last_call_type = CT_None;
-TypeID const *ForwardingCallObject::last_call_args = nullptr;
+const TypeID *ForwardingCallObject::last_call_args = nullptr;
 
 void test_call_operator_forwarding() {
   using Fn = ForwardingCallObject;
   Fn obj{};
-  Fn const &cobj = obj;
+  const Fn &cobj = obj;
   { // test call operator forwarding - single variant, single arg
     using V = std::variant<int>;
     V v(42);
@@ -134,11 +134,11 @@
   { // single argument - value type
     using V = std::variant<int>;
     V v(42);
-    V const &cv = v;
+    const V &cv = v;
     std::visit(obj, v);
     assert(Fn::check_call<int &>(Val));
     std::visit(obj, cv);
-    assert(Fn::check_call<int const &>(Val));
+    assert(Fn::check_call<const int &>(Val));
     std::visit(obj, std::move(v));
     assert(Fn::check_call<int &&>(Val));
     std::visit(obj, std::move(cv));
@@ -149,7 +149,7 @@
     using V = std::variant<int &>;
     int x = 42;
     V v(x);
-    V const &cv = v;
+    const V &cv = v;
     std::visit(obj, v);
     assert(Fn::check_call<int &>(Val));
     std::visit(obj, cv);
@@ -163,7 +163,7 @@
     using V = std::variant<int &&>;
     int x = 42;
     V v(std::move(x));
-    V const &cv = v;
+    const V &cv = v;
     std::visit(obj, v);
     assert(Fn::check_call<int &>(Val));
     std::visit(obj, cv);
@@ -174,16 +174,16 @@
     assert(Fn::check_call<int &&>(Val));
   }
   { // multi argument - multi variant
-    using S = std::string const &;
+    using S = const std::string &;
     using V = std::variant<int, S, long &&>;
-    std::string const str = "hello";
+    const std::string str = "hello";
     long l = 43;
     V v1(42);
-    V const &cv1 = v1;
+    const V &cv1 = v1;
     V v2(str);
-    V const &cv2 = v2;
+    const V &cv2 = v2;
     V v3(std::move(l));
-    V const &cv3 = v3;
+    const V &cv3 = v3;
     std::visit(obj, v1, v2, v3);
     assert((Fn::check_call<int &, S, long &>(Val)));
     std::visit(obj, cv1, cv2, std::move(v3));
@@ -243,7 +243,7 @@
   auto test = [&](auto &&... args) {
     try {
       std::visit(obj, args...);
-    } catch (std::bad_variant_access const &) {
+    } catch (const std::bad_variant_access &) {
       return true;
     } catch (...) {
     }