#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include "llvm/ADT/Twine.h" #include "llvm/Support/ManagedStatic.h" #include "revng/Support/Debug.h" template concept IsStaticallyRegisterable = requires(Type &&Value) { { Value.key() } -> std::convertible_to; }; template class RegisterManagedStaticImpl { private: struct TransparentKeyComparator { using is_transparent = std::true_type; template llvm::StringRef get(const Type &Value) const { return llvm::StringRef(Value); } llvm::StringRef get(const Registered &Value) const { return llvm::StringRef(Value.key()); } template bool operator()(const LHS &Left, const RHS &Right) const { return get(Left) < get(Right); } }; using RegistryType = std::set; static inline llvm::ManagedStatic Registry; public: template RegisterManagedStaticImpl(Types &&...Values) { auto [_, Success] = Registry->emplace(std::forward(Values)...); revng_assert(Success); } public: static const Registered *get(llvm::StringRef Name) { if (auto It = Registry->find(Name); It == Registry->end()) return nullptr; else return std::addressof(*It); } static const auto &values() { return std::as_const(*Registry); } };