[libc-commits] [libc] 1ab42ba - Revert "[libc] Extend optional to support non trivially destructible objects"

Mikhail R. Gadelha via libc-commits libc-commits at lists.llvm.org
Mon Aug 14 15:44:14 PDT 2023


Author: Mikhail R. Gadelha
Date: 2023-08-14T19:43:56-03:00
New Revision: 1ab42bac9170fcd10c9a90a64285ecbd761f122b

URL: https://github.com/llvm/llvm-project/commit/1ab42bac9170fcd10c9a90a64285ecbd761f122b
DIFF: https://github.com/llvm/llvm-project/commit/1ab42bac9170fcd10c9a90a64285ecbd761f122b.diff

LOG: Revert "[libc] Extend optional to support non trivially destructible objects"

This reverts commit 7d06f59b60e6eaebd125dad351a20108f057940b.

This patch broke libc compilation with gcc as it doesn't seem to have
__is_trivially_destructible(T).

Added: 
    

Modified: 
    libc/src/__support/CPP/optional.h
    libc/src/__support/CPP/type_traits.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/CPP/optional.h b/libc/src/__support/CPP/optional.h
index bbf9188087c1b3..a1eca2c860697a 100644
--- a/libc/src/__support/CPP/optional.h
+++ b/libc/src/__support/CPP/optional.h
@@ -36,93 +36,85 @@ LIBC_INLINE_VAR constexpr in_place_t in_place{};
 // several assumptions that the underlying type is trivially constructable,
 // copyable, or movable.
 template <typename T> class optional {
-  template <typename U, bool = !is_trivially_destructible<U>::value>
-  struct OptionalStorage {
+  template <typename U> class OptionalStorage {
     union {
       char empty;
       U stored_value;
     };
+    bool in_use;
 
-    LIBC_INLINE ~OptionalStorage() { stored_value.~U(); }
-    LIBC_INLINE constexpr OptionalStorage() : empty() {}
+  public:
+    LIBC_INLINE ~OptionalStorage() { reset(); }
+
+    LIBC_INLINE constexpr OptionalStorage() : empty(), in_use(false) {}
 
     template <typename... Args>
     LIBC_INLINE constexpr explicit OptionalStorage(in_place_t, Args &&...args)
-        : stored_value(forward<Args>(args)...) {}
-  };
+        : stored_value(forward<Args>(args)...), in_use(true) {}
 
-  template <typename U> struct OptionalStorage<U, false> {
-    union {
-      char empty;
-      U stored_value;
-    };
+    LIBC_INLINE void reset() {
+      if (in_use)
+        stored_value.~U();
+      in_use = false;
+    }
 
-    // The only 
diff erence is that this class doesn't have a destructor.
-    LIBC_INLINE constexpr OptionalStorage() : empty() {}
+    LIBC_INLINE constexpr bool has_value() const { return in_use; }
 
-    template <typename... Args>
-    LIBC_INLINE constexpr explicit OptionalStorage(in_place_t, Args &&...args)
-        : stored_value(forward<Args>(args)...) {}
+    LIBC_INLINE U &value() & { return stored_value; }
+    LIBC_INLINE constexpr U const &value() const & { return stored_value; }
+    LIBC_INLINE U &&value() && { return move(stored_value); }
   };
 
   OptionalStorage<T> storage;
-  bool in_use = false;
 
 public:
   LIBC_INLINE constexpr optional() = default;
   LIBC_INLINE constexpr optional(nullopt_t) {}
 
-  LIBC_INLINE constexpr optional(const T &t)
-      : storage(in_place, t), in_use(true) {}
+  LIBC_INLINE constexpr optional(const T &t) : storage(in_place, t) {}
   LIBC_INLINE constexpr optional(const optional &) = default;
 
-  LIBC_INLINE constexpr optional(T &&t)
-      : storage(in_place, move(t)), in_use(true) {}
+  LIBC_INLINE constexpr optional(T &&t) : storage(in_place, move(t)) {}
   LIBC_INLINE constexpr optional(optional &&O) = default;
 
   template <typename... ArgTypes>
   LIBC_INLINE constexpr optional(in_place_t, ArgTypes &&...Args)
-      : storage(in_place, forward<ArgTypes>(Args)...), in_use(true) {}
+      : storage(in_place, forward<ArgTypes>(Args)...) {}
 
-  LIBC_INLINE constexpr optional &operator=(T &&t) {
+  LIBC_INLINE optional &operator=(T &&t) {
     storage = move(t);
     return *this;
   }
-  LIBC_INLINE constexpr optional &operator=(optional &&) = default;
+  LIBC_INLINE optional &operator=(optional &&) = default;
+
+  LIBC_INLINE static constexpr optional create(const T *t) {
+    return t ? optional(*t) : optional();
+  }
 
-  LIBC_INLINE constexpr optional &operator=(const T &t) {
+  LIBC_INLINE optional &operator=(const T &t) {
     storage = t;
     return *this;
   }
-  LIBC_INLINE constexpr optional &operator=(const optional &) = default;
+  LIBC_INLINE optional &operator=(const optional &) = default;
 
-  LIBC_INLINE constexpr void reset() {
-    if (in_use)
-      storage.~OptionalStorage();
-    in_use = false;
-  }
+  LIBC_INLINE void reset() { storage.reset(); }
 
-  LIBC_INLINE constexpr const T &value() const & {
-    return storage.stored_value;
-  }
+  LIBC_INLINE constexpr const T &value() const & { return storage.value(); }
+  LIBC_INLINE T &value() & { return storage.value(); }
 
-  LIBC_INLINE constexpr T &value() & { return storage.stored_value; }
+  LIBC_INLINE constexpr explicit operator bool() const { return has_value(); }
+  LIBC_INLINE constexpr bool has_value() const { return storage.has_value(); }
+  LIBC_INLINE constexpr const T *operator->() const { return &storage.value(); }
+  LIBC_INLINE T *operator->() { return &storage.value(); }
+  LIBC_INLINE constexpr const T &operator*() const & { return value(); }
+  LIBC_INLINE T &operator*() & { return value(); }
 
-  LIBC_INLINE constexpr explicit operator bool() const { return in_use; }
-  LIBC_INLINE constexpr bool has_value() const { return in_use; }
-  LIBC_INLINE constexpr const T *operator->() const {
-    return &storage.stored_value;
-  }
-  LIBC_INLINE constexpr T *operator->() { return &storage.stored_value; }
-  LIBC_INLINE constexpr const T &operator*() const & {
-    return storage.stored_value;
+  template <typename U> LIBC_INLINE constexpr T value_or(U &&value) const & {
+    return has_value() ? value() : forward<U>(value);
   }
-  LIBC_INLINE constexpr T &operator*() & { return storage.stored_value; }
 
-  LIBC_INLINE constexpr T &&value() && { return move(storage.stored_value); }
-  LIBC_INLINE constexpr T &&operator*() && {
-    return move(storage.stored_value);
-  }
+  LIBC_INLINE T &&value() && { return move(storage.value()); }
+  LIBC_INLINE T &&operator*() && { return move(storage.value()); }
 };
 
 } // namespace cpp

diff  --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h
index 826a8e35f28c8b..316b84c5bbf095 100644
--- a/libc/src/__support/CPP/type_traits.h
+++ b/libc/src/__support/CPP/type_traits.h
@@ -214,10 +214,6 @@ constexpr bool
                      details::void_t<decltype(details::convertible_to_helper<T>(
                          declval<F>()))>> = true;
 
-template <typename T>
-struct is_trivially_destructible
-    : public integral_constant<bool, __is_trivially_destructible(T)> {};
-
 } // namespace cpp
 } // namespace __llvm_libc
 


        


More information about the libc-commits mailing list