Series operators.
This class contains the arithmetic and comparison operator overloads for piranha::series instances. The operators are implemented as inline friend functions and they will be found via argument-dependent name lookup when at least one of the two operands is an instance of piranha::series.
The operators defined here, similarly to the builtin operators in C++, promote one or both operands to a common type, if necessary, before actually performing the operation. The promotion rules are dependent on the recursion indices and coefficient types of the series, and they rely on the series rebinding mechanism to promote a series as needed (see piranha::series_is_rebindable and piranha::series_recursion_index).
These are the scenarios handled by the type promotion mechanism:
- the two arguments are of the same series type and the operator on the coefficient type of the series results in the same coefficient type. In this case there is no type promotion;
- both series arguments have the same recursion index, different coefficients, and the operator on the coefficient types results in the first (resp. second) coefficient type. In this case the result of the operations is the first (resp. second) series type;
- both series arguments have the same recursion index, different coefficients, and the operator on the coefficient types results in something other than the first or second coefficient type. In this case both series are promoted to a type resulting from the rebinding of the two series to the resulting coefficient type;
- the first (resp. second) argument has recursion index greater than the second (resp. first) one, and the result type of the operator on the coefficient type of the first (resp. second) argument and the second (resp. first) argument is the coefficient type of the first (resp. second) argument. In this case, the second (resp. first) argument is promoted to the first (resp. second);
- the first (resp. second) argument has recursion index greater than the second (resp. first) one, and the result type of the operator on the coefficient type of the first (resp. second) argument and the second (resp. first) argument is something other than the coefficient type of the first (resp. second) argument. In this case, both arguments are promoted to a type resulting from the rebinding of the first (resp. second) argument to the resulting coefficient type.
If any necessary conversion is not possible, either because the series are not rebindable or they do not support the needed constructors, the operators are disabled. The operators are also disabled if any operation needed by the implementation is not supported, or if an ambiguity arises in the type promotion algorithm (e.g., two series with same recursion index, same coefficient type which does not trigger any promotion, and different key types).
A few things to note about the operators implemented within this class:
- in case two series arguments have different symbol sets, either one or both series will be copied in a new series in which the symbols have been merged, and the operation will be performed on those series instead;
- in-place arithmetic operators are implemented as binary operators plus move-assignment (and they are thus disabled if either the corresponding binary operation or the assignment are invalid);
- series multiplication requires the coefficient types to be multipliable and a valid specialisation of piranha::series_multiplier for the promoted series type;
- division is implemented only when it reduces to coefficient division (true series division may be implemented in specific series types, e.g., piranha::polynomial);
- the comparison operators will use
operator+()
on the coefficient types to determine if any type promotion is necessary before performing the comparison.
The operators are implemented using variadic templates in order to allow overriding them via non-variadic overloads.
Definition at line 539 of file series.hpp.