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 <cstdint> 19 #include <functional> 20 #include <string> 21 22 namespace bt { 23 24 template <typename T> 25 struct IdentifierTraits { 26 // Returns a string representation of |value|. ToStringIdentifierTraits27 static std::string ToString(T value) { return std::to_string(value); } 28 }; 29 30 // Specializations for integer types return a fixed-length string. 31 template <> 32 struct IdentifierTraits<uint64_t> { 33 static std::string ToString(uint64_t value) { 34 return bt_lib_cpp_string::StringPrintf("%.16lx", value); 35 } 36 }; 37 38 // Opaque identifier type for host library layers. 39 template <typename T> 40 class Identifier { 41 static_assert(std::is_trivial_v<T>); 42 static_assert(!std::is_pointer_v<std::decay<T>>); 43 44 public: 45 using value_t = T; 46 using Traits = IdentifierTraits<T>; 47 48 constexpr explicit Identifier(const T& value) : value_(value) {} 49 Identifier() = default; 50 51 T value() const { return value_; } 52 53 // Comparison. 54 bool operator==(const Identifier& other) const { 55 return value_ == other.value_; 56 } 57 bool operator!=(const Identifier& other) const { 58 return value_ != other.value_; 59 } 60 61 // Returns a string representation of this identifier. This function allocates 62 // memory. 63 std::string ToString() const { return Traits::ToString(value_); } 64 65 private: 66 T value_; 67 }; 68 69 // Opaque identifier type for Bluetooth peers. 70 class PeerId : public Identifier<uint64_t> { 71 public: 72 constexpr explicit PeerId(uint64_t value) : Identifier<uint64_t>(value) {} 73 constexpr PeerId() : PeerId(0u) {} 74 75 bool IsValid() const { return value() != 0u; } 76 }; 77 78 constexpr PeerId kInvalidPeerId(0u); 79 80 // Generates a valid random peer identifier. This function can never return 81 // kInvalidPeerId. 82 PeerId RandomPeerId(); 83 84 } // namespace bt 85 86 // Specialization of std::hash for std::unordered_set, std::unordered_map, etc. 87 namespace std { 88 89 template <typename T> 90 struct hash<bt::Identifier<T>> { 91 size_t operator()(const bt::Identifier<T>& id) const { 92 return std::hash<T>()(id.value()); 93 } 94 }; 95 96 template <> 97 struct hash<bt::PeerId> { 98 size_t operator()(const bt::PeerId& id) const { 99 return std::hash<decltype(id.value())>()(id.value()); 100 } 101 }; 102 103 } // namespace std 104