Forráskód Böngészése

refactor: add missing ctors and typedefs

Sam Jaffe 3 hónapja
szülő
commit
aad2a243b6
1 módosított fájl, 44 hozzáadás és 4 törlés
  1. 44 4
      include/jvalidate/compat/expected.h

+ 44 - 4
include/jvalidate/compat/expected.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <type_traits>
+
 #ifdef __cpp_lib_expected
 #if __cpp_lib_expected >= 202202L
 #include <expected>
@@ -77,6 +79,12 @@ private:
 };
 
 template <typename T, typename E> class expected {
+public:
+  using value_type = T;
+  using error_type = E;
+  using unexpected_type = unexpected<E>;
+  template <typename U> using rebind = expected<U, error_type>;
+
 public:
   constexpr expected() = default;
 
@@ -84,9 +92,9 @@ public:
   constexpr explicit(!std::is_convertible_v<const U &, T> && !std::is_convertible_v<const G &, E>)
       expected(expected<U, G> const & other) {
     if (other.has_value()) {
-      *this = *other;
+      value_.template emplace<0>(*other);
     } else {
-      *this = other.error();
+      value_.template emplace<1>(other.error());
     }
   }
 
@@ -94,9 +102,9 @@ public:
   constexpr explicit(!std::is_convertible_v<U, T> && !std::is_convertible_v<G, E>)
       expected(expected<U, G> && other) {
     if (other.has_value()) {
-      *this = *std::move(other);
+      value_.template emplace<0>(*std::move(other));
     } else {
-      *this = std::move(other).error();
+      value_.template emplace<1>(std::move(other).error());
     }
   }
 
@@ -112,6 +120,22 @@ public:
   constexpr explicit(!std::is_convertible_v<G, E>) expected(unexpected<G> && e)
       : value_(std::in_place_index<1>, std::move(e).error()) {}
 
+  template <typename... Args>
+  constexpr explicit expected(std::in_place_t, Args &&... args)
+      : value_(std::in_place_index<0>, std::forward<Args>(args)...) {}
+
+  template <typename U, typename... Args>
+  constexpr explicit expected(std::in_place_t, std::initializer_list<U> il, Args &&... args)
+      : value_(std::in_place_index<0>, il, std::forward<Args>(args)...) {}
+
+  template <typename... Args>
+  constexpr explicit expected(unexpect_t, Args &&... args)
+      : value_(std::in_place_index<1>, std::forward<Args>(args)...) {}
+
+  template <typename U, typename... Args>
+  constexpr explicit expected(unexpect_t, std::initializer_list<U> il, Args &&... args)
+      : value_(std::in_place_index<1>, il, std::forward<Args>(args)...) {}
+
   constexpr explicit operator bool() const noexcept { return has_value(); }
   constexpr bool has_value() const noexcept { return value_.index() == 0; }
 
@@ -152,6 +176,12 @@ private:
 };
 
 template <typename E> class expected<void, E> {
+public:
+  using value_type = void;
+  using error_type = E;
+  using unexpected_type = unexpected<E>;
+  template <typename U> using rebind = expected<U, error_type>;
+
 public:
   constexpr expected() = default;
 
@@ -178,6 +208,16 @@ public:
   constexpr explicit(!std::is_convertible_v<G, E>) expected(unexpected<G> && e)
       : value_(std::in_place_index<1>, std::move(e).error()) {}
 
+  constexpr explicit expected(std::in_place_t) {}
+
+  template <typename... Args>
+  constexpr explicit expected(unexpect_t, Args &&... args)
+      : value_(std::in_place, std::forward<Args>(args)...) {}
+
+  template <typename U, typename... Args>
+  constexpr explicit expected(unexpect_t, std::initializer_list<U> il, Args &&... args)
+      : value_(std::in_place, il, std::forward<Args>(args)...) {}
+
   constexpr explicit operator bool() const noexcept { return has_value(); }
   constexpr bool has_value() const noexcept { return not value_.has_value(); }