Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:31

0001 #include <iostream>
0002 #include "EventFilter/Utilities/interface/value.h"
0003 #include "EventFilter/Utilities/interface/writer.h"
0004 #include <utility>
0005 #include <stdexcept>
0006 #include <cstring>
0007 #include <cassert>
0008 #ifdef JSON_USE_CPPTL
0009 #include <cpptl/conststring.h>
0010 #endif
0011 #include <cstddef>  // size_t
0012 #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
0013 #include "EventFilter/Utilities/interface/json_batchallocator.h"
0014 #endif  // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
0015 
0016 #define JSON_ASSERT_UNREACHABLE assert(false)
0017 #define JSON_ASSERT(condition) assert(condition);  //  <= change this into an exception throw
0018 #define JSON_ASSERT_MESSAGE(condition, message) \
0019   if (!(condition))                             \
0020     throw std::runtime_error(message);
0021 
0022 namespace Json {
0023 
0024   const Value Value::null;
0025   const Int Value::minInt = Int(~(UInt(-1) / 2));
0026   const Int Value::maxInt = Int(UInt(-1) / 2);
0027   const UInt Value::maxUInt = UInt(-1);
0028 
0029   // A "safe" implementation of strdup. Allow null pointer to be passed.
0030   // Also avoid warning on msvc80.
0031   //
0032   //inline char *safeStringDup( const char *czstring )
0033   //{
0034   //   if ( czstring )
0035   //   {
0036   //      const size_t length = (unsigned int)( strlen(czstring) + 1 );
0037   //      char *newString = static_cast<char *>( malloc( length ) );
0038   //      memcpy( newString, czstring, length );
0039   //      return newString;
0040   //   }
0041   //   return 0;
0042   //}
0043   //
0044   //inline char *safeStringDup( const std::string &str )
0045   //{
0046   //   if ( !str.empty() )
0047   //   {
0048   //      const size_t length = str.length();
0049   //      char *newString = static_cast<char *>( malloc( length + 1 ) );
0050   //      memcpy( newString, str.c_str(), length );
0051   //      newString[length] = 0;
0052   //      return newString;
0053   //   }
0054   //   return 0;
0055   //}
0056 
0057   ValueAllocator::~ValueAllocator() {}
0058 
0059   class DefaultValueAllocator : public ValueAllocator {
0060   public:
0061     DefaultValueAllocator() {}
0062 
0063     ~DefaultValueAllocator() override {}
0064 
0065     char *makeMemberName(const char *memberName) const override { return duplicateStringValue(memberName); }
0066 
0067     void releaseMemberName(char *memberName) const override { releaseStringValue(memberName); }
0068 
0069     char *duplicateStringValue(const char *value, unsigned int length = unknown) const override {
0070       // invesgate this old optimization
0071       //if ( !value  ||  value[0] == 0 )
0072       //   return 0;
0073 
0074       if (length == unknown)
0075         length = (unsigned int)strlen(value);
0076       char *newString = static_cast<char *>(malloc(length + 1));
0077       memcpy(newString, value, length);
0078       newString[length] = 0;
0079       return newString;
0080     }
0081 
0082     void releaseStringValue(char *value) const override {
0083       if (value)
0084         free(value);
0085     }
0086   };
0087 
0088   static ValueAllocator const *valueAllocator() {
0089     static const DefaultValueAllocator defaultAllocator;
0090     static ValueAllocator const *valueAllocator = &defaultAllocator;
0091     return valueAllocator;
0092   }
0093 
0094   static struct DummyValueAllocatorInitializer {
0095     DummyValueAllocatorInitializer() {
0096       valueAllocator();  // ensure valueAllocator() statics are initialized before main().
0097     }
0098   } dummyValueAllocatorInitializer;
0099 
0100 // //////////////////////////////////////////////////////////////////
0101 // //////////////////////////////////////////////////////////////////
0102 // //////////////////////////////////////////////////////////////////
0103 // ValueInternals...
0104 // //////////////////////////////////////////////////////////////////
0105 // //////////////////////////////////////////////////////////////////
0106 // //////////////////////////////////////////////////////////////////
0107 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0108 #include "EventFilter/Utilities/interface/json_internalarray.inl"
0109 #include "EventFilter/Utilities/interface/json_internalmap.inl"
0110 #endif  // JSON_VALUE_USE_INTERNAL_MAP
0111 
0112 #include "EventFilter/Utilities/interface/json_valueiterator.inl"
0113 
0114   // //////////////////////////////////////////////////////////////////
0115   // //////////////////////////////////////////////////////////////////
0116   // //////////////////////////////////////////////////////////////////
0117   // class Value::CommentInfo
0118   // //////////////////////////////////////////////////////////////////
0119   // //////////////////////////////////////////////////////////////////
0120   // //////////////////////////////////////////////////////////////////
0121 
0122   Value::CommentInfo::CommentInfo() : comment_(nullptr) {}
0123 
0124   Value::CommentInfo::~CommentInfo() {
0125     if (comment_)
0126       valueAllocator()->releaseStringValue(comment_);
0127   }
0128 
0129   void Value::CommentInfo::setComment(const char *text) {
0130     if (comment_)
0131       valueAllocator()->releaseStringValue(comment_);
0132     JSON_ASSERT(text);
0133     JSON_ASSERT_MESSAGE(text[0] == '\0' || text[0] == '/', "Comments must start with /");
0134     // It seems that /**/ style comments are acceptable as well.
0135     comment_ = valueAllocator()->duplicateStringValue(text);
0136   }
0137 
0138 // //////////////////////////////////////////////////////////////////
0139 // //////////////////////////////////////////////////////////////////
0140 // //////////////////////////////////////////////////////////////////
0141 // class Value::CZString
0142 // //////////////////////////////////////////////////////////////////
0143 // //////////////////////////////////////////////////////////////////
0144 // //////////////////////////////////////////////////////////////////
0145 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0146 
0147   // Notes: index_ indicates if the string was allocated when
0148   // a string is stored.
0149 
0150   Value::CZString::CZString(int index) : cstr_(nullptr), index_(index) {}
0151 
0152   Value::CZString::CZString(const char *cstr, DuplicationPolicy allocate)
0153       : cstr_(allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr), index_(allocate) {}
0154 
0155   Value::CZString::CZString(const CZString &other)
0156       : cstr_(other.index_ != noDuplication && other.cstr_ != nullptr ? valueAllocator()->makeMemberName(other.cstr_)
0157                                                                       : other.cstr_),
0158         index_(other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_) {}
0159 
0160   Value::CZString::~CZString() {
0161     if (cstr_ && index_ == duplicate)
0162       valueAllocator()->releaseMemberName(const_cast<char *>(cstr_));
0163   }
0164 
0165   void Value::CZString::swap(CZString &other) {
0166     std::swap(cstr_, other.cstr_);
0167     std::swap(index_, other.index_);
0168   }
0169 
0170   Value::CZString &Value::CZString::operator=(const CZString &other) {
0171     CZString temp(other);
0172     swap(temp);
0173     return *this;
0174   }
0175 
0176   bool Value::CZString::operator<(const CZString &other) const {
0177     if (cstr_ and other.cstr_)
0178       return strcmp(cstr_, other.cstr_) < 0;
0179     return index_ < other.index_;
0180   }
0181 
0182   bool Value::CZString::operator==(const CZString &other) const {
0183     if (cstr_ and other.cstr_)
0184       return strcmp(cstr_, other.cstr_) == 0;
0185     return index_ == other.index_;
0186   }
0187 
0188   int Value::CZString::index() const { return index_; }
0189 
0190   const char *Value::CZString::c_str() const { return cstr_; }
0191 
0192   bool Value::CZString::isStaticString() const { return index_ == noDuplication; }
0193 
0194 #endif  // ifndef JSON_VALUE_USE_INTERNAL_MAP
0195 
0196   // //////////////////////////////////////////////////////////////////
0197   // //////////////////////////////////////////////////////////////////
0198   // //////////////////////////////////////////////////////////////////
0199   // class Value::Value
0200   // //////////////////////////////////////////////////////////////////
0201   // //////////////////////////////////////////////////////////////////
0202   // //////////////////////////////////////////////////////////////////
0203 
0204   /*! \internal Default constructor initialization must be equivalent to:
0205  * memset( this, 0, sizeof(Value) )
0206  * This optimization is used in ValueInternalMap fast allocator.
0207  */
0208   Value::Value(ValueType type)
0209       : type_(type),
0210         allocated_(0),
0211         comments_(nullptr)
0212 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0213         ,
0214         itemIsUsed_(0)
0215 #endif
0216   {
0217     switch (type) {
0218       case nullValue:
0219         break;
0220       case intValue:
0221       case uintValue:
0222         value_.int_ = 0;
0223         break;
0224       case realValue:
0225         value_.real_ = 0.0;
0226         break;
0227       case stringValue:
0228         value_.string_ = nullptr;
0229         break;
0230 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0231       case arrayValue:
0232       case objectValue:
0233         value_.map_ = new ObjectValues();
0234         break;
0235 #else
0236       case arrayValue:
0237         value_.array_ = arrayAllocator()->newArray();
0238         break;
0239       case objectValue:
0240         value_.map_ = mapAllocator()->newMap();
0241         break;
0242 #endif
0243       case booleanValue:
0244         value_.bool_ = false;
0245         break;
0246       default:
0247         JSON_ASSERT_UNREACHABLE;
0248     }
0249   }
0250 
0251   Value::Value(Int value)
0252       : type_(intValue),
0253         comments_(nullptr)
0254 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0255         ,
0256         itemIsUsed_(0)
0257 #endif
0258   {
0259     value_.int_ = value;
0260   }
0261 
0262   Value::Value(UInt value)
0263       : type_(uintValue),
0264         comments_(nullptr)
0265 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0266         ,
0267         itemIsUsed_(0)
0268 #endif
0269   {
0270     value_.uint_ = value;
0271   }
0272 
0273   Value::Value(double value)
0274       : type_(realValue),
0275         comments_(nullptr)
0276 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0277         ,
0278         itemIsUsed_(0)
0279 #endif
0280   {
0281     value_.real_ = value;
0282   }
0283 
0284   Value::Value(const char *value)
0285       : type_(stringValue),
0286         allocated_(true),
0287         comments_(nullptr)
0288 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0289         ,
0290         itemIsUsed_(0)
0291 #endif
0292   {
0293     value_.string_ = valueAllocator()->duplicateStringValue(value);
0294   }
0295 
0296   Value::Value(const char *beginValue, const char *endValue)
0297       : type_(stringValue),
0298         allocated_(true),
0299         comments_(nullptr)
0300 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0301         ,
0302         itemIsUsed_(0)
0303 #endif
0304   {
0305     value_.string_ = valueAllocator()->duplicateStringValue(beginValue, UInt(endValue - beginValue));
0306   }
0307 
0308   Value::Value(const std::string &value)
0309       : type_(stringValue),
0310         allocated_(true),
0311         comments_(nullptr)
0312 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0313         ,
0314         itemIsUsed_(0)
0315 #endif
0316   {
0317     value_.string_ = valueAllocator()->duplicateStringValue(value.c_str(), (unsigned int)value.length());
0318   }
0319 
0320   Value::Value(const StaticString &value)
0321       : type_(stringValue),
0322         allocated_(false),
0323         comments_(nullptr)
0324 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0325         ,
0326         itemIsUsed_(0)
0327 #endif
0328   {
0329     value_.string_ = const_cast<char *>(value.c_str());
0330   }
0331 
0332 #ifdef JSON_USE_CPPTL
0333   Value::Value(const CppTL::ConstString &value)
0334       : type_(stringValue),
0335         allocated_(true),
0336         comments_(0)
0337 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0338         ,
0339         itemIsUsed_(0)
0340 #endif
0341   {
0342     value_.string_ = valueAllocator()->duplicateStringValue(value, value.length());
0343   }
0344 #endif
0345 
0346   Value::Value(bool value)
0347       : type_(booleanValue),
0348         comments_(nullptr)
0349 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0350         ,
0351         itemIsUsed_(0)
0352 #endif
0353   {
0354     value_.bool_ = value;
0355   }
0356 
0357   Value::Value(const Value &other)
0358       : type_(other.type_),
0359         comments_(nullptr)
0360 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0361         ,
0362         itemIsUsed_(0)
0363 #endif
0364   {
0365     switch (type_) {
0366       case nullValue:
0367       case intValue:
0368       case uintValue:
0369       case realValue:
0370       case booleanValue:
0371         value_ = other.value_;
0372         break;
0373       case stringValue:
0374         if (other.value_.string_) {
0375           value_.string_ = valueAllocator()->duplicateStringValue(other.value_.string_);
0376           allocated_ = true;
0377         } else
0378           value_.string_ = nullptr;
0379         break;
0380 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0381       case arrayValue:
0382       case objectValue:
0383         value_.map_ = new ObjectValues(*other.value_.map_);
0384         break;
0385 #else
0386       case arrayValue:
0387         value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_);
0388         break;
0389       case objectValue:
0390         value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_);
0391         break;
0392 #endif
0393       default:
0394         JSON_ASSERT_UNREACHABLE;
0395     }
0396     if (other.comments_) {
0397       comments_ = new CommentInfo[numberOfCommentPlacement];
0398       for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
0399         const CommentInfo &otherComment = other.comments_[comment];
0400         if (otherComment.comment_)
0401           comments_[comment].setComment(otherComment.comment_);
0402       }
0403     }
0404   }
0405 
0406   Value::~Value() {
0407     switch (type_) {
0408       case nullValue:
0409       case intValue:
0410       case uintValue:
0411       case realValue:
0412       case booleanValue:
0413         break;
0414       case stringValue:
0415         if (allocated_)
0416           valueAllocator()->releaseStringValue(value_.string_);
0417         break;
0418 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0419       case arrayValue:
0420       case objectValue:
0421         delete value_.map_;
0422         break;
0423 #else
0424       case arrayValue:
0425         arrayAllocator()->destructArray(value_.array_);
0426         break;
0427       case objectValue:
0428         mapAllocator()->destructMap(value_.map_);
0429         break;
0430 #endif
0431       default:
0432         JSON_ASSERT_UNREACHABLE;
0433     }
0434 
0435     if (comments_)
0436       delete[] comments_;
0437   }
0438 
0439   Value &Value::operator=(const Value &other) {
0440     Value temp(other);
0441     swap(temp);
0442     return *this;
0443   }
0444 
0445   void Value::swap(Value &other) {
0446     ValueType temp = type_;
0447     type_ = other.type_;
0448     other.type_ = temp;
0449     std::swap(value_, other.value_);
0450     int temp2 = allocated_;
0451     allocated_ = other.allocated_;
0452     other.allocated_ = temp2;
0453   }
0454 
0455   ValueType Value::type() const { return type_; }
0456 
0457   int Value::compare(const Value &other) {
0458     /*
0459    int typeDelta = other.type_ - type_;
0460    switch ( type_ )
0461    {
0462    case nullValue:
0463 
0464       return other.type_ == type_;
0465    case intValue:
0466       if ( other.type_.isNumeric()
0467    case uintValue:
0468    case realValue:
0469    case booleanValue:
0470       break;
0471    case stringValue,
0472       break;
0473    case arrayValue:
0474       delete value_.array_;
0475       break;
0476    case objectValue:
0477       delete value_.map_;
0478    default:
0479       JSON_ASSERT_UNREACHABLE;
0480    }
0481    */
0482     return 0;  // unreachable
0483   }
0484 
0485   bool Value::operator<(const Value &other) const {
0486     int typeDelta = type_ - other.type_;
0487     if (typeDelta)
0488       return typeDelta < 0 ? true : false;
0489     switch (type_) {
0490       case nullValue:
0491         return false;
0492       case intValue:
0493         return value_.int_ < other.value_.int_;
0494       case uintValue:
0495         return value_.uint_ < other.value_.uint_;
0496       case realValue:
0497         return value_.real_ < other.value_.real_;
0498       case booleanValue:
0499         return value_.bool_ < other.value_.bool_;
0500       case stringValue:
0501         return (value_.string_ == nullptr && other.value_.string_) ||
0502                (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) < 0);
0503 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0504       case arrayValue:
0505       case objectValue: {
0506         int delta = int(value_.map_->size() - other.value_.map_->size());
0507         if (delta)
0508           return delta < 0;
0509         return (*value_.map_) < (*other.value_.map_);
0510       }
0511 #else
0512       case arrayValue:
0513         return value_.array_->compare(*(other.value_.array_)) < 0;
0514       case objectValue:
0515         return value_.map_->compare(*(other.value_.map_)) < 0;
0516 #endif
0517       default:
0518         JSON_ASSERT_UNREACHABLE;
0519     }
0520     return false;  // unreachable
0521   }
0522 
0523   bool Value::operator<=(const Value &other) const { return !(other > *this); }
0524 
0525   bool Value::operator>=(const Value &other) const { return !(*this < other); }
0526 
0527   bool Value::operator>(const Value &other) const { return other < *this; }
0528 
0529   bool Value::operator==(const Value &other) const {
0530     //if ( type_ != other.type_ )
0531     // GCC 2.95.3 says:
0532     // attempt to take address of bit-field structure member `Json::Value::type_'
0533     // Beats me, but a temp solves the problem.
0534     int temp = other.type_;
0535     if (type_ != temp)
0536       return false;
0537     switch (type_) {
0538       case nullValue:
0539         return true;
0540       case intValue:
0541         return value_.int_ == other.value_.int_;
0542       case uintValue:
0543         return value_.uint_ == other.value_.uint_;
0544       case realValue:
0545         return value_.real_ == other.value_.real_;
0546       case booleanValue:
0547         return value_.bool_ == other.value_.bool_;
0548       case stringValue:
0549         return (value_.string_ == other.value_.string_) ||
0550                (other.value_.string_ && value_.string_ && strcmp(value_.string_, other.value_.string_) == 0);
0551 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0552       case arrayValue:
0553       case objectValue:
0554         return value_.map_->size() == other.value_.map_->size() && (*value_.map_) == (*other.value_.map_);
0555 #else
0556       case arrayValue:
0557         return value_.array_->compare(*(other.value_.array_)) == 0;
0558       case objectValue:
0559         return value_.map_->compare(*(other.value_.map_)) == 0;
0560 #endif
0561       default:
0562         JSON_ASSERT_UNREACHABLE;
0563     }
0564     return false;  // unreachable
0565   }
0566 
0567   bool Value::operator!=(const Value &other) const { return !(*this == other); }
0568 
0569   const char *Value::asCString() const {
0570     JSON_ASSERT(type_ == stringValue);
0571     return value_.string_;
0572   }
0573 
0574   std::string Value::asString() const {
0575     switch (type_) {
0576       case nullValue:
0577         return "";
0578       case stringValue:
0579         return value_.string_ ? value_.string_ : "";
0580       case booleanValue:
0581         return value_.bool_ ? "true" : "false";
0582       case intValue:
0583       case uintValue:
0584       case realValue:
0585       case arrayValue:
0586       case objectValue:
0587         JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
0588       default:
0589         JSON_ASSERT_UNREACHABLE;
0590     }
0591     return "";  // unreachable
0592   }
0593 
0594 #ifdef JSON_USE_CPPTL
0595   CppTL::ConstString Value::asConstString() const { return CppTL::ConstString(asString().c_str()); }
0596 #endif
0597 
0598   Value::Int Value::asInt() const {
0599     switch (type_) {
0600       case nullValue:
0601         return 0;
0602       case intValue:
0603         return value_.int_;
0604       case uintValue:
0605         JSON_ASSERT_MESSAGE(value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
0606         return value_.uint_;
0607       case realValue:
0608         JSON_ASSERT_MESSAGE(value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
0609         return Int(value_.real_);
0610       case booleanValue:
0611         return value_.bool_ ? 1 : 0;
0612       case stringValue:
0613       case arrayValue:
0614       case objectValue:
0615         JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
0616       default:
0617         JSON_ASSERT_UNREACHABLE;
0618     }
0619     return 0;  // unreachable;
0620   }
0621 
0622   Value::UInt Value::asUInt() const {
0623     switch (type_) {
0624       case nullValue:
0625         return 0;
0626       case intValue:
0627         JSON_ASSERT_MESSAGE(value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
0628         return value_.int_;
0629       case uintValue:
0630         return value_.uint_;
0631       case realValue:
0632         JSON_ASSERT_MESSAGE(value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
0633         return UInt(value_.real_);
0634       case booleanValue:
0635         return value_.bool_ ? 1 : 0;
0636       case stringValue:
0637       case arrayValue:
0638       case objectValue:
0639         JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
0640       default:
0641         JSON_ASSERT_UNREACHABLE;
0642     }
0643     return 0;  // unreachable;
0644   }
0645 
0646   double Value::asDouble() const {
0647     switch (type_) {
0648       case nullValue:
0649         return 0.0;
0650       case intValue:
0651         return value_.int_;
0652       case uintValue:
0653         return value_.uint_;
0654       case realValue:
0655         return value_.real_;
0656       case booleanValue:
0657         return value_.bool_ ? 1.0 : 0.0;
0658       case stringValue:
0659       case arrayValue:
0660       case objectValue:
0661         JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
0662       default:
0663         JSON_ASSERT_UNREACHABLE;
0664     }
0665     return 0;  // unreachable;
0666   }
0667 
0668   bool Value::asBool() const {
0669     switch (type_) {
0670       case nullValue:
0671         return false;
0672       case intValue:
0673       case uintValue:
0674         return value_.int_ != 0;
0675       case realValue:
0676         return value_.real_ != 0.0;
0677       case booleanValue:
0678         return value_.bool_;
0679       case stringValue:
0680         return value_.string_ && value_.string_[0] != 0;
0681       case arrayValue:
0682       case objectValue:
0683         return !value_.map_->empty();
0684       default:
0685         JSON_ASSERT_UNREACHABLE;
0686     }
0687     return false;  // unreachable;
0688   }
0689 
0690   bool Value::isConvertibleTo(ValueType other) const {
0691     switch (type_) {
0692       case nullValue:
0693         return true;
0694       case intValue:
0695         return (other == nullValue && value_.int_ == 0) || other == intValue ||
0696                (other == uintValue && value_.int_ >= 0) || other == realValue || other == stringValue ||
0697                other == booleanValue;
0698       case uintValue:
0699         return (other == nullValue && value_.uint_ == 0) || (other == intValue && value_.uint_ <= (unsigned)maxInt) ||
0700                other == uintValue || other == realValue || other == stringValue || other == booleanValue;
0701       case realValue:
0702         return (other == nullValue && value_.real_ == 0.0) ||
0703                (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt) ||
0704                (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt) || other == realValue ||
0705                other == stringValue || other == booleanValue;
0706       case booleanValue:
0707         return (other == nullValue && value_.bool_ == false) || other == intValue || other == uintValue ||
0708                other == realValue || other == stringValue || other == booleanValue;
0709       case stringValue:
0710         return other == stringValue || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
0711       case arrayValue:
0712         return other == arrayValue || (other == nullValue && value_.map_->empty());
0713       case objectValue:
0714         return other == objectValue || (other == nullValue && value_.map_->empty());
0715       default:
0716         JSON_ASSERT_UNREACHABLE;
0717     }
0718     return false;  // unreachable;
0719   }
0720 
0721   /// Number of values in array or object
0722   Value::UInt Value::size() const {
0723     switch (type_) {
0724       case nullValue:
0725       case intValue:
0726       case uintValue:
0727       case realValue:
0728       case booleanValue:
0729       case stringValue:
0730         return 0;
0731 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0732       case arrayValue:  // size of the array is highest index + 1
0733         if (!value_.map_->empty()) {
0734           ObjectValues::const_iterator itLast = value_.map_->end();
0735           --itLast;
0736           return (*itLast).first.index() + 1;
0737         }
0738         return 0;
0739       case objectValue:
0740         return Int(value_.map_->size());
0741 #else
0742       case arrayValue:
0743         return Int(value_.array_->size());
0744       case objectValue:
0745         return Int(value_.map_->size());
0746 #endif
0747       default:
0748         JSON_ASSERT_UNREACHABLE;
0749     }
0750     return 0;  // unreachable;
0751   }
0752 
0753   bool Value::empty() const {
0754     if (isNull() || isArray() || isObject())
0755       return size() == 0u;
0756     else
0757       return false;
0758   }
0759 
0760   bool Value::operator!() const { return isNull(); }
0761 
0762   void Value::clear() {
0763     JSON_ASSERT(type_ == nullValue || type_ == arrayValue || type_ == objectValue);
0764 
0765     switch (type_) {
0766 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0767       case arrayValue:
0768       case objectValue:
0769         value_.map_->clear();
0770         break;
0771 #else
0772       case arrayValue:
0773         value_.array_->clear();
0774         break;
0775       case objectValue:
0776         value_.map_->clear();
0777         break;
0778 #endif
0779       default:
0780         break;
0781     }
0782   }
0783 
0784   void Value::resize(UInt newSize) {
0785     JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0786     if (type_ == nullValue)
0787       *this = Value(arrayValue);
0788 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0789     UInt oldSize = size();
0790     if (newSize == 0)
0791       clear();
0792     else if (newSize > oldSize)
0793       (*this)[newSize - 1];
0794     else {
0795       for (UInt index = newSize; index < oldSize; ++index)
0796         value_.map_->erase(index);
0797       assert(size() == newSize);
0798     }
0799 #else
0800     value_.array_->resize(newSize);
0801 #endif
0802   }
0803 
0804   Value &Value::operator[](UInt index) {
0805     JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0806     if (type_ == nullValue)
0807       *this = Value(arrayValue);
0808 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0809     CZString key(index);
0810     ObjectValues::iterator it = value_.map_->lower_bound(key);
0811     if (it != value_.map_->end() && (*it).first == key)
0812       return (*it).second;
0813 
0814     ObjectValues::value_type defaultValue(key, null);
0815     it = value_.map_->insert(it, defaultValue);
0816     return (*it).second;
0817 #else
0818     return value_.array_->resolveReference(index);
0819 #endif
0820   }
0821 
0822   const Value &Value::operator[](UInt index) const {
0823     JSON_ASSERT(type_ == nullValue || type_ == arrayValue);
0824     if (type_ == nullValue)
0825       return null;
0826 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0827     CZString key(index);
0828     ObjectValues::const_iterator it = value_.map_->find(key);
0829     if (it == value_.map_->end())
0830       return null;
0831     return (*it).second;
0832 #else
0833     Value *value = value_.array_->find(index);
0834     return value ? *value : null;
0835 #endif
0836   }
0837 
0838   Value &Value::operator[](const char *key) { return resolveReference(key, false); }
0839 
0840   Value &Value::resolveReference(const char *key, bool isStatic) {
0841     JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0842     if (type_ == nullValue)
0843       *this = Value(objectValue);
0844 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0845     CZString actualKey(key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy);
0846     ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
0847     if (it != value_.map_->end() && (*it).first == actualKey)
0848       return (*it).second;
0849 
0850     ObjectValues::value_type defaultValue(actualKey, null);
0851     it = value_.map_->insert(it, defaultValue);
0852     Value &value = (*it).second;
0853     return value;
0854 #else
0855     return value_.map_->resolveReference(key, isStatic);
0856 #endif
0857   }
0858 
0859   Value Value::get(UInt index, const Value &defaultValue) const {
0860     const Value *value = &((*this)[index]);
0861     return value == &null ? defaultValue : *value;
0862   }
0863 
0864   bool Value::isValidIndex(UInt index) const { return index < size(); }
0865 
0866   const Value &Value::operator[](const char *key) const {
0867     JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0868     if (type_ == nullValue)
0869       return null;
0870 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0871     CZString actualKey(key, CZString::noDuplication);
0872     ObjectValues::const_iterator it = value_.map_->find(actualKey);
0873     if (it == value_.map_->end())
0874       return null;
0875     return (*it).second;
0876 #else
0877     const Value *value = value_.map_->find(key);
0878     return value ? *value : null;
0879 #endif
0880   }
0881 
0882   Value &Value::operator[](const std::string &key) { return (*this)[key.c_str()]; }
0883 
0884   const Value &Value::operator[](const std::string &key) const { return (*this)[key.c_str()]; }
0885 
0886   Value &Value::operator[](const StaticString &key) { return resolveReference(key, true); }
0887 
0888 #ifdef JSON_USE_CPPTL
0889   Value &Value::operator[](const CppTL::ConstString &key) { return (*this)[key.c_str()]; }
0890 
0891   const Value &Value::operator[](const CppTL::ConstString &key) const { return (*this)[key.c_str()]; }
0892 #endif
0893 
0894   Value &Value::append(const Value &value) { return (*this)[size()] = value; }
0895 
0896   Value Value::get(const char *key, const Value &defaultValue) const {
0897     const Value *value = &((*this)[key]);
0898     return value == &null ? defaultValue : *value;
0899   }
0900 
0901   Value Value::get(const std::string &key, const Value &defaultValue) const { return get(key.c_str(), defaultValue); }
0902 
0903   Value Value::removeMember(const char *key) {
0904     JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0905     if (type_ == nullValue)
0906       return null;
0907 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0908     CZString actualKey(key, CZString::noDuplication);
0909     ObjectValues::iterator it = value_.map_->find(actualKey);
0910     if (it == value_.map_->end())
0911       return null;
0912     Value old(it->second);
0913     value_.map_->erase(it);
0914     return old;
0915 #else
0916     Value *value = value_.map_->find(key);
0917     if (value) {
0918       Value old(*value);
0919       value_.map_.remove(key);
0920       return old;
0921     } else {
0922       return null;
0923     }
0924 #endif
0925   }
0926 
0927   Value Value::removeMember(const std::string &key) { return removeMember(key.c_str()); }
0928 
0929 #ifdef JSON_USE_CPPTL
0930   Value Value::get(const CppTL::ConstString &key, const Value &defaultValue) const {
0931     return get(key.c_str(), defaultValue);
0932   }
0933 #endif
0934 
0935   bool Value::isMember(const char *key) const {
0936     const Value *value = &((*this)[key]);
0937     return value != &null;
0938   }
0939 
0940   bool Value::isMember(const std::string &key) const { return isMember(key.c_str()); }
0941 
0942 #ifdef JSON_USE_CPPTL
0943   bool Value::isMember(const CppTL::ConstString &key) const { return isMember(key.c_str()); }
0944 #endif
0945 
0946   Value::Members Value::getMemberNames() const {
0947     JSON_ASSERT(type_ == nullValue || type_ == objectValue);
0948     if (type_ == nullValue)
0949       return Value::Members();
0950     Members members;
0951     members.reserve(value_.map_->size());
0952 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0953     ObjectValues::const_iterator it = value_.map_->begin();
0954     ObjectValues::const_iterator itEnd = value_.map_->end();
0955     for (; it != itEnd; ++it)
0956       members.push_back(std::string((*it).first.c_str()));
0957 #else
0958     ValueInternalMap::IteratorState it;
0959     ValueInternalMap::IteratorState itEnd;
0960     value_.map_->makeBeginIterator(it);
0961     value_.map_->makeEndIterator(itEnd);
0962     for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it))
0963       members.push_back(std::string(ValueInternalMap::key(it)));
0964 #endif
0965     return members;
0966   }
0967   //
0968   //# ifdef JSON_USE_CPPTL
0969   //EnumMemberNames
0970   //Value::enumMemberNames() const
0971   //{
0972   //   if ( type_ == objectValue )
0973   //   {
0974   //      return CppTL::Enum::any(  CppTL::Enum::transform(
0975   //         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
0976   //         MemberNamesTransform() ) );
0977   //   }
0978   //   return EnumMemberNames();
0979   //}
0980   //
0981   //
0982   //EnumValues
0983   //Value::enumValues() const
0984   //{
0985   //   if ( type_ == objectValue  ||  type_ == arrayValue )
0986   //      return CppTL::Enum::anyValues( *(value_.map_),
0987   //                                     CppTL::Type<const Value &>() );
0988   //   return EnumValues();
0989   //}
0990   //
0991   //# endif
0992 
0993   bool Value::isNull() const { return type_ == nullValue; }
0994 
0995   bool Value::isBool() const { return type_ == booleanValue; }
0996 
0997   bool Value::isInt() const { return type_ == intValue; }
0998 
0999   bool Value::isUInt() const { return type_ == uintValue; }
1000 
1001   bool Value::isIntegral() const { return type_ == intValue || type_ == uintValue || type_ == booleanValue; }
1002 
1003   bool Value::isDouble() const { return type_ == realValue; }
1004 
1005   bool Value::isNumeric() const { return isIntegral() || isDouble(); }
1006 
1007   bool Value::isString() const { return type_ == stringValue; }
1008 
1009   bool Value::isArray() const { return type_ == nullValue || type_ == arrayValue; }
1010 
1011   bool Value::isObject() const { return type_ == nullValue || type_ == objectValue; }
1012 
1013   void Value::setComment(const char *comment, CommentPlacement placement) {
1014     if (!comments_)
1015       comments_ = new CommentInfo[numberOfCommentPlacement];
1016     comments_[placement].setComment(comment);
1017   }
1018 
1019   void Value::setComment(const std::string &comment, CommentPlacement placement) {
1020     setComment(comment.c_str(), placement);
1021   }
1022 
1023   bool Value::hasComment(CommentPlacement placement) const {
1024     return comments_ != nullptr && comments_[placement].comment_ != nullptr;
1025   }
1026 
1027   std::string Value::getComment(CommentPlacement placement) const {
1028     if (hasComment(placement))
1029       return comments_[placement].comment_;
1030     return "";
1031   }
1032 
1033   std::string Value::toStyledString() const {
1034     StyledWriter writer;
1035     return writer.write(*this);
1036   }
1037 
1038   Value::const_iterator Value::begin() const {
1039     switch (type_) {
1040 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1041       case arrayValue:
1042         if (value_.array_) {
1043           ValueInternalArray::IteratorState it;
1044           value_.array_->makeBeginIterator(it);
1045           return const_iterator(it);
1046         }
1047         break;
1048       case objectValue:
1049         if (value_.map_) {
1050           ValueInternalMap::IteratorState it;
1051           value_.map_->makeBeginIterator(it);
1052           return const_iterator(it);
1053         }
1054         break;
1055 #else
1056       case arrayValue:
1057       case objectValue:
1058         if (value_.map_)
1059           return const_iterator(value_.map_->begin());
1060         break;
1061 #endif
1062       default:
1063         break;
1064     }
1065     return const_iterator();
1066   }
1067 
1068   Value::const_iterator Value::end() const {
1069     switch (type_) {
1070 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1071       case arrayValue:
1072         if (value_.array_) {
1073           ValueInternalArray::IteratorState it;
1074           value_.array_->makeEndIterator(it);
1075           return const_iterator(it);
1076         }
1077         break;
1078       case objectValue:
1079         if (value_.map_) {
1080           ValueInternalMap::IteratorState it;
1081           value_.map_->makeEndIterator(it);
1082           return const_iterator(it);
1083         }
1084         break;
1085 #else
1086       case arrayValue:
1087       case objectValue:
1088         if (value_.map_)
1089           return const_iterator(value_.map_->end());
1090         break;
1091 #endif
1092       default:
1093         break;
1094     }
1095     return const_iterator();
1096   }
1097 
1098   Value::iterator Value::begin() {
1099     switch (type_) {
1100 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1101       case arrayValue:
1102         if (value_.array_) {
1103           ValueInternalArray::IteratorState it;
1104           value_.array_->makeBeginIterator(it);
1105           return iterator(it);
1106         }
1107         break;
1108       case objectValue:
1109         if (value_.map_) {
1110           ValueInternalMap::IteratorState it;
1111           value_.map_->makeBeginIterator(it);
1112           return iterator(it);
1113         }
1114         break;
1115 #else
1116       case arrayValue:
1117       case objectValue:
1118         if (value_.map_)
1119           return iterator(value_.map_->begin());
1120         break;
1121 #endif
1122       default:
1123         break;
1124     }
1125     return iterator();
1126   }
1127 
1128   Value::iterator Value::end() {
1129     switch (type_) {
1130 #ifdef JSON_VALUE_USE_INTERNAL_MAP
1131       case arrayValue:
1132         if (value_.array_) {
1133           ValueInternalArray::IteratorState it;
1134           value_.array_->makeEndIterator(it);
1135           return iterator(it);
1136         }
1137         break;
1138       case objectValue:
1139         if (value_.map_) {
1140           ValueInternalMap::IteratorState it;
1141           value_.map_->makeEndIterator(it);
1142           return iterator(it);
1143         }
1144         break;
1145 #else
1146       case arrayValue:
1147       case objectValue:
1148         if (value_.map_)
1149           return iterator(value_.map_->end());
1150         break;
1151 #endif
1152       default:
1153         break;
1154     }
1155     return iterator();
1156   }
1157 
1158   // class PathArgument
1159   // //////////////////////////////////////////////////////////////////
1160 
1161   PathArgument::PathArgument() : kind_(kindNone) {}
1162 
1163   PathArgument::PathArgument(Value::UInt index) : index_(index), kind_(kindIndex) {}
1164 
1165   PathArgument::PathArgument(const char *key) : key_(key), kind_(kindKey) {}
1166 
1167   PathArgument::PathArgument(const std::string &key) : key_(key), kind_(kindKey) {}
1168 
1169   // class Path
1170   // //////////////////////////////////////////////////////////////////
1171 
1172   Path::Path(const std::string &path,
1173              const PathArgument &a1,
1174              const PathArgument &a2,
1175              const PathArgument &a3,
1176              const PathArgument &a4,
1177              const PathArgument &a5) {
1178     InArgs in;
1179     in.push_back(&a1);
1180     in.push_back(&a2);
1181     in.push_back(&a3);
1182     in.push_back(&a4);
1183     in.push_back(&a5);
1184     makePath(path, in);
1185   }
1186 
1187   void Path::makePath(const std::string &path, const InArgs &in) {
1188     const char *current = path.c_str();
1189     const char *end = current + path.length();
1190     InArgs::const_iterator itInArg = in.begin();
1191     while (current != end) {
1192       if (*current == '[') {
1193         ++current;
1194         if (*current == '%')
1195           addPathInArg(path, in, itInArg, PathArgument::kindIndex);
1196         else {
1197           Value::UInt index = 0;
1198           for (; current != end && *current >= '0' && *current <= '9'; ++current)
1199             index = index * 10 + Value::UInt(*current - '0');
1200           args_.push_back(index);
1201         }
1202         if (current == end || *current++ != ']')
1203           invalidPath(path, int(current - path.c_str()));
1204       } else if (*current == '%') {
1205         addPathInArg(path, in, itInArg, PathArgument::kindKey);
1206         ++current;
1207       } else if (*current == '.') {
1208         ++current;
1209       } else {
1210         const char *beginName = current;
1211         while (current != end && !strchr("[.", *current))
1212           ++current;
1213         args_.push_back(std::string(beginName, current));
1214       }
1215     }
1216   }
1217 
1218   void Path::addPathInArg(const std::string &path,
1219                           const InArgs &in,
1220                           InArgs::const_iterator &itInArg,
1221                           PathArgument::Kind kind) {
1222     if (itInArg == in.end()) {
1223       // Error: missing argument %d
1224     } else if ((*itInArg)->kind_ != kind) {
1225       // Error: bad argument type
1226     } else {
1227       args_.push_back(**itInArg);
1228     }
1229   }
1230 
1231   void Path::invalidPath(const std::string &path, int location) {
1232     // Error: invalid path.
1233   }
1234 
1235   const Value &Path::resolve(const Value &root) const {
1236     const Value *node = &root;
1237     for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1238       const PathArgument &arg = *it;
1239       if (arg.kind_ == PathArgument::kindIndex) {
1240         if (!node->isArray() || node->isValidIndex(arg.index_)) {
1241           // Error: unable to resolve path (array value expected at position...
1242         }
1243         node = &((*node)[arg.index_]);
1244       } else if (arg.kind_ == PathArgument::kindKey) {
1245         if (!node->isObject()) {
1246           // Error: unable to resolve path (object value expected at position...)
1247         }
1248         node = &((*node)[arg.key_]);
1249         if (node == &Value::null) {
1250           // Error: unable to resolve path (object has no member named '' at position...)
1251         }
1252       }
1253     }
1254     return *node;
1255   }
1256 
1257   Value Path::resolve(const Value &root, const Value &defaultValue) const {
1258     const Value *node = &root;
1259     for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1260       const PathArgument &arg = *it;
1261       if (arg.kind_ == PathArgument::kindIndex) {
1262         if (!node->isArray() || node->isValidIndex(arg.index_))
1263           return defaultValue;
1264         node = &((*node)[arg.index_]);
1265       } else if (arg.kind_ == PathArgument::kindKey) {
1266         if (!node->isObject())
1267           return defaultValue;
1268         node = &((*node)[arg.key_]);
1269         if (node == &Value::null)
1270           return defaultValue;
1271       }
1272     }
1273     return *node;
1274   }
1275 
1276   Value &Path::make(Value &root) const {
1277     Value *node = &root;
1278     for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
1279       const PathArgument &arg = *it;
1280       if (arg.kind_ == PathArgument::kindIndex) {
1281         if (!node->isArray()) {
1282           // Error: node is not an array at position ...
1283         }
1284         node = &((*node)[arg.index_]);
1285       } else if (arg.kind_ == PathArgument::kindKey) {
1286         if (!node->isObject()) {
1287           // Error: node is not an object at position...
1288         }
1289         node = &((*node)[arg.key_]);
1290       }
1291     }
1292     return *node;
1293   }
1294 
1295 }  // namespace Json