Index: clangd/Function.h =================================================================== --- clangd/Function.h +++ clangd/Function.h @@ -138,6 +138,33 @@ } namespace detail { +/// Optional-like type that sets its value to llvm::None when it was moved +/// constructed from. +template class CleaningOptional { +public: + static_assert(std::is_same::type, T>::value, + "Implementation currently only supports decayed types"); + + CleaningOptional(T Value) : Value(std::move(Value)) {} + + CleaningOptional(CleaningOptional &&Other) : Value(std::move(Other.Value)) { + Other.Value = llvm::None; + } + + CleaningOptional &operator=(CleaningOptional &&Other) { + Value = std::move(Other.Value); + Other.Value = llvm::None; + } + + explicit operator bool() const { return static_cast(Value); } + + T &operator*() { return *Value; } + const T &operator*() const { return *Value; } + +private: + llvm::Optional Value; +}; + /// Runs provided callback in destructor. Use onScopeExit helper function to /// create this object. template struct ScopeExitGuard { @@ -159,7 +186,7 @@ ScopeExitGuard &operator=(ScopeExitGuard &&Other) = default; private: - llvm::Optional F; + CleaningOptional F; }; } // namespace detail