================ @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines the ValueOrSentinel class, which is a type akin to a +/// std::optional, but uses a sentinel rather than an additional "valid" flag. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_VALUEORSENTINEL_H +#define LLVM_ADT_VALUEORSENTINEL_H + +#include <cassert> +#include <limits> +#include <optional> +#include <utility> + +namespace llvm { + +namespace detail { +/// An adjustment allows changing how the value is stored. An example use case +/// is to use zero as a sentinel value. +template <typename T> struct DefaultValueAdjustment { + constexpr static T toRepresentation(T Value) { return Value; } + constexpr static T fromRepresentation(T Value) { return Value; } +}; +} // namespace detail + +template <typename T, T Sentinel, + typename Adjust = detail::DefaultValueAdjustment<T>> +class ValueOrSentinel { +public: + constexpr ValueOrSentinel() = default; + constexpr ValueOrSentinel(std::nullopt_t) {}; + constexpr ValueOrSentinel(T Value) : Value(Adjust::toRepresentation(Value)) { + assert(this->Value != Sentinel && + "Value is sentinel (use default constructor)"); + }; + + constexpr ValueOrSentinel &operator=(T NewValue) { + Value = Adjust::toRepresentation(NewValue); + assert(Value != Sentinel && "NewValue is sentinel (use .clear())"); + return *this; + } + + constexpr bool operator==(ValueOrSentinel Other) const { + return Value == Other.Value; + } + constexpr bool operator!=(ValueOrSentinel Other) const { + return !(*this == Other); + } + + T value() const { + assert(has_value() && ".value() called on sentinel"); + return Adjust::fromRepresentation(Value); + } + T operator*() const { return value(); } + + explicit operator T() const { return value(); } + explicit constexpr operator bool() const { return has_value(); } + + constexpr void clear() { Value = Sentinel; } + constexpr bool has_value() const { return Value != Sentinel; } + + constexpr static ValueOrSentinel fromInternalRepresentation(unsigned Value) { ---------------- zwuis wrote:
`T value` https://github.com/llvm/llvm-project/pull/158120 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits