pinned: Fix some coercion cases

Change-Id: I98ed28d69b3d49d59e9e65737b7ccafd5d16fed6
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/pinned.hpp b/include/stdplus/pinned.hpp
index abf6c7f..9e04f97 100644
--- a/include/stdplus/pinned.hpp
+++ b/include/stdplus/pinned.hpp
@@ -25,7 +25,7 @@
         {
             return v;
         }
-        constexpr operator T() const
+        constexpr operator const T&() const
         {
             return v;
         }
@@ -63,7 +63,7 @@
 };
 
 template <typename T>
-Pinned(T t) -> Pinned<std::remove_cvref_t<T>>;
+Pinned(T&& t) -> Pinned<std::remove_cvref_t<T>>;
 
 template <typename T>
 struct PinnedRef : std::reference_wrapper<T>
@@ -92,6 +92,11 @@
     }
 
     template <typename U>
+    constexpr PinnedRef(PinnedRef<U> u) noexcept : wrapper(u)
+    {
+    }
+
+    template <typename U>
     constexpr PinnedRef(const std::unique_ptr<U>& u) noexcept : wrapper(*u)
     {
     }
@@ -103,7 +108,7 @@
 };
 
 template <typename T>
-PinnedRef(T t) -> PinnedRef<std::remove_reference_t<T>>;
+PinnedRef(T&& t) -> PinnedRef<std::remove_reference_t<T>>;
 
 template <typename T>
 PinnedRef(Pinned<T>& t) -> PinnedRef<T>;
@@ -112,9 +117,15 @@
 PinnedRef(const Pinned<T>& t) -> PinnedRef<const T>;
 
 template <typename T, typename Deleter>
+PinnedRef(std::unique_ptr<T, Deleter>& t) -> PinnedRef<T>;
+
+template <typename T, typename Deleter>
 PinnedRef(const std::unique_ptr<T, Deleter>& t) -> PinnedRef<T>;
 
 template <typename T>
+PinnedRef(std::shared_ptr<T>& t) -> PinnedRef<T>;
+
+template <typename T>
 PinnedRef(const std::shared_ptr<T>& t) -> PinnedRef<T>;
 
 } // namespace stdplus
diff --git a/test/pinned.cpp b/test/pinned.cpp
index a46d949..96700c9 100644
--- a/test/pinned.cpp
+++ b/test/pinned.cpp
@@ -78,6 +78,8 @@
     Pinned<std::string> pstr("hi");
     EXPECT_EQ("hi", PinnedRef<std::string>(pstr).get());
     EXPECT_EQ("hi", PinnedRef<const std::string>(pstr).get());
+    EXPECT_EQ("hi", PinnedRef(pstr).get());
+
     const Pinned<std::string> cpstr("hi");
     // EXPECT_EQ("hi", PinnedRef<std::string>(cpstr).get());
     EXPECT_EQ("hi", PinnedRef<const std::string>(cpstr).get());
@@ -86,14 +88,18 @@
 
 TEST(PinnedRef, Fundamental)
 {
-    auto uptr = std::make_unique<int>(4);
-    EXPECT_EQ(4, PinnedRef<int>(uptr));
     Pinned<int> pi = 4;
     EXPECT_EQ(4, PinnedRef<int>(pi));
     EXPECT_EQ(4, PinnedRef<const int>(pi));
+    EXPECT_EQ(4, PinnedRef(pi));
+
+    const Pinned<int> cpi = 4;
+    // EXPECT_EQ(4, PinnedRef<int>(cpi));
+    EXPECT_EQ(4, PinnedRef<const int>(cpi));
+    EXPECT_EQ(4, PinnedRef(cpi));
 }
 
-TEST(PinnedREf, NoMove)
+TEST(PinnedRef, NoMove)
 {
     // int i;
     // PinnedRef<int> ri(i);
@@ -101,9 +107,19 @@
     // PinnedRef<NoMove1> rnm1(nm1);
     // NoMove2 nm2;
     // PinnedRef<NoMove2> rnm2(nm2);
+
     NoMove3 nm3;
     PinnedRef<NoMove3> rnm3(nm3);
+    PinnedRef<const NoMove3> rnm3c(nm3);
+    PinnedRef<const NoMove3> rnm3cr(rnm3);
     PinnedRef rnm3i(nm3);
+    PinnedRef rnm3ir(rnm3);
+    PinnedRef rnm3ic(rnm3c);
+
+    const NoMove3 cnm3;
+    // PinnedRef<NoMove3> crnm3(cnm3);
+    PinnedRef<const NoMove3> crnm3c(cnm3);
+    PinnedRef crnm3i(cnm3);
 }
 
 } // namespace stdplus