tqchen commented on code in PR #16863:
URL: https://github.com/apache/tvm/pull/16863#discussion_r1558112101
##########
3rdparty/picojson/picojson.h:
##########
@@ -137,10 +146,177 @@ enum { INDENT_WIDTH = 2 };
struct null {};
+// The ordered version of hashmap. When iterating through the hashmap,
+// the elements maintain the order in which they were inserted.
+// Its API is the same as std::unordered_map.
+template <typename Key, typename T>
+class ordered_hashmap : private std::unordered_map<Key, T> {
+ public:
+ using value_type = std::pair<const Key, T>;
+
+ private:
+ template <bool IsConst>
+ struct iterator_base {
+ public:
+ using pointer = std::conditional_t<IsConst, const value_type*,
value_type*>;
+ using reference = std::conditional_t<IsConst, const value_type&,
value_type&>;
+
+ iterator_base(const iterator_base<IsConst>& other)
+ : order_index(other.order_index), obj_ptr(other.obj_ptr) {}
+
+ template <bool _IsConst = IsConst, typename = std::enable_if_t<_IsConst>>
+ iterator_base(const iterator_base<false>& other)
+ : order_index(other.order_index), obj_ptr(other.obj_ptr) {
+ static_assert(_IsConst, "This constructor should only be used for const
iterators.");
+ }
+
+ iterator_base<IsConst>& operator++() {
+ ++order_index;
+ return *this;
+ }
+ iterator_base<IsConst> operator++(int) {
+ auto tmp = *this;
+ ++order_index;
+ return tmp;
+ }
+ pointer operator->() const {
+ assert(order_index >= 0 && order_index < obj_ptr->order.size());
+ return obj_ptr->std::unordered_map<Key,
T>::find(obj_ptr->order[order_index]).operator->();
+ }
+ reference operator*() const { return *operator->(); }
+ bool operator==(const iterator_base<IsConst>& other) const {
+ return order_index == other.order_index && obj_ptr == other.obj_ptr;
+ }
+ bool operator!=(const iterator_base<IsConst>& other) const { return
!(*this == other); }
+
+ friend class ordered_hashmap;
+
+ private:
+ using obj_pointer_type = std::conditional_t<IsConst, const
ordered_hashmap*, ordered_hashmap*>;
+ iterator_base(int order_index, obj_pointer_type obj_ptr)
+ : order_index(order_index), obj_ptr(obj_ptr) {}
+
+ int order_index;
+ obj_pointer_type obj_ptr;
+ };
+
+ public:
+ using iterator = iterator_base<false>;
+ using const_iterator = iterator_base<true>;
+
+ ordered_hashmap() = default;
+ ordered_hashmap(const ordered_hashmap&) = default;
+ ordered_hashmap(ordered_hashmap&&) = default;
+ ordered_hashmap(std::initializer_list<value_type> init) :
std::unordered_map<Key, T>(init) {
+ for (const auto& pair : init) {
+ order.push_back(pair.first);
+ }
+ }
+ ordered_hashmap& operator=(const ordered_hashmap&) = default;
+ ordered_hashmap& operator=(ordered_hashmap&&) = default;
+
+ iterator begin() { return {0, this}; }
+ iterator end() { return {static_cast<int>(order.size()), this}; }
+ const_iterator begin() const { return {0, this}; }
+ const_iterator end() const { return {static_cast<int>(order.size()), this}; }
+ const_iterator cbegin() const { return {0, this}; }
+ const_iterator cend() const { return {static_cast<int>(order.size()), this};
}
+
+ using std::unordered_map<Key, T>::empty;
+ using std::unordered_map<Key, T>::size;
+ using std::unordered_map<Key, T>::at;
+
+ T& operator[](const Key& key) {
+ if (count(key) == 0) {
Review Comment:
use `std::unordered_map<Key, T>`, so you only do lookup once
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]