@@ -55,6 +55,15 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf,
55
55
56
56
namespace Json {
57
57
58
+ template <typename T>
59
+ static std::unique_ptr<T> cloneUnique (const std::unique_ptr<T>& p) {
60
+ std::unique_ptr<T> r;
61
+ if (p) {
62
+ r = std::unique_ptr<T>(new T (*p));
63
+ }
64
+ return r;
65
+ }
66
+
58
67
// This is a walkaround to avoid the static initialization of Value::null.
59
68
// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
60
69
// 8 (instead of 4) as a bit of future-proofing.
@@ -229,34 +238,6 @@ JSONCPP_NORETURN void throwLogicError(String const& msg) {
229
238
throw LogicError (msg);
230
239
}
231
240
232
- // //////////////////////////////////////////////////////////////////
233
- // //////////////////////////////////////////////////////////////////
234
- // //////////////////////////////////////////////////////////////////
235
- // class Value::CommentInfo
236
- // //////////////////////////////////////////////////////////////////
237
- // //////////////////////////////////////////////////////////////////
238
- // //////////////////////////////////////////////////////////////////
239
-
240
- Value::CommentInfo::CommentInfo () = default ;
241
-
242
- Value::CommentInfo::~CommentInfo () {
243
- if (comment_)
244
- releaseStringValue (comment_, 0u );
245
- }
246
-
247
- void Value::CommentInfo::setComment (const char * text, size_t len) {
248
- if (comment_) {
249
- releaseStringValue (comment_, 0u );
250
- comment_ = nullptr ;
251
- }
252
- JSON_ASSERT (text != nullptr );
253
- JSON_ASSERT_MESSAGE (
254
- text[0 ] == ' \0 ' || text[0 ] == ' /' ,
255
- " in Json::Value::setComment(): Comments must start with /" );
256
- // It seems that /**/ style comments are acceptable as well.
257
- comment_ = duplicateStringValue (text, len);
258
- }
259
-
260
241
// //////////////////////////////////////////////////////////////////
261
242
// //////////////////////////////////////////////////////////////////
262
243
// //////////////////////////////////////////////////////////////////
@@ -488,7 +469,6 @@ Value::Value(Value&& other) {
488
469
489
470
Value::~Value () {
490
471
releasePayload ();
491
- delete[] comments_;
492
472
value_.uint_ = 0 ;
493
473
}
494
474
@@ -521,7 +501,6 @@ void Value::swap(Value& other) {
521
501
522
502
void Value::copy (const Value& other) {
523
503
copyPayload (other);
524
- delete[] comments_;
525
504
dupMeta (other);
526
505
}
527
506
@@ -1027,7 +1006,7 @@ const Value& Value::operator[](int index) const {
1027
1006
void Value::initBasic (ValueType type, bool allocated) {
1028
1007
setType (type);
1029
1008
setIsAllocated (allocated);
1030
- comments_ = nullptr ;
1009
+ comments_ = Comments{} ;
1031
1010
start_ = 0 ;
1032
1011
limit_ = 0 ;
1033
1012
}
@@ -1086,17 +1065,7 @@ void Value::releasePayload() {
1086
1065
}
1087
1066
1088
1067
void Value::dupMeta (const Value& other) {
1089
- if (other.comments_ ) {
1090
- comments_ = new CommentInfo[numberOfCommentPlacement];
1091
- for (int comment = 0 ; comment < numberOfCommentPlacement; ++comment) {
1092
- const CommentInfo& otherComment = other.comments_ [comment];
1093
- if (otherComment.comment_ )
1094
- comments_[comment].setComment (otherComment.comment_ ,
1095
- strlen (otherComment.comment_ ));
1096
- }
1097
- } else {
1098
- comments_ = nullptr ;
1099
- }
1068
+ comments_ = other.comments_ ;
1100
1069
start_ = other.start_ ;
1101
1070
limit_ = other.limit_ ;
1102
1071
}
@@ -1468,34 +1437,49 @@ bool Value::isArray() const { return type() == arrayValue; }
1468
1437
1469
1438
bool Value::isObject () const { return type () == objectValue; }
1470
1439
1471
- void Value::setComment (const char * comment,
1472
- size_t len,
1473
- CommentPlacement placement) {
1474
- if (!comments_)
1475
- comments_ = new CommentInfo[numberOfCommentPlacement];
1476
- if ((len > 0 ) && (comment[len - 1 ] == ' \n ' )) {
1477
- // Always discard trailing newline, to aid indentation.
1478
- len -= 1 ;
1479
- }
1480
- comments_[placement].setComment (comment, len);
1440
+ Value::Comments::Comments (const Comments& that)
1441
+ : ptr_{cloneUnique (that.ptr_ )} {}
1442
+
1443
+ Value::Comments& Value::Comments::operator =(const Comments& that) {
1444
+ ptr_ = cloneUnique (that.ptr_ );
1445
+ return *this ;
1481
1446
}
1482
1447
1483
- void Value::setComment ( const char * comment, CommentPlacement placement) {
1484
- setComment (comment, strlen (comment), placement );
1448
+ bool Value::Comments::has ( CommentPlacement slot) const {
1449
+ return ptr_ && !(*ptr_)[slot]. empty ( );
1485
1450
}
1486
1451
1487
- void Value::setComment (const String& comment, CommentPlacement placement) {
1488
- setComment (comment.c_str (), comment.length (), placement);
1452
+ String Value::Comments::get (CommentPlacement slot) const {
1453
+ if (!ptr_)
1454
+ return {};
1455
+ return (*ptr_)[slot];
1456
+ }
1457
+
1458
+ void Value::Comments::set (CommentPlacement slot, String comment) {
1459
+ if (!ptr_) {
1460
+ ptr_ = std::unique_ptr<Array>(new Array ());
1461
+ }
1462
+ (*ptr_)[slot] = std::move (comment);
1463
+ }
1464
+
1465
+ void Value::setComment (String comment, CommentPlacement placement) {
1466
+ if (!comment.empty () && (comment.back () == ' \n ' )) {
1467
+ // Always discard trailing newline, to aid indentation.
1468
+ comment.pop_back ();
1469
+ }
1470
+ JSON_ASSERT (!comment.empty ());
1471
+ JSON_ASSERT_MESSAGE (
1472
+ comment[0 ] == ' \0 ' || comment[0 ] == ' /' ,
1473
+ " in Json::Value::setComment(): Comments must start with /" );
1474
+ comments_.set (placement, std::move (comment));
1489
1475
}
1490
1476
1491
1477
bool Value::hasComment (CommentPlacement placement) const {
1492
- return comments_ != nullptr && comments_[placement]. comment_ != nullptr ;
1478
+ return comments_. has (placement) ;
1493
1479
}
1494
1480
1495
1481
String Value::getComment (CommentPlacement placement) const {
1496
- if (hasComment (placement))
1497
- return comments_[placement].comment_ ;
1498
- return " " ;
1482
+ return comments_.get (placement);
1499
1483
}
1500
1484
1501
1485
void Value::setOffsetStart (ptrdiff_t start) { start_ = start; }
0 commit comments