1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/utils/common.h"
10 
11 #include <limits>
12 #include <map>
13 #include <tuple>
14 
15 namespace td {
16 
17 template <class ValueT>
18 class Enumerator {
19  public:
20   using Key = int32;
21 
add(ValueT v)22   Key add(ValueT v) {
23     CHECK(arr_.size() < static_cast<size_t>(std::numeric_limits<int32>::max() - 1));
24     auto next_id = static_cast<int32>(arr_.size() + 1);
25     bool was_inserted;
26     decltype(map_.begin()) it;
27     std::tie(it, was_inserted) = map_.emplace(std::move(v), next_id);
28     if (was_inserted) {
29       arr_.push_back(&it->first);
30     }
31     return it->second;
32   }
33 
get(Key key)34   const ValueT &get(Key key) const {
35     auto pos = static_cast<size_t>(key - 1);
36     CHECK(pos < arr_.size());
37     return *arr_[pos];
38   }
39 
40  private:
41   std::map<ValueT, int32> map_;
42   std::vector<const ValueT *> arr_;
43 };
44 
45 }  // namespace td
46