14#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_CONTEXT_H
15#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_CONTEXT_H
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/Support/Compiler.h"
40template <
class Type>
class Key {
42 static_assert(!std::is_reference<Type>::value,
43 "Reference arguments to Key<> are not allowed");
45 constexpr Key() =
default;
81 Context(std::shared_ptr<const Data> DataPtr);
99 for (
const Data *DataPtr = this->DataPtr.get(); DataPtr !=
nullptr;
100 DataPtr = DataPtr->Parent.get()) {
101 if (DataPtr->KeyPtr == &
Key)
102 return static_cast<const Type *
>(DataPtr->Value->getValuePtr());
111 assert(Val &&
"Key does not exist");
118 template <
class Type>
120 return Context(std::make_shared<Data>(
122 std::make_unique<TypedAnyStorage<std::decay_t<Type>>>(
123 std::move(
Value))}));
126 template <
class Type>
128 std::decay_t<Type>
Value) && {
129 return Context(std::make_shared<Data>(
130 Data{std::move(DataPtr), &
Key,
131 std::make_unique<TypedAnyStorage<std::decay_t<Type>>>(
132 std::move(
Value))}));
144 return std::move(*this).derive(Private, std::forward<Type>(
Value));
153 virtual ~AnyStorage() =
default;
154 virtual void *getValuePtr() = 0;
157 template <
class T>
class TypedAnyStorage :
public Context::AnyStorage {
158 static_assert(std::is_same<std::decay_t<T>, T>::value,
159 "Argument to TypedAnyStorage must be decayed");
162 TypedAnyStorage(T &&Value) : Value(std::move(Value)) {}
164 void *getValuePtr()
override {
return &Value; }
174 std::shared_ptr<const Data>
Parent;
176 std::unique_ptr<AnyStorage> Value;
179 std::shared_ptr<const Data> DataPtr;
202 template <
typename T>
204 : Restore(
Context::current().derive(
K, std::move(V))) {}
207 template <
typename T>
209 : Restore(
Context::current().derive(std::forward<T>(V))) {}
A context is an immutable container for per-request data that must be propagated through layers that ...
Context derive(const Key< Type > &Key, std::decay_t< Type > Value) const &
Derives a child context It is safe to move or destroy a parent context after calling derive().
Context()=default
Same as Context::empty(), please use Context::empty() instead.
Context derive(Type &&Value) const &
Derives a child context, using an anonymous key.
Context(Context &&)=default
Context clone() const
Clone this context object.
Context(Context const &)=delete
Copy operations for this class are deleted, use an explicit clone() method when you need a copy of th...
Context derive(Type &&Value) &&
Context & operator=(Context &&)=default
static const Context & current()
Returns the context for the current thread, creating it if needed.
static Context swapCurrent(Context Replacement)
const Type * get(const Key< Type > &Key) const
Get data stored for a typed Key.
Context & operator=(const Context &)=delete
const Type & getExisting(const Key< Type > &Key) const
A helper to get a reference to a Key that must exist in the map.
static Context empty()
Returns an empty root context that contains no data.
Context derive(const Key< Type > &Key, std::decay_t< Type > Value) &&
Values in a Context are indexed by typed keys.
Key & operator=(Key const &)=delete
Key & operator=(Key &&)=delete
WithContextValue extends Context::current() with a single value.
WithContextValue(const Key< T > &K, std::decay_t< T > V)
WithContext replaces Context::current() with a provided scope.
WithContext(const WithContext &)=delete
WithContext & operator=(const WithContext &)=delete
WithContext & operator=(WithContext &&)=delete
WithContext(WithContext &&)=delete
@ Type
An inlay hint that for a type annotation.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//