1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <cpp-string/string_printf.h> 17 18 #include <cinttypes> 19 #include <cstdint> 20 #include <functional> 21 #include <string> 22 23 namespace bt { 24 25 template <typename T> 26 struct IdentifierTraits { 27 // Returns a string representation of |value|. ToStringIdentifierTraits28 static std::string ToString(T value) { return std::to_string(value); } 29 }; 30 31 // Specializations for integer types return a fixed-length string. 32 template <> 33 struct IdentifierTraits<uint64_t> { 34 static std::string ToString(uint64_t value) { 35 return bt_lib_cpp_string::StringPrintf("%.16" PRIx64, value); 36 } 37 }; 38 39 // Opaque identifier type for host library layers. 40 template <typename T> 41 class Identifier { 42 static_assert(std::is_trivial_v<T>); 43 static_assert(!std::is_pointer_v<std::decay<T>>); 44 45 public: 46 using value_t = T; 47 using Traits = IdentifierTraits<T>; 48 49 constexpr explicit Identifier(const T& value) : value_(value) {} 50 Identifier() = default; 51 52 T value() const { return value_; } 53 54 // Comparison. 55 bool operator==(const Identifier& other) const { 56 return value_ == other.value_; 57 } 58 bool operator!=(const Identifier& other) const { 59 return value_ != other.value_; 60 } 61 62 // Returns a string representation of this identifier. This function allocates 63 // memory. 64 std::string ToString() const { return Traits::ToString(value_); } 65 66 private: 67 T value_; 68 }; 69 70 // Opaque identifier type for Bluetooth peers. 71 class PeerId : public Identifier<uint64_t> { 72 public: 73 constexpr explicit PeerId(uint64_t value) : Identifier<uint64_t>(value) {} 74 constexpr PeerId() : PeerId(0u) {} 75 76 bool IsValid() const { return value() != 0u; } 77 }; 78 79 constexpr PeerId kInvalidPeerId(0u); 80 81 // Generates a valid random peer identifier. This function can never return 82 // kInvalidPeerId. 83 PeerId RandomPeerId(); 84 85 } // namespace bt 86 87 // Specialization of std::hash for std::unordered_set, std::unordered_map, etc. 88 namespace std { 89 90 template <typename T> 91 struct hash<bt::Identifier<T>> { 92 size_t operator()(const bt::Identifier<T>& id) const { 93 return std::hash<T>()(id.value()); 94 } 95 }; 96 97 template <> 98 struct hash<bt::PeerId> { 99 size_t operator()(const bt::PeerId& id) const { 100 return std::hash<decltype(id.value())>()(id.value()); 101 } 102 }; 103 104 } // namespace std 105