-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Currently, Constants do not support all arithmetic and comparison operations, as the goal is to ensure perfect representation.
Constants support the following mixins (All mixins below are commutative):
MakesQuantityFromNumber, which permitsConstant * raw num -> QuantityConstant / raw num -> Quantity
ComposesWith, which permitsConstant * Constant -> ConstantConstant / Constant -> ConstantConstant * QuantityMaker -> QuantityMakerConstant / QuantityMaker -> QuantityMakerConstant * SingularNameFor -> SingularNameForConstant / SingularNameFor -> SingularNameFor
SupportsRationalPowers, which permitsau::pow<integer>(Constant) -> Constantau::root<integer>(Constant) -> Constant
CanScaleByMagnitude, which permitsConstant * Magnitude -> ConstantConstant / Magnitude -> Constant
Plus implicit conversion to Quantity and therefore all the op(Constant, Quantity) -> op(Quantity, Quantity) operations supported on Quantities.
This leaves a few gaps when working purely in the Constant domain (Or, equivalently, in the Constant and Magnitude domain). See below:
Arithmetic Operators
| Operator | LHS Operand | RHS Operand | Status |
|---|---|---|---|
+ (Unary) |
Constant |
N/A | Prohibited but desired |
- (Unary) |
Constant |
N/A | Permitted |
+ |
Constant |
Constant |
Prohibited but desired |
- |
Constant |
Constant |
Prohibited but desired |
* |
Constant |
Constant |
Permitted |
/ |
Constant |
Constant |
Permitted |
% |
Constant |
Constant |
Prohibited but desired |
~ (Unary) |
Constant |
N/A | Prohibited |
& |
Constant |
Constant |
Prohibited |
| |
Constant |
Constant |
Prohibited |
^ |
Constant |
Constant |
Prohibited |
<< |
Constant |
Constant |
Prohibited |
>> |
Constant |
Constant |
Prohibited |
Comparison Operators
| Operator | LHS Operand | RHS Operand | Status |
|---|---|---|---|
== |
Constant |
Constant |
Prohibited but desired |
!= |
Constant |
Constant |
Prohibited but desired |
< |
Constant |
Constant |
Prohibited but desired |
> |
Constant |
Constant |
Prohibited but desired |
<= |
Constant |
Constant |
Prohibited but desired |
>= |
Constant |
Constant |
Prohibited but desired |
<=> |
Constant |
Constant |
Out of scope, C++20 only |
For arithmetic operators, we need to be mindful about maintaining safety, particularly when working with prefixes, ScaledUnits, Pows, and RatioPows. We have previously talked about only supporting the subset of cases that are safe, which makes sense to me, though I can't recall what those unsafe cases actually are.
I think comparison operators will be more straightforward.
To summarize, I would like for there to be support for the following, from highest to lowest priority:
- All comparison operators
Constant + ConstantandConstant - Constant- This is a real point of friction for my team today. One common pattern we have is to have some
Constant<Seconds>which we wish to subtract 1ms from. We are forced to convert to theQuantitydomain (eg withCONST - milli(seconds)(1)) rather than staying in theConstantdomain (eg withCONST - make_constant(milli(seconds) * mag<1>()))
- This is a real point of friction for my team today. One common pattern we have is to have some
Constant % Constant- This is probably a bit more controversial and less generally useful, but still seems like we ought to provide it if we can.
- Unary
+Constant- This is a no-op, but could be provided just for consistency and symmetry with the unary minus operator. As with floats and doubles, there is no integer promotion for the unary plus operator to apply, so the operand is just returned as is.