1*bb722a7dSDimitry Andric //===-- Holds an expected or unexpected value -------------------*- C++ -*-===// 2*bb722a7dSDimitry Andric // 3*bb722a7dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bb722a7dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bb722a7dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bb722a7dSDimitry Andric // 7*bb722a7dSDimitry Andric //===----------------------------------------------------------------------===// 8*bb722a7dSDimitry Andric 9*bb722a7dSDimitry Andric #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_EXPECTED_H 10*bb722a7dSDimitry Andric #define LLVM_LIBC_SRC___SUPPORT_CPP_EXPECTED_H 11*bb722a7dSDimitry Andric 12*bb722a7dSDimitry Andric #include "src/__support/macros/attributes.h" 13*bb722a7dSDimitry Andric #include "src/__support/macros/config.h" 14*bb722a7dSDimitry Andric 15*bb722a7dSDimitry Andric namespace LIBC_NAMESPACE_DECL { 16*bb722a7dSDimitry Andric namespace cpp { 17*bb722a7dSDimitry Andric 18*bb722a7dSDimitry Andric // This is used to hold an unexpected value so that a different constructor is 19*bb722a7dSDimitry Andric // selected. 20*bb722a7dSDimitry Andric template <class T> class unexpected { 21*bb722a7dSDimitry Andric T value; 22*bb722a7dSDimitry Andric 23*bb722a7dSDimitry Andric public: unexpected(T value)24*bb722a7dSDimitry Andric LIBC_INLINE constexpr explicit unexpected(T value) : value(value) {} error()25*bb722a7dSDimitry Andric LIBC_INLINE constexpr T error() { return value; } 26*bb722a7dSDimitry Andric }; 27*bb722a7dSDimitry Andric 28*bb722a7dSDimitry Andric template <class T> explicit unexpected(T) -> unexpected<T>; 29*bb722a7dSDimitry Andric 30*bb722a7dSDimitry Andric template <class T, class E> class expected { 31*bb722a7dSDimitry Andric union { 32*bb722a7dSDimitry Andric T exp; 33*bb722a7dSDimitry Andric E unexp; 34*bb722a7dSDimitry Andric }; 35*bb722a7dSDimitry Andric bool is_expected; 36*bb722a7dSDimitry Andric 37*bb722a7dSDimitry Andric public: expected(T exp)38*bb722a7dSDimitry Andric LIBC_INLINE constexpr expected(T exp) : exp(exp), is_expected(true) {} expected(unexpected<E> unexp)39*bb722a7dSDimitry Andric LIBC_INLINE constexpr expected(unexpected<E> unexp) 40*bb722a7dSDimitry Andric : unexp(unexp.error()), is_expected(false) {} 41*bb722a7dSDimitry Andric has_value()42*bb722a7dSDimitry Andric LIBC_INLINE constexpr bool has_value() const { return is_expected; } 43*bb722a7dSDimitry Andric value()44*bb722a7dSDimitry Andric LIBC_INLINE constexpr T &value() { return exp; } error()45*bb722a7dSDimitry Andric LIBC_INLINE constexpr E &error() { return unexp; } value()46*bb722a7dSDimitry Andric LIBC_INLINE constexpr const T &value() const { return exp; } error()47*bb722a7dSDimitry Andric LIBC_INLINE constexpr const E &error() const { return unexp; } 48*bb722a7dSDimitry Andric 49*bb722a7dSDimitry Andric LIBC_INLINE constexpr operator bool() const { return is_expected; } 50*bb722a7dSDimitry Andric 51*bb722a7dSDimitry Andric LIBC_INLINE constexpr T &operator*() { return exp; } 52*bb722a7dSDimitry Andric LIBC_INLINE constexpr const T &operator*() const { return exp; } 53*bb722a7dSDimitry Andric LIBC_INLINE constexpr T *operator->() { return &exp; } 54*bb722a7dSDimitry Andric LIBC_INLINE constexpr const T *operator->() const { return &exp; } 55*bb722a7dSDimitry Andric }; 56*bb722a7dSDimitry Andric 57*bb722a7dSDimitry Andric } // namespace cpp 58*bb722a7dSDimitry Andric } // namespace LIBC_NAMESPACE_DECL 59*bb722a7dSDimitry Andric 60*bb722a7dSDimitry Andric #endif // LLVM_LIBC_SRC___SUPPORT_CPP_EXPECTED_H 61