109 using key_type =
typename owner_type::info_type::key_type;
111 static std::mutex mutex_;
112 static std::unordered_map<key_type, std::unique_ptr<owner_type>> instances;
114 using info_type =
typename owner_type::info_type;
116 static auto init(
const info_type&
info) -> owner_type& {
117 std::lock_guard<std::mutex> lock{mutex_};
119 const auto key =
info.key();
120 if (instances.contains(key)) {
121 throw std::runtime_error(std::format(
"duplicate multiton key {}", key));
124 auto instance = std::make_unique<owner_type>(
info);
125 auto [it, inserted] = instances.emplace(key, std::move(instance));
127 throw std::runtime_error(std::format(
"failed to register multiton key {}", key));
132 static void init(std::initializer_list<info_type> infos) {
133 init(std::span{infos.begin(), infos.size()});
136 static void init(std::span<const info_type> infos) {
137 std::lock_guard<std::mutex> lock{mutex_};
139 std::unordered_set<key_type> pending_keys;
140 for (
const auto&
info : infos) {
141 const auto key =
info.key();
142 if (instances.contains(key) || !pending_keys.emplace(key).second) {
143 throw std::runtime_error(std::format(
"duplicate multiton key {}", key));
147 std::vector<std::pair<key_type, std::unique_ptr<owner_type>>> pending;
148 pending.reserve(infos.size());
149 for (
const auto&
info : infos) {
150 pending.emplace_back(
info.key(), std::make_unique<owner_type>(
info));
153 for (
auto& [key, instance] : pending) {
154 instances.emplace(std::move(key), std::move(instance));
159 static bool contains(
const key_type& key){
160 std::lock_guard<std::mutex> lock{mutex_};
161 return instances.contains(key);
164 template<
typename Fn>
165 static void for_each(Fn&& fn) {
166 std::lock_guard<std::mutex> lock{mutex_};
167 for (
auto& [key, instance] : instances) {
168 std::invoke(fn, *instance);
173 static auto get(
const key_type& key) -> owner_type& {
174 std::lock_guard<std::mutex> lock { mutex_ };
175 auto it = instances.find(key);
176 if (it != instances.end()) {
180 throw std::runtime_error(std::format(
"uninitialized multiton {}",key));