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

Side by Side Diff: base/values.cc

Issue 2558023002: Inline FundamentalValue into base::Value (Closed)
Patch Set: Remove {} from if Created 4 years 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 | « base/values.h ('k') | base/values_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
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(bool in_bool) : type_(Type::BOOLEAN), bool_value_(in_bool) {}
79
80 Value::Value(int in_int) : type_(Type::INTEGER), int_value_(in_int) {}
81
82 Value::Value(double in_double) : type_(Type::DOUBLE), double_value_(in_double) {
83 if (!std::isfinite(double_value_)) {
84 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
85 << "values cannot be represented in JSON";
86 double_value_ = 0.0;
87 }
88 }
89
78 Value::~Value() { 90 Value::~Value() {
79 } 91 }
80 92
93 void Value::InternalCopyFrom(const Value& that) {
94 type_ = that.type_;
95 switch (type_) {
96 case Type::NONE:
97 // Nothing to do
98 return;
99
100 case Type::BOOLEAN:
101 bool_value_ = that.bool_value_;
102 return;
103 case Type::INTEGER:
104 int_value_ = that.int_value_;
105 return;
106 case Type::DOUBLE:
107 double_value_ = that.double_value_;
108 return;
109
110 // TODO(crbug.com/646113): Implement these once the corresponding derived
111 // classes are removed.
112 case Type::STRING:
113 case Type::BINARY:
114 case Type::LIST:
115 case Type::DICTIONARY:
116 return;
117 }
118 }
119
81 // static 120 // static
82 std::unique_ptr<Value> Value::CreateNullValue() { 121 std::unique_ptr<Value> Value::CreateNullValue() {
83 return WrapUnique(new Value(Type::NONE)); 122 return WrapUnique(new Value(Type::NONE));
84 } 123 }
85 124
86 // static 125 // static
87 const char* Value::GetTypeName(Value::Type type) { 126 const char* Value::GetTypeName(Value::Type type) {
88 DCHECK_GE(static_cast<int>(type), 0); 127 DCHECK_GE(static_cast<int>(type), 0);
89 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames)); 128 DCHECK_LT(static_cast<size_t>(type), arraysize(kTypeNames));
90 return kTypeNames[static_cast<size_t>(type)]; 129 return kTypeNames[static_cast<size_t>(type)];
91 } 130 }
92 131
132 bool Value::GetBool() const {
133 CHECK(is_bool());
134 return bool_value_;
135 }
136
137 int Value::GetInt() const {
138 CHECK(is_int());
139 return int_value_;
140 }
141
142 double Value::GetDouble() const {
143 if (is_double())
144 return double_value_;
145 if (is_int())
146 return int_value_;
147 CHECK(false);
148 return 0.0;
149 }
150
93 bool Value::GetAsBinary(const BinaryValue** out_value) const { 151 bool Value::GetAsBinary(const BinaryValue** out_value) const {
94 return false; 152 return false;
95 } 153 }
96 154
97 bool Value::GetAsBoolean(bool* out_value) const { 155 bool Value::GetAsBoolean(bool* out_value) const {
98 return false; 156 if (out_value && is_bool()) {
157 *out_value = bool_value_;
158 return true;
159 }
160 return is_bool();
99 } 161 }
100 162
101 bool Value::GetAsInteger(int* out_value) const { 163 bool Value::GetAsInteger(int* out_value) const {
102 return false; 164 if (out_value && is_int()) {
165 *out_value = int_value_;
166 return true;
167 }
168 return is_int();
103 } 169 }
104 170
105 bool Value::GetAsDouble(double* out_value) const { 171 bool Value::GetAsDouble(double* out_value) const {
106 return false; 172 if (out_value && is_double()) {
173 *out_value = double_value_;
174 return true;
175 } else if (out_value && is_int()) {
176 // Allow promotion from int to double.
177 *out_value = int_value_;
178 return true;
179 }
180 return is_double() || is_int();
107 } 181 }
108 182
109 bool Value::GetAsString(std::string* out_value) const { 183 bool Value::GetAsString(std::string* out_value) const {
110 return false; 184 return false;
111 } 185 }
112 186
113 bool Value::GetAsString(string16* out_value) const { 187 bool Value::GetAsString(string16* out_value) const {
114 return false; 188 return false;
115 } 189 }
116 190
(...skipping 13 matching lines...) Expand all
130 return false; 204 return false;
131 } 205 }
132 206
133 bool Value::GetAsDictionary(const DictionaryValue** out_value) const { 207 bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
134 return false; 208 return false;
135 } 209 }
136 210
137 Value* Value::DeepCopy() const { 211 Value* Value::DeepCopy() const {
138 // This method should only be getting called for null Values--all subclasses 212 // This method should only be getting called for null Values--all subclasses
139 // need to provide their own implementation;. 213 // need to provide their own implementation;.
140 DCHECK(IsType(Type::NONE)); 214 switch (type()) {
141 return CreateNullValue().release(); 215 case Type::NONE:
216 return CreateNullValue().release();
217
218 // For now, make FundamentalValues for backward-compatibility. Convert to
219 // Value when that code is deleted.
220 case Type::BOOLEAN:
221 return new FundamentalValue(bool_value_);
222 case Type::INTEGER:
223 return new FundamentalValue(int_value_);
224 case Type::DOUBLE:
225 return new FundamentalValue(double_value_);
226
227 default:
228 // All other types should be handled by subclasses.
229 NOTREACHED();
230 return nullptr;
231 }
142 } 232 }
143 233
144 std::unique_ptr<Value> Value::CreateDeepCopy() const { 234 std::unique_ptr<Value> Value::CreateDeepCopy() const {
145 return WrapUnique(DeepCopy()); 235 return WrapUnique(DeepCopy());
146 } 236 }
147 237
148 bool Value::Equals(const Value* other) const { 238 bool Value::Equals(const Value* other) const {
149 // This method should only be getting called for null Values--all subclasses 239 if (other->type() != type())
150 // need to provide their own implementation;. 240 return false;
151 DCHECK(IsType(Type::NONE)); 241
152 return other->IsType(Type::NONE); 242 switch (type()) {
243 case Type::NONE:
244 return true;
245 case Type::BOOLEAN:
246 return bool_value_ == other->bool_value_;
247 case Type::INTEGER:
248 return int_value_ == other->int_value_;
249 case Type::DOUBLE:
250 return double_value_ == other->double_value_;
251 default:
252 // This method should only be getting called for the above types -- all
253 // subclasses need to provide their own implementation;.
254 NOTREACHED();
255 return false;
256 }
153 } 257 }
154 258
155 // static 259 // static
156 bool Value::Equals(const Value* a, const Value* b) { 260 bool Value::Equals(const Value* a, const Value* b) {
157 if ((a == NULL) && (b == NULL)) return true; 261 if ((a == NULL) && (b == NULL)) return true;
158 if ((a == NULL) ^ (b == NULL)) return false; 262 if ((a == NULL) ^ (b == NULL)) return false;
159 return a->Equals(b); 263 return a->Equals(b);
160 } 264 }
161 265
162 Value::Value(Type type) : type_(type) {} 266 Value::Value(Type type) : type_(type) {}
jdoerrie 2016/12/23 14:18:26 According to the proposal this constructor should
vabr (Chromium) 2016/12/23 21:34:22 Seems fine with me, done. brettw@ -- please let me
163 267
164 Value::Value(const Value& that) : type_(that.type_) {} 268 Value::Value(const Value& that) {
269 InternalCopyFrom(that);
270 }
271
272 Value::Value(Value&& that) {
273 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving
274 // and copying differ.
275 InternalCopyFrom(that);
276 }
165 277
166 Value& Value::operator=(const Value& that) { 278 Value& Value::operator=(const Value& that) {
167 type_ = that.type_; 279 if (this != &that)
280 InternalCopyFrom(that);
281
282 return *this;
283 }
284
285 Value& Value::operator=(Value&& that) {
286 if (this != &that) {
287 // TODO(crbug.com/646113): Implement InternalMoveFrom for types where moving
288 // and copying differ.
289 InternalCopyFrom(that);
290 }
291
168 return *this; 292 return *this;
169 } 293 }
170 294
171 ///////////////////// FundamentalValue //////////////////// 295 ///////////////////// FundamentalValue ////////////////////
172 296
173 FundamentalValue::FundamentalValue(bool in_value) 297 FundamentalValue::FundamentalValue(bool in_value) : Value(in_value) {}
174 : Value(Type::BOOLEAN), boolean_value_(in_value) {}
175 298
176 FundamentalValue::FundamentalValue(int in_value) 299 FundamentalValue::FundamentalValue(int in_value) : Value(in_value) {}
177 : Value(Type::INTEGER), integer_value_(in_value) {}
178 300
179 FundamentalValue::FundamentalValue(double in_value) 301 FundamentalValue::FundamentalValue(double in_value) : Value(in_value) {}
180 : Value(Type::DOUBLE), double_value_(in_value) {
181 if (!std::isfinite(double_value_)) {
182 NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
183 << "values cannot be represented in JSON";
184 double_value_ = 0.0;
185 }
186 }
187 302
188 FundamentalValue::~FundamentalValue() { 303 FundamentalValue::~FundamentalValue() {}
189 }
190
191 bool FundamentalValue::GetAsBoolean(bool* out_value) const {
192 if (out_value && IsType(Type::BOOLEAN))
193 *out_value = boolean_value_;
194 return (IsType(Type::BOOLEAN));
195 }
196
197 bool FundamentalValue::GetAsInteger(int* out_value) const {
198 if (out_value && IsType(Type::INTEGER))
199 *out_value = integer_value_;
200 return (IsType(Type::INTEGER));
201 }
202
203 bool FundamentalValue::GetAsDouble(double* out_value) const {
204 if (out_value && IsType(Type::DOUBLE))
205 *out_value = double_value_;
206 else if (out_value && IsType(Type::INTEGER))
207 *out_value = integer_value_;
208 return (IsType(Type::DOUBLE) || IsType(Type::INTEGER));
209 }
210
211 FundamentalValue* FundamentalValue::DeepCopy() const {
212 switch (GetType()) {
213 case Type::BOOLEAN:
214 return new FundamentalValue(boolean_value_);
215
216 case Type::INTEGER:
217 return new FundamentalValue(integer_value_);
218
219 case Type::DOUBLE:
220 return new FundamentalValue(double_value_);
221
222 default:
223 NOTREACHED();
224 return NULL;
225 }
226 }
227
228 bool FundamentalValue::Equals(const Value* other) const {
229 if (other->GetType() != GetType())
230 return false;
231
232 switch (GetType()) {
233 case Type::BOOLEAN: {
234 bool lhs, rhs;
235 return GetAsBoolean(&lhs) && other->GetAsBoolean(&rhs) && lhs == rhs;
236 }
237 case Type::INTEGER: {
238 int lhs, rhs;
239 return GetAsInteger(&lhs) && other->GetAsInteger(&rhs) && lhs == rhs;
240 }
241 case Type::DOUBLE: {
242 double lhs, rhs;
243 return GetAsDouble(&lhs) && other->GetAsDouble(&rhs) && lhs == rhs;
244 }
245 default:
246 NOTREACHED();
247 return false;
248 }
249 }
250 304
251 ///////////////////// StringValue //////////////////// 305 ///////////////////// StringValue ////////////////////
252 306
253 StringValue::StringValue(StringPiece in_value) 307 StringValue::StringValue(StringPiece in_value)
254 : Value(Type::STRING), value_(in_value.as_string()) { 308 : Value(Type::STRING), value_(in_value.as_string()) {
255 DCHECK(IsStringUTF8(in_value)); 309 DCHECK(IsStringUTF8(in_value));
256 } 310 }
257 311
258 StringValue::StringValue(const string16& in_value) 312 StringValue::StringValue(const string16& in_value)
259 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {} 313 : Value(Type::STRING), value_(UTF16ToUTF8(in_value)) {}
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 } 1219 }
1166 1220
1167 std::ostream& operator<<(std::ostream& out, const Value::Type& type) { 1221 std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
1168 if (static_cast<int>(type) < 0 || 1222 if (static_cast<int>(type) < 0 ||
1169 static_cast<size_t>(type) >= arraysize(kTypeNames)) 1223 static_cast<size_t>(type) >= arraysize(kTypeNames))
1170 return out << "Invalid Type (index = " << static_cast<int>(type) << ")"; 1224 return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
1171 return out << Value::GetTypeName(type); 1225 return out << Value::GetTypeName(type);
1172 } 1226 }
1173 1227
1174 } // namespace base 1228 } // namespace base
OLDNEW
« no previous file with comments | « base/values.h ('k') | base/values_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698