3 #include <c10/util/Exception.h> 7 #include <initializer_list> 9 #include <unordered_map> 15 template <
typename Key,
typename Value>
24 using Iterator =
typename std::vector<Item>::iterator;
25 using ConstIterator =
typename std::vector<Item>::const_iterator;
49 OrderedDict(std::initializer_list<Item> initializer_list);
94 Value*
find(
const Key& key) noexcept;
98 const Value*
find(
const Key& key)
const noexcept;
101 bool contains(
const Key& key)
const noexcept;
111 ConstIterator
begin()
const;
117 ConstIterator
end()
const;
122 size_t size()
const noexcept;
129 void reserve(
size_t requested_capacity);
136 template <
typename K,
typename V>
137 Value&
insert(K&& key, V&& value);
142 Value&
insert(Key key, Value&& value);
158 const std::vector<Item>&
items()
const noexcept;
162 ::std::vector<Key>
keys()
const;
166 ::std::vector<Value>
values()
const;
170 ::std::vector<std::pair<Key, Value>>
pairs()
const;
174 ::std::unordered_map<Key, size_t> index_;
177 ::std::vector<Item> items_;
180 ::std::string key_description_{
"Key"};
185 template <
typename Key,
typename Value>
189 Item(Key key, Value value) : pair_(
std::move(key),
std::move(value)) {}
212 const Key&
key() const noexcept {
222 const Value&
value() const noexcept {
227 const std::pair<const Key, Value>&
pair() const noexcept {
234 ::std::pair<const Key, Value> pair_;
239 template <
typename Key,
typename Value>
241 : key_description_(
std::move(key_description)) {}
243 template <
typename Key,
typename Value>
245 : index_(other.index_), key_description_(other.key_description_) {
248 for (
const auto& item : other.items_) {
249 items_.push_back(item);
253 template <
typename Key,
typename Value>
256 index_ = other.index_;
258 for (
auto& item : other.items_) {
259 items_.push_back(item);
261 key_description_ = other.key_description_;
265 template <
typename Key,
typename Value>
267 std::initializer_list<Item> initializer_list)
269 items_.reserve(initializer_list.size());
270 for (
auto& item : initializer_list) {
272 items_.emplace_back(item.key(), std::move(item.value()));
273 index_.emplace(std::move(item.key()),
size() - 1);
277 template <
typename Key,
typename Value>
279 return items_.begin();
282 template <
typename Key,
typename Value>
285 return items_.begin();
288 template <
typename Key,
typename Value>
293 template <
typename Key,
typename Value>
299 template <
typename Key,
typename Value>
301 AT_CHECK(!items_.empty(),
"Called front() on an empty OrderedDict");
302 return items_.front();
305 template <
typename Key,
typename Value>
308 AT_CHECK(!items_.empty(),
"Called front() on an empty OrderedDict");
309 return items_.front();
312 template <
typename Key,
typename Value>
314 AT_CHECK(!items_.empty(),
"Called back() on an empty OrderedDict");
315 return items_.back();
318 template <
typename Key,
typename Value>
321 AT_CHECK(!items_.empty(),
"Called back() on an empty OrderedDict");
322 return items_.back();
325 template <
typename Key,
typename Value>
328 AT_CHECK(index < items_.size(),
"Index ", index,
" is out of bounds");
329 return items_[index];
332 template <
typename Key,
typename Value>
335 AT_CHECK(index < items_.size(),
"Index ", index,
" is out of bounds");
336 return items_[index];
339 template <
typename Key,
typename Value>
341 if (
auto* value =
find(key)) {
344 AT_ERROR(key_description_,
" '", key,
"' is not defined");
347 template <
typename Key,
typename Value>
349 if (
auto* value =
find(key)) {
352 AT_ERROR(key_description_,
" '", key,
"' is not defined");
355 template <
typename Key,
typename Value>
356 template <
typename K,
typename V>
359 index_.count(key) == 0, key_description_,
" '", key,
"' already defined");
361 items_.emplace_back(key, std::forward<V>(value));
362 index_.emplace(std::forward<K>(key),
size() - 1);
363 return items_.back().value();
366 template <
typename Key,
typename Value>
368 return insert<Key, Value>(std::move(key), std::move(value));
371 template <
typename Key,
typename Value>
374 for (
auto& item : other) {
376 insert(std::move(item.key()), std::move(item.value()));
380 template <
typename Key,
typename Value>
383 for (
auto& item : other) {
385 insert(item.key(), item.value());
389 template <
typename Key,
typename Value>
391 auto iterator = index_.find(key);
392 if (iterator == index_.end()) {
395 return &items_[iterator->second].value();
398 template <
typename Key,
typename Value>
400 auto iterator = index_.find(key);
401 if (iterator == index_.end()) {
404 return &items_[iterator->second].value();
407 template <
typename Key,
typename Value>
409 return find(key) !=
nullptr;
412 template <
typename Key,
typename Value>
418 template <
typename Key,
typename Value>
420 return items_.size();
423 template <
typename Key,
typename Value>
425 return items_.empty();
428 template <
typename Key,
typename Value>
430 return key_description_;
433 template <
typename Key,
typename Value>
434 const std::vector<typename OrderedDict<Key, Value>::Item>&
OrderedDict<
440 template <
typename Key,
typename Value>
442 std::vector<Key>
keys;
443 keys.reserve(
size());
444 for (
const auto& item : items_) {
445 keys.push_back(item.key());
450 template <
typename Key,
typename Value>
452 std::vector<Value>
values;
453 values.reserve(
size());
454 for (
const auto& item : items_) {
455 values.push_back(item.value());
460 template <
typename Key,
typename Value>
462 std::vector<std::pair<Key, Value>>
values;
463 values.reserve(
size());
464 for (
const auto& item : items_) {
465 values.push_back(item.pair());
470 template <
typename Key,
typename Value>
472 index_.reserve(requested_capacity);
473 items_.reserve(requested_capacity);
Item(Key key, Value value)
Constructs a new item.
Item & operator[](size_t index)
Returns the item at the index-th position in the OrderedDict.
Value * operator->()
Allows access to the value using the arrow operator.
::std::vector< Value > values() const
Returns a newly allocated vector and copies all values from this OrderedDict into the vector...
size_t size() const noexcept
Returns the number of items currently stored in the OrderedDict.
Iterator begin()
Returns an iterator to the first item in the OrderedDict.
Iterator end()
Returns an iterator one past the last item in the OrderedDict.
Value & insert(K &&key, V &&value)
Inserts a new (key, value) pair into the OrderedDict.
Value & value() noexcept
Returns a reference to the value.
Value * find(const Key &key) noexcept
Returns a pointer to the value associated with the given key, or a nullptr if no such key is stored i...
bool contains(const Key &key) const noexcept
Returns true if the key is present in the OrderedDict.
bool is_empty() const noexcept
Returns true if the OrderedDict contains no elements.
const Value & value() const noexcept
Returns a reference to the value.
const Key & key() const noexcept
Returns a reference to the key.
void update(OrderedDict &&other)
Inserts all items from other into this OrderedDict.
void reserve(size_t requested_capacity)
Resizes internal storage to fit at least requested_capacity items without requiring reallocation...
const std::string & key_description() const noexcept
Returns the key description string the OrderedDict was constructed with.
const Value & operator*() const
Returns a reference to the value.
Item & back()
Returns the very last item in the OrderedDict and throws an exception if it is empty.
Value & operator*()
Returns a reference to the value.
::std::vector< std::pair< Key, Value > > pairs() const
Returns a newly allocated vector and copies all keys and values from this OrderedDict into a vector o...
OrderedDict & operator=(const OrderedDict &other)
Assigns items from other to this OrderedDict.
const std::vector< Item > & items() const noexcept
Returns the items stored in the OrderedDict.
::std::vector< Key > keys() const
Returns a newly allocated vector and copies all keys from this OrderedDict into the vector...
const Value * operator->() const
Allows access to the value using the arrow operator.
OrderedDict(std::string key_description="Key")
Constructs the OrderedDict with a short description of the kinds of keys stored in the OrderedDict...
void clear()
Removes all items from this OrderedDict.
An ordered dictionary implementation, akin to Python's OrderedDict.
Item & front()
Returns the very first item in the OrderedDict and throws an exception if it is empty.
const std::pair< const Key, Value > & pair() const noexcept
Returns a (key, value) pair.