optional.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include <optional>
  9. namespace base {
  10. template <typename Type>
  11. struct optional_wrap_once {
  12. using type = std::optional<Type>;
  13. };
  14. template <typename Type>
  15. struct optional_wrap_once<std::optional<Type>> {
  16. using type = std::optional<Type>;
  17. };
  18. template <typename Type>
  19. using optional_wrap_once_t = typename optional_wrap_once<std::decay_t<Type>>::type;
  20. template <typename Type>
  21. struct optional_chain_result {
  22. using type = optional_wrap_once_t<Type>;
  23. };
  24. template <>
  25. struct optional_chain_result<void> {
  26. using type = bool;
  27. };
  28. template <typename Type>
  29. using optional_chain_result_t = typename optional_chain_result<Type>::type;
  30. template <typename Type>
  31. optional_wrap_once_t<Type> make_optional(Type &&value) {
  32. return optional_wrap_once_t<Type> { std::forward<Type>(value) };
  33. }
  34. } // namespace base
  35. template <typename Type, typename Method>
  36. inline auto operator|(const std::optional<Type> &value, Method method)
  37. -> base::optional_chain_result_t<decltype(method(*value))> {
  38. if constexpr (std::is_same_v<decltype(method(*value)), void>) {
  39. return value ? (method(*value), true) : false;
  40. } else {
  41. return value
  42. ? base::optional_chain_result_t<decltype(method(*value))>(
  43. method(*value))
  44. : std::nullopt;
  45. }
  46. }