void CLogic::quantize_to_allowed_states( CValue &value, const value_set &allowed_states ) const { const CValue *nearest_allowed_state = NULL; float distance_to_current = 0; float distance_to_nearest_allowed_state = 0; bool first = true; for( value_set::const_iterator i = allowed_states.begin(); i != allowed_states.end(); i++ ) { const CValue *allowed_state = *i; if( value.get_type() != allowed_state->get_type() ) { INTEGRA_TRACE_ERROR << "Value type mismatch whilst quantizing to allowed states"; continue; } distance_to_current = value.get_distance( *allowed_state ); if( first || distance_to_current < distance_to_nearest_allowed_state ) { distance_to_nearest_allowed_state = distance_to_current; nearest_allowed_state = allowed_state; first = false; } } if( !nearest_allowed_state ) { INTEGRA_TRACE_ERROR << "failed to quantize to allowed states - allowed states is empty"; return; } assert( nearest_allowed_state->get_type() == value.get_type() ); value = *nearest_allowed_state; }
bool CStateInfo::test_constraint( const CValue &value ) const { CValue::type endpoint_type = get_type(); if( value.get_type() != endpoint_type ) { CValue *fixed_type = value.transmogrify( endpoint_type ); bool test_result = test_constraint( *fixed_type ); delete fixed_type; return test_result; } const IConstraint &constraint = get_constraint(); const IValueRange *range = constraint.get_value_range(); if( range ) { switch( value.get_type() ) { case CValue::STRING: { /* for strings, range constraint defines min/max length */ const string &string_value = value; int string_length = string_value.length(); if( string_length < ( int ) range->get_minimum() ) return false; if( string_length > ( int ) range->get_maximum() ) return false; return true; } case CValue::INTEGER: { /* for integers, range constraint defines min/max value */ int int_value = value; if( int_value < ( int ) range->get_minimum() ) return false; if( int_value > ( int ) range->get_maximum() ) return false; return true; } case CValue::FLOAT: { /* for floats, range constraint defines min/max value */ float float_value = value; if( float_value < ( float ) range->get_minimum() ) return false; if( float_value > ( float ) range->get_maximum() ) return false; return true; } default: INTEGRA_TRACE_ERROR << "unhandled value type"; return false; } } else /* allowed value constraint */ { const value_set *allowed_states = constraint.get_allowed_states(); assert( allowed_states ); for( value_set::const_iterator i = allowed_states->begin(); i != allowed_states->end(); i++ ) { if( value.is_equal( **i ) ) { return true; } } return false; //not found } }