diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -78,7 +78,7 @@
 "`P2465R3 <https://wg21.link/P2465R3>`__","LWG","Standard Library Modules ``std`` and ``std.compat``","July 2022","",""
 "`P2467R1 <https://wg21.link/P2467R1>`__","LWG","Support exclusive mode for ``fstreams``","July 2022","",""
 "`P2474R2 <https://wg21.link/P2474R2>`__","LWG","``views::repeat``","July 2022","","","|ranges|"
-"`P2494R2 <https://wg21.link/P2494R2>`__","LWG","Relaxing range adaptors to allow for move only types","July 2022","","","|ranges|"
+"`P2494R2 <https://wg21.link/P2494R2>`__","LWG","Relaxing range adaptors to allow for move only types","July 2022","|Complete|","17.0","|ranges|"
 "`P2499R0 <https://wg21.link/P2499R0>`__","LWG","``string_view`` range constructor should be ``explicit``","July 2022","|Complete|","16.0","|ranges|"
 "`P2502R2 <https://wg21.link/P2502R2>`__","LWG","``std::generator``: Synchronous Coroutine Generator for Ranges","July 2022","","","|ranges|"
 "`P2508R1 <https://wg21.link/P2508R1>`__","LWG","Exposing ``std::basic-format-string``","July 2022","|Complete|","15.0"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -597,7 +597,6 @@
   __ranges/common_view.h
   __ranges/concepts.h
   __ranges/container_compatible_range.h
-  __ranges/copyable_box.h
   __ranges/counted.h
   __ranges/dangling.h
   __ranges/data.h
@@ -614,6 +613,7 @@
   __ranges/istream_view.h
   __ranges/join_view.h
   __ranges/lazy_split_view.h
+  __ranges/movable_box.h
   __ranges/non_propagating_cache.h
   __ranges/owning_view.h
   __ranges/range_adaptor.h
diff --git a/libcxx/include/__ranges/copyable_box.h b/libcxx/include/__ranges/copyable_box.h
deleted file mode 100644
--- a/libcxx/include/__ranges/copyable_box.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___RANGES_COPYABLE_BOX_H
-#define _LIBCPP___RANGES_COPYABLE_BOX_H
-
-#include <__concepts/constructible.h>
-#include <__concepts/copyable.h>
-#include <__concepts/movable.h>
-#include <__config>
-#include <__memory/addressof.h>
-#include <__memory/construct_at.h>
-#include <__type_traits/is_nothrow_constructible.h>
-#include <__type_traits/is_nothrow_copy_constructible.h>
-#include <__type_traits/is_nothrow_default_constructible.h>
-#include <__utility/move.h>
-#include <optional>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if _LIBCPP_STD_VER >= 20
-
-// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
-// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
-// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
-// to handle the case where the copy construction fails after destroying the object.
-//
-// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
-// __copyable_box that does this, see below for the details.
-
-template<class _Tp>
-concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>;
-
-namespace ranges {
-  // Primary template - uses std::optional and introduces an empty state in case assignment fails.
-  template<__copy_constructible_object _Tp>
-  class __copyable_box {
-    _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
-
-  public:
-    template<class ..._Args>
-      requires is_constructible_v<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
-      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
-      : __val_(in_place, std::forward<_Args>(__args)...)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
-      requires default_initializable<_Tp>
-      : __val_(in_place)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box const& __other)
-      noexcept(is_nothrow_copy_constructible_v<_Tp>)
-    {
-      if (this != std::addressof(__other)) {
-        if (__other.__has_value()) __val_.emplace(*__other);
-        else                       __val_.reset();
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box&& __other)
-      noexcept(is_nothrow_move_constructible_v<_Tp>)
-    {
-      if (this != std::addressof(__other)) {
-        if (__other.__has_value()) __val_.emplace(std::move(*__other));
-        else                       __val_.reset();
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
-  };
-
-  // This partial specialization implements an optimization for when we know we don't need to store
-  // an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
-  //
-  // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
-  //    directly and avoid using std::optional.
-  // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
-  //    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
-  //
-  // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
-  // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
-  // whenever we can apply any of these optimizations for both the copy assignment and the move assignment
-  // operator.
-  template<class _Tp>
-  concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
-
-  template<class _Tp>
-  concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
-
-  template<__copy_constructible_object _Tp>
-    requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>
-  class __copyable_box<_Tp> {
-    _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
-
-  public:
-    template<class ..._Args>
-      requires is_constructible_v<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit __copyable_box(in_place_t, _Args&& ...__args)
-      noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
-      : __val_(std::forward<_Args>(__args)...)
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
-      requires default_initializable<_Tp>
-      : __val_()
-    { }
-
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default;
-
-    // Implementation of assignment operators in case we perform optimization (1)
-    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default;
-    _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default;
-
-    // Implementation of assignment operators in case we perform optimization (2)
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept {
-      static_assert(is_nothrow_copy_constructible_v<_Tp>);
-      if (this != std::addressof(__other)) {
-        std::destroy_at(std::addressof(__val_));
-        std::construct_at(std::addressof(__val_), __other.__val_);
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept {
-      static_assert(is_nothrow_move_constructible_v<_Tp>);
-      if (this != std::addressof(__other)) {
-        std::destroy_at(std::addressof(__val_));
-        std::construct_at(std::addressof(__val_), std::move(__other.__val_));
-      }
-      return *this;
-    }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); }
-    _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); }
-
-    _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
-  };
-} // namespace ranges
-
-#endif // _LIBCPP_STD_VER >= 20
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
diff --git a/libcxx/include/__ranges/drop_while_view.h b/libcxx/include/__ranges/drop_while_view.h
--- a/libcxx/include/__ranges/drop_while_view.h
+++ b/libcxx/include/__ranges/drop_while_view.h
@@ -20,8 +20,8 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/enable_borrowed_range.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
@@ -82,7 +82,7 @@
 
 private:
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
   static constexpr bool _UseCache = forward_range<_View>;
   using _Cache                    = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h
