8#include <userver/compiler/impl/constexpr.hpp> 
    9#include <userver/compiler/impl/lifetime.hpp> 
   10#include <userver/compiler/impl/tls.hpp> 
   12#if __cplusplus 
>= 202002L 
&& 
   13    (__clang_major__ 
>= 13 
|| !defined(__clang__
) && __GNUC__ 
>= 9
) 
   15#define USERVER_IMPL_UNEVALUATED_LAMBDAS 
   18USERVER_NAMESPACE_BEGIN
 
   24bool AreCoroutineSwitchesAllowed() 
noexcept;
 
   26void IncrementLocalCoroutineSwitchBans() 
noexcept;
 
   28void DecrementLocalCoroutineSwitchBans() 
noexcept;
 
   30#ifdef USERVER_IMPL_UNEVALUATED_LAMBDAS 
   31template <
typename T, 
typename Factory = 
decltype([] { 
return T{}; })>
 
   32using UniqueDefaultFactory = Factory;
 
   35struct UniqueDefaultFactory final {
 
   36  static_assert(!
sizeof(T),
 
   37                "Defaulted syntax for compiler::ThreadLocal is unavailable on " 
   38                "your compiler. Please use the lambda-factory syntax, see the " 
   39                "documentation for compiler::ThreadLocal.");
 
   48template <
typename VariableType>
 
   49class ThreadLocalScope final {
 
   51  ThreadLocalScope(ThreadLocalScope&&) = 
delete;
 
   52  ThreadLocalScope& operator=(ThreadLocalScope&&) = 
delete;
 
   62  explicit ThreadLocalScope(VariableType& variable) 
noexcept;
 
   65  VariableType& operator*() && 
noexcept = 
delete;
 
   68  VariableType* operator->() && 
noexcept = 
delete;
 
   72  static_assert(!std::is_reference_v<VariableType>);
 
   73  static_assert(!std::is_const_v<VariableType>);
 
   75  VariableType& variable_;
 
  136template <
typename VariableType,
 
  137          typename Factory = impl::UniqueDefaultFactory<VariableType>>
 
  138class ThreadLocal final {
 
  139  static_assert(std::is_empty_v<Factory>);
 
  141      std::is_same_v<VariableType, std::invoke_result_t<
const Factory&>>);
 
  147      : factory_(factory) {}
 
  149  ThreadLocalScope<VariableType> Use() {
 
  150    return ThreadLocalScope<VariableType>(impl::ThreadLocal(factory_));
 
  161template <
typename Factory>
 
  162ThreadLocal(Factory factory)
 
  163    -> ThreadLocal<std::invoke_result_t<
const Factory&>, Factory>;
 
  165template <
typename VariableType>
 
  166ThreadLocalScope<VariableType>::ThreadLocalScope(
 
  167    VariableType& variable) 
noexcept 
  168    : variable_(variable) {
 
  170  impl::IncrementLocalCoroutineSwitchBans();
 
  174template <
typename VariableType>
 
  175ThreadLocalScope<VariableType>::~ThreadLocalScope() {
 
  177  impl::DecrementLocalCoroutineSwitchBans();
 
  181template <
typename VariableType>
 
  182VariableType& ThreadLocalScope<VariableType>::
operator*() & 
noexcept   
  187template <
typename VariableType>
 
  188VariableType* ThreadLocalScope<VariableType>::
operator->() & 
noexcept