mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2024-11-12 21:09:01 +00:00
236 lines
7.4 KiB
C++
236 lines
7.4 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2011-2019 Bolero MURAKAMI
|
|
https://github.com/bolero-MURAKAMI/Sprout
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
=============================================================================*/
|
|
#ifndef SPROUT_COMPLEX_COMPLEX_HPP
|
|
#define SPROUT_COMPLEX_COMPLEX_HPP
|
|
|
|
#include <complex>
|
|
#include <sprout/config.hpp>
|
|
#include <sprout/array/array.hpp>
|
|
|
|
namespace sprout {
|
|
template<typename T>
|
|
class complex;
|
|
|
|
namespace detail {
|
|
template<typename Complex>
|
|
inline SPROUT_CONSTEXPR typename Complex::value_type
|
|
complex_norm(Complex const& x) {
|
|
return x.real() * x.real() + x.imag() * x.imag();
|
|
}
|
|
} // namespace detail
|
|
|
|
//
|
|
// complex
|
|
//
|
|
template<typename T>
|
|
class complex {
|
|
private:
|
|
typedef sprout::array<T, 2> array_type;
|
|
public:
|
|
typedef T value_type;
|
|
typedef typename array_type::iterator iterator;
|
|
typedef typename array_type::const_iterator const_iterator;
|
|
typedef typename array_type::reference reference;
|
|
typedef typename array_type::const_reference const_reference;
|
|
typedef typename array_type::size_type size_type;
|
|
typedef typename array_type::pointer pointer;
|
|
typedef typename array_type::const_pointer const_pointer;
|
|
typedef typename array_type::reverse_iterator reverse_iterator;
|
|
typedef typename array_type::const_reverse_iterator const_reverse_iterator;
|
|
public:
|
|
SPROUT_STATIC_CONSTEXPR size_type static_size = array_type::static_size;
|
|
private:
|
|
array_type elems_;
|
|
public:
|
|
SPROUT_CONSTEXPR complex(T const& re = T(), T const& im = T()) SPROUT_NOEXCEPT
|
|
: elems_{{re, im}}
|
|
{}
|
|
SPROUT_CXX14_CONSTEXPR complex(complex const&) = default;
|
|
template<typename U>
|
|
SPROUT_CONSTEXPR complex(complex<U> const& other) SPROUT_NOEXCEPT
|
|
: elems_{{other.real(), other.imag()}}
|
|
{}
|
|
template<typename U>
|
|
SPROUT_CONSTEXPR complex(std::complex<U> const& other) SPROUT_NOEXCEPT
|
|
: elems_{{other.real(), other.imag()}}
|
|
{}
|
|
SPROUT_CONSTEXPR T const& real() const SPROUT_NOEXCEPT {
|
|
return elems_[0];
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR T& real() SPROUT_NOEXCEPT {
|
|
return elems_[0];
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR void real(T re) SPROUT_NOEXCEPT {
|
|
elems_[0] = re;
|
|
}
|
|
SPROUT_CONSTEXPR T const& imag() const SPROUT_NOEXCEPT {
|
|
return elems_[1];
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR T& imag() SPROUT_NOEXCEPT {
|
|
return elems_[1];
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR void imag(T im) SPROUT_NOEXCEPT {
|
|
elems_[1] = im;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator=(T const& rhs) SPROUT_NOEXCEPT {
|
|
real() = rhs;
|
|
imag() = T();
|
|
return *this;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator+=(T const& rhs) SPROUT_NOEXCEPT {
|
|
real() += rhs;
|
|
return *this;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator-=(T const& rhs) SPROUT_NOEXCEPT {
|
|
real() -= rhs;
|
|
return *this;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator*=(T const& rhs) SPROUT_NOEXCEPT {
|
|
real() *= rhs;
|
|
imag() *= rhs;
|
|
return *this;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator/=(T const& rhs) SPROUT_NOEXCEPT {
|
|
real() /= rhs;
|
|
imag() /= rhs;
|
|
return *this;
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR complex& operator=(complex const& rhs) SPROUT_NOEXCEPT {
|
|
real() = rhs.real();
|
|
imag() = rhs.imag();
|
|
return *this;
|
|
}
|
|
template<typename X>
|
|
SPROUT_CXX14_CONSTEXPR complex& operator=(complex<X> const& rhs) SPROUT_NOEXCEPT {
|
|
real() = rhs.real();
|
|
imag() = rhs.imag();
|
|
return *this;
|
|
}
|
|
template<typename X>
|
|
SPROUT_CXX14_CONSTEXPR complex& operator+=(complex<X> const& rhs) SPROUT_NOEXCEPT {
|
|
real() += rhs.real();
|
|
imag() += rhs.imag();
|
|
return *this;
|
|
}
|
|
template<typename X>
|
|
SPROUT_CXX14_CONSTEXPR complex& operator-=(complex<X> const& rhs) SPROUT_NOEXCEPT {
|
|
real() -= rhs.real();
|
|
imag() -= rhs.imag();
|
|
return *this;
|
|
}
|
|
template<typename X>
|
|
SPROUT_CXX14_CONSTEXPR complex& operator*=(complex<X> const& rhs) SPROUT_NOEXCEPT {
|
|
return *this = complex(
|
|
real() * rhs.real() - imag() * rhs.imag(),
|
|
real() * rhs.imag() + imag() * rhs.real()
|
|
);
|
|
}
|
|
template<typename X>
|
|
SPROUT_CXX14_CONSTEXPR complex& operator/=(complex<X> const& rhs) SPROUT_NOEXCEPT {
|
|
T n = sprout::detail::complex_norm(rhs);
|
|
return *this = complex(
|
|
(real() * rhs.real() + imag() * rhs.imag()) / n,
|
|
(imag() * rhs.real() - real() * rhs.imag()) / n
|
|
);
|
|
}
|
|
// iterators:
|
|
SPROUT_CXX14_CONSTEXPR iterator begin() SPROUT_NOEXCEPT {
|
|
return elems_.begin();
|
|
}
|
|
SPROUT_CONSTEXPR const_iterator begin() const SPROUT_NOEXCEPT {
|
|
return elems_.begin();
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR iterator end() SPROUT_NOEXCEPT {
|
|
return elems_.end();
|
|
}
|
|
SPROUT_CONSTEXPR const_iterator end() const SPROUT_NOEXCEPT {
|
|
return elems_.end();
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR reverse_iterator rbegin() SPROUT_NOEXCEPT {
|
|
return elems_.rbegin();
|
|
}
|
|
SPROUT_CONSTEXPR const_reverse_iterator rbegin() const SPROUT_NOEXCEPT {
|
|
return elems_.rbegin();
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR reverse_iterator rend() SPROUT_NOEXCEPT {
|
|
return elems_.rend();
|
|
}
|
|
SPROUT_CONSTEXPR const_reverse_iterator rend() const SPROUT_NOEXCEPT {
|
|
return elems_.rend();
|
|
}
|
|
SPROUT_CONSTEXPR const_iterator cbegin() const SPROUT_NOEXCEPT {
|
|
return elems_.cbegin();
|
|
}
|
|
SPROUT_CONSTEXPR const_iterator cend() const SPROUT_NOEXCEPT {
|
|
return elems_.cbegin();
|
|
}
|
|
SPROUT_CONSTEXPR const_reverse_iterator crbegin() const SPROUT_NOEXCEPT {
|
|
return elems_.crbegin();
|
|
}
|
|
SPROUT_CONSTEXPR const_reverse_iterator crend() const SPROUT_NOEXCEPT {
|
|
return elems_.crend();
|
|
}
|
|
// capacity:
|
|
SPROUT_CONSTEXPR size_type size() const SPROUT_NOEXCEPT {
|
|
return elems_.size();
|
|
}
|
|
SPROUT_CONSTEXPR size_type max_size() const SPROUT_NOEXCEPT {
|
|
return elems_.max_size();
|
|
}
|
|
SPROUT_CONSTEXPR bool empty() const SPROUT_NOEXCEPT {
|
|
return elems_.empty();
|
|
}
|
|
// element access:
|
|
SPROUT_CXX14_CONSTEXPR reference operator[](size_type i) {
|
|
return elems_[i];
|
|
}
|
|
SPROUT_CONSTEXPR const_reference operator[](size_type i) const {
|
|
return elems_[i];
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR reference at(size_type i) {
|
|
return elems_.at(i);
|
|
}
|
|
SPROUT_CONSTEXPR const_reference at(size_type i) const {
|
|
return elems_.at(i);
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR reference front() {
|
|
return elems_.front();
|
|
}
|
|
SPROUT_CONSTEXPR const_reference front() const {
|
|
return elems_.front();
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR reference back() {
|
|
return elems_.back();
|
|
}
|
|
SPROUT_CONSTEXPR const_reference back() const {
|
|
return elems_.back();
|
|
}
|
|
|
|
SPROUT_CXX14_CONSTEXPR pointer data() SPROUT_NOEXCEPT {
|
|
return elems_.data();
|
|
}
|
|
SPROUT_CONSTEXPR const_pointer data() const SPROUT_NOEXCEPT {
|
|
return elems_.data();
|
|
}
|
|
SPROUT_CXX14_CONSTEXPR pointer c_array() SPROUT_NOEXCEPT {
|
|
return elems_.c_array();
|
|
}
|
|
SPROUT_CONSTEXPR const_pointer c_array() const SPROUT_NOEXCEPT {
|
|
return elems_.c_array();
|
|
}
|
|
|
|
template<typename U>
|
|
SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator std::complex<U>() const SPROUT_NOEXCEPT {
|
|
return std::complex<U>(real(), imag());
|
|
}
|
|
};
|
|
template<typename T>
|
|
SPROUT_CONSTEXPR_OR_CONST typename sprout::complex<T>::size_type sprout::complex<T>::static_size;
|
|
} // namespace sprout
|
|
|
|
#endif // #ifndef SPROUT_COMPLEX_COMPLEX_HPP
|