#pragma once #include #include #include namespace NYT::NGlobal { //////////////////////////////////////////////////////////////////////////////// namespace NDetail { class TGlobalVariablesRegistry; } // namespace NDetail //////////////////////////////////////////////////////////////////////////////// inline constexpr size_t GlobalVariableMaxByteSize = 32; using TErasedStorage = NYT::TErasedStorage; // NB(arkady-e1ppa): Accessor must ensure thread-safety on its own. using TAccessor = TErasedStorage(*)() noexcept; //////////////////////////////////////////////////////////////////////////////// // Usage: /* * // public.h file: * // NB: It's important to mark it inline for linker to deduplicate * // addresses accross different UT's. * inline constexpr NGlobal::TVariableTag MyGlobalVarTag = {}; * * * * // some_stuff.cpp file * * TErasedStorage GetMyVar() * { * // definition here * } * NGlobal::Variable MyGlobalVar{MyGlobalVarTag, &GetMyVar}; * * * * // other_stuff.cpp file * * * int ReadMyVar() * { * auto erased = NGlobal::GetErasedVariable(MyGlobalVarTag); * return erased->AsConcrete(); * } */ class TVariableTag { public: TVariableTag() = default; TVariableTag(const TVariableTag& other) = delete; TVariableTag& operator=(const TVariableTag& other) = delete; private: friend class ::NYT::NGlobal::NDetail::TGlobalVariablesRegistry; mutable std::atomic Initialized_ = false; mutable std::atomic Key_ = -1; }; //////////////////////////////////////////////////////////////////////////////// // Defined in impl.cpp. // |std::nullopt| iff global variable with a given tag is not present. std::optional GetErasedVariable(const TVariableTag& tag); //////////////////////////////////////////////////////////////////////////////// } // namespace NYT::NGlobal