Line data Source code
1 : // 2 : // Copyright 2024 OpenModelViewer Authors 3 : // 4 : // Licensed under the Apache License, Version 2.0 (the "License"); 5 : // you may not use this file except in compliance with the License. 6 : // You may obtain a copy of the License at 7 : // 8 : // http://www.apache.org/licenses/LICENSE-2.0 9 : // 10 : // Unless required by applicable law or agreed to in writing, software 11 : // distributed under the License is distributed on an "AS IS" BASIS, 12 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 : // See the License for the specific language governing permissions and 14 : // limitations under the License. 15 : // 16 : 17 : #pragma once 18 : 19 : #include <cstdint> 20 : #include <ostream> 21 : #include <functional> 22 : 23 : namespace openmodelviewer::core::id 24 : { 25 : using UniqueIdType = std::uint32_t; 26 : 27 : /** 28 : * @brief Strongly-typed wrapper for a unique identifier. 29 : * 30 : * This template provides a reusable ID type that can be distinguished 31 : * by its tag type. The underlying value is a 32-bit unsigned integer, 32 : * where 0 is reserved to indicate an invalid ID. 33 : * 34 : * @tparam Tag A distinct tag type used to differentiate ID domains. 35 : */ 36 : template<typename Tag> 37 : struct UniqueId 38 : { 39 : /** 40 : * @brief The underlying numeric value of the ID. 41 : */ 42 : UniqueIdType raw = 0; 43 : 44 : /** 45 : * @brief Checks whether the ID is valid (i.e., not zero). 46 : * @return True if the ID is valid, false otherwise. 47 : */ 48 3 : constexpr bool isValid() const noexcept { return raw != 0; } 49 : 50 : /** 51 : * @brief Equality comparison operator. 52 : * 53 : * Compares the raw values of two UniqueId instances. 54 : * 55 : * @param other Another UniqueId to compare with. 56 : * @return True if both IDs have the same value. 57 : */ 58 254 : constexpr bool operator==(UniqueId other) const noexcept { return raw == other.raw; } 59 : 60 : /** 61 : * @brief Inequality comparison operator. 62 : * 63 : * @param other Another UniqueId to compare with. 64 : * @return True if the IDs are different. 65 : */ 66 2 : constexpr bool operator!=(UniqueId other) const noexcept { return raw != other.raw; } 67 : 68 : /** 69 : * @brief Less-than comparison operator. 70 : * 71 : * Useful for ordered containers like std::set or sorting. 72 : * 73 : * @param other Another UniqueId to compare with. 74 : * @return True if this ID is less than the other. 75 : */ 76 2 : constexpr bool operator<(UniqueId other) const noexcept { return raw < other.raw; } 77 : 78 : /** 79 : * @brief Greater-than comparison operator. 80 : * 81 : * @param other Another UniqueId to compare with. 82 : * @return True if this ID is greater than the other. 83 : */ 84 2 : constexpr bool operator>(UniqueId other) const noexcept { return raw > other.raw; } 85 : 86 : /** 87 : * @brief Returns an invalid UniqueId (with value 0). 88 : * 89 : * @return A UniqueId representing an invalid or uninitialized state. 90 : */ 91 : static constexpr UniqueId Invalid() noexcept { return UniqueId{ 0 }; } 92 : }; 93 : 94 : /** 95 : * @brief Output stream operator for UniqueId. 96 : * 97 : * Writes the raw numeric value of the ID to the given stream. 98 : * 99 : * @tparam Tag The tag type of the UniqueId. 100 : * @param os The output stream. 101 : * @param id The UniqueId to write. 102 : * @return Reference to the output stream. 103 : */ 104 : template<typename Tag> 105 1 : inline std::ostream& operator<<(std::ostream& os, const UniqueId<Tag>& id) 106 : { 107 1 : return os << id.raw; 108 : } 109 : } // namespace openmodelviewer::core::id 110 : 111 : namespace std 112 : { 113 : /** 114 : * @brief Hash specialization for UniqueId. 115 : * 116 : * Enables UniqueId to be used as a key in unordered containers such as std::unordered_map. 117 : * 118 : * @tparam Tag The tag type used to distinguish the ID domain. 119 : */ 120 : template<typename Tag> 121 : struct hash<openmodelviewer::core::id::UniqueId<Tag>> 122 : { 123 : /** 124 : * @brief Computes a hash value from the raw ID. 125 : * 126 : * @param id The UniqueId to hash. 127 : * @return The hash value. 128 : */ 129 537 : std::size_t operator()(const openmodelviewer::core::id::UniqueId<Tag>& id) const noexcept 130 : { 131 537 : return std::hash<openmodelviewer::core::id::UniqueIdType>{}(id.raw); 132 : } 133 : }; 134 : } // namespace std