--- a/libcxx/include/__ranges/filter_view.h
+++ b/libcxx/include/__ranges/filter_view.h
@@ -28,7 +28,7 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/non_propagating_cache.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
@@ -53,7 +53,7 @@
     requires view<_View> && is_object_v<_Pred>
   class filter_view : public view_interface<filter_view<_View, _Pred>> {
     _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-    _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+    _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
     // We cache the result of begin() to allow providing an amortized O(1) begin() whenever
     // the underlying range is at least a forward_range.
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -27,7 +27,6 @@
 #include <__iterator/incrementable_traits.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/unreachable_sentinel.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/view_interface.h>
 #include <__type_traits/conditional.h>
diff --git a/libcxx/include/__ranges/movable_box.h b/libcxx/include/__ranges/movable_box.h
new file mode 100644
--- /dev/null
+++ b/libcxx/include/__ranges/movable_box.h
@@ -0,0 +1,191 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_MOVABLE_BOX_H
+#define _LIBCPP___RANGES_MOVABLE_BOX_H
+
+#include <__concepts/constructible.h>
+#include <__concepts/copyable.h>
+#include <__concepts/movable.h>
+#include <__config>
+#include <__memory/addressof.h>
+#include <__memory/construct_at.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_nothrow_copy_constructible.h>
+#include <__type_traits/is_nothrow_default_constructible.h>
+#include <__utility/move.h>
+#include <optional>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+// __movable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into
+// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state
+// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary
+// to handle the case where the copy construction fails after destroying the object.
+//
+// In some cases, we can completely avoid the use of an empty state; we provide a specialization of
+// __movable_box that does this, see below for the details.
+
+// clang-format off
+template <class _Tp>
+concept __movable_box_object =
+#if _LIBCPP_STD_VER >= 23
+  move_constructible<_Tp>
+#else
+  copy_constructible<_Tp>
+#endif
+  && is_object_v<_Tp>;
+// clang-format on
+
+namespace ranges {
+// Primary template - uses std::optional and introduces an empty state in case assignment fails.
+template <__movable_box_object _Tp>
+class __movable_box {
+  _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
+
+public:
+  template <class... _Args>
+    requires is_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
+      is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(in_place, std::forward<_Args>(__args)...) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+    requires default_initializable<_Tp>
+      : __val_(in_place) {}
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&)      = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
+  operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>)
+    requires copy_constructible<_Tp>
+  {
+    if (this != std::addressof(__other)) {
+      if (__other.__has_value())
+        __val_.emplace(*__other);
+      else
+        __val_.reset();
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
+    requires movable<_Tp>
+  = default;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
+  operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) {
+    if (this != std::addressof(__other)) {
+      if (__other.__has_value())
+        __val_.emplace(std::move(*__other));
+      else
+        __val_.reset();
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return __val_.operator->(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
+};
+
+// This partial specialization implements an optimization for when we know we don't need to store
+// an empty state to represent failure to perform an assignment. For copy-assignment, this happens:
+//
+// 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator
+//    directly and avoid using std::optional.
+// 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as
+//    destroy-and-then-construct and we know it will never fail, so we don't need an empty state.
+//
+// The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and
+// nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled
+// whenever we can apply any of these optimizations for both the copy assignment and the move assignment
+// operator.
+template <class _Tp>
+concept __doesnt_need_empty_state =
+    (copy_constructible<_Tp>
+         // 1. If copy_constructible<T> is true, movable-box<T> should store only a T if either T models
+         // copyable, or is_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true.
+         ? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>)
+         // 2. Otherwise, movable-box<T> should store only a T if either T models movable or
+         // is_nothrow_move_constructible_v<T> is true.
+         : movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
+
+template <__movable_box_object _Tp>
+  requires __doesnt_need_empty_state<_Tp>
+class __movable_box<_Tp> {
+  _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
+
+public:
+  template <class... _Args>
+    requires is_constructible_v<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
+      is_nothrow_constructible_v<_Tp, _Args...>)
+      : __val_(std::forward<_Args>(__args)...) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
+    requires default_initializable<_Tp>
+      : __val_() {}
+
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&)      = default;
+
+  // Implementation of assignment operators in case we perform optimization (1)
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&)
+    requires copyable<_Tp>
+  = default;
+  _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
+    requires movable<_Tp>
+  = default;
+
+  // Implementation of assignment operators in case we perform optimization (2)
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept {
+    static_assert(is_nothrow_copy_constructible_v<_Tp>);
+    if (this != std::addressof(__other)) {
+      std::destroy_at(std::addressof(__val_));
+      std::construct_at(std::addressof(__val_), __other.__val_);
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept {
+    static_assert(is_nothrow_move_constructible_v<_Tp>);
+    if (this != std::addressof(__other)) {
+      std::destroy_at(std::addressof(__val_));
+      std::construct_at(std::addressof(__val_), std::move(__other.__val_));
+    }
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__val_); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__val_); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
+};
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_MOVABLE_BOX_H
diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h
--- a/libcxx/include/__ranges/single_view.h
+++ b/libcxx/include/__ranges/single_view.h
@@ -12,7 +12,7 @@
 
 #include <__concepts/constructible.h>
 #include <__config>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
 #include <__type_traits/decay.h>
@@ -31,48 +31,41 @@
 #if _LIBCPP_STD_VER >= 20
 
 namespace ranges {
-  template<copy_constructible _Tp>
-    requires is_object_v<_Tp>
-  class single_view : public view_interface<single_view<_Tp>> {
-    __copyable_box<_Tp> __value_;
+template <move_constructible _Tp>
+  requires is_object_v<_Tp>
+class single_view : public view_interface<single_view<_Tp>> {
+  __movable_box<_Tp> __value_;
 
-  public:
-    _LIBCPP_HIDE_FROM_ABI
-    single_view() requires default_initializable<_Tp> = default;
+public:
+  _LIBCPP_HIDE_FROM_ABI single_view()
+    requires default_initializable<_Tp>
+  = default;
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
+    requires copy_constructible<_Tp>
+      : __value_(in_place, __t) {}
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
 
-    template<class... _Args>
-      requires constructible_from<_Tp, _Args...>
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr explicit single_view(in_place_t, _Args&&... __args)
+  template <class... _Args>
+    requires constructible_from<_Tp, _Args...>
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
       : __value_{in_place, std::forward<_Args>(__args)...} {}
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* begin() noexcept { return data(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* begin() const noexcept { return data(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* end() noexcept { return data() + 1; }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* end() const noexcept { return data() + 1; }
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    static constexpr size_t size() noexcept { return 1; }
+  _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr _Tp* data() noexcept { return __value_.operator->(); }
+  _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
 
-    _LIBCPP_HIDE_FROM_ABI
-    constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
-  };
+  _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
+};
 
 template<class _Tp>
 single_view(_Tp) -> single_view<_Tp>;
diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h
--- a/libcxx/include/__ranges/take_while_view.h
+++ b/libcxx/include/__ranges/take_while_view.h
@@ -20,7 +20,7 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
 #include <__type_traits/decay.h>
@@ -60,7 +60,7 @@
   class __sentinel;
 
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
 
 public:
   _LIBCPP_HIDE_FROM_ABI take_while_view()
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -26,8 +26,8 @@
 #include <__ranges/access.h>
 #include <__ranges/all.h>
 #include <__ranges/concepts.h>
-#include <__ranges/copyable_box.h>
 #include <__ranges/empty.h>
+#include <__ranges/movable_box.h>
 #include <__ranges/range_adaptor.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
@@ -62,13 +62,13 @@
   regular_invocable<_Fn&, range_reference_t<_View>> &&
   __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
 
-template<input_range _View, copy_constructible _Fn>
+template<input_range _View, move_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
 class transform_view : public view_interface<transform_view<_View, _Fn>> {
   template<bool> class __iterator;
   template<bool> class __sentinel;
 
-  _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
+  _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __func_;
   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
 
 public:
@@ -161,7 +161,7 @@
   >;
 };
 
-template<input_range _View, copy_constructible _Fn>
+template<input_range _View, move_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
 template<bool _Const>
 class transform_view<_View, _Fn>::__iterator
@@ -357,7 +357,7 @@
   }
 };
 
-template<input_range _View, copy_constructible _Fn>
+template<input_range _View, move_constructible _Fn>
   requires __transform_view_constraints<_View, _Fn>
 template<bool _Const>
 class transform_view<_View, _Fn>::__sentinel {
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1350,7 +1350,6 @@
       module common_view                { private header "__ranges/common_view.h" }
       module concepts                   { private header "__ranges/concepts.h" }
       module container_compatible_range { private header "__ranges/container_compatible_range.h" }
-      module copyable_box               { private header "__ranges/copyable_box.h" }
       module counted                    {
         private header "__ranges/counted.h"
         export span
@@ -1373,6 +1372,7 @@
       }
       module join_view                  { private header "__ranges/join_view.h" }
       module lazy_split_view            { private header "__ranges/lazy_split_view.h" }
+      module movable_box                { private header "__ranges/movable_box.h" }
       module non_propagating_cache      { private header "__ranges/non_propagating_cache.h" }
       module owning_view                { private header "__ranges/owning_view.h" }
       module range_adaptor              { private header "__ranges/range_adaptor.h" }
diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -593,7 +593,6 @@
 #include <__ranges/common_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/common_view.h'}}
 #include <__ranges/concepts.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/concepts.h'}}
 #include <__ranges/container_compatible_range.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/container_compatible_range.h'}}
-#include <__ranges/copyable_box.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/copyable_box.h'}}
 #include <__ranges/counted.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/counted.h'}}
 #include <__ranges/dangling.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/dangling.h'}}
 #include <__ranges/data.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/data.h'}}
@@ -610,6 +609,7 @@
 #include <__ranges/istream_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/istream_view.h'}}
 #include <__ranges/join_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/join_view.h'}}
 #include <__ranges/lazy_split_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/lazy_split_view.h'}}
+#include <__ranges/movable_box.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/movable_box.h'}}
 #include <__ranges/non_propagating_cache.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/non_propagating_cache.h'}}
 #include <__ranges/owning_view.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/owning_view.h'}}
 #include <__ranges/range_adaptor.h> // expected-error@*:* {{use of private header from outside its module: '__ranges/range_adaptor.h'}}
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/properties.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/properties.compile.pass.cpp
deleted file mode 100644
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/properties.compile.pass.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Test various properties of <copyable-box>
-
-#include <ranges>
-
-#include <optional>
-
-#include "types.h"
-
-template <class T>
-constexpr bool valid_copyable_box = requires {
-  typename std::ranges::__copyable_box<T>;
-};
-
-struct NotCopyConstructible {
-  NotCopyConstructible() = default;
-  NotCopyConstructible(NotCopyConstructible&&) = default;
-  NotCopyConstructible(NotCopyConstructible const&) = delete;
-  NotCopyConstructible& operator=(NotCopyConstructible&&) = default;
-  NotCopyConstructible& operator=(NotCopyConstructible const&) = default;
-};
-
-static_assert(!valid_copyable_box<void>); // not an object type
-static_assert(!valid_copyable_box<int&>); // not an object type
-static_assert(!valid_copyable_box<NotCopyConstructible>);
-
-// primary template
-static_assert(sizeof(std::ranges::__copyable_box<CopyConstructible>) == sizeof(std::optional<CopyConstructible>));
-
-// optimization #1
-static_assert(sizeof(std::ranges::__copyable_box<Copyable>) == sizeof(Copyable));
-static_assert(alignof(std::ranges::__copyable_box<Copyable>) == alignof(Copyable));
-
-// optimization #2
-static_assert(sizeof(std::ranges::__copyable_box<NothrowCopyConstructible>) == sizeof(NothrowCopyConstructible));
-static_assert(alignof(std::ranges::__copyable_box<NothrowCopyConstructible>) == alignof(NothrowCopyConstructible));
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/arrow.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/arrow.pass.cpp
@@ -19,11 +19,11 @@
 
 #include "types.h"
 
-template<class T>
+template <class T>
 constexpr void check() {
   // non-const version
   {
-    std::ranges::__copyable_box<T> x(std::in_place, 10);
+    std::ranges::__movable_box<T> x(std::in_place, 10);
     T* result = x.operator->();
     static_assert(noexcept(x.operator->()));
     assert(result->value == 10);
@@ -32,7 +32,7 @@
 
   // const version
   {
-    std::ranges::__copyable_box<T> const x(std::in_place, 10);
+    std::ranges::__movable_box<T> const x(std::in_place, 10);
     const T* result = x.operator->();
     static_assert(noexcept(x.operator->()));
     assert(result->value == 10);
@@ -41,8 +41,8 @@
 }
 
 constexpr bool test() {
-  check<CopyConstructible>(); // primary template
-  check<Copyable>(); // optimization #1
+  check<CopyConstructible>();        // primary template
+  check<Copyable>();                 // optimization #1
   check<NothrowCopyConstructible>(); // optimization #2
   return true;
 }
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.copy.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.copy.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.copy.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.copy.pass.cpp
@@ -24,8 +24,8 @@
 constexpr bool test() {
   // Test the primary template
   {
-    using Box = std::ranges::__copyable_box<CopyConstructible>;
-    static_assert( std::is_copy_assignable_v<Box>);
+    using Box = std::ranges::__movable_box<CopyConstructible>;
+    static_assert(std::is_copy_assignable_v<Box>);
     static_assert(!std::is_nothrow_copy_assignable_v<Box>);
 
     {
@@ -51,8 +51,8 @@
 
   // Test optimization #1 for copy-assignment
   {
-    using Box = std::ranges::__copyable_box<Copyable>;
-    static_assert( std::is_copy_assignable_v<Box>);
+    using Box = std::ranges::__movable_box<Copyable>;
+    static_assert(std::is_copy_assignable_v<Box>);
     static_assert(!std::is_nothrow_copy_assignable_v<Box>);
 
     {
@@ -80,7 +80,7 @@
 
   // Test optimization #2 for copy-assignment
   {
-    using Box = std::ranges::__copyable_box<NothrowCopyConstructible>;
+    using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
     static_assert(std::is_copy_assignable_v<Box>);
     static_assert(std::is_nothrow_copy_assignable_v<Box>);
 
@@ -112,7 +112,7 @@
 // through throwing an exception.
 #if !defined(TEST_HAS_NO_EXCEPTIONS)
 void test_empty_state() {
-  using Box = std::ranges::__copyable_box<ThrowsOnCopy>;
+  using Box = std::ranges::__movable_box<ThrowsOnCopy>;
 
   // assign non-empty to empty
   {
@@ -137,7 +137,7 @@
   }
   // assign empty to empty
   {
-    Box x = create_empty_box();
+    Box x       = create_empty_box();
     Box const y = create_empty_box();
     Box& result = (x = y);
 
@@ -147,7 +147,7 @@
   }
   // check self-assignment in empty case
   {
-    Box x = create_empty_box();
+    Box x       = create_empty_box();
     Box& result = (x = x);
 
     assert(&result == &x);
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.move.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.move.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/assign.move.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/assign.move.pass.cpp
@@ -24,8 +24,8 @@
 constexpr bool test() {
   // Test the primary template
   {
-    using Box = std::ranges::__copyable_box<CopyConstructible>;
-    static_assert( std::is_move_assignable_v<Box>);
+    using Box = std::ranges::__movable_box<CopyConstructible>;
+    static_assert(std::is_move_assignable_v<Box>);
     static_assert(!std::is_nothrow_move_assignable_v<Box>);
 
     {
@@ -51,9 +51,10 @@
 
   // Make sure that we use the native move assignment in the primary template if we can.
   {
-    using Box = std::ranges::__copyable_box<CopyConstructibleMovable>;
+    using Box = std::ranges::__movable_box<CopyConstructibleMovable>;
     static_assert(std::is_move_assignable_v<Box>);
-    static_assert(std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<CopyConstructibleMovable>);
+    static_assert(
+        std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<CopyConstructibleMovable>);
 
     {
       Box x(std::in_place, 5);
@@ -80,8 +81,8 @@
 
   // Test optimization #1 for move assignment
   {
-    using Box = std::ranges::__copyable_box<Copyable>;
-    static_assert( std::is_move_assignable_v<Box>);
+    using Box = std::ranges::__movable_box<Copyable>;
+    static_assert(std::is_move_assignable_v<Box>);
     static_assert(!std::is_nothrow_move_assignable_v<Box>);
 
     {
@@ -109,9 +110,10 @@
 
   // Test optimization #1 for move assignment with a type that uses optimization #2 for copy assignment
   {
-    using Box = std::ranges::__copyable_box<MovableNothrowCopyConstructible>;
+    using Box = std::ranges::__movable_box<MovableNothrowCopyConstructible>;
     static_assert(std::is_move_assignable_v<Box>);
-    static_assert(std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<MovableNothrowCopyConstructible>);
+    static_assert(
+        std::is_nothrow_move_assignable_v<Box> == std::is_nothrow_move_assignable_v<MovableNothrowCopyConstructible>);
 
     {
       Box x(std::in_place, 5);
@@ -138,7 +140,7 @@
 
   // Test optimization #2 for move assignment
   {
-    using Box = std::ranges::__copyable_box<NothrowCopyConstructible>;
+    using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
     static_assert(std::is_move_assignable_v<Box>);
     static_assert(std::is_nothrow_move_assignable_v<Box>);
 
@@ -170,7 +172,7 @@
 // through throwing an exception.
 #if !defined(TEST_HAS_NO_EXCEPTIONS)
 void test_empty_state() {
-  using Box = std::ranges::__copyable_box<ThrowsOnCopy>;
+  using Box = std::ranges::__movable_box<ThrowsOnCopy>;
 
   // assign non-empty to empty
   {
@@ -186,7 +188,7 @@
   // assign empty to non-empty
   {
     Box x(std::in_place, 5);
-    Box y = create_empty_box();
+    Box y       = create_empty_box();
     Box& result = (x = std::move(y));
 
     assert(&result == &x);
@@ -195,8 +197,8 @@
   }
   // assign empty to empty
   {
-    Box x = create_empty_box();
-    Box y = create_empty_box();
+    Box x       = create_empty_box();
+    Box y       = create_empty_box();
     Box& result = (x = std::move(y));
 
     assert(&result == &x);
@@ -205,7 +207,7 @@
   }
   // check self-assignment in empty case
   {
-    Box x = create_empty_box();
+    Box x       = create_empty_box();
     Box& result = (x = std::move(x));
 
     assert(&result == &x);
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.default.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.default.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.default.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.default.pass.cpp
@@ -18,19 +18,19 @@
 
 #include "types.h"
 
-template<class T>
-using Box = std::ranges::__copyable_box<T>;
+template <class T>
+using Box = std::ranges::__movable_box<T>;
 
 struct NoDefault {
   NoDefault() = delete;
 };
 static_assert(!std::is_default_constructible_v<Box<NoDefault>>);
 
-template<bool Noexcept>
+template <bool Noexcept>
 struct DefaultNoexcept {
   DefaultNoexcept() noexcept(Noexcept);
 };
-static_assert( std::is_nothrow_default_constructible_v<Box<DefaultNoexcept<true>>>);
+static_assert(std::is_nothrow_default_constructible_v<Box<DefaultNoexcept<true>>>);
 static_assert(!std::is_nothrow_default_constructible_v<Box<DefaultNoexcept<false>>>);
 
 constexpr bool test() {
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.in_place.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.in_place.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/ctor.in_place.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/ctor.in_place.pass.cpp
@@ -19,9 +19,9 @@
 
 #include "types.h"
 
-struct UnknownType { };
+struct UnknownType {};
 
-template<bool Noexcept>
+template <bool Noexcept>
 struct NothrowConstructible {
   explicit NothrowConstructible(int) noexcept(Noexcept);
 };
@@ -29,7 +29,7 @@
 constexpr bool test() {
   // Test the primary template
   {
-    using Box = std::ranges::__copyable_box<CopyConstructible>;
+    using Box = std::ranges::__movable_box<CopyConstructible>;
     Box x(std::in_place, 5);
     assert((*x).value == 5);
 
@@ -38,7 +38,7 @@
 
   // Test optimization #1
   {
-    using Box = std::ranges::__copyable_box<Copyable>;
+    using Box = std::ranges::__movable_box<Copyable>;
     Box x(std::in_place, 5);
     assert((*x).value == 5);
 
@@ -47,15 +47,17 @@
 
   // Test optimization #2
   {
-    using Box = std::ranges::__copyable_box<NothrowCopyConstructible>;
+    using Box = std::ranges::__movable_box<NothrowCopyConstructible>;
     Box x(std::in_place, 5);
     assert((*x).value == 5);
 
     static_assert(!std::is_constructible_v<Box, std::in_place_t, UnknownType>);
   }
 
-  static_assert( std::is_nothrow_constructible_v<std::ranges::__copyable_box<NothrowConstructible<true>>, std::in_place_t, int>);
-  static_assert(!std::is_nothrow_constructible_v<std::ranges::__copyable_box<NothrowConstructible<false>>, std::in_place_t, int>);
+  static_assert(
+      std::is_nothrow_constructible_v<std::ranges::__movable_box<NothrowConstructible<true>>, std::in_place_t, int>);
+  static_assert(
+      !std::is_nothrow_constructible_v<std::ranges::__movable_box<NothrowConstructible<false>>, std::in_place_t, int>);
 
   return true;
 }
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/deref.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/deref.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/deref.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/deref.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/deref.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/deref.pass.cpp
@@ -19,11 +19,11 @@
 
 #include "types.h"
 
-template<class T>
+template <class T>
 constexpr void check() {
   // non-const version
   {
-    std::ranges::__copyable_box<T> x(std::in_place, 10);
+    std::ranges::__movable_box<T> x(std::in_place, 10);
     T& result = *x;
     static_assert(noexcept(*x));
     assert(result.value == 10);
@@ -31,7 +31,7 @@
 
   // const version
   {
-    std::ranges::__copyable_box<T> const x(std::in_place, 10);
+    std::ranges::__movable_box<T> const x(std::in_place, 10);
     T const& result = *x;
     static_assert(noexcept(*x));
     assert(result.value == 10);
@@ -39,8 +39,8 @@
 }
 
 constexpr bool test() {
-  check<CopyConstructible>(); // primary template
-  check<Copyable>(); // optimization #1
+  check<CopyConstructible>();        // primary template
+  check<Copyable>();                 // optimization #1
   check<NothrowCopyConstructible>(); // optimization #2
   return true;
 }
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/has_value.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/has_value.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/has_value.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/has_value.pass.cpp
@@ -18,15 +18,15 @@
 
 #include "types.h"
 
-template<class T>
+template <class T>
 constexpr void check() {
-  std::ranges::__copyable_box<T> const x(std::in_place, 10);
+  std::ranges::__movable_box<T> const x(std::in_place, 10);
   assert(x.__has_value());
 }
 
 constexpr bool test() {
-  check<CopyConstructible>(); // primary template
-  check<Copyable>(); // optimization #1
+  check<CopyConstructible>();        // primary template
+  check<Copyable>();                 // optimization #1
   check<NothrowCopyConstructible>(); // optimization #2
   return true;
 }
@@ -39,7 +39,7 @@
   // through throwing an exception.
 #if !defined(TEST_HAS_NO_EXCEPTIONS)
   {
-    std::ranges::__copyable_box<ThrowsOnCopy> x = create_empty_box();
+    std::ranges::__movable_box<ThrowsOnCopy> x = create_empty_box();
     assert(!x.__has_value());
   }
 #endif
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/no_unique_address.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/no_unique_address.pass.cpp
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/no_unique_address.pass.cpp
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/no_unique_address.pass.cpp
@@ -16,19 +16,19 @@
 #include <utility>
 
 bool copied = false;
-bool moved = false;
+bool moved  = false;
 
 struct Empty {
-  Empty() noexcept { }
+  Empty() noexcept {}
   Empty(Empty const&) noexcept { copied = true; }
   Empty(Empty&&) noexcept { moved = true; }
   Empty& operator=(Empty const&) = delete;
-  Empty& operator=(Empty&&) = delete;
+  Empty& operator=(Empty&&)      = delete;
 };
 
-using Box = std::ranges::__copyable_box<Empty>;
+using Box = std::ranges::__movable_box<Empty>;
 
-struct Inherit : Box { };
+struct Inherit : Box {};
 
 struct Hold : Box {
   [[no_unique_address]] Inherit member;
@@ -37,7 +37,7 @@
 int main(int, char**) {
   Hold box;
 
-  Box& base = static_cast<Box&>(box);
+  Box& base   = static_cast<Box&>(box);
   Box& member = static_cast<Box&>(box.member);
 
   // Despite [[no_unique_address]], the two objects have the same type so they
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp
new file mode 100644
--- /dev/null
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/properties.compile.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// Test various properties of <movable-box>
+
+#include <ranges>
+
+#include <optional>
+
+#include "types.h"
+#include "MoveOnly.h"
+
+template <class T>
+constexpr bool valid_movable_box = requires { typename std::ranges::__movable_box<T>; };
+
+struct NotCopyConstructible {
+  NotCopyConstructible()                                       = default;
+  NotCopyConstructible(NotCopyConstructible&&)                 = default;
+  NotCopyConstructible(NotCopyConstructible const&)            = delete;
+  NotCopyConstructible& operator=(NotCopyConstructible&&)      = default;
+  NotCopyConstructible& operator=(NotCopyConstructible const&) = default;
+};
+
+struct NotMoveConstructible {
+  NotMoveConstructible()                                  = default;
+  NotMoveConstructible(NotMoveConstructible&&)            = delete;
+  NotMoveConstructible& operator=(NotMoveConstructible&&) = delete;
+};
+
+static_assert(!valid_movable_box<void>); // not an object type
+static_assert(!valid_movable_box<int&>); // not an object type
+static_assert(!valid_movable_box<NotMoveConstructible>);
+static_assert(valid_movable_box<NotCopyConstructible>);
+static_assert(valid_movable_box<MoveOnly>);
+
+// primary template
+static_assert(sizeof(std::ranges::__movable_box<CopyConstructible>) == sizeof(std::optional<CopyConstructible>));
+static_assert(sizeof(std::ranges::__movable_box<CopyConstructible>) == sizeof(std::optional<CopyConstructible>));
+
+// optimization #1
+static_assert(sizeof(std::ranges::__movable_box<Copyable>) == sizeof(Copyable));
+static_assert(alignof(std::ranges::__movable_box<Copyable>) == alignof(Copyable));
+
+// optimization #2
+static_assert(sizeof(std::ranges::__movable_box<NothrowCopyConstructible>) == sizeof(NothrowCopyConstructible));
+static_assert(alignof(std::ranges::__movable_box<NothrowCopyConstructible>) == alignof(NothrowCopyConstructible));
diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/types.h b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/types.h
rename from libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/types.h
rename to libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/types.h
--- a/libcxx/test/libcxx/ranges/range.adaptors/range.copy.wrap/types.h
+++ b/libcxx/test/libcxx/ranges/range.adaptors/range.move.wrap/types.h
@@ -16,15 +16,15 @@
 
 #include "test_macros.h"
 
-// NOTE: These types are strongly tied to the implementation of __copyable_box. See the documentation
-//       in __copyable_box for the meaning of optimizations #1 and #2.
+// NOTE: These types are strongly tied to the implementation of __movable_box. See the documentation
+//       in __movable_box for the meaning of optimizations #1 and #2.
 
 // Copy constructible, but neither copyable nor nothrow_copy/move_constructible. This uses the primary template.
 struct CopyConstructible {
   constexpr CopyConstructible() = default;
-  constexpr explicit CopyConstructible(int x) : value(x) { }
+  constexpr explicit CopyConstructible(int x) : value(x) {}
   CopyConstructible(CopyConstructible const&) noexcept(false) = default;
-  CopyConstructible& operator=(CopyConstructible const&) = delete;
+  CopyConstructible& operator=(CopyConstructible const&)      = delete;
 
   int value = -1;
 };
@@ -33,105 +33,102 @@
 static_assert(!std::movable<CopyConstructible>);
 static_assert(!std::is_nothrow_move_constructible_v<CopyConstructible>);
 
-
 // Copy constructible and movable, but not copyable. This uses the primary template, however we're
 // still able to use the native move-assignment operator in this case.
 struct CopyConstructibleMovable {
   constexpr CopyConstructibleMovable() = default;
-  constexpr explicit CopyConstructibleMovable(int x) : value(x) { }
+  constexpr explicit CopyConstructibleMovable(int x) : value(x) {}
   CopyConstructibleMovable(CopyConstructibleMovable const&) noexcept(false) = default;
-  CopyConstructibleMovable(CopyConstructibleMovable&&) noexcept(false) = default;
-  CopyConstructibleMovable& operator=(CopyConstructibleMovable const&) = delete;
+  CopyConstructibleMovable(CopyConstructibleMovable&&) noexcept(false)      = default;
+  CopyConstructibleMovable& operator=(CopyConstructibleMovable const&)      = delete;
 
   constexpr CopyConstructibleMovable& operator=(CopyConstructibleMovable&& other) {
-    value = other.value;
+    value           = other.value;
     did_move_assign = true;
     return *this;
   }
 
-  int value = -1;
+  int value            = -1;
   bool did_move_assign = false;
 };
 
-
 // Copyable type that is not nothrow_copy/move_constructible.
 // This triggers optimization #1 for the copy assignment and the move assignment.
 struct Copyable {
   constexpr Copyable() = default;
-  constexpr explicit Copyable(int x) : value(x) { }
+  constexpr explicit Copyable(int x) : value(x) {}
   Copyable(Copyable const&) noexcept(false) = default;
 
   constexpr Copyable& operator=(Copyable const& other) noexcept(false) {
-    value = other.value;
+    value           = other.value;
     did_copy_assign = true;
     return *this;
   }
 
   constexpr Copyable& operator=(Copyable&& other) noexcept(false) {
-    value = other.value;
+    value           = other.value;
     did_move_assign = true;
     return *this;
   }
 
-  int value = -1;
+  int value            = -1;
   bool did_copy_assign = false;
   bool did_move_assign = false;
 };
-static_assert( std::copyable<Copyable>);
+static_assert(std::copyable<Copyable>);
 static_assert(!std::is_nothrow_copy_constructible_v<Copyable>);
-static_assert( std::movable<Copyable>);
+static_assert(std::movable<Copyable>);
 static_assert(!std::is_nothrow_move_constructible_v<Copyable>);
 
-
 // Non-copyable type that is nothrow_copy_constructible and nothrow_move_constructible.
 // This triggers optimization #2 for the copy assignment and the move assignment.
 struct NothrowCopyConstructible {
   constexpr NothrowCopyConstructible() = default;
-  constexpr explicit NothrowCopyConstructible(int x) : value(x) { }
-  NothrowCopyConstructible(NothrowCopyConstructible const&) noexcept = default;
-  NothrowCopyConstructible(NothrowCopyConstructible&&) noexcept = default;
+  constexpr explicit NothrowCopyConstructible(int x) : value(x) {}
+  NothrowCopyConstructible(NothrowCopyConstructible const&) noexcept   = default;
+  NothrowCopyConstructible(NothrowCopyConstructible&&) noexcept        = default;
   NothrowCopyConstructible& operator=(NothrowCopyConstructible const&) = delete;
 
   int value = -1;
 };
 static_assert(!std::copyable<NothrowCopyConstructible>);
-static_assert( std::is_nothrow_copy_constructible_v<NothrowCopyConstructible>);
+static_assert(std::is_nothrow_copy_constructible_v<NothrowCopyConstructible>);
 static_assert(!std::movable<NothrowCopyConstructible>);
-static_assert( std::is_nothrow_move_constructible_v<NothrowCopyConstructible>);
-
+static_assert(std::is_nothrow_move_constructible_v<NothrowCopyConstructible>);
 
 // Non-copyable type that is nothrow_copy_constructible, and that is movable but NOT nothrow_move_constructible.
 // This triggers optimization #2 for the copy assignment, and optimization #1 for the move assignment.
 struct MovableNothrowCopyConstructible {
   constexpr MovableNothrowCopyConstructible() = default;
-  constexpr explicit MovableNothrowCopyConstructible(int x) : value(x) { }
-  MovableNothrowCopyConstructible(MovableNothrowCopyConstructible const&) noexcept = default;
+  constexpr explicit MovableNothrowCopyConstructible(int x) : value(x) {}
+  MovableNothrowCopyConstructible(MovableNothrowCopyConstructible const&) noexcept   = default;
   MovableNothrowCopyConstructible(MovableNothrowCopyConstructible&&) noexcept(false) = default;
   constexpr MovableNothrowCopyConstructible& operator=(MovableNothrowCopyConstructible&& other) {
-    value = other.value;
+    value           = other.value;
     did_move_assign = true;
     return *this;
   }
 
-  int value = -1;
+  int value            = -1;
   bool did_move_assign = false;
 };
 static_assert(!std::copyable<MovableNothrowCopyConstructible>);
-static_assert( std::is_nothrow_copy_constructible_v<MovableNothrowCopyConstructible>);
-static_assert( std::movable<MovableNothrowCopyConstructible>);
+static_assert(std::is_nothrow_copy_constructible_v<MovableNothrowCopyConstructible>);
+static_assert(std::movable<MovableNothrowCopyConstructible>);
 static_assert(!std::is_nothrow_move_constructible_v<MovableNothrowCopyConstructible>);
 
-
 #if !defined(TEST_HAS_NO_EXCEPTIONS)
 // A type that we can make throw when copied from. This is used to create a
 // copyable-box in the empty state.
 static constexpr int THROW_WHEN_COPIED_FROM = 999;
 struct ThrowsOnCopy {
   constexpr ThrowsOnCopy() = default;
-  constexpr explicit ThrowsOnCopy(int x) : value(x) { }
+  constexpr explicit ThrowsOnCopy(int x) : value(x) {}
   ThrowsOnCopy(ThrowsOnCopy const& other) {
-    if (other.value == THROW_WHEN_COPIED_FROM) throw 0;
-    else                                       value = other.value;
+    if (other.value == THROW_WHEN_COPIED_FROM)
+      throw 0;
+    else
+      value = other.value;
   }
 
   ThrowsOnCopy& operator=(ThrowsOnCopy const&) = delete; // prevent from being copyable
@@ -142,9 +139,9 @@
 // Creates an empty box. The only way to do that is to try assigning one box
 // to another and have that fail due to an exception when calling the copy
 // constructor. The assigned-to box will then be in the empty state.
-inline std::ranges::__copyable_box<ThrowsOnCopy> create_empty_box() {
-  std::ranges::__copyable_box<ThrowsOnCopy> box1;
-  std::ranges::__copyable_box<ThrowsOnCopy> box2(std::in_place, THROW_WHEN_COPIED_FROM);
+inline std::ranges::__movable_box<ThrowsOnCopy> create_empty_box() {
+  std::ranges::__movable_box<ThrowsOnCopy> box1;
+  std::ranges::__movable_box<ThrowsOnCopy> box2(std::in_place, THROW_WHEN_COPIED_FROM);
   try {
     box1 = box2; // throws during assignment, which is implemented as a call to the copy ctor
   } catch (...) {
diff --git a/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp
--- a/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp
@@ -19,8 +19,8 @@
 
 // Can't invoke without arguments.
 static_assert(!std::is_invocable_v<decltype((std::views::single))>);
-// Can't invoke with a move-only type.
-static_assert(!std::is_invocable_v<decltype((std::views::single)), MoveOnly>);
+// Invoke with a move-only type.
+static_assert(std::is_invocable_v<decltype((std::views::single)), MoveOnly>);
 
 constexpr bool test() {
   // Lvalue.
diff --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt
--- a/libcxx/utils/data/ignore_format.txt
+++ b/libcxx/utils/data/ignore_format.txt
@@ -559,7 +559,6 @@
 libcxx/include/__ranges/all.h
 libcxx/include/__ranges/common_view.h
 libcxx/include/__ranges/concepts.h
-libcxx/include/__ranges/copyable_box.h
 libcxx/include/__ranges/counted.h
 libcxx/include/__ranges/data.h
 libcxx/include/__ranges/drop_view.h