Add downgrade conversion from SharedPtr to WeakPtr
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 327dee4..359eb22 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1799,6 +1799,13 @@
     writeln!(out, "}}");
     writeln!(
         out,
+        "void cxxbridge1$weak_ptr${}$downgrade(const ::std::shared_ptr<{}>& shared, ::std::weak_ptr<{}> *weak) noexcept {{",
+        instance, inner, inner,
+    );
+    writeln!(out, "  ::new (weak) ::std::weak_ptr<{}>(shared);", inner);
+    writeln!(out, "}}");
+    writeln!(
+        out,
         "void cxxbridge1$weak_ptr${}$drop(::std::weak_ptr<{}> *self) noexcept {{",
         instance, inner,
     );
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index f13fca4..690dbf9 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1242,6 +1242,7 @@
     let prefix = format!("cxxbridge1$weak_ptr${}$", ident.to_symbol(types));
     let link_null = format!("{}null", prefix);
     let link_clone = format!("{}clone", prefix);
+    let link_downgrade = format!("{}downgrade", prefix);
     let link_drop = format!("{}drop", prefix);
 
     let begin_span =
@@ -1266,6 +1267,13 @@
                 }
                 __clone(this, new);
             }
+            unsafe fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void) {
+                extern "C" {
+                    #[link_name = #link_downgrade]
+                    fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void);
+                }
+                __downgrade(shared, weak);
+            }
             unsafe fn __drop(this: *mut ::std::ffi::c_void) {
                 extern "C" {
                     #[link_name = #link_drop]
diff --git a/src/cxx.cc b/src/cxx.cc
index e573b44..2e1cc15 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -520,6 +520,11 @@
       std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \
     new (ptr) std::weak_ptr<CXX_TYPE>(self);                                   \
   }                                                                            \
+  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade(                        \
+      const std::shared_ptr<CXX_TYPE> &shared,                                 \
+      std::weak_ptr<CXX_TYPE> *weak) noexcept {                                \
+    new (weak) std::weak_ptr<CXX_TYPE>(shared);                                \
+  }                                                                            \
   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop(                             \
       const std::weak_ptr<CXX_TYPE> *self) noexcept {                          \
     self->~weak_ptr();                                                         \
diff --git a/src/shared_ptr.rs b/src/shared_ptr.rs
index 9269e5a..18f600f 100644
--- a/src/shared_ptr.rs
+++ b/src/shared_ptr.rs
@@ -1,5 +1,6 @@
 use crate::kind::Trivial;
 use crate::string::CxxString;
+use crate::weak_ptr::{WeakPtr, WeakPtrTarget};
 use crate::ExternType;
 use core::ffi::c_void;
 use core::fmt::{self, Debug, Display};
@@ -61,6 +62,24 @@
         let this = self as *const Self as *const c_void;
         unsafe { T::__get(this).as_ref() }
     }
+
+    /// Constructs new WeakPtr as a non-owning reference to the object managed
+    /// by `self`. If `self` manages no object, the WeakPtr manages no object
+    /// too.
+    ///
+    /// Matches the behavior of [std::weak_ptr\<T\>::weak_ptr(const std::shared_ptr\<T\> \&)](https://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr).
+    pub fn downgrade(self: &SharedPtr<T>) -> WeakPtr<T>
+    where
+        T: WeakPtrTarget,
+    {
+        let this = self as *const Self as *const c_void;
+        let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit();
+        let new = weak_ptr.as_mut_ptr().cast();
+        unsafe {
+            T::__downgrade(this, new);
+            weak_ptr.assume_init()
+        }
+    }
 }
 
 unsafe impl<T> Send for SharedPtr<T> where T: Send + Sync + SharedPtrTarget {}
diff --git a/src/weak_ptr.rs b/src/weak_ptr.rs
index d73ee8f..9038f4e 100644
--- a/src/weak_ptr.rs
+++ b/src/weak_ptr.rs
@@ -5,6 +5,11 @@
 use core::mem::MaybeUninit;
 
 /// Binding to C++ `std::weak_ptr<T>`.
+///
+/// The typical way to construct a WeakPtr from Rust is by [downgrading] from a
+/// SharedPtr.
+///
+/// [downgrading]: crate::SharedPtr::downgrade
 #[repr(C)]
 pub struct WeakPtr<T>
 where
@@ -69,6 +74,8 @@
     #[doc(hidden)]
     unsafe fn __clone(this: *const c_void, new: *mut c_void);
     #[doc(hidden)]
+    unsafe fn __downgrade(shared: *const c_void, new: *mut c_void);
+    #[doc(hidden)]
     unsafe fn __drop(this: *mut c_void);
 }
 
@@ -94,6 +101,15 @@
                 }
                 __clone(this, new);
             }
+            unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$downgrade")]
+                        fn __downgrade(shared: *const c_void, weak: *mut c_void);
+                    }
+                }
+                __downgrade(shared, weak);
+            }
             unsafe fn __drop(this: *mut c_void) {
                 extern "C" {
                     attr! {