Expr Simplify::visit(const Cast *op, ExprInfo *bounds) { // We don't try to reason about bounds through casts for now Expr value = mutate(op->value, nullptr); if (may_simplify(op->type) && may_simplify(op->value.type())) { const Call *call = value.as<Call>(); const Cast *cast = value.as<Cast>(); const Broadcast *broadcast_value = value.as<Broadcast>(); const Ramp *ramp_value = value.as<Ramp>(); double f = 0.0; int64_t i = 0; uint64_t u = 0; if (call && (call->is_intrinsic(Call::indeterminate_expression) || call->is_intrinsic(Call::signed_integer_overflow))) { if (call->is_intrinsic(Call::indeterminate_expression)) { return make_indeterminate_expression(op->type); } else { return make_signed_integer_overflow(op->type); } } else if (value.type() == op->type) { return value; } else if (op->type.is_int() && const_float(value, &f) && std::isfinite(f)) { // float -> int return IntImm::make(op->type, safe_numeric_cast<int64_t>(f)); } else if (op->type.is_uint() && const_float(value, &f) && std::isfinite(f)) { // float -> uint return UIntImm::make(op->type, safe_numeric_cast<uint64_t>(f)); } else if (op->type.is_float() && const_float(value, &f)) { // float -> float return FloatImm::make(op->type, f); } else if (op->type.is_int() && const_int(value, &i)) { // int -> int return IntImm::make(op->type, i); } else if (op->type.is_uint() && const_int(value, &i)) { // int -> uint return UIntImm::make(op->type, safe_numeric_cast<uint64_t>(i)); } else if (op->type.is_float() && const_int(value, &i)) { // int -> float return FloatImm::make(op->type, safe_numeric_cast<double>(i)); } else if (op->type.is_int() && const_uint(value, &u)) { // uint -> int return IntImm::make(op->type, safe_numeric_cast<int64_t>(u)); } else if (op->type.is_uint() && const_uint(value, &u)) { // uint -> uint return UIntImm::make(op->type, u); } else if (op->type.is_float() && const_uint(value, &u)) { // uint -> float return FloatImm::make(op->type, safe_numeric_cast<double>(u)); } else if (cast && op->type.code() == cast->type.code() && op->type.bits() < cast->type.bits()) { // If this is a cast of a cast of the same type, where the // outer cast is narrower, the inner cast can be // eliminated. return mutate(Cast::make(op->type, cast->value), bounds); } else if (cast && (op->type.is_int() || op->type.is_uint()) && (cast->type.is_int() || cast->type.is_uint()) && op->type.bits() <= cast->type.bits() && op->type.bits() <= op->value.type().bits()) { // If this is a cast between integer types, where the // outer cast is narrower than the inner cast and the // inner cast's argument, the inner cast can be // eliminated. The inner cast is either a sign extend // or a zero extend, and the outer cast truncates the extended bits return mutate(Cast::make(op->type, cast->value), bounds); } else if (broadcast_value) { // cast(broadcast(x)) -> broadcast(cast(x)) return mutate(Broadcast::make(Cast::make(op->type.element_of(), broadcast_value->value), broadcast_value->lanes), bounds); } else if (ramp_value && op->type.element_of() == Int(64) && op->value.type().element_of() == Int(32)) { // cast(ramp(a, b, w)) -> ramp(cast(a), cast(b), w) return mutate(Ramp::make(Cast::make(op->type.element_of(), ramp_value->base), Cast::make(op->type.element_of(), ramp_value->stride), ramp_value->lanes), bounds); } } if (value.same_as(op->value)) { return op; } else { return Cast::make(op->type, value); } }
int main (){ Any *a2 = x1x_f ( ); Any *a4 = x1x_f ( ); Any *a3 = a4; Any a5 = Int(0); Any a6 = Int(0); a3[a5.i] = a6; Any a12 = Int(0); Any a35 = Int(0); Any a36 = Int( sizeof( a2 ) / sizeof( a2[0] ) ); Any a13 = a2[a12.i]; Any a10 = toStr ( a13 ); println ( a10 ); Any a19 = Int(1); a35 = Int(0); a36 = Int( sizeof( a2 ) / sizeof( a2[0] ) ); Any a20 = a2[a19.i]; Any a17 = toStr ( a20 ); println ( a17 ); Any a26 = Int(0); a35 = Int(0); a36 = Int( sizeof( a3 ) / sizeof( a3[0] ) ); Any a27 = a3[a26.i]; Any a24 = toStr ( a27 ); println ( a24 ); Any a33 = Int(1); a35 = Int(0); a36 = Int( sizeof( a3 ) / sizeof( a3[0] ) ); Any a34 = a3[a33.i]; Any a31 = toStr ( a34 ); println ( a31 ); return 0; }
namespace Json { const Value Value::null; const Int Value::minInt = Int ( ~ (UInt (-1) / 2) ); const Int Value::maxInt = Int ( UInt (-1) / 2 ); const UInt Value::maxUInt = UInt (-1); ValueAllocator::~ValueAllocator () { } class DefaultValueAllocator : public ValueAllocator { public: virtual ~DefaultValueAllocator () { } virtual char* makeMemberName ( const char* memberName ) { return duplicateStringValue ( memberName ); } virtual void releaseMemberName ( char* memberName ) { releaseStringValue ( memberName ); } virtual char* duplicateStringValue ( const char* value, unsigned int length = unknown ) { //@todo invesgate this old optimization //if ( !value || value[0] == 0 ) // return 0; if ( length == unknown ) length = (unsigned int)strlen (value); char* newString = static_cast<char*> ( malloc ( length + 1 ) ); memcpy ( newString, value, length ); newString[length] = 0; return newString; } virtual void releaseStringValue ( char* value ) { if ( value ) free ( value ); } }; static ValueAllocator*& valueAllocator () { static ValueAllocator* valueAllocator = new DefaultValueAllocator; return valueAllocator; } static struct DummyValueAllocatorInitializer { DummyValueAllocatorInitializer () { valueAllocator (); // ensure valueAllocator() statics are initialized before main(). } } dummyValueAllocatorInitializer; // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // class Value::CZString // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // Notes: index_ indicates if the string was allocated when // a string is stored. Value::CZString::CZString ( int index ) : cstr_ ( 0 ) , index_ ( index ) { } Value::CZString::CZString ( const char* cstr, DuplicationPolicy allocate ) : cstr_ ( allocate == duplicate ? valueAllocator ()->makeMemberName (cstr) : cstr ) , index_ ( allocate ) { } Value::CZString::CZString ( const CZString& other ) : cstr_ ( other.index_ != noDuplication&& other.cstr_ != 0 ? valueAllocator ()->makeMemberName ( other.cstr_ ) : other.cstr_ ) , index_ ( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_ ) { } Value::CZString::~CZString () { if ( cstr_ && index_ == duplicate ) valueAllocator ()->releaseMemberName ( const_cast<char*> ( cstr_ ) ); } void Value::CZString::swap ( CZString& other ) noexcept { std::swap ( cstr_, other.cstr_ ); std::swap ( index_, other.index_ ); } Value::CZString& Value::CZString::operator = ( const CZString& other ) { CZString temp ( other ); swap ( temp ); return *this; } bool Value::CZString::operator< ( const CZString& other ) const { if ( cstr_ ) return strcmp ( cstr_, other.cstr_ ) < 0; return index_ < other.index_; } bool Value::CZString::operator== ( const CZString& other ) const { if ( cstr_ ) return strcmp ( cstr_, other.cstr_ ) == 0; return index_ == other.index_; } int Value::CZString::index () const { return index_; } const char* Value::CZString::c_str () const { return cstr_; } bool Value::CZString::isStaticString () const { return index_ == noDuplication; } // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // class Value::Value // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// /*! \internal Default constructor initialization must be equivalent to: * memset( this, 0, sizeof(Value) ) * This optimization is used in ValueInternalMap fast allocator. */ Value::Value ( ValueType type ) : type_ ( type ) , allocated_ ( 0 ) { switch ( type ) { case nullValue: break; case intValue: case uintValue: value_.int_ = 0; break; case realValue: value_.real_ = 0.0; break; case stringValue: value_.string_ = 0; break; case arrayValue: case objectValue: value_.map_ = new ObjectValues (); break; case booleanValue: value_.bool_ = false; break; default: JSON_ASSERT_UNREACHABLE; } } Value::Value ( Int value ) : type_ ( intValue ) { value_.int_ = value; } Value::Value ( UInt value ) : type_ ( uintValue ) { value_.uint_ = value; } Value::Value ( double value ) : type_ ( realValue ) { value_.real_ = value; } Value::Value ( const char* value ) : type_ ( stringValue ) , allocated_ ( true ) { value_.string_ = valueAllocator ()->duplicateStringValue ( value ); } Value::Value ( const char* beginValue, const char* endValue ) : type_ ( stringValue ) , allocated_ ( true ) { value_.string_ = valueAllocator ()->duplicateStringValue ( beginValue, UInt (endValue - beginValue) ); } Value::Value ( std::string const& value ) : type_ ( stringValue ) , allocated_ ( true ) { value_.string_ = valueAllocator ()->duplicateStringValue ( value.c_str (), (unsigned int)value.length () ); } Value::Value (beast::String const& beastString) : type_ ( stringValue ) , allocated_ ( true ) { value_.string_ = valueAllocator ()->duplicateStringValue ( beastString.toStdString ().c_str (), (unsigned int)beastString.length () ); } Value::Value ( const StaticString& value ) : type_ ( stringValue ) , allocated_ ( false ) { value_.string_ = const_cast<char*> ( value.c_str () ); } Value::Value ( bool value ) : type_ ( booleanValue ) { value_.bool_ = value; } Value::Value ( const Value& other ) : type_ ( other.type_ ) { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: value_ = other.value_; break; case stringValue: if ( other.value_.string_ ) { value_.string_ = valueAllocator ()->duplicateStringValue ( other.value_.string_ ); allocated_ = true; } else value_.string_ = 0; break; case arrayValue: case objectValue: value_.map_ = new ObjectValues ( *other.value_.map_ ); break; default: JSON_ASSERT_UNREACHABLE; } } Value::~Value () { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: break; case stringValue: if ( allocated_ ) valueAllocator ()->releaseStringValue ( value_.string_ ); break; case arrayValue: case objectValue: delete value_.map_; break; default: JSON_ASSERT_UNREACHABLE; } } Value& Value::operator= ( const Value& other ) { Value temp ( other ); swap ( temp ); return *this; } Value::Value ( Value&& other ) noexcept : value_ ( other.value_ ) , type_ ( other.type_ ) , allocated_ ( other.allocated_ ) { std::memset( &other, 0, sizeof(Value) ); } Value& Value::operator= ( Value&& other ) noexcept { swap ( other ); return *this; } void Value::swap ( Value& other ) noexcept { std::swap ( value_, other.value_ ); ValueType temp = type_; type_ = other.type_; other.type_ = temp; int temp2 = allocated_; allocated_ = other.allocated_; other.allocated_ = temp2; } ValueType Value::type () const { return type_; } static int integerCmp (Int i, UInt ui) { // All negative numbers are less than all unsigned numbers. if (i < 0) return -1; // All unsigned numbers with bit 0 set are too big for signed integers. if (ui & 0x8000) return 1; // Now we can safely compare. return (i < ui) ? -1 : (i == ui) ? 0 : 1; } bool operator < (const Value& x, const Value& y) { if (auto signum = x.type_ - y.type_) { if (x.type_ == intValue && y.type_ == uintValue) signum = integerCmp (x.value_.int_, y.value_.uint_); else if (x.type_ == uintValue && y.type_ == intValue) signum = - integerCmp (y.value_.int_, x.value_.uint_); return signum < 0; } switch (x.type_) { case nullValue: return false; case intValue: return x.value_.int_ < y.value_.int_; case uintValue: return x.value_.uint_ < y.value_.uint_; case realValue: return x.value_.real_ < y.value_.real_; case booleanValue: return x.value_.bool_ < y.value_.bool_; case stringValue: return (x.value_.string_ == 0 && y.value_.string_) || (y.value_.string_ && x.value_.string_ && strcmp (x.value_.string_, y.value_.string_) < 0); case arrayValue: case objectValue: { if (int signum = int (x.value_.map_->size ()) - y.value_.map_->size ()) return signum < 0; return *x.value_.map_ < *y.value_.map_; } default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable } bool operator== (const Value& x, const Value& y) { if (x.type_ != y.type_) { if (x.type_ == intValue && y.type_ == uintValue) return ! integerCmp (x.value_.int_, y.value_.uint_); if (x.type_ == uintValue && y.type_ == intValue) return ! integerCmp (y.value_.int_, x.value_.uint_); return false; } switch (x.type_) { case nullValue: return true; case intValue: return x.value_.int_ == y.value_.int_; case uintValue: return x.value_.uint_ == y.value_.uint_; case realValue: return x.value_.real_ == y.value_.real_; case booleanValue: return x.value_.bool_ == y.value_.bool_; case stringValue: return x.value_.string_ == y.value_.string_ || (y.value_.string_ && x.value_.string_ && ! strcmp (x.value_.string_, y.value_.string_)); case arrayValue: case objectValue: return x.value_.map_->size () == y.value_.map_->size () && *x.value_.map_ == *y.value_.map_; default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable } const char* Value::asCString () const { JSON_ASSERT ( type_ == stringValue ); return value_.string_; } std::string Value::asString () const { switch ( type_ ) { case nullValue: return ""; case stringValue: return value_.string_ ? value_.string_ : ""; case booleanValue: return value_.bool_ ? "true" : "false"; case intValue: return beast::lexicalCastThrow <std::string> (value_.int_); case uintValue: case realValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE ( false, "Type is not convertible to string" ); default: JSON_ASSERT_UNREACHABLE; } return ""; // unreachable } Value::Int Value::asInt () const { switch ( type_ ) { case nullValue: return 0; case intValue: return value_.int_; case uintValue: JSON_ASSERT_MESSAGE ( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" ); return value_.uint_; case realValue: JSON_ASSERT_MESSAGE ( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" ); return Int ( value_.real_ ); case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: return beast::lexicalCastThrow <int> (value_.string_); case arrayValue: case objectValue: JSON_ASSERT_MESSAGE ( false, "Type is not convertible to int" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } Value::UInt Value::asUInt () const { switch ( type_ ) { case nullValue: return 0; case intValue: JSON_ASSERT_MESSAGE ( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" ); return value_.int_; case uintValue: return value_.uint_; case realValue: JSON_ASSERT_MESSAGE ( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" ); return UInt ( value_.real_ ); case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: return beast::lexicalCastThrow <unsigned int> (value_.string_); case arrayValue: case objectValue: JSON_ASSERT_MESSAGE ( false, "Type is not convertible to uint" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } double Value::asDouble () const { switch ( type_ ) { case nullValue: return 0.0; case intValue: return value_.int_; case uintValue: return value_.uint_; case realValue: return value_.real_; case booleanValue: return value_.bool_ ? 1.0 : 0.0; case stringValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE ( false, "Type is not convertible to double" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } bool Value::asBool () const { switch ( type_ ) { case nullValue: return false; case intValue: case uintValue: return value_.int_ != 0; case realValue: return value_.real_ != 0.0; case booleanValue: return value_.bool_; case stringValue: return value_.string_ && value_.string_[0] != 0; case arrayValue: case objectValue: return value_.map_->size () != 0; default: JSON_ASSERT_UNREACHABLE; } return false; // unreachable; } bool Value::isConvertibleTo ( ValueType other ) const { switch ( type_ ) { case nullValue: return true; case intValue: return ( other == nullValue && value_.int_ == 0 ) || other == intValue || ( other == uintValue && value_.int_ >= 0 ) || other == realValue || other == stringValue || other == booleanValue; case uintValue: return ( other == nullValue && value_.uint_ == 0 ) || ( other == intValue && value_.uint_ <= (unsigned)maxInt ) || other == uintValue || other == realValue || other == stringValue || other == booleanValue; case realValue: return ( other == nullValue && value_.real_ == 0.0 ) || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt ) || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt ) || other == realValue || other == stringValue || other == booleanValue; case booleanValue: return ( other == nullValue && value_.bool_ == false ) || other == intValue || other == uintValue || other == realValue || other == stringValue || other == booleanValue; case stringValue: return other == stringValue || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) ); case arrayValue: return other == arrayValue || ( other == nullValue && value_.map_->size () == 0 ); case objectValue: return other == objectValue || ( other == nullValue && value_.map_->size () == 0 ); default: JSON_ASSERT_UNREACHABLE; } return false; // unreachable; } /// Number of values in array or object Value::UInt Value::size () const { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: case stringValue: return 0; case arrayValue: // size of the array is highest index + 1 if ( !value_.map_->empty () ) { ObjectValues::const_iterator itLast = value_.map_->end (); --itLast; return (*itLast).first.index () + 1; } return 0; case objectValue: return Int ( value_.map_->size () ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } Value::operator bool () const { if (isNull ()) return false; if (isString ()) { auto s = asCString(); return s && strlen(s); } return ! (isArray () || isObject ()) || size (); } void Value::clear () { JSON_ASSERT ( type_ == nullValue || type_ == arrayValue || type_ == objectValue ); switch ( type_ ) { case arrayValue: case objectValue: value_.map_->clear (); break; default: break; } } void Value::resize ( UInt newSize ) { JSON_ASSERT ( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) *this = Value ( arrayValue ); UInt oldSize = size (); if ( newSize == 0 ) clear (); else if ( newSize > oldSize ) (*this)[ newSize - 1 ]; else { for ( UInt index = newSize; index < oldSize; ++index ) value_.map_->erase ( index ); assert ( size () == newSize ); } } Value& Value::operator[] ( UInt index ) { JSON_ASSERT ( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) *this = Value ( arrayValue ); CZString key ( index ); ObjectValues::iterator it = value_.map_->lower_bound ( key ); if ( it != value_.map_->end () && (*it).first == key ) return (*it).second; ObjectValues::value_type defaultValue ( key, null ); it = value_.map_->insert ( it, defaultValue ); return (*it).second; } const Value& Value::operator[] ( UInt index ) const { JSON_ASSERT ( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) return null; CZString key ( index ); ObjectValues::const_iterator it = value_.map_->find ( key ); if ( it == value_.map_->end () ) return null; return (*it).second; } Value& Value::operator[] ( const char* key ) { return resolveReference ( key, false ); } Value& Value::resolveReference ( const char* key, bool isStatic ) { JSON_ASSERT ( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) *this = Value ( objectValue ); CZString actualKey ( key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy ); ObjectValues::iterator it = value_.map_->lower_bound ( actualKey ); if ( it != value_.map_->end () && (*it).first == actualKey ) return (*it).second; ObjectValues::value_type defaultValue ( actualKey, null ); it = value_.map_->insert ( it, defaultValue ); Value& value = (*it).second; return value; } Value Value::get ( UInt index, const Value& defaultValue ) const { const Value* value = & ((*this)[index]); return value == &null ? defaultValue : *value; } bool Value::isValidIndex ( UInt index ) const { return index < size (); } const Value& Value::operator[] ( const char* key ) const { JSON_ASSERT ( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return null; CZString actualKey ( key, CZString::noDuplication ); ObjectValues::const_iterator it = value_.map_->find ( actualKey ); if ( it == value_.map_->end () ) return null; return (*it).second; } Value& Value::operator[] ( std::string const& key ) { return (*this)[ key.c_str () ]; } const Value& Value::operator[] ( std::string const& key ) const { return (*this)[ key.c_str () ]; } Value& Value::operator[] ( const StaticString& key ) { return resolveReference ( key, true ); } Value& Value::append ( const Value& value ) { return (*this)[size ()] = value; } Value Value::get ( const char* key, const Value& defaultValue ) const { const Value* value = & ((*this)[key]); return value == &null ? defaultValue : *value; } Value Value::get ( std::string const& key, const Value& defaultValue ) const { return get ( key.c_str (), defaultValue ); } Value Value::removeMember ( const char* key ) { JSON_ASSERT ( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return null; CZString actualKey ( key, CZString::noDuplication ); ObjectValues::iterator it = value_.map_->find ( actualKey ); if ( it == value_.map_->end () ) return null; Value old (it->second); value_.map_->erase (it); return old; } Value Value::removeMember ( std::string const& key ) { return removeMember ( key.c_str () ); } bool Value::isMember ( const char* key ) const { const Value* value = & ((*this)[key]); return value != &null; } bool Value::isMember ( std::string const& key ) const { return isMember ( key.c_str () ); } Value::Members Value::getMemberNames () const { JSON_ASSERT ( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return Value::Members (); Members members; members.reserve ( value_.map_->size () ); ObjectValues::const_iterator it = value_.map_->begin (); ObjectValues::const_iterator itEnd = value_.map_->end (); for ( ; it != itEnd; ++it ) members.push_back ( std::string ( (*it).first.c_str () ) ); return members; } bool Value::isNull () const { return type_ == nullValue; } bool Value::isBool () const { return type_ == booleanValue; } bool Value::isInt () const { return type_ == intValue; } bool Value::isUInt () const { return type_ == uintValue; } bool Value::isIntegral () const { return type_ == intValue || type_ == uintValue || type_ == booleanValue; } bool Value::isDouble () const { return type_ == realValue; } bool Value::isNumeric () const { return isIntegral () || isDouble (); } bool Value::isString () const { return type_ == stringValue; } bool Value::isArray () const { return type_ == nullValue || type_ == arrayValue; } bool Value::isObject () const { return type_ == nullValue || type_ == objectValue; } std::string Value::toStyledString () const { StyledWriter writer; return writer.write ( *this ); } Value::const_iterator Value::begin () const { switch ( type_ ) { case arrayValue: case objectValue: if ( value_.map_ ) return const_iterator ( value_.map_->begin () ); break; default: break; } return const_iterator (); } Value::const_iterator Value::end () const { switch ( type_ ) { case arrayValue: case objectValue: if ( value_.map_ ) return const_iterator ( value_.map_->end () ); break; default: break; } return const_iterator (); } Value::iterator Value::begin () { switch ( type_ ) { case arrayValue: case objectValue: if ( value_.map_ ) return iterator ( value_.map_->begin () ); break; default: break; } return iterator (); } Value::iterator Value::end () { switch ( type_ ) { case arrayValue: case objectValue: if ( value_.map_ ) return iterator ( value_.map_->end () ); break; default: break; } return iterator (); } } // namespace Json
Int operator+(int x) { return *this + Int(x); }
Int operator*(int x) { return *this * Int(x); }
void aliasing() { // If the loop container is only used for a declaration of a temporary // variable to hold each element, we can name the new variable for the // converted range-based loop as the temporary variable's name. // In the following case, "T" is used as a temporary variable to hold each // element, and thus we consider the name "T" aliased to the loop. // The extra blank braces are left as a placeholder for after the variable // declaration is deleted. for (int I = 0; I < N; ++I) { Val &T = Arr[I]; {} int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & T : Arr) // CHECK-FIXES-NOT: Val &{{[a-z_]+}} = // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; // The container was not only used to initialize a temporary loop variable for // the container's elements, so we do not alias the new loop variable. for (int I = 0; I < N; ++I) { Val &T = Arr[I]; int Y = T.X; int Z = Arr[I].X + T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & Elem : Arr) // CHECK-FIXES-NEXT: Val &T = Elem; // CHECK-FIXES-NEXT: int Y = T.X; // CHECK-FIXES-NEXT: int Z = Elem.X + T.X; for (int I = 0; I < N; ++I) { Val T = Arr[I]; int Y = T.X; int Z = Arr[I].X + T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & Elem : Arr) // CHECK-FIXES-NEXT: Val T = Elem; // CHECK-FIXES-NEXT: int Y = T.X; // CHECK-FIXES-NEXT: int Z = Elem.X + T.X; // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>) // which provide a subscript operator[]. for (int I = 0; I < V.size(); ++I) { Val &T = V[I]; {} int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & T : V) // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; // The same with a call to at() for (int I = 0; I < Pv->size(); ++I) { Val &T = Pv->at(I); {} int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & T : *Pv) // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; for (int I = 0; I < N; ++I) { Val &T = func(Arr[I]); int Y = T.X; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & Elem : Arr) // CHECK-FIXES-NEXT: Val &T = func(Elem); // CHECK-FIXES-NEXT: int Y = T.X; int IntArr[N]; for (unsigned I = 0; I < N; ++I) { if (int Alias = IntArr[I]) { sideEffect(Alias); } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: if (Alias) for (unsigned I = 0; I < N; ++I) { while (int Alias = IntArr[I]) { sideEffect(Alias); } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: while (Alias) for (unsigned I = 0; I < N; ++I) { switch (int Alias = IntArr[I]) { default: sideEffect(Alias); } } // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: switch (Alias) for (unsigned I = 0; I < N; ++I) { for (int Alias = IntArr[I]; Alias < N; ++Alias) { sideEffect(Alias); } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias) for (unsigned I = 0; I < N; ++I) { for (unsigned J = 0; int Alias = IntArr[I]; ++J) { sideEffect(Alias); } } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J) struct IntRef { IntRef(const int& i); }; for (int I = 0; I < N; ++I) { IntRef Int(IntArr[I]); } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int & Elem : IntArr) // CHECK-FIXES-NEXT: IntRef Int(Elem); // Ensure that removing the alias doesn't leave empty lines behind. for (int I = 0; I < N; ++I) { auto &X = IntArr[I]; X = 0; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (int & X : IntArr) { // CHECK-FIXES-NEXT: {{^ X = 0;$}} // CHECK-FIXES-NEXT: {{^ }$}} }
Any f_add(Any a, Any b) { return Int(a.data.i + b.data.i); }
void solve() { result = ( math::mod_pow(Int(3), n, m) + m - 1 ) % m; }
/*double df(double x) { double h = 1e-5; return (f(x+h)-f(x))/h; } */ double g(double x) { return Int(x) - alpha * alpha - 5 * sqrt(x); }
static void buildConstraint(vec<Formula>& ps, vec<Int>& Cs, vec<Formula>& carry, vec<int>& base, int digit_no, vec<vec<Formula> >& out_digits, int max_cost, PBOptions* options) { assert(ps.size() == Cs.size()); if (FEnv::topSize() > max_cost) throw Exception_TooBig(); /** pf("buildConstraint("); for (int i = 0; i < ps.size(); i++) pf("%d*%s ", Cs[i], (*debug_names)[index(ps[i])]); pf("+ %d carry)\n", carry.size()); **/ if (digit_no == base.size()){ out_digits.push(); // Final digit, build sorter for rest: // -- add carry bits: if (options->opt_sorting_network_encoding == unarySortAddEncoding) buildSorter(ps, Cs, carry, out_digits.last(), options); else { for (int i = 0; i < carry.size(); i++) ps.push(carry[i]), Cs.push(1); buildSorter(ps, Cs, out_digits.last(), options); } }else{ vec<Formula> ps_rem; vec<int> Cs_rem; vec<Formula> ps_div; vec<Int> Cs_div; // Split sum according to base: int B = base[digit_no]; for (int i = 0; i < Cs.size(); i++){ Int div = Cs[i] / Int(B); int rem = toint(Cs[i] % Int(B)); if (div > 0){ ps_div.push(ps[i]); Cs_div.push(div); } if (rem > 0){ ps_rem.push(ps[i]); Cs_rem.push(rem); } } vec<Formula> result; if (options->opt_sorting_network_encoding == unarySortAddEncoding) buildSorter(ps_rem, Cs_rem, carry, result, options); else { // Add carry bits: for (int i = 0; i < carry.size(); i++) ps_rem.push(carry[i]), Cs_rem.push(1); // Build sorting network: buildSorter(ps_rem, Cs_rem, result, options); } // Get carry bits: carry.clear(); for (int i = B-1; i < result.size(); i += B) carry.push(result[i]); out_digits.push(); for (int i = 0; i < B-1; i++){ Formula out = _0_; for (int j = 0; j < result.size(); j += B){ int n = j+B-1; if (j + i < result.size()) out |= result[j + i] & ((n >= result.size()) ? _1_ : ~result[n]); } out_digits.last().push(out); } buildConstraint(ps_div, Cs_div, carry, base, digit_no+1, out_digits, max_cost, options); // <<== change to normal loop } }
void visit(const Pipeline *op) { if (op->buffer != func.name()) { IRMutator::visit(op); } else { // We're interested in the case where exactly one of the // mins of the buffer depends on the loop_var, and none of // the extents do. string dim = ""; Expr min, extent; for (size_t i = 0; i < func.args().size(); i++) { string min_name = func.name() + "." + func.args()[i] + ".min"; string extent_name = func.name() + "." + func.args()[i] + ".extent"; assert(scope.contains(min_name) && scope.contains(extent_name)); Expr this_min = scope.get(min_name); Expr this_extent = scope.get(extent_name); if (ExprDependsOnVar(this_extent, loop_var).result) { min = Expr(); extent = Expr(); break; } if (ExprDependsOnVar(this_min, loop_var).result) { if (min.defined()) { min = Expr(); extent = Expr(); break; } else { dim = func.args()[i]; min = this_min; extent = this_extent; } } } if (min.defined()) { // Ok, we've isolated a function, a dimension to slide along, and loop variable to slide over log(2) << "Sliding " << func.name() << " over dimension " << dim << " along loop variable " << loop_var << "\n"; Expr loop_var_expr = new Variable(Int(32), loop_var); Expr steady_state = loop_var_expr > loop_min; Expr initial_min = substitute(loop_var, loop_min, min); // The new min is one beyond the max we reached on the last loop iteration Expr new_min = substitute(loop_var, loop_var_expr - 1, min + extent); // The new extent is the old extent shrunk by how much we trimmed off the min Expr new_extent = extent + min - new_min; new_min = new Select(steady_state, new_min, initial_min); new_extent = new Select(steady_state, new_extent, extent); stmt = new LetStmt(func.name() + "." + dim + ".extent", new_extent, op); stmt = new LetStmt(func.name() + "." + dim + ".min", new_min, stmt); } else { log(2) << "Could not perform sliding window optimization of " << func.name() << " over " << loop_var << "\n"; stmt = op; } } }
namespace Json { template <typename T> static std::unique_ptr<T> cloneUnique(const std::unique_ptr<T>& p) { std::unique_ptr<T> r; if (p) { r = std::unique_ptr<T>(new T(*p)); } return r; } // This is a walkaround to avoid the static initialization of Value::null. // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of // 8 (instead of 4) as a bit of future-proofing. #if defined(__ARMEL__) #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) #else #define ALIGNAS(byte_alignment) #endif // static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; // const unsigned char& kNullRef = kNull[0]; // const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); // const Value& Value::nullRef = null; // static Value const& Value::nullSingleton() { static Value const nullStatic; return nullStatic; } // for backwards compatibility, we'll leave these global references around, but // DO NOT use them in JSONCPP library code any more! Value const& Value::null = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton(); const Int Value::minInt = Int(~(UInt(-1) / 2)); const Int Value::maxInt = Int(UInt(-1) / 2); const UInt Value::maxUInt = UInt(-1); #if defined(JSON_HAS_INT64) const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); const UInt64 Value::maxUInt64 = UInt64(-1); // The constant is hard-coded because some compiler have trouble // converting Value::maxUInt64 to a double correctly (AIX/xlC). // Assumes that UInt64 is a 64 bits integer. static const double maxUInt64AsDouble = 18446744073709551615.0; #endif // defined(JSON_HAS_INT64) const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); const LargestUInt Value::maxLargestUInt = LargestUInt(-1); const UInt Value::defaultRealPrecision = 17; #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template <typename T, typename U> static inline bool InRange(double d, T min, U max) { // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn // return d >= static_cast<double>(min) && d <= static_cast<double>(max); return d >= min && d <= max; } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) static inline double integerToDouble(Json::UInt64 value) { return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1)); } template <typename T> static inline double integerToDouble(T value) { return static_cast<double>(value); } template <typename T, typename U> static inline bool InRange(double d, T min, U max) { return d >= integerToDouble(min) && d <= integerToDouble(max); } #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) /** Duplicates the specified string value. * @param value Pointer to the string to duplicate. Must be zero-terminated if * length is "unknown". * @param length Length of the value. if equals to unknown, then it will be * computed using strlen(value). * @return Pointer on the duplicate instance of string. */ static inline char* duplicateStringValue(const char* value, size_t length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. if (length >= static_cast<size_t>(Value::maxInt)) length = Value::maxInt - 1; char* newString = static_cast<char*>(malloc(length + 1)); if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateStringValue(): " "Failed to allocate string value buffer"); } memcpy(newString, value, length); newString[length] = 0; return newString; } /* Record the length as a prefix. */ static inline char* duplicateAndPrefixStringValue(const char* value, unsigned int length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U, "in Json::Value::duplicateAndPrefixStringValue(): " "length too big for prefixing"); unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U; char* newString = static_cast<char*>(malloc(actualLength)); if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " "Failed to allocate string value buffer"); } *reinterpret_cast<unsigned*>(newString) = length; memcpy(newString + sizeof(unsigned), value, length); newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later return newString; } inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, unsigned* length, char const** value) { if (!isPrefixed) { *length = static_cast<unsigned>(strlen(prefixed)); *value = prefixed; } else { *length = *reinterpret_cast<unsigned const*>(prefixed); *value = prefixed + sizeof(unsigned); } } /** Free the string duplicated by * duplicateStringValue()/duplicateAndPrefixStringValue(). */ #if JSONCPP_USING_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { unsigned length = 0; char const* valueDecoded; decodePrefixedString(true, value, &length, &valueDecoded); size_t const size = sizeof(unsigned) + length + 1U; memset(value, 0, size); free(value); } static inline void releaseStringValue(char* value, unsigned length) { // length==0 => we allocated the strings memory size_t size = (length == 0) ? strlen(value) : length; memset(value, 0, size); free(value); } #else // !JSONCPP_USING_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { free(value); } static inline void releaseStringValue(char* value, unsigned) { free(value); } #endif // JSONCPP_USING_SECURE_MEMORY } // namespace Json
void CodeGen_X86::visit(const Cast *op) { if (!op->type.is_vector()) { // We only have peephole optimizations for vectors in here. CodeGen_Posix::visit(op); return; } vector<Expr> matches; struct Pattern { Target::Feature feature; bool wide_op; Type type; int min_lanes; string intrin; Expr pattern; }; static Pattern patterns[] = { { Target::FeatureEnd, true, Int(8, 16), 0, "llvm.x86.sse2.padds.b", i8_sat(wild_i16x_ + wild_i16x_) }, { Target::FeatureEnd, true, Int(8, 16), 0, "llvm.x86.sse2.psubs.b", i8_sat(wild_i16x_ - wild_i16x_) }, { Target::FeatureEnd, true, UInt(8, 16), 0, "llvm.x86.sse2.paddus.b", u8_sat(wild_u16x_ + wild_u16x_) }, { Target::FeatureEnd, true, UInt(8, 16), 0, "llvm.x86.sse2.psubus.b", u8(max(wild_i16x_ - wild_i16x_, 0)) }, { Target::FeatureEnd, true, Int(16, 8), 0, "llvm.x86.sse2.padds.w", i16_sat(wild_i32x_ + wild_i32x_) }, { Target::FeatureEnd, true, Int(16, 8), 0, "llvm.x86.sse2.psubs.w", i16_sat(wild_i32x_ - wild_i32x_) }, { Target::FeatureEnd, true, UInt(16, 8), 0, "llvm.x86.sse2.paddus.w", u16_sat(wild_u32x_ + wild_u32x_) }, { Target::FeatureEnd, true, UInt(16, 8), 0, "llvm.x86.sse2.psubus.w", u16(max(wild_i32x_ - wild_i32x_, 0)) }, // Only use the avx2 version if we have > 8 lanes { Target::AVX2, true, Int(16, 16), 9, "llvm.x86.avx2.pmulh.w", i16((wild_i32x_ * wild_i32x_) / 65536) }, { Target::AVX2, true, UInt(16, 16), 9, "llvm.x86.avx2.pmulhu.w", u16((wild_u32x_ * wild_u32x_) / 65536) }, { Target::FeatureEnd, true, Int(16, 8), 0, "llvm.x86.sse2.pmulh.w", i16((wild_i32x_ * wild_i32x_) / 65536) }, { Target::FeatureEnd, true, UInt(16, 8), 0, "llvm.x86.sse2.pmulhu.w", u16((wild_u32x_ * wild_u32x_) / 65536) }, { Target::FeatureEnd, true, UInt(8, 16), 0, "llvm.x86.sse2.pavg.b", u8(((wild_u16x_ + wild_u16x_) + 1) / 2) }, { Target::FeatureEnd, true, UInt(16, 8), 0, "llvm.x86.sse2.pavg.w", u16(((wild_u32x_ + wild_u32x_) + 1) / 2) }, { Target::FeatureEnd, false, Int(16, 8), 0, "packssdwx8", i16_sat(wild_i32x_) }, { Target::FeatureEnd, false, Int(8, 16), 0, "packsswbx16", i8_sat(wild_i16x_) }, { Target::FeatureEnd, false, UInt(8, 16), 0, "packuswbx16", u8_sat(wild_i16x_) }, { Target::SSE41, false, UInt(16, 8), 0, "packusdwx8", u16_sat(wild_i32x_) } }; for (size_t i = 0; i < sizeof(patterns)/sizeof(patterns[0]); i++) { const Pattern &pattern = patterns[i]; if (!target.has_feature(pattern.feature)) { continue; } if (op->type.lanes() < pattern.min_lanes) { continue; } if (expr_match(pattern.pattern, op, matches)) { bool match = true; if (pattern.wide_op) { // Try to narrow the matches to the target type. for (size_t i = 0; i < matches.size(); i++) { matches[i] = lossless_cast(op->type, matches[i]); if (!matches[i].defined()) match = false; } } if (match) { value = call_intrin(op->type, pattern.type.lanes(), pattern.intrin, matches); return; } } } #if LLVM_VERSION >= 38 // Workaround for https://llvm.org/bugs/show_bug.cgi?id=24512 // LLVM uses a numerically unstable method for vector // uint32->float conversion before AVX. if (op->value.type().element_of() == UInt(32) && op->type.is_float() && op->type.is_vector() && !target.has_feature(Target::AVX)) { Type signed_type = Int(32, op->type.lanes()); // Convert the top 31 bits to float using the signed version Expr top_bits = cast(signed_type, op->value / 2); top_bits = cast(op->type, top_bits); // Convert the bottom bit Expr bottom_bit = cast(signed_type, op->value % 2); bottom_bit = cast(op->type, bottom_bit); // Recombine as floats codegen(top_bits + top_bits + bottom_bit); return; } #endif CodeGen_Posix::visit(op); }
Triple< Int > egcd( Int a, Int b ) { if( !b ) return Triple< Int >( a, Int( 1 ), Int( 0 ) ); Triple< Int > q = egcd( b, a % b ); return Triple< Int >( q.d, q.y, q.x - a / b * q.y ); }
std::string lineWrap(const std::string &input, const UInt maximumLineLength) { if (maximumLineLength == 0) { return input; } std::string result = input; std::string::size_type lineStartPosition = result.find_first_not_of(' '); //don't wrap any leading spaces in the string while (lineStartPosition != std::string::npos) { //------------------------------------------------ const std::string::size_type searchFromPosition = lineStartPosition + maximumLineLength; if (searchFromPosition >= result.length()) { break; } //------------------------------------------------ //first check to see if there is another new line character before the maximum line length //we can't use find for this unfortunately because it doesn't take both a beginning and an end for its search range std::string::size_type nextLineStartPosition = std::string::npos; for (std::string::size_type currentPosition = lineStartPosition; currentPosition <= searchFromPosition; currentPosition++) { if (result[currentPosition] == '\n') { nextLineStartPosition = currentPosition + 1; break; } } //------------------------------------------------ //if there ia another new line character before the maximum line length, we need to start this loop again from that position if (nextLineStartPosition != std::string::npos) { lineStartPosition = nextLineStartPosition; } else { std::string::size_type spacePosition = std::string::npos; //search backwards for the last space character (must use signed Int because lineStartPosition can be 0) for (Int currentPosition = Int(searchFromPosition); currentPosition >= Int(lineStartPosition); currentPosition--) { if (result[currentPosition] == ' ') { spacePosition = currentPosition; break; } } //if we didn't find a space searching backwards, we must hyphenate if (spacePosition == std::string::npos) { result.insert(searchFromPosition, "-\n"); lineStartPosition = searchFromPosition + 2; //make sure the next search ignores the hyphen } else //if we found a space to split on, replace it with a new line character { result.replace(spacePosition, 1, 1, '\n'); lineStartPosition = spacePosition + 1; } } //------------------------------------------------ } return result; }
std::pair< std::vector< SParamOptMsg< SamplePointT > >, bool > ParameterOptimizationServer< SamplePointT, SamplePointGrid > ::GetNConvergedElements( ) { typedef GeometricOptimizationBase<SamplePointT> Base; const Int nMaxElements = nProcessingElements * LocalSetup.InputParameters().nOptNumElementPerPE * 3; if( VoxelQueue.Size() > nMaxElements ) { GET_LOG( osLogFile ) << "Number of elements from structure: " << VoxelQueue.Size() << std::endl; GET_LOG( osLogFile ) << " exceeds the maximum number of elements to be fitted: " << nMaxElements << std::endl; GET_LOG( osLogFile ) << "Limiting to " << nMaxElements << " elements " << std::endl; VoxelQueue.RandomizedSetMaxElements( nMaxElements ); } std::queue<int> WaitQueue; for( int i = 1; i <= (nProcessingElements - 1); i ++ ) // start from 1, since 0 is Server WaitQueue.push( i ); typedef XDMParallel::MultiElementDistribution<SamplePointT> MultiElementDistributor; MultiElementDistributor SingleVoxelDistributor(1); Utilities::WorkUnitDistribution( VoxelQueue, SingleVoxelDistributor, WaitQueue, Base::Comm, osLogFile, 0, XDMParallel::FIT_MC ); GET_LOG( osLogFile ) << "Finished with Initial Work Unit Distribution " << std::endl; typedef SParamOptMsg< SamplePointT > ParamOptMsg; vector<ParamOptMsg> oConvergedSamplePoints; Int nElementsToFit = LocalSetup.InputParameters().nOptNumElementPerPE; // parameters? int NumClients = nProcessingElements -1; Int NumElementsUsed = NumClients; while( ! VoxelQueue.Empty() || WaitQueue.size() < NumClients || Int( oConvergedSamplePoints.size() ) >= nElementsToFit ) { Int nClientPE; Int nCommand; vector<ParamOptMsg> TmpResult; ParamOptMsg oOptResult; NumElementsUsed ++; Base::Comm.RecvCommand( &nClientPE, &nCommand ); RUNTIME_ASSERT( nCommand == XDMParallel::REPORT_MC, "\nDriver::Server: Unknown command from client recv \n" ); Base::Comm.RecvWorkUnitList( nClientPE, TmpResult ); RUNTIME_ASSERT( TmpResult.size() == 1, "[This error check shall be removed after debugging] Error: Size mismatch in PMC\n " ); oOptResult = TmpResult[0]; if( oOptResult.bConverged ) oConvergedSamplePoints.push_back( oOptResult ); if ( oConvergedSamplePoints.size() < nElementsToFit && (NumElementsUsed < nMaxElements) ) // if there's still voxels left Utilities::WorkUnitDistribution( VoxelQueue, SingleVoxelDistributor, WaitQueue, Base::Comm, osLogFile, 0, XDMParallel::FIT_MC ); else // tell client that we're done Base::Comm.SendCommand( nMyID, nClientPE, XDMParallel::WAIT ); } if( oConvergedSamplePoints.size() > nElementsToFit ) { GET_LOG( osLogFile ) << "Needed " << nElementsToFit << " Ended with " << oConvergedSamplePoints.size() << std::endl; std::sort( oConvergedSamplePoints.begin(), oConvergedSamplePoints.end() ); // sort by quality, ascending int nExtraPoints = oConvergedSamplePoints.size() - nElementsToFit; oConvergedSamplePoints.erase( oConvergedSamplePoints.begin(), oConvergedSamplePoints.begin() + nExtraPoints ); // keep only the last nElementsToFit GET_LOG( osLogFile ) << "List has been trimed to the best " << oConvergedSamplePoints.size() << " elements " << std::endl; } return std::make_pair( oConvergedSamplePoints, oConvergedSamplePoints.size() >= nElementsToFit ); }
Expr BufferBuilder::build() const { std::vector<Expr> args(10); if (buffer_memory.defined()) { args[0] = buffer_memory; } else { args[0] = Call::make(type_of<struct halide_buffer_t *>(), Call::alloca, {(int)sizeof(halide_buffer_t)}, Call::Intrinsic); } std::string shape_var_name = unique_name('t'); Expr shape_var = Variable::make(type_of<halide_dimension_t *>(), shape_var_name); if (shape_memory.defined()) { args[1] = shape_memory; } else if (dimensions == 0) { args[1] = make_zero(type_of<halide_dimension_t *>()); } else { args[1] = shape_var; } if (host.defined()) { args[2] = host; } else { args[2] = make_zero(type_of<void *>()); } if (device.defined()) { args[3] = device; } else { args[3] = make_zero(UInt(64)); } if (device_interface.defined()) { args[4] = device_interface; } else { args[4] = make_zero(type_of<struct halide_device_interface_t *>()); } args[5] = (int)type.code(); args[6] = type.bits(); args[7] = dimensions; std::vector<Expr> shape; for (size_t i = 0; i < (size_t)dimensions; i++) { if (i < mins.size()) { shape.push_back(mins[i]); } else { shape.push_back(0); } if (i < extents.size()) { shape.push_back(extents[i]); } else { shape.push_back(0); } if (i < strides.size()) { shape.push_back(strides[i]); } else { shape.push_back(0); } // per-dimension flags, currently unused. shape.push_back(0); } for (const Expr &e : shape) { internal_assert(e.type() == Int(32)) << "Buffer shape fields must be int32_t:" << e << "\n"; } Expr shape_arg = Call::make(type_of<halide_dimension_t *>(), Call::make_struct, shape, Call::Intrinsic); if (shape_memory.defined()) { args[8] = shape_arg; } else if (dimensions == 0) { args[8] = make_zero(type_of<halide_dimension_t *>()); } else { args[8] = shape_var; } Expr flags = make_zero(UInt(64)); if (host_dirty.defined()) { flags = select(host_dirty, make_const(UInt(64), halide_buffer_flag_host_dirty), make_zero(UInt(64))); } if (device_dirty.defined()) { flags = flags | select(device_dirty, make_const(UInt(64), halide_buffer_flag_device_dirty), make_zero(UInt(64))); } args[9] = flags; Expr e = Call::make(type_of<struct halide_buffer_t *>(), Call::buffer_init, args, Call::Extern); if (!shape_memory.defined() && dimensions != 0) { e = Let::make(shape_var_name, shape_arg, e); } return e; }
int main(int argc, char* argv[]) { // initialise random Random::Random(); int ncycle = 10; int burnin = 100; int every = 10; int until = 1000; int mlsize = -1; int keep = 0; string datafile = ""; string initfile = ""; string treefile = ""; string name = ""; string path = "./"; string prepath = ""; string directory = ""; RRMode rr = gtr; RASMode ras = gam; int discrate = 0; // 0 : continuous int empfreq = 0; // 1 : global freq, 2: site specific freq int ncat = 1; // 0 : cat, -1 max, otherwise, fixed number of modes int statcenter = 1; int qmode = 0; // 0 : serial submission // 1 : parallel submission // 2 : qsub submission // 3 : qprep submission // read arguments try { if (argc == 1) { throw(0); } int i = 1; while (i < argc) { string s = argv[i]; if (s == "-d") { i++; datafile = argv[i]; } else if (s == "-t") { i++; treefile = argv[i]; } else if (s == "-i") { i++; initfile = argv[i]; } else if (s == "-keep") { keep = 1; } else if (s == "-poisson") { rr = poisson; } else if (s == "-jtt") { rr = jtt; } else if (s == "-wag") { rr = wag; } else if (s == "-gtr") { rr = gtr; } else if (s == "-empfreq") { empfreq = 1; } else if (s == "-siteempfreq") { empfreq = 2; } else if (s == "-uni") { ras = uni; } else if (s == "-gamma") { ras = gam; } else if (s == "-invgamma") { ras = invgam; } else if (s == "-discrate") { discrate = 4; i++; string temp = argv[i]; if (IsInt(temp)) { discrate = Int(temp); } else { i--; } } else if (s == "-cat") { ncat = 0; } else if (s == "-max") { ncat = -1; } else if (s == "-ncat") { i++; ncat = atoi(argv[i]); } else if (s == "-statfree") { statcenter = 1; } else if (s == "-statflat") { statcenter = 0; } else if (s == "-mlsize") { i++; mlsize = atoi(argv[i]); } else if (s == "-ncycle") { i++; ncycle = atoi(argv[i]); } else if (s == "-p") { i++; path = argv[i]; } else if ((s == "-qsub") || (s == "-qprep")) { if (s == "-qsub") { qmode = 2; } if (s == "-qprep") { qmode = 3; } i++; prepath = argv[i]; i++; directory = argv[i]; } else if (s == "-bg") { qmode = 1; } else if ( (s == "-x") || (s == "-extract") ) { i++; s = argv[i]; if (! IsInt(s)) { throw(0); } burnin = atoi(argv[i]); i++; s = argv[i]; if (IsInt(s)) { every = atoi(argv[i]); i++; s = argv[i]; if (IsInt(s)) { until = atoi(argv[i]); } else { i--; } } else { i--; } } else { if (i != (argc -1)) { throw(0); } name = argv[i]; } i++; } if (name == "") { cerr << "give it a name ! \n"; throw(0); } } catch(...) { cerr << "ml : wrong command\n"; exit(1); } if (mlsize == -1) { mlsize = until; } ofstream* qsub_os = 0; if (qmode > 1) { qsub_os = new ofstream((name + ".qsub").c_str()); } if ((treefile == "") && (initfile == "") && (datafile == "")) { if (qmode>1) { path = prepath + directory; } Chain chain(name, 0, path); chain.ML(ncycle, burnin, every, until, mlsize, keep); exit(1); } int Ntree = 1; Tree* tree = 0; if (treefile == "") { // assumes only one tree; but should be specified by the initfile if (initfile == "") { cerr << "error: should specify a tree\n"; exit(1); } } else { ifstream is(treefile.c_str()); is >> Ntree; tree = new Tree[Ntree]; for (int n=0; n<Ntree; n++) { tree[n].ReadFromStream(is, 1); } } MCParameters* mParam = new MCParameters(); if (datafile != "") { mParam->ReadDataFromFile(datafile); } if (initfile != "") { mParam->InitFromFile(initfile); } else { mParam->Init(rr,empfreq, ncat, statcenter, ras, discrate); } if (! mParam->DataOK) { cerr << "error: should specify a datafile\n"; exit(1); } if (! Ntree) { string currentname = name; if (qmode == 0) { Chain chain(mParam, currentname, path); chain.ML(ncycle, burnin, every, until, mlsize, keep); } else if (qmode == 1) { Chain chain(mParam, currentname, path); ostringstream launch; launch << "../ml "; if (path != "./") { launch << "-p " << path << ' '; } launch << "-x " << burnin << ' ' << every << ' ' << until; launch << " -ncycle " << ncycle << " -mlsize " << mlsize << ' '; if (keep) { launch << " -keep "; } launch << name << " &"; cerr << launch.str() << '\n'; system(launch.str().c_str()); } else { path = prepath + directory; Chain chain(mParam, currentname, path); ofstream os((currentname + ".launch").c_str()); os << prepath << "ml "; os << " -x " << burnin << ' ' << every << ' ' << until; os << " -ncycle " << ncycle; os << " -mlsize " << mlsize; if (keep) { os << " -keep "; } os << " -p " << path << ' ' << currentname << '\n'; (*qsub_os) << "qsub -o /baie/home/usertest/out -e /baie/home/usertest/err" << currentname << ".launch\n"; } } else { for (int n=0; n<Ntree; n++) { // prune the tree of all supernumerary species, and init the parameter Tree inittree(&tree[n]); TaxaParameters taxaparam(&inittree); for (int i=0; i<taxaparam.Ntaxa; i++) { string species = taxaparam.GetSpeciesName(i); int found = 0; int j=0; while ( (!found) && (j<mParam->Ntaxa) ) { found = (species == mParam->SpeciesNames[j]); j++; } if (! found) { // cerr << species << " not found : eliminate..."; // cerr.flush(); inittree.Eliminate(species); // cerr << "ok\n"; // cerr.flush(); } } inittree.Simplify(); // inittree.Phylip(cerr,0,0,1,0); // cerr << "\n"; // cerr.flush(); mParam->GetCurrentState()->SetTree(inittree); mParam->GetCurrentState()->SetBranchLengths(Random); ostringstream s; s << name << "_" << n; string currentname = s.str(); if (qmode == 0) { Chain chain(mParam, currentname, path); chain.ML(ncycle, burnin, every, until, mlsize, keep); } else if (qmode == 1) { Chain chain(mParam, currentname, path); ostringstream launch; launch << "../ml "; if (path != "./") { launch << "-p path "; } launch << "-x " << burnin << ' ' << every << ' ' << until; launch << " -ncycle " << ncycle << " -mlsize " << mlsize << ' '; if (keep) { launch << "-keep "; } launch << name << " &"; cerr << launch.str() << '\n'; cerr.flush(); system(launch.str().c_str()); } else { path = prepath + directory; Chain chain(mParam, currentname, path); ofstream os((currentname + ".launch").c_str()); os << prepath << "ml "; os << " -x " << burnin << ' ' << every << ' ' << until; os << " -ncycle " << ncycle; os << " -mlsize " << mlsize; if (keep) { os << " -keep "; } os << " -p " << path << ' ' << currentname << '\n'; (*qsub_os) << "qsub -e " << path << currentname << ".err -o " << path << currentname << ".out " << currentname << ".launch\n"; } } } if (qmode>1) { qsub_os->close(); string chmod = "chmod +x " + name + ".qsub"; system(chmod.c_str()); } if (qmode == 2) { string submit = "./" + name + ".qsub"; system(submit.c_str()); } }
/* * Output statistics. */ void Integrator::outputStatistics(std::ostream& out) { if (!domain().isMaster()) { UTIL_THROW("May be called only on domain master"); } double time = timer().time(); int nAtomTot = atomStorage().nAtomTotal(); int nProc = 1; #ifdef UTIL_MPI nProc = domain().communicator().Get_size(); #endif // Output total time for the run out << std::endl; out << "Time Statistics" << std::endl; out << "nStep " << iStep_ << std::endl; out << "run time " << time << " sec" << std::endl; out << "time / nStep " << time/double(iStep_) << " sec" << std::endl; double factor1 = 1.0/double(iStep_); double factor2 = double(nProc)/(double(iStep_)*double(nAtomTot)); double totalT = 0.0; out << std::endl; out << "T = Time per processor, M = nstep = # steps" << std::endl << "P = # procs, N = # atoms (total, all processors)" << std::endl << std::endl; out << " " << " T/M [sec] " << " T*P/(N*M) " << " Percent (%)" << std::endl; out << "Total " << Dbl(time*factor1, 12, 6) << " " << Dbl(time*factor2, 12, 6) << " " << Dbl(100.0, 12, 6, true) << std::endl; double integrate1T = timer().time(INTEGRATE1); totalT += integrate1T; out << "Integrate1 " << Dbl(integrate1T*factor1, 12, 6) << " " << Dbl(integrate1T*factor2, 12, 6) << " " << Dbl(100.0*integrate1T/time, 12, 6, true) << std::endl; double checkT = timer().time(CHECK); totalT += checkT; out << "Check " << Dbl(checkT*factor1, 12, 6) << " " << Dbl(checkT*factor2, 12, 6) << " " << Dbl(100.0*checkT/time, 12, 6, true) << std::endl; double allReduceT = timer().time(ALLREDUCE); totalT += allReduceT; out << "AllReduce " << Dbl(allReduceT*factor1, 12, 6) << " " << Dbl(allReduceT*factor2, 12, 6) << " " << Dbl(100.0*allReduceT/time, 12, 6, true) << std::endl; double transformFT = timer().time(TRANSFORM_F); totalT += transformFT; out << "Transform (forward) " << Dbl(transformFT*factor1, 12, 6) << " " << Dbl(transformFT*factor2, 12, 6) << " " << Dbl(100.0*transformFT/time, 12, 6, true) << std::endl; double exchangeT = timer().time(EXCHANGE); totalT += exchangeT; out << "Exchange " << Dbl(exchangeT*factor1, 12, 6) << " " << Dbl(exchangeT*factor2, 12, 6) << " " << Dbl(100.0*exchangeT/time, 12, 6, true) << std::endl; double cellListT = timer().time(CELLLIST); totalT += cellListT; out << "CellList " << Dbl(cellListT*factor1, 12, 6) << " " << Dbl(cellListT*factor2, 12, 6) << " " << Dbl(100.0*cellListT/time, 12, 6, true) << std::endl; double transformRT = timer().time(TRANSFORM_R); totalT += transformRT; out << "Transform (reverse) " << Dbl(transformRT*factor1, 12, 6) << " " << Dbl(transformRT*factor2, 12, 6) << " " << Dbl(100.0*transformRT/time, 12, 6, true) << std::endl; double pairListT = timer().time(PAIRLIST); totalT += pairListT; out << "PairList " << Dbl(pairListT*factor1, 12, 6) << " " << Dbl(pairListT*factor2, 12, 6) << " " << Dbl(100.0*pairListT/time, 12, 6, true) << std::endl; double updateT = timer().time(UPDATE); totalT += updateT; out << "Update " << Dbl(updateT*factor1, 12, 6) << " " << Dbl(updateT*factor2, 12, 6) << " " << Dbl(100.0*updateT/time, 12, 6, true) << std::endl; double zeroForceT = timer().time(ZERO_FORCE); totalT += zeroForceT; out << "Zero Forces " << Dbl(zeroForceT*factor1, 12, 6) << " " << Dbl(zeroForceT*factor2, 12, 6) << " " << Dbl(100.0*zeroForceT/time, 12 , 6, true) << std::endl; double pairForceT = timer().time(PAIR_FORCE); totalT += pairForceT; out << "Pair Forces " << Dbl(pairForceT*factor1, 12, 6) << " " << Dbl(pairForceT*factor2, 12, 6) << " " << Dbl(100.0*pairForceT/time, 12 , 6, true) << std::endl; #ifdef INTER_BOND if (nBondType()) { double bondForceT = timer().time(BOND_FORCE); totalT += bondForceT; out << "Bond Forces " << Dbl(bondForceT*factor1, 12, 6) << " " << Dbl(bondForceT*factor2, 12, 6) << " " << Dbl(100.0*bondForceT/time, 12 , 6, true) << std::endl; } #endif #ifdef INTER_ANGLE if (nAngleType()) { double angleForceT = timer().time(ANGLE_FORCE); totalT += angleForceT; out << "Angle Forces " << Dbl(angleForceT*factor1, 12, 6) << " " << Dbl(angleForceT*factor2, 12, 6) << " " << Dbl(100.0*angleForceT/time, 12 , 6, true) << std::endl; } #endif #ifdef INTER_DIHEDRAL if (nDihedralType()) { double dihedralForceT = timer().time(DIHEDRAL_FORCE); totalT += dihedralForceT; out << "Dihedral Forces " << Dbl(dihedralForceT*factor1, 12, 6) << " " << Dbl(dihedralForceT*factor2, 12, 6) << " " << Dbl(100.0*dihedralForceT/time, 12 , 6, true) << std::endl; } #endif #ifdef INTER_EXTERNAL if (hasExternal()) { double externalForceT = timer().time(DIHEDRAL_FORCE); totalT += externalForceT; out << "External Forces " << Dbl(externalForceT*factor1, 12, 6) << " " << Dbl(externalForceT*factor2, 12, 6) << " " << Dbl(100.0*externalForceT/time, 12 , 6, true) << std::endl; } #endif double integrate2T = timer().time(INTEGRATE2); totalT += integrate2T; out << "Integrate2 " << Dbl(integrate2T*factor1, 12, 6) << " " << Dbl(integrate2T*factor2, 12, 6) << " " << Dbl(100.0*integrate2T/time, 12, 6, true) << std::endl; double analyzerT = timer().time(ANALYZER); totalT += analyzerT; out << "Analyzers " << Dbl(analyzerT*factor1, 12, 6) << " " << Dbl(analyzerT*factor2, 12, 6) << " " << Dbl(100.0*analyzerT/time, 12, 6, true) << std::endl; #ifdef DDMD_MODIFIERS double modifierT = timer().time(MODIFIER); totalT += modifierT; out << "Modifiers " << Dbl(modifierT*factor1, 12, 6) << " " << Dbl(modifierT*factor2, 12, 6) << " " << Dbl(100.0*modifierT/time, 12, 6, true) << std::endl; #endif out << std::endl; // Output info about timer resolution double tick = MPI::Wtick(); out << "Timer resolution " << Dbl(tick, 12, 6) << " " << Dbl(tick*double(nProc)/double(nAtomTot), 12, 6) << " " << Dbl(100.0*tick*double(iStep_)/time, 12, 6, true) << std::endl; out << std::endl; // Output exchange / reneighbor statistics int buildCounter = pairPotential().pairList().buildCounter(); out << "buildCounter " << Int(buildCounter, 12) << std::endl; out << "steps per build " << Dbl(double(iStep_)/double(buildCounter), 12, 6) << std::endl; out << std::endl; }
Expr::Expr(int32_t val) : contents(new ExprContents(makeIntImm(val), Int(32))) { contents->isImmediate = true; }
Int iabs(Int i) { if(i<Int(0)) return -i; return i; }
Expr::Expr(const Var &v) : contents(new ExprContents(makeVar((v.name())), Int(32))) { contents->isVar = true; contents->vars.push_back(v); }
Int operator-(int x) { return *this - Int(x); }
void SeqNumIndex<Int>::getValueAppend(llong id, valvec<byte>* val, DbContext*) const { Int keyAsVal = Int(this->m_min + id); val->append((byte*)&keyAsVal, sizeof(Int)); }
Int operator/(int x) { return *this / Int(x); }
int main (){ Any a5 = Str("N"); Any a8 = Int( strlen( a5.s) ); Any a9 = Int(0); Any a4 = f ( a5 ); println ( a4 ); Any a10 = Str("K"); Any a13 = Int( strlen( a10.s) ); Any a14 = Int(0); a9 = f ( a10 ); println ( a9 ); Any a15 = Str("Q"); Any a18 = Int( strlen( a15.s) ); Any a19 = Int(0); a14 = f ( a15 ); println ( a14 ); Any a20 = Str("B"); Any a23 = Int( strlen( a20.s) ); Any a24 = Int(0); a19 = f ( a20 ); println ( a19 ); Any a25 = Str("R"); Any a28 = Int( strlen( a25.s) ); Any a29 = Int(0); a24 = f ( a25 ); println ( a24 ); Any a30 = Str("Q"); Any a33 = Int( strlen( a30.s) ); Any a34 = Int(0); a29 = f ( a30 ); println ( a29 ); Any a35 = Str("e"); Any a38 = Int( strlen( a35.s) ); Any a39 = Int(0); a34 = f ( a35 ); println ( a34 ); Any a40 = Str("1"); Any a43 = Int( strlen( a40.s) ); Any a44 = Int(0); a39 = f ( a40 ); println ( a39 ); return 0; }
Any len ( Any a0 ){ Any a2 = Int( sizeof( a0 ) / sizeof( a0[0] ) ); return a2; }
void PDFDate::ParseString(std::string inValue) { if(inValue.length() < 2 || inValue[0] != 'D' || inValue[1] != ':') { Year = -1; return; } Year = Int(inValue.substr(2,4)); Month = -1; Day = -1; Hour = -1; Minute = -1; Second = -1; UTC = eUndefined; HourFromUTC = -1; MinuteFromUTC = -1; if(inValue.length() < 7) return; Month = Int(inValue.substr(6,2)); if(inValue.length() < 9) return; Day = Int(inValue.substr(8,2)); if(inValue.length() < 11) return; Hour = Int(inValue.substr(10,2)); if(inValue.length() < 13) return; Minute = Int(inValue.substr(12,2)); if(inValue.length() < 15) return; Second = Int(inValue.substr(14,2)); if(inValue.length() < 17) return; if(inValue[16] == 'Z') { UTC = eSame; } else if(inValue[16] == '-' || inValue[16] == '+') { UTC = (inValue[16] == '-') ? eEarlier:eLater; if(inValue.length() < 18) return; HourFromUTC = Int(inValue.substr(17,2)); if(inValue.length() < 21) // skipping ' return; MinuteFromUTC = Int(inValue.substr(20,2)); } }
namespace Json { const Value Value::null; const Int Value::minInt = Int( ~(UInt(-1)/2) ); const Int Value::maxInt = Int( UInt(-1)/2 ); const UInt Value::maxUInt = UInt(-1); // A "safe" implementation of strdup. Allow null pointer to be passed. // Also avoid warning on msvc80. // //inline char *safeStringDup( const char *czstring ) //{ // if ( czstring ) // { // const size_t length = (unsigned int)( strlen(czstring) + 1 ); // char *newString = static_cast<char *>( malloc( length ) ); // memcpy( newString, czstring, length ); // return newString; // } // return 0; //} // //inline char *safeStringDup( const std::string &str ) //{ // if ( !str.empty() ) // { // const size_t length = str.length(); // char *newString = static_cast<char *>( malloc( length + 1 ) ); // memcpy( newString, str.c_str(), length ); // newString[length] = 0; // return newString; // } // return 0; //} ValueAllocator::~ValueAllocator() { } class DefaultValueAllocator : public ValueAllocator { public: virtual ~DefaultValueAllocator() { } virtual char *makeMemberName( const char *memberName ) { return duplicateStringValue( memberName ); } virtual void releaseMemberName( char *memberName ) { releaseStringValue( memberName ); } virtual char *duplicateStringValue( const char *value, unsigned int length = unknown ) { //@todo invesgate this old optimization //if ( !value || value[0] == 0 ) // return 0; if ( length == unknown ) length = (unsigned int)strlen(value); char *newString = static_cast<char *>( malloc( length + 1 ) ); memcpy( newString, value, length ); newString[length] = 0; return newString; } virtual void releaseStringValue( char *value ) { if ( value ) free( value ); } }; static ValueAllocator *&valueAllocator() { static DefaultValueAllocator defaultAllocator; static ValueAllocator *valueAllocator = &defaultAllocator; return valueAllocator; } static struct DummyValueAllocatorInitializer { DummyValueAllocatorInitializer() { valueAllocator(); // ensure valueAllocator() statics are initialized before main(). } } dummyValueAllocatorInitializer; // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ValueInternals... // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// #ifdef JSON_VALUE_USE_INTERNAL_MAP # include "json_internalarray.inl" # include "json_internalmap.inl" #endif // JSON_VALUE_USE_INTERNAL_MAP # include "json_valueiterator.inl" // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // class Value::CommentInfo // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// Value::CommentInfo::CommentInfo() : comment_( 0 ) { } Value::CommentInfo::~CommentInfo() { if ( comment_ ) valueAllocator()->releaseStringValue( comment_ ); } void Value::CommentInfo::setComment( const char *text ) { if ( comment_ ) valueAllocator()->releaseStringValue( comment_ ); JSON_ASSERT( text ); JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); // It seems that /**/ style comments are acceptable as well. comment_ = valueAllocator()->duplicateStringValue( text ); } // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // class Value::CZString // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// # ifndef JSON_VALUE_USE_INTERNAL_MAP // Notes: index_ indicates if the string was allocated when // a string is stored. Value::CZString::CZString( int index ) : cstr_( 0 ) , index_( index ) { } Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) : cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr) : cstr ) , index_( allocate ) { } Value::CZString::CZString( const CZString &other ) : cstr_( other.index_ != noDuplication && other.cstr_ != 0 ? valueAllocator()->makeMemberName( other.cstr_ ) : other.cstr_ ) , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) : other.index_ ) { } Value::CZString::~CZString() { if ( cstr_ && index_ == duplicate ) valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) ); } void Value::CZString::swap( CZString &other ) { std::swap( cstr_, other.cstr_ ); std::swap( index_, other.index_ ); } Value::CZString & Value::CZString::operator =( const CZString &other ) { CZString temp( other ); swap( temp ); return *this; } bool Value::CZString::operator<( const CZString &other ) const { if ( cstr_ ) return strcmp( cstr_, other.cstr_ ) < 0; return index_ < other.index_; } bool Value::CZString::operator==( const CZString &other ) const { if ( cstr_ ) return strcmp( cstr_, other.cstr_ ) == 0; return index_ == other.index_; } int Value::CZString::index() const { return index_; } const char * Value::CZString::c_str() const { return cstr_; } bool Value::CZString::isStaticString() const { return index_ == noDuplication; } #endif // ifndef JSON_VALUE_USE_INTERNAL_MAP // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // class Value::Value // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// /*! \internal Default constructor initialization must be equivalent to: * memset( this, 0, sizeof(Value) ) * This optimization is used in ValueInternalMap fast allocator. */ Value::Value( ValueType type ) : type_( type ) , allocated_( 0 ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { switch ( type ) { case nullValue: break; case intValue: case uintValue: value_.int_ = 0; break; case realValue: value_.real_ = 0.0; break; case stringValue: value_.string_ = 0; break; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_ = new ObjectValues(); break; #else case arrayValue: value_.array_ = arrayAllocator()->newArray(); break; case objectValue: value_.map_ = mapAllocator()->newMap(); break; #endif case booleanValue: value_.bool_ = false; break; default: JSON_ASSERT_UNREACHABLE; } } Value::Value( Int value ) : type_( intValue ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.int_ = value; } Value::Value( UInt value ) : type_( uintValue ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.uint_ = value; } Value::Value( double value ) : type_( realValue ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.real_ = value; } Value::Value( const char *value ) : type_( stringValue ) , allocated_( true ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.string_ = valueAllocator()->duplicateStringValue( value ); } Value::Value( const char *beginValue, const char *endValue ) : type_( stringValue ) , allocated_( true ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.string_ = valueAllocator()->duplicateStringValue( beginValue, UInt(endValue - beginValue) ); } Value::Value( const std::string &value ) : type_( stringValue ) , allocated_( true ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(), (unsigned int)value.length() ); } Value::Value( const StaticString &value ) : type_( stringValue ) , allocated_( false ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.string_ = const_cast<char *>( value.c_str() ); } # ifdef JSON_USE_CPPTL Value::Value( const CppTL::ConstString &value ) : type_( stringValue ) , allocated_( true ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() ); } # endif Value::Value( bool value ) : type_( booleanValue ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { value_.bool_ = value; } Value::Value( const Value &other ) : type_( other.type_ ) , comments_( 0 ) # ifdef JSON_VALUE_USE_INTERNAL_MAP , itemIsUsed_( 0 ) #endif { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: value_ = other.value_; break; case stringValue: if ( other.value_.string_ ) { value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ ); allocated_ = true; } else value_.string_ = 0; break; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_ = new ObjectValues( *other.value_.map_ ); break; #else case arrayValue: value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ ); break; case objectValue: value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ ); break; #endif default: JSON_ASSERT_UNREACHABLE; } if ( other.comments_ ) { comments_ = new CommentInfo[numberOfCommentPlacement]; for ( int comment =0; comment < numberOfCommentPlacement; ++comment ) { const CommentInfo &otherComment = other.comments_[comment]; if ( otherComment.comment_ ) comments_[comment].setComment( otherComment.comment_ ); } } } Value::~Value() { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: break; case stringValue: if ( allocated_ ) valueAllocator()->releaseStringValue( value_.string_ ); break; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: delete value_.map_; break; #else case arrayValue: arrayAllocator()->destructArray( value_.array_ ); break; case objectValue: mapAllocator()->destructMap( value_.map_ ); break; #endif default: JSON_ASSERT_UNREACHABLE; } if ( comments_ ) delete[] comments_; } Value & Value::operator=( const Value &other ) { Value temp( other ); swap( temp ); return *this; } void Value::swap( Value &other ) { ValueType temp = type_; type_ = other.type_; other.type_ = temp; std::swap( value_, other.value_ ); int temp2 = allocated_; allocated_ = other.allocated_; other.allocated_ = temp2; } ValueType Value::type() const { return type_; } int Value::compare( const Value &other ) { /* int typeDelta = other.type_ - type_; switch ( type_ ) { case nullValue: return other.type_ == type_; case intValue: if ( other.type_.isNumeric() case uintValue: case realValue: case booleanValue: break; case stringValue, break; case arrayValue: delete value_.array_; break; case objectValue: delete value_.map_; default: JSON_ASSERT_UNREACHABLE; } */ return 0; // unreachable } bool Value::operator <( const Value &other ) const { int typeDelta = type_ - other.type_; if ( typeDelta ) return typeDelta < 0 ? true : false; switch ( type_ ) { case nullValue: return false; case intValue: return value_.int_ < other.value_.int_; case uintValue: return value_.uint_ < other.value_.uint_; case realValue: return value_.real_ < other.value_.real_; case booleanValue: return value_.bool_ < other.value_.bool_; case stringValue: return ( value_.string_ == 0 && other.value_.string_ ) || ( other.value_.string_ && value_.string_ && strcmp( value_.string_, other.value_.string_ ) < 0 ); #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: { int delta = int( value_.map_->size() - other.value_.map_->size() ); if ( delta ) return delta < 0; return (*value_.map_) < (*other.value_.map_); } #else case arrayValue: return value_.array_->compare( *(other.value_.array_) ) < 0; case objectValue: return value_.map_->compare( *(other.value_.map_) ) < 0; #endif default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable } bool Value::operator <=( const Value &other ) const { return !(other > *this); } bool Value::operator >=( const Value &other ) const { return !(*this < other); } bool Value::operator >( const Value &other ) const { return other < *this; } bool Value::operator ==( const Value &other ) const { //if ( type_ != other.type_ ) // GCC 2.95.3 says: // attempt to take address of bit-field structure member `Json::Value::type_' // Beats me, but a temp solves the problem. int temp = other.type_; if ( type_ != temp ) return false; switch ( type_ ) { case nullValue: return true; case intValue: return value_.int_ == other.value_.int_; case uintValue: return value_.uint_ == other.value_.uint_; case realValue: return value_.real_ == other.value_.real_; case booleanValue: return value_.bool_ == other.value_.bool_; case stringValue: return ( value_.string_ == other.value_.string_ ) || ( other.value_.string_ && value_.string_ && strcmp( value_.string_, other.value_.string_ ) == 0 ); #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: return value_.map_->size() == other.value_.map_->size() && (*value_.map_) == (*other.value_.map_); #else case arrayValue: return value_.array_->compare( *(other.value_.array_) ) == 0; case objectValue: return value_.map_->compare( *(other.value_.map_) ) == 0; #endif default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable } bool Value::operator !=( const Value &other ) const { return !( *this == other ); } const char * Value::asCString() const { JSON_ASSERT( type_ == stringValue ); return value_.string_; } std::string Value::asString() const { switch ( type_ ) { case nullValue: return ""; case stringValue: return value_.string_ ? value_.string_ : ""; case booleanValue: return value_.bool_ ? "true" : "false"; case intValue: case uintValue: case realValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" ); default: JSON_ASSERT_UNREACHABLE; } return ""; // unreachable } # ifdef JSON_USE_CPPTL CppTL::ConstString Value::asConstString() const { return CppTL::ConstString( asString().c_str() ); } # endif Value::Int Value::asInt() const { switch ( type_ ) { case nullValue: return 0; case intValue: return value_.int_; case uintValue: JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" ); return value_.uint_; case realValue: JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" ); return Int( value_.real_ ); case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } Value::UInt Value::asUInt() const { switch ( type_ ) { case nullValue: return 0; case intValue: JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" ); return value_.int_; case uintValue: return value_.uint_; case realValue: JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" ); return UInt( value_.real_ ); case booleanValue: return value_.bool_ ? 1 : 0; case stringValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } double Value::asDouble() const { switch ( type_ ) { case nullValue: return 0.0; case intValue: return value_.int_; case uintValue: return value_.uint_; case realValue: return value_.real_; case booleanValue: return value_.bool_ ? 1.0 : 0.0; case stringValue: case arrayValue: case objectValue: JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" ); default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } bool Value::asBool() const { switch ( type_ ) { case nullValue: return false; case intValue: case uintValue: return value_.int_ != 0; case realValue: return value_.real_ != 0.0; case booleanValue: return value_.bool_; case stringValue: return value_.string_ && value_.string_[0] != 0; case arrayValue: case objectValue: return value_.map_->size() != 0; default: JSON_ASSERT_UNREACHABLE; } return false; // unreachable; } bool Value::isConvertibleTo( ValueType other ) const { switch ( type_ ) { case nullValue: return true; case intValue: return ( other == nullValue && value_.int_ == 0 ) || other == intValue || ( other == uintValue && value_.int_ >= 0 ) || other == realValue || other == stringValue || other == booleanValue; case uintValue: return ( other == nullValue && value_.uint_ == 0 ) || ( other == intValue && value_.uint_ <= (unsigned)maxInt ) || other == uintValue || other == realValue || other == stringValue || other == booleanValue; case realValue: return ( other == nullValue && value_.real_ == 0.0 ) || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt ) || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt ) || other == realValue || other == stringValue || other == booleanValue; case booleanValue: return ( other == nullValue && value_.bool_ == false ) || other == intValue || other == uintValue || other == realValue || other == stringValue || other == booleanValue; case stringValue: return other == stringValue || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) ); case arrayValue: return other == arrayValue || ( other == nullValue && value_.map_->size() == 0 ); case objectValue: return other == objectValue || ( other == nullValue && value_.map_->size() == 0 ); default: JSON_ASSERT_UNREACHABLE; } return false; // unreachable; } /// Number of values in array or object Value::UInt Value::size() const { switch ( type_ ) { case nullValue: case intValue: case uintValue: case realValue: case booleanValue: case stringValue: return 0; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: // size of the array is highest index + 1 if ( !value_.map_->empty() ) { ObjectValues::const_iterator itLast = value_.map_->end(); --itLast; return (*itLast).first.index()+1; } return 0; case objectValue: return Int( value_.map_->size() ); #else case arrayValue: return Int( value_.array_->size() ); case objectValue: return Int( value_.map_->size() ); #endif default: JSON_ASSERT_UNREACHABLE; } return 0; // unreachable; } bool Value::empty() const { if ( isNull() || isArray() || isObject() ) return size() == 0u; else return false; } bool Value::operator!() const { return isNull(); } void Value::clear() { JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue ); switch ( type_ ) { #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: case objectValue: value_.map_->clear(); break; #else case arrayValue: value_.array_->clear(); break; case objectValue: value_.map_->clear(); break; #endif default: break; } } void Value::resize( UInt newSize ) { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) *this = Value( arrayValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP UInt oldSize = size(); if ( newSize == 0 ) clear(); else if ( newSize > oldSize ) (*this)[ newSize - 1 ]; else { for ( UInt index = newSize; index < oldSize; ++index ) value_.map_->erase( index ); assert( size() == newSize ); } #else value_.array_->resize( newSize ); #endif } Value & Value::operator[]( UInt index ) { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) *this = Value( arrayValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString key( index ); ObjectValues::iterator it = value_.map_->lower_bound( key ); if ( it != value_.map_->end() && (*it).first == key ) return (*it).second; ObjectValues::value_type defaultValue( key, null ); it = value_.map_->insert( it, defaultValue ); return (*it).second; #else return value_.array_->resolveReference( index ); #endif } const Value & Value::operator[]( UInt index ) const { JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString key( index ); ObjectValues::const_iterator it = value_.map_->find( key ); if ( it == value_.map_->end() ) return null; return (*it).second; #else Value *value = value_.array_->find( index ); return value ? *value : null; #endif } Value & Value::operator[]( const char *key ) { return resolveReference( key, false ); } Value & Value::resolveReference( const char *key, bool isStatic ) { JSON_ASSERT( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) *this = Value( objectValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey( key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy ); ObjectValues::iterator it = value_.map_->lower_bound( actualKey ); if ( it != value_.map_->end() && (*it).first == actualKey ) return (*it).second; ObjectValues::value_type defaultValue( actualKey, null ); it = value_.map_->insert( it, defaultValue ); Value &value = (*it).second; return value; #else return value_.map_->resolveReference( key, isStatic ); #endif } Value Value::get( UInt index, const Value &defaultValue ) const { const Value *value = &((*this)[index]); return value == &null ? defaultValue : *value; } bool Value::isValidIndex( UInt index ) const { return index < size(); } const Value & Value::operator[]( const char *key ) const { JSON_ASSERT( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey( key, CZString::noDuplication ); ObjectValues::const_iterator it = value_.map_->find( actualKey ); if ( it == value_.map_->end() ) return null; return (*it).second; #else const Value *value = value_.map_->find( key ); return value ? *value : null; #endif } Value & Value::operator[]( const std::string &key ) { return (*this)[ key.c_str() ]; } const Value & Value::operator[]( const std::string &key ) const { return (*this)[ key.c_str() ]; } Value & Value::operator[]( const StaticString &key ) { return resolveReference( key, true ); } # ifdef JSON_USE_CPPTL Value & Value::operator[]( const CppTL::ConstString &key ) { return (*this)[ key.c_str() ]; } const Value & Value::operator[]( const CppTL::ConstString &key ) const { return (*this)[ key.c_str() ]; } # endif Value & Value::append( const Value &value ) { return (*this)[size()] = value; } Value Value::get( const char *key, const Value &defaultValue ) const { const Value *value = &((*this)[key]); return value == &null ? defaultValue : *value; } Value Value::get( const std::string &key, const Value &defaultValue ) const { return get( key.c_str(), defaultValue ); } Value Value::removeMember( const char* key ) { JSON_ASSERT( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP CZString actualKey( key, CZString::noDuplication ); ObjectValues::iterator it = value_.map_->find( actualKey ); if ( it == value_.map_->end() ) return null; Value old(it->second); value_.map_->erase(it); return old; #else Value *value = value_.map_->find( key ); if (value) { Value old(*value); value_.map_.remove( key ); return old; } else { return null; } #endif } Value Value::removeMember( const std::string &key ) { return removeMember( key.c_str() ); } # ifdef JSON_USE_CPPTL Value Value::get( const CppTL::ConstString &key, const Value &defaultValue ) const { return get( key.c_str(), defaultValue ); } # endif bool Value::isMember( const char *key ) const { const Value *value = &((*this)[key]); return value != &null; } bool Value::isMember( const std::string &key ) const { return isMember( key.c_str() ); } # ifdef JSON_USE_CPPTL bool Value::isMember( const CppTL::ConstString &key ) const { return isMember( key.c_str() ); } #endif Value::Members Value::getMemberNames() const { JSON_ASSERT( type_ == nullValue || type_ == objectValue ); if ( type_ == nullValue ) return Value::Members(); Members members; members.reserve( value_.map_->size() ); #ifndef JSON_VALUE_USE_INTERNAL_MAP ObjectValues::const_iterator it = value_.map_->begin(); ObjectValues::const_iterator itEnd = value_.map_->end(); for ( ; it != itEnd; ++it ) members.push_back( std::string( (*it).first.c_str() ) ); #else ValueInternalMap::IteratorState it; ValueInternalMap::IteratorState itEnd; value_.map_->makeBeginIterator( it ); value_.map_->makeEndIterator( itEnd ); for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) ) members.push_back( std::string( ValueInternalMap::key( it ) ) ); #endif return members; } // //# ifdef JSON_USE_CPPTL //EnumMemberNames //Value::enumMemberNames() const //{ // if ( type_ == objectValue ) // { // return CppTL::Enum::any( CppTL::Enum::transform( // CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), // MemberNamesTransform() ) ); // } // return EnumMemberNames(); //} // // //EnumValues //Value::enumValues() const //{ // if ( type_ == objectValue || type_ == arrayValue ) // return CppTL::Enum::anyValues( *(value_.map_), // CppTL::Type<const Value &>() ); // return EnumValues(); //} // //# endif bool Value::isNull() const { return type_ == nullValue; } bool Value::isBool() const { return type_ == booleanValue; } bool Value::isInt() const { return type_ == intValue; } bool Value::isUInt() const { return type_ == uintValue; } bool Value::isIntegral() const { return type_ == intValue || type_ == uintValue || type_ == booleanValue; } bool Value::isDouble() const { return type_ == realValue; } bool Value::isNumeric() const { return isIntegral() || isDouble(); } bool Value::isString() const { return type_ == stringValue; } bool Value::isArray() const { return type_ == nullValue || type_ == arrayValue; } bool Value::isObject() const { return type_ == nullValue || type_ == objectValue; } void Value::setComment( const char *comment, CommentPlacement placement ) { if ( !comments_ ) comments_ = new CommentInfo[numberOfCommentPlacement]; comments_[placement].setComment( comment ); } void Value::setComment( const std::string &comment, CommentPlacement placement ) { setComment( comment.c_str(), placement ); } bool Value::hasComment( CommentPlacement placement ) const { return comments_ != 0 && comments_[placement].comment_ != 0; } std::string Value::getComment( CommentPlacement placement ) const { if ( hasComment(placement) ) return comments_[placement].comment_; return ""; } std::string Value::toStyledString() const { StyledWriter writer; return writer.write( *this ); } Value::const_iterator Value::begin() const { switch ( type_ ) { #ifdef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: if ( value_.array_ ) { ValueInternalArray::IteratorState it; value_.array_->makeBeginIterator( it ); return const_iterator( it ); } break; case objectValue: if ( value_.map_ ) { ValueInternalMap::IteratorState it; value_.map_->makeBeginIterator( it ); return const_iterator( it ); } break; #else case arrayValue: case objectValue: if ( value_.map_ ) return const_iterator( value_.map_->begin() ); break; #endif default: break; } return const_iterator(); } Value::const_iterator Value::end() const { switch ( type_ ) { #ifdef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: if ( value_.array_ ) { ValueInternalArray::IteratorState it; value_.array_->makeEndIterator( it ); return const_iterator( it ); } break; case objectValue: if ( value_.map_ ) { ValueInternalMap::IteratorState it; value_.map_->makeEndIterator( it ); return const_iterator( it ); } break; #else case arrayValue: case objectValue: if ( value_.map_ ) return const_iterator( value_.map_->end() ); break; #endif default: break; } return const_iterator(); } Value::iterator Value::begin() { switch ( type_ ) { #ifdef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: if ( value_.array_ ) { ValueInternalArray::IteratorState it; value_.array_->makeBeginIterator( it ); return iterator( it ); } break; case objectValue: if ( value_.map_ ) { ValueInternalMap::IteratorState it; value_.map_->makeBeginIterator( it ); return iterator( it ); } break; #else case arrayValue: case objectValue: if ( value_.map_ ) return iterator( value_.map_->begin() ); break; #endif default: break; } return iterator(); } Value::iterator Value::end() { switch ( type_ ) { #ifdef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: if ( value_.array_ ) { ValueInternalArray::IteratorState it; value_.array_->makeEndIterator( it ); return iterator( it ); } break; case objectValue: if ( value_.map_ ) { ValueInternalMap::IteratorState it; value_.map_->makeEndIterator( it ); return iterator( it ); } break; #else case arrayValue: case objectValue: if ( value_.map_ ) return iterator( value_.map_->end() ); break; #endif default: break; } return iterator(); } // class PathArgument // ////////////////////////////////////////////////////////////////// PathArgument::PathArgument() : kind_( kindNone ) { } PathArgument::PathArgument( Value::UInt index ) : index_( index ) , kind_( kindIndex ) { } PathArgument::PathArgument( const char *key ) : key_( key ) , kind_( kindKey ) { } PathArgument::PathArgument( const std::string &key ) : key_( key.c_str() ) , kind_( kindKey ) { } // class Path // ////////////////////////////////////////////////////////////////// Path::Path( const std::string &path, const PathArgument &a1, const PathArgument &a2, const PathArgument &a3, const PathArgument &a4, const PathArgument &a5 ) { InArgs in; in.push_back( &a1 ); in.push_back( &a2 ); in.push_back( &a3 ); in.push_back( &a4 ); in.push_back( &a5 ); makePath( path, in ); } void Path::makePath( const std::string &path, const InArgs &in ) { const char *current = path.c_str(); const char *end = current + path.length(); InArgs::const_iterator itInArg = in.begin(); while ( current != end ) { if ( *current == '[' ) { ++current; if ( *current == '%' ) addPathInArg( path, in, itInArg, PathArgument::kindIndex ); else { Value::UInt index = 0; for ( ; current != end && *current >= '0' && *current <= '9'; ++current ) index = index * 10 + Value::UInt(*current - '0'); args_.push_back( index ); } if ( current == end || *current++ != ']' ) invalidPath( path, int(current - path.c_str()) ); } else if ( *current == '%' ) { addPathInArg( path, in, itInArg, PathArgument::kindKey ); ++current; } else if ( *current == '.' ) { ++current; } else { const char *beginName = current; while ( current != end && !strchr( "[.", *current ) ) ++current; args_.push_back( std::string( beginName, current ) ); } } } void Path::addPathInArg( const std::string &path, const InArgs &in, InArgs::const_iterator &itInArg, PathArgument::Kind kind ) { if ( itInArg == in.end() ) { // Error: missing argument %d } else if ( (*itInArg)->kind_ != kind ) { // Error: bad argument type } else { args_.push_back( **itInArg ); } } void Path::invalidPath( const std::string &path, int location ) { // Error: invalid path. } const Value & Path::resolve( const Value &root ) const { const Value *node = &root; for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) { const PathArgument &arg = *it; if ( arg.kind_ == PathArgument::kindIndex ) { if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) { // Error: unable to resolve path (array value expected at position... } node = &((*node)[arg.index_]); } else if ( arg.kind_ == PathArgument::kindKey ) { if ( !node->isObject() ) { // Error: unable to resolve path (object value expected at position...) } node = &((*node)[arg.key_]); if ( node == &Value::null ) { // Error: unable to resolve path (object has no member named '' at position...) } } } return *node; } Value Path::resolve( const Value &root, const Value &defaultValue ) const { const Value *node = &root; for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) { const PathArgument &arg = *it; if ( arg.kind_ == PathArgument::kindIndex ) { if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) return defaultValue; node = &((*node)[arg.index_]); } else if ( arg.kind_ == PathArgument::kindKey ) { if ( !node->isObject() ) return defaultValue; node = &((*node)[arg.key_]); if ( node == &Value::null ) return defaultValue; } } return *node; } Value & Path::make( Value &root ) const { Value *node = &root; for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) { const PathArgument &arg = *it; if ( arg.kind_ == PathArgument::kindIndex ) { if ( !node->isArray() ) { // Error: node is not an array at position ... } node = &((*node)[arg.index_]); } else if ( arg.kind_ == PathArgument::kindKey ) { if ( !node->isObject() ) { // Error: node is not an object at position... } node = &((*node)[arg.key_]); } } return *node; } } // namespace Json
Int FromDegree(double dDegree) { // Also very simple return Int(dDegree / (360. / (1 << GPWIDTH))); }