| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CONTENT_COMMON_ID_TYPE_H_ | 5 #ifndef BASE_ID_TYPE_H_ |
| 6 #define CONTENT_COMMON_ID_TYPE_H_ | 6 #define BASE_ID_TYPE_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <cstddef> | 9 #include <cstddef> |
| 10 #include <ostream> | 10 #include <ostream> |
| 11 #include <type_traits> | 11 #include <type_traits> |
| 12 | 12 |
| 13 // IdType32<>, IdType64<>, etc. wrap an integer id in a custom, type-safe type. | 13 // IdType32<>, IdType64<>, etc. wrap an integer id in a custom, type-safe type. |
| 14 // | 14 // |
| 15 // IdType32<Foo> is an alternative to int, for a class Foo with methods like: | 15 // IdType32<Foo> is an alternative to int, for a class Foo with methods like: |
| 16 // | 16 // |
| 17 // int GetId() { return id_; }; | 17 // int GetId() { return id_; }; |
| 18 // static Foo* FromId(int id) { return g_all_foos_by_id[id]; } | 18 // static Foo* FromId(int id) { return g_all_foos_by_id[id]; } |
| 19 // | 19 // |
| 20 // Such methods are a standard means of safely referring to objects across | 20 // Such methods are a standard means of safely referring to objects across |
| 21 // thread and process boundaries. But if a nearby class Bar also represents | 21 // thread and process boundaries. But if a nearby class Bar also represents |
| 22 // its IDs as a bare int, horrific mixups are possible -- one example, of many, | 22 // its IDs as a bare int, horrific mixups are possible -- one example, of many, |
| 23 // is http://crrev.com/365437. IdType<> offers compile-time protection against | 23 // is http://crrev.com/365437. IdType<> offers compile-time protection against |
| 24 // such mishaps, since IdType32<Foo> is incompatible with IdType32<Bar>, even | 24 // such mishaps, since IdType32<Foo> is incompatible with IdType32<Bar>, even |
| 25 // though both just compile down to an int32_t. | 25 // though both just compile down to an int32_t. |
| 26 // | 26 // |
| 27 // Templates in this file: | 27 // Templates in this file: |
| 28 // IdType32<T> / IdTypeU32<T>: Signed / unsigned 32-bit IDs | 28 // IdType32<T> / IdTypeU32<T>: Signed / unsigned 32-bit IDs |
| 29 // IdType64<T> / IdTypeU64<T>: Signed / unsigned 64-bit IDs | 29 // IdType64<T> / IdTypeU64<T>: Signed / unsigned 64-bit IDs |
| 30 // IdType<>: For when you need a different underlying type or | 30 // IdType<>: For when you need a different underlying type or |
| 31 // a default/invalid value other than zero. | 31 // a default/null value other than zero. |
| 32 // | 32 // |
| 33 // IdType32<Foo> behaves just like an int32_t in the following aspects: | 33 // IdType32<Foo> behaves just like an int32_t in the following aspects: |
| 34 // - it can be used as a key in std::map and/or std::unordered_map; | 34 // - it can be used as a key in std::map and/or std::unordered_map; |
| 35 // - it can be used as an argument to DCHECK_EQ or streamed to LOG(ERROR); | 35 // - it can be used as an argument to DCHECK_EQ or streamed to LOG(ERROR); |
| 36 // - it has the same memory footprint and runtime overhead as int32_t; | 36 // - it has the same memory footprint and runtime overhead as int32_t; |
| 37 // - it can be copied by memcpy. | 37 // - it can be copied by memcpy. |
| 38 // | 38 // |
| 39 // IdType32<Foo> has the following differences from a bare int32_t: | 39 // IdType32<Foo> has the following differences from a bare int32_t: |
| 40 // - it forces coercions to go through GetUnsafeValue and FromUnsafeValue; | 40 // - it forces coercions to go through GetUnsafeValue and FromUnsafeValue; |
| 41 // - it restricts the set of available operations (i.e. no multiplication); | 41 // - it restricts the set of available operations (i.e. no multiplication); |
| 42 // - it ensures initialization to zero and allows checking against | 42 // - it ensures initialization to zero and allows checking against |
| 43 // default-initialized values via is_null method. | 43 // default-initialized values via is_null method. |
| 44 | 44 |
| 45 namespace content { | 45 namespace base { |
| 46 | 46 |
| 47 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> | 47 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> |
| 48 class IdType { | 48 class IdType { |
| 49 public: | 49 public: |
| 50 IdType() : value_(kInvalidValue) {} | 50 IdType() : value_(kInvalidValue) {} |
| 51 bool is_null() const { return value_ == kInvalidValue; } | 51 bool is_null() const { return value_ == kInvalidValue; } |
| 52 | 52 |
| 53 static IdType FromUnsafeValue(WrappedType value) { return IdType(value); } | 53 static IdType FromUnsafeValue(WrappedType value) { return IdType(value); } |
| 54 WrappedType GetUnsafeValue() const { return value_; } | 54 WrappedType GetUnsafeValue() const { return value_; } |
| 55 | 55 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 template <typename TypeMarker> | 95 template <typename TypeMarker> |
| 96 using IdTypeU64 = IdType<TypeMarker, uint64_t, 0>; | 96 using IdTypeU64 = IdType<TypeMarker, uint64_t, 0>; |
| 97 | 97 |
| 98 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> | 98 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue> |
| 99 std::ostream& operator<<( | 99 std::ostream& operator<<( |
| 100 std::ostream& stream, | 100 std::ostream& stream, |
| 101 const IdType<TypeMarker, WrappedType, kInvalidValue>& id) { | 101 const IdType<TypeMarker, WrappedType, kInvalidValue>& id) { |
| 102 return stream << id.GetUnsafeValue(); | 102 return stream << id.GetUnsafeValue(); |
| 103 } | 103 } |
| 104 | 104 |
| 105 } // namespace content | 105 } // namespace base |
| 106 | 106 |
| 107 #endif // CONTENT_COMMON_ID_TYPE_H_ | 107 #endif // CONTENT_COMMON_ID_TYPE_H_ |
| OLD | NEW |