#ifndef C10_UTIL_OPTIONAL_H_ #define C10_UTIL_OPTIONAL_H_ #include #include // Macros.h is not needed, but it does namespace shenanigans that lots // of downstream code seems to rely on. Feel free to remove it and fix // up builds. namespace c10 { // NOLINTNEXTLINE(misc-unused-using-decls) using std::bad_optional_access; // NOLINTNEXTLINE(misc-unused-using-decls) using std::make_optional; // NOLINTNEXTLINE(misc-unused-using-decls) using std::nullopt; // NOLINTNEXTLINE(misc-unused-using-decls) using std::nullopt_t; // NOLINTNEXTLINE(misc-unused-using-decls) using std::optional; namespace detail_ { // the call to convert(b) has return type A and converts b to type A iff b // decltype(b) is implicitly convertible to A template constexpr U convert(U v) { return v; } } // namespace detail_ template constexpr T value_or_else(const optional& v, F&& func) { static_assert( std::is_convertible_v, T>, "func parameters must be a callable that returns a type convertible to the value stored in the optional"); return v.has_value() ? *v : detail_::convert(std::forward(func)()); } template constexpr T value_or_else(optional&& v, F&& func) { static_assert( std::is_convertible_v, T>, "func parameters must be a callable that returns a type convertible to the value stored in the optional"); return v.has_value() ? constexpr_move(std::move(v).contained_val()) : detail_::convert(std::forward(func)()); } } // namespace c10 #endif // C10_UTIL_OPTIONAL_H_