in src/Elastic.Apm/Libraries/Newtonsoft.Json/Linq/JValue.cs [354:498]
private static bool Operation(ExpressionType operation, object? objA, object? objB, out object? result)
{
if (objA is string || objB is string)
{
if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign)
{
result = objA?.ToString() + objB?.ToString();
return true;
}
}
#if HAVE_BIG_INTEGER
if (objA is BigInteger || objB is BigInteger)
{
if (objA == null || objB == null)
{
result = null;
return true;
}
// not that this will lose the fraction
// BigInteger doesn't have operators with non-integer types
BigInteger i1 = ConvertUtils.ToBigInteger(objA);
BigInteger i2 = ConvertUtils.ToBigInteger(objB);
switch (operation)
{
case ExpressionType.Add:
case ExpressionType.AddAssign:
result = i1 + i2;
return true;
case ExpressionType.Subtract:
case ExpressionType.SubtractAssign:
result = i1 - i2;
return true;
case ExpressionType.Multiply:
case ExpressionType.MultiplyAssign:
result = i1 * i2;
return true;
case ExpressionType.Divide:
case ExpressionType.DivideAssign:
result = i1 / i2;
return true;
}
}
else
#endif
if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
{
if (objA == null || objB == null)
{
result = null;
return true;
}
decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture);
switch (operation)
{
case ExpressionType.Add:
case ExpressionType.AddAssign:
result = d1 + d2;
return true;
case ExpressionType.Subtract:
case ExpressionType.SubtractAssign:
result = d1 - d2;
return true;
case ExpressionType.Multiply:
case ExpressionType.MultiplyAssign:
result = d1 * d2;
return true;
case ExpressionType.Divide:
case ExpressionType.DivideAssign:
result = d1 / d2;
return true;
}
}
else if (objA is float || objB is float || objA is double || objB is double)
{
if (objA == null || objB == null)
{
result = null;
return true;
}
double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
switch (operation)
{
case ExpressionType.Add:
case ExpressionType.AddAssign:
result = d1 + d2;
return true;
case ExpressionType.Subtract:
case ExpressionType.SubtractAssign:
result = d1 - d2;
return true;
case ExpressionType.Multiply:
case ExpressionType.MultiplyAssign:
result = d1 * d2;
return true;
case ExpressionType.Divide:
case ExpressionType.DivideAssign:
result = d1 / d2;
return true;
}
}
else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte ||
objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte)
{
if (objA == null || objB == null)
{
result = null;
return true;
}
long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture);
long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture);
switch (operation)
{
case ExpressionType.Add:
case ExpressionType.AddAssign:
result = l1 + l2;
return true;
case ExpressionType.Subtract:
case ExpressionType.SubtractAssign:
result = l1 - l2;
return true;
case ExpressionType.Multiply:
case ExpressionType.MultiplyAssign:
result = l1 * l2;
return true;
case ExpressionType.Divide:
case ExpressionType.DivideAssign:
result = l1 / l2;
return true;
}
}
result = null;
return false;
}