1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef sw_ID_hpp 16*03ce13f7SAndroid Build Coastguard Worker #define sw_ID_hpp 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp" 19*03ce13f7SAndroid Build Coastguard Worker 20*03ce13f7SAndroid Build Coastguard Worker #include <cstdint> 21*03ce13f7SAndroid Build Coastguard Worker #include <unordered_map> 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker namespace sw { 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker // SpirvID is a strongly-typed identifier backed by a uint32_t. 26*03ce13f7SAndroid Build Coastguard Worker // The template parameter T is not actually used by the implementation of 27*03ce13f7SAndroid Build Coastguard Worker // ID; instead it is used to prevent implicit casts between identifiers of 28*03ce13f7SAndroid Build Coastguard Worker // different T types. 29*03ce13f7SAndroid Build Coastguard Worker // IDs are typically used as a map key to value of type T. 30*03ce13f7SAndroid Build Coastguard Worker template<typename T> 31*03ce13f7SAndroid Build Coastguard Worker class SpirvID 32*03ce13f7SAndroid Build Coastguard Worker { 33*03ce13f7SAndroid Build Coastguard Worker public: 34*03ce13f7SAndroid Build Coastguard Worker SpirvID() = default; 35*03ce13f7SAndroid Build Coastguard Worker inline SpirvID(uint32_t id); 36*03ce13f7SAndroid Build Coastguard Worker 37*03ce13f7SAndroid Build Coastguard Worker inline bool operator==(const SpirvID<T> &rhs) const; 38*03ce13f7SAndroid Build Coastguard Worker inline bool operator!=(const SpirvID<T> &rhs) const; 39*03ce13f7SAndroid Build Coastguard Worker inline bool operator<(const SpirvID<T> &rhs) const; 40*03ce13f7SAndroid Build Coastguard Worker 41*03ce13f7SAndroid Build Coastguard Worker // Returns the numerical value of the identifier. 42*03ce13f7SAndroid Build Coastguard Worker inline uint32_t value() const; 43*03ce13f7SAndroid Build Coastguard Worker 44*03ce13f7SAndroid Build Coastguard Worker private: 45*03ce13f7SAndroid Build Coastguard Worker uint32_t id = 0; // Valid ids are in the range "0 < id < Bound". 46*03ce13f7SAndroid Build Coastguard Worker }; 47*03ce13f7SAndroid Build Coastguard Worker 48*03ce13f7SAndroid Build Coastguard Worker template<typename T> SpirvID(uint32_t id)49*03ce13f7SAndroid Build Coastguard WorkerSpirvID<T>::SpirvID(uint32_t id) 50*03ce13f7SAndroid Build Coastguard Worker : id(id) 51*03ce13f7SAndroid Build Coastguard Worker {} 52*03ce13f7SAndroid Build Coastguard Worker 53*03ce13f7SAndroid Build Coastguard Worker template<typename T> operator ==(const SpirvID<T> & rhs) const54*03ce13f7SAndroid Build Coastguard Workerbool SpirvID<T>::operator==(const SpirvID<T> &rhs) const 55*03ce13f7SAndroid Build Coastguard Worker { 56*03ce13f7SAndroid Build Coastguard Worker return id == rhs.id; 57*03ce13f7SAndroid Build Coastguard Worker } 58*03ce13f7SAndroid Build Coastguard Worker 59*03ce13f7SAndroid Build Coastguard Worker template<typename T> operator !=(const SpirvID<T> & rhs) const60*03ce13f7SAndroid Build Coastguard Workerbool SpirvID<T>::operator!=(const SpirvID<T> &rhs) const 61*03ce13f7SAndroid Build Coastguard Worker { 62*03ce13f7SAndroid Build Coastguard Worker return id != rhs.id; 63*03ce13f7SAndroid Build Coastguard Worker } 64*03ce13f7SAndroid Build Coastguard Worker 65*03ce13f7SAndroid Build Coastguard Worker template<typename T> operator <(const SpirvID<T> & rhs) const66*03ce13f7SAndroid Build Coastguard Workerbool SpirvID<T>::operator<(const SpirvID<T> &rhs) const 67*03ce13f7SAndroid Build Coastguard Worker { 68*03ce13f7SAndroid Build Coastguard Worker return id < rhs.id; 69*03ce13f7SAndroid Build Coastguard Worker } 70*03ce13f7SAndroid Build Coastguard Worker 71*03ce13f7SAndroid Build Coastguard Worker template<typename T> value() const72*03ce13f7SAndroid Build Coastguard Workeruint32_t SpirvID<T>::value() const 73*03ce13f7SAndroid Build Coastguard Worker { 74*03ce13f7SAndroid Build Coastguard Worker // Assert that we don't attempt to use unassigned IDs. 75*03ce13f7SAndroid Build Coastguard Worker // Use if(id != 0) { ... } to avoid invalid code paths. 76*03ce13f7SAndroid Build Coastguard Worker ASSERT(id != 0); 77*03ce13f7SAndroid Build Coastguard Worker 78*03ce13f7SAndroid Build Coastguard Worker return id; 79*03ce13f7SAndroid Build Coastguard Worker } 80*03ce13f7SAndroid Build Coastguard Worker 81*03ce13f7SAndroid Build Coastguard Worker // HandleMap<T> is an unordered map of SpirvID<T> to T. 82*03ce13f7SAndroid Build Coastguard Worker template<typename T> 83*03ce13f7SAndroid Build Coastguard Worker using HandleMap = std::unordered_map<SpirvID<T>, T>; 84*03ce13f7SAndroid Build Coastguard Worker 85*03ce13f7SAndroid Build Coastguard Worker } // namespace sw 86*03ce13f7SAndroid Build Coastguard Worker 87*03ce13f7SAndroid Build Coastguard Worker namespace std { 88*03ce13f7SAndroid Build Coastguard Worker 89*03ce13f7SAndroid Build Coastguard Worker // std::hash implementation for sw::SpirvID<T> 90*03ce13f7SAndroid Build Coastguard Worker template<typename T> 91*03ce13f7SAndroid Build Coastguard Worker struct hash<sw::SpirvID<T> > 92*03ce13f7SAndroid Build Coastguard Worker { operator ()std::hash93*03ce13f7SAndroid Build Coastguard Worker std::size_t operator()(const sw::SpirvID<T> &id) const noexcept 94*03ce13f7SAndroid Build Coastguard Worker { 95*03ce13f7SAndroid Build Coastguard Worker return std::hash<uint32_t>()(id.value()); 96*03ce13f7SAndroid Build Coastguard Worker } 97*03ce13f7SAndroid Build Coastguard Worker }; 98*03ce13f7SAndroid Build Coastguard Worker 99*03ce13f7SAndroid Build Coastguard Worker } // namespace std 100*03ce13f7SAndroid Build Coastguard Worker 101*03ce13f7SAndroid Build Coastguard Worker #endif // sw_ID_hpp 102