handle: Cleanup noexcept guarantees

Some of our noexcept guarantees were just wrong, and we weren't
providing it for the move constructor when possible.

Change-Id: I48452a4f07655d7cc479ca8ab8d744a59c119459
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/stdplus/handle/copyable.hpp b/src/stdplus/handle/copyable.hpp
index df383db..ef93263 100644
--- a/src/stdplus/handle/copyable.hpp
+++ b/src/stdplus/handle/copyable.hpp
@@ -1,6 +1,7 @@
 #pragma once
 #include <optional>
 #include <stdplus/handle/managed.hpp>
+#include <type_traits>
 #include <utility>
 
 namespace stdplus
@@ -40,13 +41,12 @@
          *  @param[in] maybeV - Maybe the object being managed
          */
         template <typename... Vs>
-        constexpr explicit Handle(std::optional<T>&& maybeV,
-                                  Vs&&... vs) noexcept :
+        constexpr explicit Handle(std::optional<T>&& maybeV, Vs&&... vs) :
             MHandle(std::move(maybeV), std::forward<Vs>(vs)...)
         {
         }
         template <typename... Vs>
-        constexpr explicit Handle(T&& maybeV, Vs&&... vs) noexcept :
+        constexpr explicit Handle(T&& maybeV, Vs&&... vs) :
             MHandle(std::move(maybeV), std::forward<Vs>(vs)...)
         {
         }
@@ -56,7 +56,9 @@
             reset(other.maybe_value());
         }
 
-        constexpr Handle(Handle&& other) noexcept : MHandle(std::move(other))
+        constexpr Handle(Handle&& other) noexcept(
+            std::is_nothrow_move_constructible_v<MHandle>) :
+            MHandle(std::move(other))
         {
         }
 
@@ -71,7 +73,7 @@
             return *this;
         }
 
-        constexpr Handle& operator=(Handle&& other) noexcept
+        constexpr Handle& operator=(Handle&& other)
         {
             MHandle::operator=(std::move(other));
             return *this;
diff --git a/src/stdplus/handle/managed.hpp b/src/stdplus/handle/managed.hpp
index de6a9f1..94c0bfa 100644
--- a/src/stdplus/handle/managed.hpp
+++ b/src/stdplus/handle/managed.hpp
@@ -2,6 +2,7 @@
 #include <cstdlib>
 #include <optional>
 #include <tuple>
+#include <type_traits>
 #include <utility>
 
 namespace stdplus
@@ -37,14 +38,12 @@
          *  @param[in] maybeV - Maybe the object being managed
          */
         template <typename... Vs>
-        constexpr explicit Handle(std::optional<T>&& maybeV,
-                                  Vs&&... vs) noexcept :
-            as(std::forward<Vs>(vs)...),
-            maybeT(std::move(maybeV))
+        constexpr explicit Handle(std::optional<T>&& maybeV, Vs&&... vs) :
+            as(std::forward<Vs>(vs)...), maybeT(std::move(maybeV))
         {
         }
         template <typename... Vs>
-        constexpr explicit Handle(T&& maybeV, Vs&&... vs) noexcept :
+        constexpr explicit Handle(T&& maybeV, Vs&&... vs) :
             as(std::forward<Vs>(vs)...), maybeT(std::move(maybeV))
         {
         }
@@ -52,8 +51,11 @@
         Handle(const Handle& other) = delete;
         Handle& operator=(const Handle& other) = delete;
 
-        constexpr Handle(Handle&& other) :
-            as(std::move(other.as)), maybeT(std::move(other.maybeT))
+        constexpr Handle(Handle&& other) noexcept(
+            std::is_nothrow_move_constructible_v<std::tuple<As...>>&&
+                std::is_nothrow_move_constructible_v<std::optional<T>>) :
+            as(std::move(other.as)),
+            maybeT(std::move(other.maybeT))
         {
             other.maybeT = std::nullopt;
         }