Skip to content

Commit

Permalink
[math] Support TComplex arithmetic operations with any possible type
Browse files Browse the repository at this point in the history
Generalize the arithmetic operator overloads of TComplex to general
arithmetic types with templates.

I'm using some `enable_if` for arithmetic types only, so we can be sure
that nothing unexpected will happen for non-arithmetic types that
implement arithmetic operators with `double` themselves.

Closes root-project#13730.
  • Loading branch information
guitargeek committed Sep 28, 2023
1 parent 6e556ce commit 993cc13
Showing 1 changed file with 28 additions and 19 deletions.
47 changes: 28 additions & 19 deletions math/mathcore/inc/TComplex.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#include "TMath.h"

#include "Rtypes.h"

#include <string>
#include <type_traits>


class TComplex {
Expand Down Expand Up @@ -74,25 +76,32 @@ class TComplex {
TComplex operator +()
{return *this;}

// Simple operators complex - double
TComplex operator *(Double_t c) const
{return TComplex(fRe*c,fIm*c);}
TComplex operator +(Double_t c) const
{return TComplex(fRe+c, fIm);}
TComplex operator /(Double_t c) const
{return TComplex(fRe/c,fIm/c);}
TComplex operator -(Double_t c) const
{return TComplex(fRe-c, fIm);}

// Simple operators double - complex
friend TComplex operator *(Double_t d, const TComplex & c)
{return TComplex(d*c.fRe,d*c.fIm);}
friend TComplex operator +(Double_t d, const TComplex & c)
{return TComplex(d+c.fRe, c.fIm);}
friend TComplex operator /(Double_t d, const TComplex & c)
{return TComplex(d*c.fRe,-d*c.fIm)/c.Rho2();}
friend TComplex operator -(Double_t d, const TComplex & c)
{return TComplex(d-c.fRe, -c.fIm);}
// Metafunction to figure out whether a type is arithmetic. This is used for
// the arithmetic operator implementation, so we can be sure that nothing
// unexpected will happen for non-arithmetic types that implement these
// operators with `double` themselves.
template<class T>
using enable_if_arithmetic = typename std::enable_if<std::is_arithmetic<T>::value, bool>::type;

// Simple operators complex - arithmetic
template <class T, enable_if_arithmetic<T> = true>
TComplex operator *(T c) const { return {fRe*c,fIm*c}; }
template <class T, enable_if_arithmetic<T> = true>
TComplex operator +(T c) const { return {fRe+c, fIm}; }
template <class T, enable_if_arithmetic<T> = true>
TComplex operator /(T c) const { return {fRe/c,fIm/c}; }
template <class T, enable_if_arithmetic<T> = true>
TComplex operator -(T c) const { return {fRe-c, fIm}; }

// Simple operators arithmetic - complex
template <class T, enable_if_arithmetic<T> = true>
friend TComplex operator *(T d, const TComplex & c) { return {d*c.fRe,d*c.fIm}; }
template <class T, enable_if_arithmetic<T> = true>
friend TComplex operator +(T d, const TComplex & c) { return {d+c.fRe, c.fIm}; }
template <class T, enable_if_arithmetic<T> = true>
friend TComplex operator /(T d, const TComplex & c) { return TComplex{d*c.fRe,-d*c.fIm} / c.Rho2(); }
template <class T, enable_if_arithmetic<T> = true>
friend TComplex operator -(T d, const TComplex & c) { return {d-c.fRe, -c.fIm}; }

// Convertors
operator Double_t () const {return fRe;}
Expand Down

0 comments on commit 993cc13

Please sign in to comment.