Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- CustomizableOptional.h - Optional with custom storage ----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
  10. #define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
  11.  
  12. #include "llvm/ADT/Hashing.h"
  13. #include "llvm/Support/Compiler.h"
  14. #include "llvm/Support/type_traits.h"
  15. #include <cassert>
  16. #include <new>
  17. #include <optional>
  18. #include <utility>
  19.  
  20. namespace clang {
  21.  
  22. namespace optional_detail {
  23. template <typename> class OptionalStorage;
  24. } // namespace optional_detail
  25.  
  26. // Optional type which internal storage can be specialized by providing
  27. // OptionalStorage. The interface follows std::optional.
  28. template <typename T> class CustomizableOptional {
  29.   optional_detail::OptionalStorage<T> Storage;
  30.  
  31. public:
  32.   using value_type = T;
  33.  
  34.   constexpr CustomizableOptional() = default;
  35.   constexpr CustomizableOptional(std::nullopt_t) {}
  36.  
  37.   constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {}
  38.   constexpr CustomizableOptional(const CustomizableOptional &O) = default;
  39.  
  40.   constexpr CustomizableOptional(T &&y)
  41.       : Storage(std::in_place, std::move(y)) {}
  42.   constexpr CustomizableOptional(CustomizableOptional &&O) = default;
  43.  
  44.   template <typename... ArgTypes>
  45.   constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args)
  46.       : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {}
  47.  
  48.   // Allow conversion from std::optional<T>.
  49.   constexpr CustomizableOptional(const std::optional<T> &y)
  50.       : CustomizableOptional(y ? *y : CustomizableOptional()) {}
  51.   constexpr CustomizableOptional(std::optional<T> &&y)
  52.       : CustomizableOptional(y ? std::move(*y) : CustomizableOptional()) {}
  53.  
  54.   CustomizableOptional &operator=(T &&y) {
  55.     Storage = std::move(y);
  56.     return *this;
  57.   }
  58.   CustomizableOptional &operator=(CustomizableOptional &&O) = default;
  59.  
  60.   /// Create a new object by constructing it in place with the given arguments.
  61.   template <typename... ArgTypes> void emplace(ArgTypes &&...Args) {
  62.     Storage.emplace(std::forward<ArgTypes>(Args)...);
  63.   }
  64.  
  65.   CustomizableOptional &operator=(const T &y) {
  66.     Storage = y;
  67.     return *this;
  68.   }
  69.   CustomizableOptional &operator=(const CustomizableOptional &O) = default;
  70.  
  71.   void reset() { Storage.reset(); }
  72.  
  73.   LLVM_DEPRECATED("Use &*X instead.", "&*X")
  74.   constexpr const T *getPointer() const { return &Storage.value(); }
  75.   LLVM_DEPRECATED("Use &*X instead.", "&*X")
  76.   T *getPointer() { return &Storage.value(); }
  77.   LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
  78.   constexpr const T &value() const & { return Storage.value(); }
  79.   LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
  80.   T &value() & { return Storage.value(); }
  81.  
  82.   constexpr explicit operator bool() const { return has_value(); }
  83.   constexpr bool has_value() const { return Storage.has_value(); }
  84.   constexpr const T *operator->() const { return &Storage.value(); }
  85.   T *operator->() { return &Storage.value(); }
  86.   constexpr const T &operator*() const & { return Storage.value(); }
  87.   T &operator*() & { return Storage.value(); }
  88.  
  89.   template <typename U> constexpr T value_or(U &&alt) const & {
  90.     return has_value() ? operator*() : std::forward<U>(alt);
  91.   }
  92.  
  93.   LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
  94.   T &&value() && { return std::move(Storage.value()); }
  95.   T &&operator*() && { return std::move(Storage.value()); }
  96.  
  97.   template <typename U> T value_or(U &&alt) && {
  98.     return has_value() ? std::move(operator*()) : std::forward<U>(alt);
  99.   }
  100.  
  101.   // Allow conversion to std::optional<T>.
  102.   explicit operator std::optional<T> &() const & {
  103.     return *this ? **this : std::optional<T>();
  104.   }
  105.   explicit operator std::optional<T> &&() const && {
  106.     return *this ? std::move(**this) : std::optional<T>();
  107.   }
  108. };
  109.  
  110. template <typename T>
  111. CustomizableOptional(const T &) -> CustomizableOptional<T>;
  112.  
  113. template <class T>
  114. llvm::hash_code hash_value(const CustomizableOptional<T> &O) {
  115.   return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false);
  116. }
  117.  
  118. template <typename T, typename U>
  119. constexpr bool operator==(const CustomizableOptional<T> &X,
  120.                           const CustomizableOptional<U> &Y) {
  121.   if (X && Y)
  122.     return *X == *Y;
  123.   return X.has_value() == Y.has_value();
  124. }
  125.  
  126. template <typename T, typename U>
  127. constexpr bool operator!=(const CustomizableOptional<T> &X,
  128.                           const CustomizableOptional<U> &Y) {
  129.   return !(X == Y);
  130. }
  131.  
  132. template <typename T, typename U>
  133. constexpr bool operator<(const CustomizableOptional<T> &X,
  134.                          const CustomizableOptional<U> &Y) {
  135.   if (X && Y)
  136.     return *X < *Y;
  137.   return X.has_value() < Y.has_value();
  138. }
  139.  
  140. template <typename T, typename U>
  141. constexpr bool operator<=(const CustomizableOptional<T> &X,
  142.                           const CustomizableOptional<U> &Y) {
  143.   return !(Y < X);
  144. }
  145.  
  146. template <typename T, typename U>
  147. constexpr bool operator>(const CustomizableOptional<T> &X,
  148.                          const CustomizableOptional<U> &Y) {
  149.   return Y < X;
  150. }
  151.  
  152. template <typename T, typename U>
  153. constexpr bool operator>=(const CustomizableOptional<T> &X,
  154.                           const CustomizableOptional<U> &Y) {
  155.   return !(X < Y);
  156. }
  157.  
  158. template <typename T>
  159. constexpr bool operator==(const CustomizableOptional<T> &X, std::nullopt_t) {
  160.   return !X;
  161. }
  162.  
  163. template <typename T>
  164. constexpr bool operator==(std::nullopt_t, const CustomizableOptional<T> &X) {
  165.   return X == std::nullopt;
  166. }
  167.  
  168. template <typename T>
  169. constexpr bool operator!=(const CustomizableOptional<T> &X, std::nullopt_t) {
  170.   return !(X == std::nullopt);
  171. }
  172.  
  173. template <typename T>
  174. constexpr bool operator!=(std::nullopt_t, const CustomizableOptional<T> &X) {
  175.   return X != std::nullopt;
  176. }
  177.  
  178. template <typename T>
  179. constexpr bool operator<(const CustomizableOptional<T> &, std::nullopt_t) {
  180.   return false;
  181. }
  182.  
  183. template <typename T>
  184. constexpr bool operator<(std::nullopt_t, const CustomizableOptional<T> &X) {
  185.   return X.has_value();
  186. }
  187.  
  188. template <typename T>
  189. constexpr bool operator<=(const CustomizableOptional<T> &X, std::nullopt_t) {
  190.   return !(std::nullopt < X);
  191. }
  192.  
  193. template <typename T>
  194. constexpr bool operator<=(std::nullopt_t, const CustomizableOptional<T> &X) {
  195.   return !(X < std::nullopt);
  196. }
  197.  
  198. template <typename T>
  199. constexpr bool operator>(const CustomizableOptional<T> &X, std::nullopt_t) {
  200.   return std::nullopt < X;
  201. }
  202.  
  203. template <typename T>
  204. constexpr bool operator>(std::nullopt_t, const CustomizableOptional<T> &X) {
  205.   return X < std::nullopt;
  206. }
  207.  
  208. template <typename T>
  209. constexpr bool operator>=(const CustomizableOptional<T> &X, std::nullopt_t) {
  210.   return std::nullopt <= X;
  211. }
  212.  
  213. template <typename T>
  214. constexpr bool operator>=(std::nullopt_t, const CustomizableOptional<T> &X) {
  215.   return X <= std::nullopt;
  216. }
  217.  
  218. template <typename T>
  219. constexpr bool operator==(const CustomizableOptional<T> &X, const T &Y) {
  220.   return X && *X == Y;
  221. }
  222.  
  223. template <typename T>
  224. constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) {
  225.   return Y && X == *Y;
  226. }
  227.  
  228. template <typename T>
  229. constexpr bool operator!=(const CustomizableOptional<T> &X, const T &Y) {
  230.   return !(X == Y);
  231. }
  232.  
  233. template <typename T>
  234. constexpr bool operator!=(const T &X, const CustomizableOptional<T> &Y) {
  235.   return !(X == Y);
  236. }
  237.  
  238. template <typename T>
  239. constexpr bool operator<(const CustomizableOptional<T> &X, const T &Y) {
  240.   return !X || *X < Y;
  241. }
  242.  
  243. template <typename T>
  244. constexpr bool operator<(const T &X, const CustomizableOptional<T> &Y) {
  245.   return Y && X < *Y;
  246. }
  247.  
  248. template <typename T>
  249. constexpr bool operator<=(const CustomizableOptional<T> &X, const T &Y) {
  250.   return !(Y < X);
  251. }
  252.  
  253. template <typename T>
  254. constexpr bool operator<=(const T &X, const CustomizableOptional<T> &Y) {
  255.   return !(Y < X);
  256. }
  257.  
  258. template <typename T>
  259. constexpr bool operator>(const CustomizableOptional<T> &X, const T &Y) {
  260.   return Y < X;
  261. }
  262.  
  263. template <typename T>
  264. constexpr bool operator>(const T &X, const CustomizableOptional<T> &Y) {
  265.   return Y < X;
  266. }
  267.  
  268. template <typename T>
  269. constexpr bool operator>=(const CustomizableOptional<T> &X, const T &Y) {
  270.   return !(X < Y);
  271. }
  272.  
  273. template <typename T>
  274. constexpr bool operator>=(const T &X, const CustomizableOptional<T> &Y) {
  275.   return !(X < Y);
  276. }
  277.  
  278. } // namespace clang
  279.  
  280. #endif // CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
  281.