blob: e90a8ccb939cdf3156f380920ba37dd06794787f [file] [log] [blame]
Ben Claytonab51bbf2019-02-20 14:36:27 +00001// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
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#ifndef sw_ID_hpp
16#define sw_ID_hpp
17
Nicolas Capensff9bb522021-11-08 21:29:29 -050018#include "System/Debug.hpp"
19
Ben Claytonab51bbf2019-02-20 14:36:27 +000020#include <cstdint>
Ben Claytonbc1c067be2019-12-17 20:37:37 +000021#include <unordered_map>
Ben Claytonab51bbf2019-02-20 14:36:27 +000022
Nicolas Capens157ba262019-12-10 17:49:14 -050023namespace sw {
24
25// SpirvID is a strongly-typed identifier backed by a uint32_t.
26// The template parameter T is not actually used by the implementation of
27// ID; instead it is used to prevent implicit casts between identifiers of
28// different T types.
29// IDs are typically used as a map key to value of type T.
Ben Claytonbc1c067be2019-12-17 20:37:37 +000030template<typename T>
Nicolas Capens157ba262019-12-10 17:49:14 -050031class SpirvID
Ben Claytonab51bbf2019-02-20 14:36:27 +000032{
Nicolas Capens157ba262019-12-10 17:49:14 -050033public:
Ben Clayton19b43a62019-12-10 11:57:00 +000034 SpirvID() = default;
35 inline SpirvID(uint32_t id);
Nicolas Capensff9bb522021-11-08 21:29:29 -050036
Ben Clayton19b43a62019-12-10 11:57:00 +000037 inline bool operator==(const SpirvID<T> &rhs) const;
38 inline bool operator!=(const SpirvID<T> &rhs) const;
39 inline bool operator<(const SpirvID<T> &rhs) const;
Ben Claytonab51bbf2019-02-20 14:36:27 +000040
Nicolas Capensff9bb522021-11-08 21:29:29 -050041 // Returns the numerical value of the identifier.
Ben Clayton19b43a62019-12-10 11:57:00 +000042 inline uint32_t value() const;
Ben Claytonbc1c067be2019-12-17 20:37:37 +000043
Nicolas Capens157ba262019-12-10 17:49:14 -050044private:
Nicolas Capensff9bb522021-11-08 21:29:29 -050045 uint32_t id = 0; // Valid ids are in the range "0 < id < Bound".
Nicolas Capens157ba262019-12-10 17:49:14 -050046};
Ben Claytonab51bbf2019-02-20 14:36:27 +000047
Ben Clayton19b43a62019-12-10 11:57:00 +000048template<typename T>
49SpirvID<T>::SpirvID(uint32_t id)
50 : id(id)
51{}
52
53template<typename T>
54bool SpirvID<T>::operator==(const SpirvID<T> &rhs) const
55{
56 return id == rhs.id;
57}
58
59template<typename T>
60bool SpirvID<T>::operator!=(const SpirvID<T> &rhs) const
61{
62 return id != rhs.id;
63}
64
65template<typename T>
66bool SpirvID<T>::operator<(const SpirvID<T> &rhs) const
67{
68 return id < rhs.id;
69}
70
71template<typename T>
72uint32_t SpirvID<T>::value() const
73{
Nicolas Capensff9bb522021-11-08 21:29:29 -050074 // Assert that we don't attempt to use unassigned IDs.
75 // Use if(id != 0) { ... } to avoid invalid code paths.
76 ASSERT(id != 0);
77
Ben Clayton19b43a62019-12-10 11:57:00 +000078 return id;
79}
80
Nicolas Capens157ba262019-12-10 17:49:14 -050081// HandleMap<T> is an unordered map of SpirvID<T> to T.
Ben Claytonbc1c067be2019-12-17 20:37:37 +000082template<typename T>
Nicolas Capens157ba262019-12-10 17:49:14 -050083using HandleMap = std::unordered_map<SpirvID<T>, T>;
Ben Clayton19b43a62019-12-10 11:57:00 +000084
Ben Claytonbc1c067be2019-12-17 20:37:37 +000085} // namespace sw
Ben Claytonab51bbf2019-02-20 14:36:27 +000086
Ben Claytonbc1c067be2019-12-17 20:37:37 +000087namespace std {
Ben Clayton19b43a62019-12-10 11:57:00 +000088
Nicolas Capens157ba262019-12-10 17:49:14 -050089// std::hash implementation for sw::SpirvID<T>
90template<typename T>
Ben Claytonbc1c067be2019-12-17 20:37:37 +000091struct hash<sw::SpirvID<T> >
Nicolas Capens157ba262019-12-10 17:49:14 -050092{
Ben Claytonbc1c067be2019-12-17 20:37:37 +000093 std::size_t operator()(const sw::SpirvID<T> &id) const noexcept
Ben Claytonab51bbf2019-02-20 14:36:27 +000094 {
Nicolas Capens157ba262019-12-10 17:49:14 -050095 return std::hash<uint32_t>()(id.value());
96 }
97};
98
Ben Claytonbc1c067be2019-12-17 20:37:37 +000099} // namespace std
Ben Claytonab51bbf2019-02-20 14:36:27 +0000100
101#endif // sw_ID_hpp