15 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_ 16 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_ 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/Support/Compiler.h" 21 #include <type_traits> 41 template <
class Type>
class Key {
43 static_assert(!std::is_reference<Type>::value,
44 "Reference arguments to Key<> are not allowed");
46 constexpr
Key() =
default;
75 static const Context ¤t();
82 Context(std::shared_ptr<const Data> DataPtr);
102 for (
const Data *DataPtr = this->DataPtr.get(); DataPtr !=
nullptr;
103 DataPtr = DataPtr->Parent.get()) {
104 if (DataPtr->KeyPtr == &
Key)
105 return static_cast<const Type *
>(DataPtr->Value->getValuePtr());
114 assert(Val &&
"Key does not exist");
121 template <
class Type>
123 typename std::decay<Type>::type
Value)
const & {
124 return Context(std::make_shared<Data>(Data{
126 llvm::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
127 std::move(
Value))}));
130 template <
class Type>
133 typename std::decay<Type>::type
Value) && {
134 return Context(std::make_shared<Data>(Data{
135 std::move(DataPtr), &
Key,
136 llvm::make_unique<TypedAnyStorage<typename std::decay<Type>::type>>(
137 std::move(
Value))}));
144 return derive(Private, std::forward<Type>(
Value));
149 return std::move(*this).derive(Private, std::forward<Type>(
Value));
158 virtual ~AnyStorage() =
default;
159 virtual void *getValuePtr() = 0;
162 template <
class T>
class TypedAnyStorage :
public Context::AnyStorage {
163 static_assert(std::is_same<
typename std::decay<T>::type, T>::value,
164 "Argument to TypedAnyStorage must be decayed");
169 void *getValuePtr()
override {
return &
Value; }
179 std::shared_ptr<const Data> Parent;
181 std::unique_ptr<AnyStorage>
Value;
184 std::shared_ptr<const Data> DataPtr;
207 template <
typename T>
209 : Restore(
Context::current().derive(K, std::move(V))) {}
212 template <
typename T>
214 : Restore(
Context::current().derive(std::forward<T>(V))) {}
223 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_ Key & operator=(Key const &)=delete
Values in a Context are indexed by typed keys.
Context derive(Type &&Value) &&
Context derive(const Key< Type > &Key, typename std::decay< Type >::type Value) &&
static Context swapCurrent(Context Replacement)
A context is an immutable container for per-request data that must be propagated through layers that ...
WithContext replaces Context::current() with a provided scope.
const Type & getExisting(const Key< Type > &Key) const
A helper to get a reference to a Key that must exist in the map.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Context derive(const Key< Type > &Key, typename std::decay< Type >::type Value) const &
Derives a child context It is safe to move or destroy a parent context after calling derive()...
WithContextValue(const Key< T > &K, typename std::decay< T >::type V)
WithContextValue extends Context::current() with a single value.
Context derive(Type &&Value) const &
Derives a child context, using an anonymous key.