Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49bf32d3 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ia03f7e3d,Ief31910b into main

* changes:
  FTL: Add Optional<T>::ok_or and FTL_TRY
  FTL: Touch up Concat
parents 58558d18 189d1825
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -57,7 +57,7 @@ struct Concat<N, T, Ts...> : Concat<N + details::StaticString<T>::N, Ts...> {
template <std::size_t N>
template <std::size_t N>
struct Concat<N> {
struct Concat<N> {
  static constexpr std::size_t max_size() { return N; }
  static constexpr std::size_t max_size() { return N; }
  constexpr std::size_t size() const { return end_ - buffer_; }
  constexpr std::size_t size() const { return static_cast<std::size_t>(end_ - buffer_); }


  constexpr const char* c_str() const { return buffer_; }
  constexpr const char* c_str() const { return buffer_; }


@@ -68,6 +68,8 @@ struct Concat<N> {


 protected:
 protected:
  constexpr Concat() : end_(buffer_) {}
  constexpr Concat() : end_(buffer_) {}
  constexpr Concat(const Concat&) = delete;

  constexpr void append() { *end_ = '\0'; }
  constexpr void append() { *end_ = '\0'; }


  char buffer_[N + 1];
  char buffer_[N + 1];
+48 −0
Original line number Original line Diff line number Diff line
@@ -18,9 +18,57 @@


#include <android-base/expected.h>
#include <android-base/expected.h>
#include <ftl/optional.h>
#include <ftl/optional.h>
#include <ftl/unit.h>


#include <utility>
#include <utility>


// Given an expression `expr` that evaluates to an ftl::Expected<T, E> result (R for short), FTL_TRY
// unwraps T out of R, or bails out of the enclosing function F if R has an error E. The return type
// of F must be R, since FTL_TRY propagates R in the error case. As a special case, ftl::Unit may be
// used as the error E to allow FTL_TRY expressions when F returns `void`.
//
// The non-standard syntax requires `-Wno-gnu-statement-expression-from-macro-expansion` to compile.
// The UnitToVoid conversion allows the macro to be used for early exit from a function that returns
// `void`.
//
// Example usage:
//
//   using StringExp = ftl::Expected<std::string, std::errc>;
//
//   StringExp repeat(StringExp exp) {
//     const std::string str = FTL_TRY(exp);
//     return StringExp(str + str);
//   }
//
//   assert(StringExp("haha"s) == repeat(StringExp("ha"s)));
//   assert(repeat(ftl::Unexpected(std::errc::bad_message)).has_error([](std::errc e) {
//     return e == std::errc::bad_message;
//   }));
//
//
// FTL_TRY may be used in void-returning functions by using ftl::Unit as the error type:
//
//   void uppercase(char& c, ftl::Optional<char> opt) {
//     c = std::toupper(FTL_TRY(std::move(opt).ok_or(ftl::Unit())));
//   }
//
//   char c = '?';
//   uppercase(c, std::nullopt);
//   assert(c == '?');
//
//   uppercase(c, 'a');
//   assert(c == 'A');
//
#define FTL_TRY(expr)                                                     \
  ({                                                                      \
    auto exp_ = (expr);                                                   \
    if (!exp_.has_value()) {                                              \
      using E = decltype(exp_)::error_type;                               \
      return android::ftl::details::UnitToVoid<E>::from(std::move(exp_)); \
    }                                                                     \
    exp_.value();                                                         \
  })

namespace android::ftl {
namespace android::ftl {


// Superset of base::expected<T, E> with monadic operations.
// Superset of base::expected<T, E> with monadic operations.
+9 −1
Original line number Original line Diff line number Diff line
@@ -20,13 +20,14 @@
#include <optional>
#include <optional>
#include <utility>
#include <utility>


#include <android-base/expected.h>
#include <ftl/details/optional.h>
#include <ftl/details/optional.h>


namespace android::ftl {
namespace android::ftl {


// Superset of std::optional<T> with monadic operations, as proposed in https://wg21.link/P0798R8.
// Superset of std::optional<T> with monadic operations, as proposed in https://wg21.link/P0798R8.
//
//
// TODO: Remove in C++23.
// TODO: Remove standard APIs in C++23.
//
//
template <typename T>
template <typename T>
struct Optional final : std::optional<T> {
struct Optional final : std::optional<T> {
@@ -109,6 +110,13 @@ struct Optional final : std::optional<T> {
    return std::forward<F>(f)();
    return std::forward<F>(f)();
  }
  }


  // Maps this Optional<T> to expected<T, E> where nullopt becomes E.
  template <typename E>
  constexpr auto ok_or(E&& e) && -> base::expected<T, E> {
    if (has_value()) return std::move(value());
    return base::unexpected(std::forward<E>(e));
  }

  // Delete new for this class. Its base doesn't have a virtual destructor, and
  // Delete new for this class. Its base doesn't have a virtual destructor, and
  // if it got deleted via base class pointer, it would cause undefined
  // if it got deleted via base class pointer, it would cause undefined
  // behavior. There's not a good reason to allocate this object on the heap
  // behavior. There's not a good reason to allocate this object on the heap
+18 −0
Original line number Original line Diff line number Diff line
@@ -58,4 +58,22 @@ constexpr auto unit_fn(F&& f) -> UnitFn<std::decay_t<F>> {
  return {std::forward<F>(f)};
  return {std::forward<F>(f)};
}
}


namespace details {

// Identity function for all T except Unit, which maps to void.
template <typename T>
struct UnitToVoid {
  template <typename U>
  static auto from(U&& value) {
    return value;
  }
};

template <>
struct UnitToVoid<Unit> {
  template <typename U>
  static void from(U&&) {}
};

}  // namespace details
}  // namespace android::ftl
}  // namespace android::ftl
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,5 +41,6 @@ cc_test {
        "-Wextra",
        "-Wextra",
        "-Wpedantic",
        "-Wpedantic",
        "-Wthread-safety",
        "-Wthread-safety",
        "-Wno-gnu-statement-expression-from-macro-expansion",
    ],
    ],
}
}
Loading