1 // Copyright (C) 2023 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License") override; 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #include <cstdint> 18 #include <limits> 19 #include <optional> 20 #include <type_traits> 21 #include <unordered_map> 22 23 namespace gfxstream { 24 namespace magma { 25 26 // A container with automatic monotonically increasing key values. 27 template <typename K, typename V, std::enable_if_t<std::is_integral_v<K>, bool> = true> 28 class MonotonicMap { 29 public: MonotonicMap()30 MonotonicMap() { 31 static_assert(std::numeric_limits<K>::max() >= std::numeric_limits<int64_t>::max(), 32 "Key type should be sufficiently large so as to not overflow."); 33 } 34 35 // Creates a new object using the provided parameters with the constructor, and returns the new 36 // key associated with it. 37 template <typename... Params> create(Params &&...params)38 K create(Params&&... params) { 39 assert(mNextKey < std::numeric_limits<K>::max()); 40 auto key = mNextKey++; 41 auto [it, emplaced] = mMap.emplace(key, V(std::forward<Params>(params)...)); 42 return key; 43 } 44 45 // Returns a pointer to the object associated with the given key, or nullptr if the key is 46 // invalid. The pointer remains valid until the container is destroyed or the key is removed. get(const K & key)47 V* get(const K& key) { 48 auto it = mMap.find(key); 49 if (it == mMap.end()) { 50 return nullptr; 51 } 52 return &it->second; 53 } 54 55 // Destroys the object with the associated key and removes it from the map. Returns true iff the 56 // key was valid. erase(const K & key)57 bool erase(const K& key) { return mMap.erase(key) > 0; } 58 59 private: 60 K mNextKey = 1; 61 std::unordered_map<K, V> mMap; 62 }; 63 64 } // namespace magma 65 } // namespace gfxstream 66