Fix issue #13352 - Only perform Algebraic arithmetic with allowed types.

Adds a static check allowed!T before trying any particular numeric type. Also checks for an exact type match in case of a raw (non-Variant) operand and prefers that to one of the fixed numeric types. Finally, it loosens the restriction for opArithmetic to only work for equal Variant types.

https://issues.dlang.org/show_bug.cgi?id=13352
Throwing a const or immutable exception breaks the type system, as they can be caught using a mutable reference:
```d
static immutable ex = new Exception("");
bool ran = false;
try throw ex;
catch(Exception e)
{
    ran = true;
}
assert(ran);
```
Also, throwing the same exception will cause serious problems if the same error is raised in a catch block that catched the exception.