/* * Copyright (c) 2018 Jaroslav Jindrak * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBCPP_COMPLEX #define LIBCPP_COMPLEX #include namespace std { template class complex { public: using value_type = T; constexpr complex(const value_type& re = value_type{}, const value_type& im = value_type{}) : real_{re}, imag_{im} { /* DUMMY BODY */ } constexpr complex(const complex& other) : real_{other.real_}, imag_{other.imag_} { /* DUMMY BODY */ } template constexpr complex(const complex& other) : real_(other.real_), imag_(other.imag_) { /* DUMMY BODY */ } constexpr value_type real() const { return real_; } void real(value_type val) { real_ = val; } constexpr value_type imag() const { return imag_; } void imag(value_type val) { imag_ = val; } complex& operator=(const value_type& val) { real_ = val; imag_ = value_type{}; return *this; } complex& operator+=(const value_type& val) { real_ += val; return *this; } complex& operator-=(const value_type& val) { real_ -= val; return *this; } complex& operator*=(const value_type& val) { real_ *= val; imag_ *= val; return *this; } complex& operator/=(const value_type& val) { real_ /= val; imag_ /= val; return *this; } complex& operator=(const complex& other) { real_ = other.real_; imag_ = other.imag_; return *this; } template complex& operator=(const complex& rhs) { real_ = rhs.real_; imag_ = rhs.imag_; return *this; } template complex& operator+=(const complex& rhs) { real_ += rhs.real_; imag_ += rhs.imag_; return *this; } template complex& operator-=(const complex& rhs) { real_ -= rhs.real_; imag_ -= rhs.imag_; return *this; } template complex& operator*=(const complex& rhs) { real_ = real_ * rhs.real_ - imag_ * rhs.imag_; imag_ = real_ * rhs.imag_ - imag_ * rhs.real_; return *this; } template complex& operator/=(const complex& rhs) { real_ = (real_ * rhs.real_ + imag_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); imag_ = (imag_ * rhs.real_ - real_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); return *this; } private: value_type real_; value_type imag_; }; template<> class complex { public: using value_type = float; constexpr complex(const value_type& re = value_type{}, const value_type& im = value_type{}) : real_{re}, imag_{im} { /* DUMMY BODY */ } constexpr complex(const complex& other) : real_{other.real_}, imag_{other.imag_} { /* DUMMY BODY */ } template constexpr complex(const complex& other) : real_(other.real_), imag_(other.imag_) { /* DUMMY BODY */ } constexpr value_type real() const { return real_; } void real(value_type val) { real_ = val; } constexpr value_type imag() const { return imag_; } void imag(value_type val) { imag_ = val; } complex& operator=(const value_type& val) { real_ = val; imag_ = value_type{}; return *this; } complex& operator+=(const value_type& val) { real_ += val; return *this; } complex& operator-=(const value_type& val) { real_ -= val; return *this; } complex& operator*=(const value_type& val) { real_ *= val; imag_ *= val; return *this; } complex& operator/=(const value_type& val) { real_ /= val; imag_ /= val; return *this; } complex& operator=(const complex& other) { real_ = other.real_; imag_ = other.imag_; return *this; } template complex& operator=(const complex& rhs) { real_ = rhs.real_; imag_ = rhs.imag_; return *this; } template complex& operator+=(const complex& rhs) { real_ += rhs.real_; imag_ += rhs.imag_; return *this; } template complex& operator-=(const complex& rhs) { real_ -= rhs.real_; imag_ -= rhs.imag_; return *this; } template complex& operator*=(const complex& rhs) { real_ = real_ * rhs.real_ - imag_ * rhs.imag_; imag_ = real_ * rhs.imag_ - imag_ * rhs.real_; return *this; } template complex& operator/=(const complex& rhs) { real_ = (real_ * rhs.real_ + imag_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); imag_ = (imag_ * rhs.real_ - real_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); return *this; } private: value_type real_; value_type imag_; }; template<> class complex { public: using value_type = double; constexpr complex(const value_type& re = value_type{}, const value_type& im = value_type{}) : real_{re}, imag_{im} { /* DUMMY BODY */ } constexpr complex(const complex& other) : real_{other.real_}, imag_{other.imag_} { /* DUMMY BODY */ } template constexpr complex(const complex& other) : real_(other.real_), imag_(other.imag_) { /* DUMMY BODY */ } constexpr value_type real() const { return real_; } void real(value_type val) { real_ = val; } constexpr value_type imag() const { return imag_; } void imag(value_type val) { imag_ = val; } complex& operator=(const value_type& val) { real_ = val; imag_ = value_type{}; return *this; } complex& operator+=(const value_type& val) { real_ += val; return *this; } complex& operator-=(const value_type& val) { real_ -= val; return *this; } complex& operator*=(const value_type& val) { real_ *= val; imag_ *= val; return *this; } complex& operator/=(const value_type& val) { real_ /= val; imag_ /= val; return *this; } complex& operator=(const complex& other) { real_ = other.real_; imag_ = other.imag_; return *this; } template complex& operator=(const complex& rhs) { real_ = rhs.real_; imag_ = rhs.imag_; return *this; } template complex& operator+=(const complex& rhs) { real_ += rhs.real_; imag_ += rhs.imag_; return *this; } template complex& operator-=(const complex& rhs) { real_ -= rhs.real_; imag_ -= rhs.imag_; return *this; } template complex& operator*=(const complex& rhs) { real_ = real_ * rhs.real_ - imag_ * rhs.imag_; imag_ = real_ * rhs.imag_ - imag_ * rhs.real_; return *this; } template complex& operator/=(const complex& rhs) { real_ = (real_ * rhs.real_ + imag_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); imag_ = (imag_ * rhs.real_ - real_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); return *this; } private: value_type real_; value_type imag_; }; template<> class complex { public: using value_type = long double; constexpr complex(const value_type& re = value_type{}, const value_type& im = value_type{}) : real_{re}, imag_{im} { /* DUMMY BODY */ } constexpr complex(const complex& other) : real_{other.real_}, imag_{other.imag_} { /* DUMMY BODY */ } template constexpr complex(const complex& other) : real_(other.real_), imag_(other.imag_) { /* DUMMY BODY */ } constexpr value_type real() const { return real_; } void real(value_type val) { real_ = val; } constexpr value_type imag() const { return imag_; } void imag(value_type val) { imag_ = val; } complex& operator=(const value_type& val) { real_ = val; imag_ = value_type{}; return *this; } complex& operator+=(const value_type& val) { real_ += val; return *this; } complex& operator-=(const value_type& val) { real_ -= val; return *this; } complex& operator*=(const value_type& val) { real_ *= val; imag_ *= val; return *this; } complex& operator/=(const value_type& val) { real_ /= val; imag_ /= val; return *this; } complex& operator=(const complex& other) { real_ = other.real_; imag_ = other.imag_; return *this; } template complex& operator=(const complex& rhs) { real_ = rhs.real_; imag_ = rhs.imag_; return *this; } template complex& operator+=(const complex& rhs) { real_ += rhs.real_; imag_ += rhs.imag_; return *this; } template complex& operator-=(const complex& rhs) { real_ -= rhs.real_; imag_ -= rhs.imag_; return *this; } template complex& operator*=(const complex& rhs) { real_ = real_ * rhs.real_ - imag_ * rhs.imag_; imag_ = real_ * rhs.imag_ - imag_ * rhs.real_; return *this; } template complex& operator/=(const complex& rhs) { real_ = (real_ * rhs.real_ + imag_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); imag_ = (imag_ * rhs.real_ - real_ * rhs.imag_) / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_); return *this; } private: value_type real_; value_type imag_; }; /** * 26.4.6, operators: */ template complex operator+(const complex& lhs, const complex& rhs) { return complex{lhs} += rhs; } template complex operator+(const complex& lhs, const T& rhs) { return complex{lhs} += rhs; } template complex operator+(const T& lhs, const complex& rhs) { return complex{lhs} += rhs; } template complex operator-(const complex& lhs, const complex& rhs) { return complex{lhs} -= rhs; } template complex operator-(const complex& lhs, const T& rhs) { return complex{lhs} -= rhs; } template complex operator-(const T& lhs, const complex& rhs) { return complex{lhs} -= rhs; } template complex operator*(const complex& lhs, const complex& rhs) { return complex{lhs} *= rhs; } template complex operator*(const complex& lhs, const T& rhs) { return complex{lhs} *= rhs; } template complex operator*(const T& lhs, const complex& rhs) { return complex{lhs} *= rhs; } template complex operator/(const complex& lhs, const complex& rhs) { return complex{lhs} /= rhs; } template complex operator/(const complex& lhs, const T& rhs) { return complex{lhs} /= rhs; } template complex operator/(const T& lhs, const complex& rhs) { return complex{lhs} /= rhs; } template complex operator+(const complex& c) { return complex{c}; } template complex operator-(const complex& c) { return complex{-c.real(), -c.imag()}; } template constexpr bool operator==(const complex& lhs, const complex& rhs) { return lhs.real() == rhs.real() && lhs.imag() == rhs.imag(); } template constexpr bool operator==(const complex& lhs, const T& rhs) { return lhs.real() == rhs && lhs.imag() == T{}; } template constexpr bool operator==(const T& lhs, const complex& rhs) { return lhs == rhs.real() && T{} == rhs.imag(); } template constexpr bool operator!=(const complex& lhs, const complex& rhs) { return lhs.real() != rhs.real() || lhs.imag() != rhs.imag(); } template constexpr bool operator!=(const complex& lhs, const T& rhs) { return lhs.real() != rhs || lhs.imag() != T{}; } template constexpr bool operator!=(const T& lhs, const complex& rhs) { return lhs != rhs.real() || T{} != rhs.imag(); } template basic_istream& operator>>(basic_istream& is, const complex& c) { // TODO: implement } template basic_ostream& operator<<(basic_ostream& os, const complex& c) { basic_ostringstream oss{}; oss.flags(os.flags()); oss.imbue(os.getloc()); oss.precision(os.precision()); oss << "(" << c.real() << "," << c.imag() << ")"; return os << oss.str(); } /** * 26.4.7, values: */ template constexpr T real(const complex& c) { return c.real(); } template constexpr T imag(const complex& c) { return c.imag(); } template T abs(const complex& c) { return c.real() * c.real() + c.imag() * c.imag(); } template T arg(const complex& c) { // TODO: implement return c; } template T norm(const complex& c) { return abs(c) * abs(c); } template complex conj(const complex& c) { // TODO: implement return c; } template complex proj(const complex& c) { // TODO: implement return c; } template complex polar(const T&, const T& = T{}) { // TODO: implement return complex{}; } /** * 26.4.8, transcendentals: */ template complex acos(const complex& c) { // TODO: implement return c; } template complex asin(const complex& c) { // TODO: implement return c; } template complex atan(const complex& c) { // TODO: implement return c; } template complex acosh(const complex& c) { // TODO: implement return c; } template complex asinh(const complex& c) { // TODO: implement return c; } template complex atanh(const complex& c) { // TODO: implement return c; } template complex cos(const complex& c) { // TODO: implement return c; } template complex cosh(const complex& c) { // TODO: implement return c; } template complex exp(const complex& c) { // TODO: implement return c; } template complex log(const complex& c) { // TODO: implement return c; } template complex log10(const complex& c) { // TODO: implement return c; } template complex pow(const complex& base, const T& exp) { // TODO: implement return base; } template complex pow(const complex& base, const complex& exp) { // TODO: implement return base; } template complex pow(const T& base, const complex& exp) { // TODO: implement return complex{base}; } template complex sin(const complex& c) { // TODO: implement return c; } template complex sinh(const complex& c) { // TODO: implement return c; } template complex sqrt(const complex& c) { // TODO: implement return c; } template complex tan(const complex& c) { // TODO: implement return c; } template complex tanh(const complex& c) { // TODO: implement return c; } /** * 26.4.10, complex literals: */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" inline namespace literals { inline namespace complex_literals { constexpr complex operator ""il(long double val) { return complex{0.0L, val}; } constexpr complex operator ""il(unsigned long long val) { return complex{0.0L, static_cast(val)}; } constexpr complex operator ""i(long double val) { return complex{0.0, static_cast(val)}; } constexpr complex operator ""i(unsigned long long val) { return complex{0.0, static_cast(val)}; } constexpr complex operator ""if(long double val) { return complex{0.0f, static_cast(val)}; } constexpr complex operator ""if(unsigned long long val) { return complex{0.0f, static_cast(val)}; } }} #pragma GCC diagnostic pop } #endif