chromium/v8/include/v8-maybe.h

// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef INCLUDE_V8_MAYBE_H_
#define INCLUDE_V8_MAYBE_H_

#include <type_traits>
#include <utility>

#include "v8-internal.h"  // NOLINT(build/include_directory)
#include "v8config.h"     // NOLINT(build/include_directory)

namespace v8 {

namespace api_internal {
// Called when ToChecked is called on an empty Maybe.
V8_EXPORT void FromJustIsNothing();
}  // namespace api_internal

/**
 * A simple Maybe type, representing an object which may or may not have a
 * value, see https://hackage.haskell.org/package/base/docs/Data-Maybe.html.
 *
 * If an API method returns a Maybe<>, the API method can potentially fail
 * either because an exception is thrown, or because an exception is pending,
 * e.g. because a previous API call threw an exception that hasn't been caught
 * yet, or because a TerminateExecution exception was thrown. In that case, a
 * "Nothing" value is returned.
 */
template <class T>
class Maybe {};

template <class T>
inline Maybe<T> Nothing() {}

template <class T>
inline Maybe<T> Just(const T& t) {}

// Don't use forwarding references here but instead use two overloads.
// Forwarding references only work when type deduction takes place, which is not
// the case for callsites such as Just<Type>(t).
template <class T, std::enable_if_t<!std::is_lvalue_reference_v<T>>* = nullptr>
inline Maybe<T> Just(T&& t) {}

// A template specialization of Maybe<T> for the case of T = void.
template <>
class Maybe<void> {};

inline Maybe<void> JustVoid() {}

}  // namespace v8

#endif  // INCLUDE_V8_MAYBE_H_