Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: content/browser/download/id_type.h

Issue 1529363006: Introducing SavePackageId and SaveItemId as distinct IdType<...>-based types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing... Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/browser/download/id_type_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CONTENT_BROWSER_DOWNLOAD_ID_TYPE_H_
6 #define CONTENT_BROWSER_DOWNLOAD_ID_TYPE_H_
ncarter (slow) 2016/01/07 00:48:50 Let's put this in content/common for now.
Łukasz Anforowicz 2016/01/07 18:02:13 Done.
7
8 #include <ostream>
9
10 #include "base/containers/hash_tables.h"
11
12 // Problem:
13 //
14 // void f(int foo_id, int bar_id);
15 // ...
16 // // Arguments passed in a wrong order:
17 // f(bar_id, foo_id); // Compiles - sigh... :-(
18 //
19 // Solution:
20 //
21 // using FooId = content::IdType<Foo, uint64_t, 0>;
22 // using BarId = content::IdType<Bar, uint64_t, 0>;
ncarter (slow) 2016/01/07 00:48:50 Id prefer if we had a design that didn't require t
Łukasz Anforowicz 2016/01/07 18:02:12 I agree that this is desirable, although: 1) I wo
ncarter (slow) 2016/01/07 20:14:32 I like this idea, a lot. It looks like, in existi
Łukasz Anforowicz 2016/01/07 21:43:01 Done. (changed IdType32/64 to wrap a signed integ
23 // void f(FooId foo_id, BarId bar_id);
24 // ...
25 // // Arguments passed in a wrong order:
26 // f(bar_id, foo_id); // Doesn't compile anymore - yay! :-)
27 //
28 // Typically FooId would be declared like this:
29 //
30 // foo_id.h:
31 //
32 // #include "content/browser/download/id_type.h"
33 //
34 // namespace foo_namespace {
35 //
36 // class Foo;
37 // using FooId = content::IdType<Foo, uint64_t, 0>;
38 //
39 // } // namespace foo_namespace
40 //
41 // For most practical purposes, FooId declared like above behaves just like
42 // an uint64_t, except that:
43 //
44 // 1. FooId only supports a subset of uint64_t operations:
45 // - ==, !=, <, hashing
46 // - stream output
47 // - copy construction and assignment
48 //
49 // 2. FooId does not implicitly coerce to/from other uint64_t values and
50 // to/from content::IdType<SomeOtherType, ...>. Explicit coercion to/from
51 // uint64_t is possible through the following FooId methods:
52 // - static FooId FromUnsafeValue(uint64_t)
53 // - uint64_t GetUnsafeValue()
54 //
55 // 3. Default-constructed FooId contains a "null" / "invalid" value specified
56 // by the 3rd argument of the IdType<...> template. Testing against this
57 // value can be done by the following FooId methods:
58 // - bool is_valid()
59 // - bool is_null()
60 //
61 // 4. The presence of a custom default constructor means that FooId is not a
62 // "trivial" class and therefore is not a POD type (unlike an uint64_t).
63 // At the same time FooId has almost all of the properties of a POD type:
64 // - is "trivially copyable" (i.e. is memcpy-able),
65 // - has "standard layout" (i.e. interops with things expecting C layout).
66 // See http://stackoverflow.com/a/7189821 for more info about these
67 // concepts.
68
69 namespace content {
70
71 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
ncarter (slow) 2016/01/07 00:48:50 I don't really know C++ templates well, so I wonde
Łukasz Anforowicz 2016/01/07 18:02:12 I've tried this ans got an error: ../../content/co
ncarter (slow) 2016/01/07 20:14:32 I really like the solution of expose a ready-to-us
Łukasz Anforowicz 2016/01/07 21:43:01 Acknowledged.
72 struct IdType {
ncarter (slow) 2016/01/07 00:48:50 why struct? IdType has no public data members.
Łukasz Anforowicz 2016/01/07 18:02:13 I changed to a class. RE: why No particular reas
73 public:
74 IdType() : value_(kInvalidValue) {}
75 bool is_valid() const { return value_ != kInvalidValue; }
76 bool is_null() const { return value_ == kInvalidValue; }
77
78 static IdType FromUnsafeValue(WrappedType value) { return IdType(value); }
79 WrappedType GetUnsafeValue() const { return value_; }
80
81 IdType(const IdType& other) = default;
82 IdType& operator=(const IdType& other) = default;
83
84 bool operator==(const IdType& other) const { return value_ == other.value_; }
85 bool operator!=(const IdType& other) const { return value_ != other.value_; }
86 bool operator<(const IdType& other) const { return value_ < other.value_; }
87
88 protected:
89 explicit IdType(WrappedType val) : value_(val) {}
90
91 private:
92 WrappedType value_;
93 };
94
95 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
96 std::ostream& operator<<(
97 std::ostream& stream,
98 const IdType<TypeMarker, WrappedType, kInvalidValue>& id) {
99 return stream << id.GetUnsafeValue();
100 }
101
102 } // namespace content
103
104 namespace BASE_HASH_NAMESPACE {
105
106 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
107 struct hash<content::IdType<TypeMarker, WrappedType, kInvalidValue>> {
108 using argument_type = content::IdType<TypeMarker, WrappedType, kInvalidValue>;
109 using result_type = std::size_t;
110 result_type operator()(const argument_type& id) const {
111 return BASE_HASH_NAMESPACE::hash<WrappedType>()(id.GetUnsafeValue());
112 }
113 };
114
115 } // namespace BASE_HASH_NAMESPACE
116
117 // If defined(COMPILER_MSVC) then BASE_HASH_NAMESPACE == std.
118 // In this case we need to avoid defininig std::hash<...> second time
119 // (it has already been defined above).
120 #if !defined(COMPILER_MSVC)
121
122 namespace std {
123
124 template <typename TypeMarker, typename WrappedType, WrappedType kInvalidValue>
125 struct hash<content::IdType<TypeMarker, WrappedType, kInvalidValue>> {
126 using argument_type = content::IdType<TypeMarker, WrappedType, kInvalidValue>;
127 using result_type = std::size_t;
128 result_type operator()(const argument_type& id) const {
129 return std::hash<WrappedType>()(id.GetUnsafeValue());
130 }
131 };
132
133 } // namespace std;
134
135 #endif // !defined(COMPILER_MSVC)
136
137 #endif // CONTENT_BROWSER_DOWNLOAD_ID_TYPE_H_
OLDNEW
« no previous file with comments | « no previous file | content/browser/download/id_type_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698