]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson: let an errorator to be converted into more errorated one.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 9 Sep 2019 20:42:21 +0000 (22:42 +0200)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Wed, 20 Nov 2019 19:36:17 +0000 (20:36 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/crimson/common/errorator.h

index 155570e71882185fa690914fa82c9756f33176a6..410d69176d1e49718c966cc3a9008beeae42c056 100644 (file)
@@ -48,7 +48,6 @@ struct errorator {
   template <class... ValuesT>
   class future : private seastar::future<ValuesT...> {
     using base_t = seastar::future<ValuesT...>;
-    using errorator_type = ceph::errorator<WrappedAllowedErrorsT...>;
 
     // TODO: let `exception` use other type than `ct_error`.
     template <_impl::ct_error V>
@@ -174,12 +173,27 @@ struct errorator {
 
     using base_t::base_t;
 
+  public:
+    using errorator_type = ceph::errorator<WrappedAllowedErrorsT...>;
+
     [[gnu::always_inline]]
     future(base_t&& base)
       : base_t(std::move(base)) {
     }
 
-  public:
+    template <template <class...> class ErroratedFuture,
+              class = std::void_t<
+                typename ErroratedFuture<ValuesT...>::errorator_type>>
+    operator ErroratedFuture<ValuesT...> () && {
+      using dest_errorator_t = \
+        typename ErroratedFuture<ValuesT...>::errorator_type;
+      using this_errorator_t = errorator<WrappedAllowedErrorsT...>;
+
+      static_assert(!dest_errorator_t::template is_less_errorated_v<this_errorator_t>,
+                    "conversion is possible to more-or-eq errorated future!");
+      return std::move(*this).as_plain_future();
+    }
+
     // initialize future as failed without throwing. `make_exception_future()`
     // internally uses `std::make_exception_ptr()`. cppreference.com shouldn't
     // be misinterpreted when it says:
@@ -299,6 +313,28 @@ struct errorator {
   using extend = errorator<WrappedAllowedErrorsT...,
                            NewWrappedAllowedErrorsT...>;
 
+  // comparing errorators
+  template <class ErrorT>
+  struct is_carried {
+    static constexpr bool value = \
+      ((WrappedAllowedErrorsT::instance == ErrorT::instance) || ...);
+  };
+  template <class ErrorT>
+  static constexpr bool is_carried_v = is_carried<ErrorT>::value;
+
+  template <class>
+  struct is_less_errorated {
+    // NOP.
+  };
+  template <class... OtherWrappedAllowedErrorsT>
+  struct is_less_errorated<errorator<OtherWrappedAllowedErrorsT...>> {
+    static constexpr bool value = \
+      ((!is_carried_v<OtherWrappedAllowedErrorsT>) || ...);
+  };
+  template <class OtherErrorator>
+  static constexpr bool is_less_errorated_v = \
+    is_less_errorated<OtherErrorator>::value;
+
 private:
   struct ignore_marker_t{};