OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 MOJO_SYSTEM_MEMORY_H_ | 5 #ifndef MOJO_SYSTEM_MEMORY_H_ |
6 #define MOJO_SYSTEM_MEMORY_H_ | 6 #define MOJO_SYSTEM_MEMORY_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <string.h> // For |memcpy()|. | 10 #include <string.h> // For |memcpy()|. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 // Provides a convenient way to implicitly get null |UserPointer<Type>|s. | 82 // Provides a convenient way to implicitly get null |UserPointer<Type>|s. |
83 struct NullUserPointer {}; | 83 struct NullUserPointer {}; |
84 | 84 |
85 // Represents a user pointer to a single |Type| (which must be POD), for Mojo | 85 // Represents a user pointer to a single |Type| (which must be POD), for Mojo |
86 // primitive parameters. | 86 // primitive parameters. |
87 // | 87 // |
88 // Use a const |Type| for in parameters, and non-const |Type|s for out and | 88 // Use a const |Type| for in parameters, and non-const |Type|s for out and |
89 // in-out parameters (in which case the |Put()| method is available). | 89 // in-out parameters (in which case the |Put()| method is available). |
90 template <typename Type> | 90 template <typename Type> |
91 class UserPointer { | 91 class UserPointer { |
| 92 private: |
| 93 typedef typename internal::VoidToChar<Type>::type NonVoidType; |
| 94 |
92 public: | 95 public: |
93 // Instead of explicitly using these constructors, you can often use | 96 // Instead of explicitly using these constructors, you can often use |
94 // |MakeUserPointer()| (or |NullUserPointer()| for null pointers). (The common | 97 // |MakeUserPointer()| (or |NullUserPointer()| for null pointers). (The common |
95 // exception is when you have, e.g., a |char*| and want to get a | 98 // exception is when you have, e.g., a |char*| and want to get a |
96 // |UserPointer<void>|.) | 99 // |UserPointer<void>|.) |
97 UserPointer() : pointer_(NULL) {} | 100 UserPointer() : pointer_(NULL) {} |
98 explicit UserPointer(Type* pointer) : pointer_(pointer) {} | 101 explicit UserPointer(Type* pointer) : pointer_(pointer) {} |
99 // Allow implicit conversion from the "null user pointer". | 102 // Allow implicit conversion from the "null user pointer". |
100 UserPointer(NullUserPointer) : pointer_(NULL) {} | 103 UserPointer(NullUserPointer) : pointer_(NULL) {} |
101 ~UserPointer() {} | 104 ~UserPointer() {} |
102 | 105 |
103 // Allow assignment from the "null user pointer". | 106 // Allow assignment from the "null user pointer". |
104 UserPointer<Type>& operator=(NullUserPointer) { | 107 UserPointer<Type>& operator=(NullUserPointer) { |
105 pointer_ = NULL; | 108 pointer_ = NULL; |
106 return *this; | 109 return *this; |
107 } | 110 } |
108 | 111 |
109 // Allow conversion to a "non-const" |UserPointer|. | 112 // Allow conversion to a "non-const" |UserPointer|. |
110 operator UserPointer<const Type>() const { | 113 operator UserPointer<const Type>() const { |
111 return UserPointer<const Type>(pointer_); | 114 return UserPointer<const Type>(pointer_); |
112 } | 115 } |
113 | 116 |
114 bool IsNull() const { | 117 bool IsNull() const { |
115 return !pointer_; | 118 return !pointer_; |
116 } | 119 } |
117 | 120 |
118 // We want to force a copy here, so return |Type| not |const Type&|. | 121 // Gets the value (of type |Type|) pointed to by this user pointer. Use this |
| 122 // when you'd use the rvalue |*user_pointer|, but be aware that this may be |
| 123 // costly -- so if the value will be used multiple times, you should save it. |
| 124 // |
| 125 // (We want to force a copy here, so return |Type| not |const Type&|.) |
119 Type Get() const { | 126 Type Get() const { |
120 internal::CheckUserPointerHelper<sizeof(Type), | 127 internal::CheckUserPointerHelper<sizeof(Type), |
121 MOJO_ALIGNOF(Type)>(pointer_); | 128 MOJO_ALIGNOF(Type)>(pointer_); |
122 return *pointer_; | 129 return *pointer_; |
123 } | 130 } |
124 | 131 |
| 132 // TODO(vtl): Add a |GetArray()| method (see |PutArray()|). |
| 133 |
| 134 // Puts a value (of type |Type|, or of type |char| if |Type| is |void|) to the |
| 135 // location pointed to by this user pointer. Use this when you'd use the |
| 136 // lvalue |*user_pointer|. Since this may be costly, you should avoid using |
| 137 // this (for the same user pointer) more than once. |
| 138 // |
125 // Note: This |Put()| method is not valid when |T| is const, e.g., |const | 139 // Note: This |Put()| method is not valid when |T| is const, e.g., |const |
126 // uint32_t|, but it's okay to include them so long as this template is only | 140 // uint32_t|, but it's okay to include them so long as this template is only |
127 // implicitly instantiated (see 14.7.1 of the C++11 standard) and not | 141 // implicitly instantiated (see 14.7.1 of the C++11 standard) and not |
128 // explicitly instantiated. (On implicit instantiation, only the declarations | 142 // explicitly instantiated. (On implicit instantiation, only the declarations |
129 // need be valid, not the definitions.) | 143 // need be valid, not the definitions.) |
130 // | 144 // |
131 // If |Type| is |void|, we "convert" it to |char|, so that it makes sense. | 145 // If |Type| is |void|, we "convert" it to |char|, so that it makes sense. |
132 // (Otherwise, we'd need a suitable specialization to exclude |Put()|.) | 146 // (Otherwise, we'd need a suitable specialization to exclude |Put()|.) |
133 // | 147 // |
134 // In C++11, we could do something like: | 148 // In C++11, we could do something like: |
135 // template <typename _Type = Type> | 149 // template <typename _Type = Type> |
136 // typename enable_if<!is_const<_Type>::value && | 150 // typename enable_if<!is_const<_Type>::value && |
137 // !is_void<_Type>::value>::type Put( | 151 // !is_void<_Type>::value>::type Put( |
138 // const _Type& value) { ... } | 152 // const _Type& value) { ... } |
139 // (which obviously be correct), but C++03 doesn't allow default function | 153 // (which obviously be correct), but C++03 doesn't allow default function |
140 // template arguments. | 154 // template arguments. |
141 void Put(const typename internal::VoidToChar<Type>::type& value) { | 155 void Put(const NonVoidType& value) { |
142 internal::CheckUserPointerHelper<sizeof(Type), | 156 internal::CheckUserPointerHelper<sizeof(NonVoidType), |
143 MOJO_ALIGNOF(Type)>(pointer_); | 157 MOJO_ALIGNOF(NonVoidType)>(pointer_); |
144 *pointer_ = value; | 158 *pointer_ = value; |
145 } | 159 } |
146 | 160 |
| 161 // Puts an array (of type |Type|, or just a buffer if |Type| is |void|) and |
| 162 // size |count| (number of elements, or number of bytes if |Type| is |void|) |
| 163 // to the location pointed to by this user pointer. Use this when you'd do |
| 164 // something like |memcpy(user_pointer, source, count * sizeof(Type))|. |
| 165 // |
| 166 // Note: The same comments about the validity of |Put()| (except for the part |
| 167 // about |void|) apply here. |
| 168 void PutArray(const Type* source, size_t count) { |
| 169 internal::CheckUserPointerWithCountHelper<sizeof(NonVoidType), |
| 170 MOJO_ALIGNOF(NonVoidType)>(source, |
| 171 count); |
| 172 memcpy(pointer_, source, count * sizeof(NonVoidType)); |
| 173 } |
| 174 |
| 175 // Gets a |UserPointer| at offset |i| (in |Type|s) relative to this. This |
| 176 // method is not valid if |Type| is |void| (TODO(vtl): Maybe I should make it |
| 177 // valid, with the offset in bytes?). |
147 UserPointer At(size_t i) const { | 178 UserPointer At(size_t i) const { |
148 return UserPointer(pointer_ + i); | 179 return UserPointer(pointer_ + i); |
149 } | 180 } |
150 | 181 |
151 // TODO(vtl): This is temporary. Get rid of this. (We should pass | 182 // TODO(vtl): This is temporary. Get rid of this. (We should pass |
152 // |UserPointer<>|s along appropriately, or access data in a safe way | 183 // |UserPointer<>|s along appropriately, or access data in a safe way |
153 // everywhere.) | 184 // everywhere.) |
154 Type* GetPointerUnsafe() const { | 185 Type* GetPointerUnsafe() const { |
155 return pointer_; | 186 return pointer_; |
156 } | 187 } |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 // Provides a convenient way to make a |UserPointerValue<Type>|. | 348 // Provides a convenient way to make a |UserPointerValue<Type>|. |
318 template <typename Type> | 349 template <typename Type> |
319 inline UserPointerValue<Type> MakeUserPointerValue(Type* pointer) { | 350 inline UserPointerValue<Type> MakeUserPointerValue(Type* pointer) { |
320 return UserPointerValue<Type>(pointer); | 351 return UserPointerValue<Type>(pointer); |
321 } | 352 } |
322 | 353 |
323 } // namespace system | 354 } // namespace system |
324 } // namespace mojo | 355 } // namespace mojo |
325 | 356 |
326 #endif // MOJO_SYSTEM_MEMORY_H_ | 357 #endif // MOJO_SYSTEM_MEMORY_H_ |
OLD | NEW |