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

Side by Side Diff: base/values.cc

Issue 2645073002: Inline FundamentalValue into base::Value (Closed)
Patch Set: Typedef FundamentalValue to Value Created 3 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "base/values.h" 5 #include "base/values.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return CopyDictionaryWithoutEmptyChildren( 68 return CopyDictionaryWithoutEmptyChildren(
69 static_cast<const DictionaryValue&>(node)); 69 static_cast<const DictionaryValue&>(node));
70 70
71 default: 71 default:
72 return node.CreateDeepCopy(); 72 return node.CreateDeepCopy();
73 } 73 }
74 } 74 }
75 75
76 } // namespace 76 } // namespace
77 77
78 Value::~Value() {
79 }
80
81 // static 78 // static
82 std::unique_ptr<Value> Value::CreateNullValue() { 79 std::unique_ptr<Value> Value::CreateNullValue() {
83 return WrapUnique(new Value(Type::NONE)); 80 return WrapUnique(new Value(Type::NONE));
84 } 81 }
85 82
83 Value::Value(const Value& that) {
84 InternalCopyFrom(that);
85 }
86
87 Value::Value(Value&& that) {
88 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving
89 // and copying differ.
90 InternalCopyFrom(that);
91 }
92
93 Value::Value() : type_(Type::NONE) {}
94
95 Value::Value(Type type) : type_(type) {
96 // Initialize with the default value.
97 switch (type_) {
98 case Type::NONE:
99 return;
100
101 case Type::BOOLEAN:
102 bool_value_ = bool();
103 return;
104 case Type::INTEGER:
105 int_value_ = int();
106 return;
107 case Type::DOUBLE:
108 double_value_ = double();
109 return;
110
111 // TODO(crbug.com/646113): Implement these once the corresponding derived
112 // classes are removed.
113 case Type::STRING:
114 case Type::BINARY:
115 case Type::LIST:
116 case Type::DICTIONARY:
117 return;
118 }
119 NOTREACHED();
120 return;
121 }
122
123 Value::Value(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
124
125 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
126
127 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
128 if (!std::isfinite(double_value_)) {
129 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
130 << "values cannot be represented in JSON";
131 double_value_ = 0.0;
132 }
133 }
134
135 Value& Value::operator=(const Value& that) {
136 if (this != &that)
137 InternalCopyFrom(that);
138
139 return *this;
140 }
141
142 Value& Value::operator=(Value&& that) {
143 if (this != &that) {
144 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving
145 // and copying differ.
146 InternalCopyFrom(that);
147 }
148
149 return *this;
150 }
151
152 Value::~Value() {}
153
86 // static 154 // static
87 const char* Value::GetTypeName(Value::Type type) { 155 const char* Value::GetTypeName(Value::Type type) {
88 DCHECK_GE(static_cast<int>(type), 0); 156 DCHECK_GE(static_cast<int>(type), 0);
89 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); 157 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
90 return kTypeNames[static_cast<size_t>(type)]; 158 return kTypeNames[static_cast<size_t>(type)];
91 } 159 }
92 160
93 bool Value::GetAsBinary(const BinaryValue** out_value) const { 161 bool Value::GetBool() const {
94 return false; 162 CHECK(is_bool());
163 return bool_value_;
164 }
165
166 int Value::GetInt() const {
167 CHECK(is_int());
168 return int_value_;
169 }
170
171 double Value::GetDouble() const {
172 if (is_double())
173 return double_value_;
174 if (is_int())
175 return int_value_;
176 CHECK(false);
177 return 0.0;
95 } 178 }
96 179
97 bool Value::GetAsBoolean(bool* out_value) const { 180 bool Value::GetAsBoolean(bool* out_value) const {
98 return false; 181 if (out_value && is_bool()) {
182 *out_value = bool_value_;
183 return true;
184 }
185 return is_bool();
99 } 186 }
100 187
101 bool Value::GetAsInteger(int* out_value) const { 188 bool Value::GetAsInteger(int* out_value) const {
102 return false; 189 if (out_value && is_int()) {
190 *out_value = int_value_;
191 return true;
192 }
193 return is_int();
103 } 194 }
104 195
105 bool Value::GetAsDouble(double* out_value) const { 196 bool Value::GetAsDouble(double* out_value) const {
106 return false; 197 if (out_value && is_double()) {
198 *out_value = double_value_;
199 return true;
200 } else if (out_value && is_int()) {
201 // Allow promotion from int to double.
202 *out_value = int_value_;
203 return true;
204 }
205 return is_double() || is_int();
107 } 206 }
108 207
109 bool Value::GetAsString(std::string* out_value) const { 208 bool Value::GetAsString(std::string* out_value) const {
110 return false; 209 return false;
111 } 210 }
112 211
113 bool Value::GetAsString(string16* out_value) const { 212 bool Value::GetAsString(string16* out_value) const {
114 return false; 213 return false;
115 } 214 }
116 215
117 bool Value::GetAsString(const StringValue** out_value) const { 216 bool Value::GetAsString(const StringValue** out_value) const {
118 return false; 217 return false;
119 } 218 }
120 219
121 bool Value::GetAsString(StringPiece* out_value) const { 220 bool Value::GetAsString(StringPiece* out_value) const {
122 return false; 221 return false;
123 } 222 }
124 223
224 bool Value::GetAsBinary(const BinaryValue** out_value) const {
225 return false;
226 }
227
125 bool Value::GetAsList(ListValue** out_value) { 228 bool Value::GetAsList(ListValue** out_value) {
126 return false; 229 return false;
127 } 230 }
128 231
129 bool Value::GetAsList(const ListValue** out_value) const { 232 bool Value::GetAsList(const ListValue** out_value) const {
130 return false; 233 return false;
131 } 234 }
132 235
133 bool Value::GetAsDictionary(DictionaryValue** out_value) { 236 bool Value::GetAsDictionary(DictionaryValue** out_value) {
134 return false; 237 return false;
135 } 238 }
136 239
137 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 240 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
138 return false; 241 return false;
139 } 242 }
140 243
141 Value* Value::DeepCopy() const { 244 Value* Value::DeepCopy() const {
142 // This method should only be getting called for null Values--all subclasses 245 // This method should only be getting called for null Values--all subclasses
143 // need to provide their own implementation;. 246 // need to provide their own implementation;.
144 DCHECK(IsType(Type::NONE)); 247 switch (type()) {
145 return CreateNullValue().release(); 248 case Type::NONE:
249 return CreateNullValue().release();
250
251 // For now, make FundamentalValues for backward-compatibility. Convert to
252 // Value when that code is deleted.
253 case Type::BOOLEAN:
254 return new FundamentalValue(bool_value_);
255 case Type::INTEGER:
256 return new FundamentalValue(int_value_);
257 case Type::DOUBLE:
258 return new FundamentalValue(double_value_);
259
260 default:
261 // All other types should be handled by subclasses.
262 NOTREACHED();
263 return nullptr;
264 }
146 } 265 }
147 266
148 std::unique_ptr<Value> Value::CreateDeepCopy() const { 267 std::unique_ptr<Value> Value::CreateDeepCopy() const {
149 return WrapUnique(DeepCopy()); 268 return WrapUnique(DeepCopy());
150 } 269 }
151 270
152 bool Value::Equals(const Value* other) const { 271 bool Value::Equals(const Value* other) const {
153 // This method should only be getting called for null Values--all subclasses 272 if (other->type() != type())
154 // need to provide their own implementation;. 273 return false;
155 DCHECK(IsType(Type::NONE)); 274
156 return other->IsType(Type::NONE); 275 switch (type()) {
276 case Type::NONE:
277 return true;
278 case Type::BOOLEAN:
279 return bool_value_ == other->bool_value_;
280 case Type::INTEGER:
281 return int_value_ == other->int_value_;
282 case Type::DOUBLE:
283 return double_value_ == other->double_value_;
284 default:
285 // This method should only be getting called for the above types -- all
286 // subclasses need to provide their own implementation;.
287 NOTREACHED();
288 return false;
289 }
157 } 290 }
158 291
159 // static 292 // static
160 bool Value::Equals(const Value* a, const Value* b) { 293 bool Value::Equals(const Value* a, const Value* b) {
161 if ((a == NULL) && (b == NULL)) return true; 294 if ((a == NULL) && (b == NULL)) return true;
162 if ((a == NULL) ^ (b == NULL)) return false; 295 if ((a == NULL) ^ (b == NULL)) return false;
163 return a->Equals(b); 296 return a->Equals(b);
164 } 297 }
165 298
166 Value::Value(Type type) : type_(type) {} 299 void Value::InternalCopyFrom(const Value& that) {
300 type_ = that.type_;
301 switch (type_) {
302 case Type::NONE:
303 // Nothing to do.
304 return;
167 305
168 Value::Value(const Value& that) : type_(that.type_) {} 306 case Type::BOOLEAN:
307 bool_value_ = that.bool_value_;
308 return;
309 case Type::INTEGER:
310 int_value_ = that.int_value_;
311 return;
312 case Type::DOUBLE:
313 double_value_ = that.double_value_;
314 return;
169 315
170 Value& Value::operator=(const Value& that) { 316 // Currently it is not safe to copy from these types.
171 type_ = that.type_; 317 // TODO(crbug.com/646113): Implement these once the corresponding derived
172 return *this; 318 // classes are removed.
173 } 319 case Type::STRING:
174 320 case Type::BINARY:
175 ///////////////////// FundamentalValue //////////////////// 321 case Type::LIST:
176 322 case Type::DICTIONARY:
177 FundamentalValue::FundamentalValue(bool in_value) 323 NOTREACHED();
178 : Value(Type::BOOLEAN), boolean_value_(in_value) {} 324 return;
179
180 FundamentalValue::FundamentalValue(int in_value)
181 : Value(Type::INTEGER), integer_value_(in_value) {}
182
183 FundamentalValue::FundamentalValue(double in_value)
184 : Value(Type::DOUBLE), double_value_(in_value) {
185 if (!std::isfinite(double_value_)) {
186 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
187 << "values cannot be represented in JSON";
188 double_value_ = 0.0;
189 } 325 }
190 } 326 }
191 327
192 FundamentalValue::~FundamentalValue() {
193 }
194
195 bool FundamentalValue::GetAsBoolean(bool* out_value) const {
196 if (out_value && IsType(Type::BOOLEAN))
197 *out_value = boolean_value_;
198 return (IsType(Type::BOOLEAN));
199 }
200
201 bool FundamentalValue::GetAsInteger(int* out_value) const {
202 if (out_value && IsType(Type::INTEGER))
203 *out_value = integer_value_;
204 return (IsType(Type::INTEGER));
205 }
206
207 bool FundamentalValue::GetAsDouble(double* out_value) const {
208 if (out_value && IsType(Type::DOUBLE))
209 *out_value = double_value_;
210 else if (out_value && IsType(Type::INTEGER))
211 *out_value = integer_value_;
212 return (IsType(Type::DOUBLE) || IsType(Type::INTEGER));
213 }
214
215 FundamentalValue* FundamentalValue::DeepCopy() const {
216 switch (GetType()) {
217 case Type::BOOLEAN:
218 return new FundamentalValue(boolean_value_);
219
220 case Type::INTEGER:
221 return new FundamentalValue(integer_value_);
222
223 case Type::DOUBLE:
224 return new FundamentalValue(double_value_);
225
226 default:
227 NOTREACHED();
228 return NULL;
229 }
230 }
231
232 bool FundamentalValue::Equals(const Value* other) const {
233 if (other->GetType() != GetType())
234 return false;
235
236 switch (GetType()) {
237 case Type::BOOLEAN: {
238 bool lhs, rhs;
239 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
240 }
241 case Type::INTEGER: {
242 int lhs, rhs;
243 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
244 }
245 case Type::DOUBLE: {
246 double lhs, rhs;
247 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
248 }
249 default:
250 NOTREACHED();
251 return false;
252 }
253 }
254
255 ///////////////////// StringValue //////////////////// 328 ///////////////////// StringValue ////////////////////
256 329
257 StringValue::StringValue(StringPiece in_value) 330 StringValue::StringValue(StringPiece in_value)
258 : Value(Type::STRING), value_(in_value.as_string()) { 331 : Value(Type::STRING), value_(in_value.as_string()) {
259 DCHECK(IsStringUTF8(in_value)); 332 DCHECK(IsStringUTF8(in_value));
260 } 333 }
261 334
262 StringValue::StringValue(const string16& in_value) 335 StringValue::StringValue(const string16& in_value)
263 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} 336 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {}
264 337
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 } 1248 }
1176 1249
1177 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1250 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1178 if (static_cast<int>(type) < 0 || 1251 if (static_cast<int>(type) < 0 ||
1179 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1252 static_cast<size_t>(type) >= arraysize(kTypeNames))
1180 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1253 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1181 return out << Value::GetTypeName(type); 1254 return out << Value::GetTypeName(type);
1182 } 1255 }
1183 1256
1184 } // namespace base 1257 } // namespace base
OLDNEW
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | skia/ext/benchmarking_canvas.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698