Operators
Power Function
a**x for pow(a, x) (as in Python), “raise a to the power of x”.
infix right precedence (group Power), so a**b**c parses as a**(b**c).
Boolean and Bitwise Operators
No mixed types allowed (you need to explicitly cast one side instead).
Logical (Bool) Operators
Example:
aBoolandanotherBool -> Bool
The following word operators are used on Bool (only):
| Operator | Meaning |
|---|---|
and |
logical and |
or |
logical or |
nand |
logical nand |
nor |
logical nor |
xor |
logical xor |
not |
logical not |
Words like and and or IMHO are a bit clearer than && and ||, so they are recommended.
And actually and / or are valid C++ keywords, too.
not in addition to ! (for boolean negation), as not is a bit clearer than ! (especially as many modern languages like Rust and Swift use ! also for error handling).
xor in Cilia is a logical/Bool operator (unlike C++, where it is a bitwise operator).
Still also use && and || for boolean operation,
- as C/C++/Java/C# programmers are used to it,
- as we want
&&=and||=anyway.
Still also ! for negation, as we keep != for “not equal” anyway. (We could use <> instead of !=, but that’s really not familiar to C/C++ programmers.)
and/or/nand/nor/not are not also used for bitwise operations, because bitwise operators bind more strongly than logical operators.
The keyword is not supported.not_eq
Bitwise (Int) Operators
Example:
anInt&anotherInt -> Int
| Operator | Meaning |
|---|---|
& |
bitwise and |
| |
bitwise or |
~ |
bitwise negation |
^ |
bitwise xor |
All bind tightly.
| Operator | Meaning |
|---|---|
&= |
bitwise and assign |
|= |
bitwise or assign |
^= |
bitwise xor assign |
The keywords , bitand, bitor, compl, and_eq, or_eq are not supported.xor_eq
Equality
- Default
operator==- If not defined, then
- use negated
operator!=(if defined), or - use
operator<=>(if defined), or - use elementwise comparison with
==- Only possible if all elements themselves offer the
operator==. - Optimization for simple types: Byte-by-byte comparison.
- Only possible if all elements themselves offer the
- use negated
- If not defined, then
- Default
operator!=- If not defined, then
- use negated
operator==(if defined), or - use
operator<=>(if defined), or - use negated generated
operator==.
- use negated
- If not defined, then
Range Operator .. and ..<
1..10and0..<10are ranges- as in Kotlin
- Similar, but different:
- Swift would be
and1...100..<10 - Rust would be
and1..=100..10 - Cpp2 would be
and1..=10(as of recently)0..<10
- Swift would be
- Different kinds of ranges:
1..3– 1, 2, 3Range(1, 3)
0..<3– 0, 1, 2RangeExclusiveEnd(0, 3)
- Range with step (especially to iterate with the given step size in the
forloop)1..6:2– 1, 3, 5RangeByStep(1, 6, 2)
0..<6:2– 0, 2, 4RangeExclusiveEndByStep(0, 6, 2)
- Downwards iterating range (especially to iterate downwards in the
forloop).
Step size is mandatory here (to make it clear that we are counting down, to avoid wrong conclusions).8..0:-1– 8, 7, 6, 5, 4, 3, 2, 1, 0RangeByStep(8, 0, -1)- Not
, as8..0Range(8, 0)is always empty (it is counting up, not down!) - Not
8..<0:-1- With staticAssert in
RangeExclusiveEndByStepthatstep > 0:
“The range operator with exclusive end (..<) is not compatible with negative increments, because when counting downwards it would be necessary/logical to write..>and that is not available.” - It simply would be too much, IMHO.
- Use
8..1:-1instead.
- With staticAssert in
- If both start and end of the range are compile time constants, then it may be warned when the range contains no elements at all (e.g. when
start >= endwithstep > 0). - Incomplete ranges (need lower and/or upper bounds to be set before use)
..2– …, 1, 2RangeTo(2)
..<3– …, 1, 2RangeToExclusiveEnd(3)
0..– 0, 1, 2, …RangeFrom(0)
..RangeFull()
- Incomplete range with step
..2:2–RangeToByStep(2, 2)..<3:2–RangeToExclusiveEndByStep(3, 2)0..:2–RangeFromByStep(0, 2)..:2–RangeFullByStep(2)
- See Rust Ranges and Slices
Bit-Shift & Rotation
>>Shift right- Logical shift with unsigned integers,
- arithmetic shift with signed integers.
<<Shift left- Here a logical shift left with unsigned integers is the same as an arithmetic shift left with signed integers.
>>>Rotate right- Circular shift right,
- only defined for unsigned integers,
- and only for fixed size integers (i.e. not for
BigUInt).
<<<Rotate left- Circular shift left,
- only defined for unsigned integers,
- and only for fixed size integers (i.e. not for
BigUInt).
Operator Declaration
- Keyword
operatorinstead offunc. - As with normal functions: Parameters are passed as
inby default (i.e.const T&orconst T).
Assignment Operator
class Int256 {
operator =(Int256 other) { ... }
}
- No return of this-reference,
- as in Swift,
- so
if a = b { ... }is not accidentally allowed.
- Move assignment
class Int256 { operator =(move Int256 other) { ... } }
Arithmetic Operators
operator (Int256 a) + (Int256 b) -> Int256 { ... }
operator (Int256 a) - (Int256 b) -> Int256 { ... }
operator (Int256 a) * (Int256 b) -> Int256 { ... }
operator (Int256 a) / (Int256 b) -> Int256 { ... }
operator (Int256 a) % (Int256 b) -> Int256 { ... }
Shift and Rotate Operators
operator (Int256 a) << (Int shiftCount) -> Int256 { ... }
operator (Int256 a) >> (Int shiftCount) -> Int256 { ... }
operator (UInt256 a) <<< (Int shiftCount) -> UInt256 { ... }
operator (UInt256 a) >>> (Int shiftCount) -> UInt256 { ... }
Compound Assignment Operators
class Int256 {
operator +=(Int256 other) { ... }
operator -=(Int256 other) { ... }
operator *=(Int256 other) { ... }
operator /=(Int256 other) { ... }
operator %=(Int256 other) { ... }
operator <<=(Int shiftCount) { ... }
operator >>=(Int shiftCount) { ... }
operator &=(Int256 other) { ... }
operator |=(Int256 other) { ... }
operator ^=(Int256 other) { ... }
}
class UInt256 {
operator <<<=(Int shiftCount) { ... }
operator >>>=(Int shiftCount) { ... }
}
Increment and Decrement Operators
operator ++(inout Int256 x) -> Int256& { ... } // pre-increment
operator (inout Int256 x)++ -> Int256 { ... } // post-increment
operator --(inout Int256 x) -> Int256& { ... } // pre-decrement
operator (inout Int256 x)-- -> Int256 { ... } // post-decrement
Relational and Comparison Operators
operator (Int256 a) == (Int256 b) -> Bool { ... }
operator (Int256 a) != (Int256 b) -> Bool { ... }
operator (Int256 a) < (Int256 b) -> Bool { ... }
operator (Int256 a) > (Int256 b) -> Bool { ... }
operator (Int256 a) <= (Int256 b) -> Bool { ... }
operator (Int256 a) >= (Int256 b) -> Bool { ... }
operator (Int256 a) <=> (Int256 b) -> StrongOrdering { ... }
operator (Int256 a) ≠ (Int256 b) -> Bool { return a != b }
operator (Int256 a) ≤ (Int256 b) -> Bool { return a <= b }
operator (Int256 a) ≥ (Int256 b) -> Bool { return a >= b }
Logical Operators
- Boolean operators
operator (Bool a) and (Bool b) -> Bool { ... } operator (Bool a) or (Bool b) -> Bool { ... } operator (Bool a) nand (Bool b) -> Bool { ... } operator (Bool a) nor (Bool b) -> Bool { ... } operator (Bool a) xor (Bool b) -> Bool { ... } operator not(Bool a) -> Bool { ... } operator (Bool a) && (Bool b) -> Bool { return a and b } operator (Bool a) || (Bool b) -> Bool { return a or b } operator !(Bool a) -> Bool { return not a }- Defined for
Bool(not for integers), - operators
!, not,~&&and||, not.&and|
- Defined for
- Bitwise operators
operator (Int256 a) & (Int256 b) -> Int256 { ... } operator (Int256 a) | (Int256 b) -> Int256 { ... } operator (Int256 a) ^ (Int256 b) -> Int256 { ... } operator ~(Int256 a) -> Int256 { ... }- Defined for integers (not for
Bool), - operators
~, not,!&,|and^, not.&&and||
- Defined for integers (not for
Subscript/Bracket Operator
class MyArray<type T> {
// Array subscript
operator [Int i] -> T& {
return data[i]
}
}
class MyImage<type T> {
// 2D array (i.e. image like) subscript
operator [Int x, y] -> T& {
return data[x + y*stride]
}
}
Parenthesis/Functor Operator
class MyFunctor {
// Functor call
operator (Int a, Float b, String c) -> String {
...
}
}