Sprout/sprout/complex/complex.hpp

237 lines
7.3 KiB
C++
Raw Normal View History

2013-08-08 09:54:33 +00:00
/*=============================================================================
2016-02-25 09:48:28 +00:00
Copyright (c) 2011-2016 Bolero MURAKAMI
2013-08-08 09:54:33 +00:00
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)
=============================================================================*/
2012-08-28 16:16:12 +00:00
#ifndef SPROUT_COMPLEX_COMPLEX_HPP
#define SPROUT_COMPLEX_COMPLEX_HPP
2014-07-22 00:33:13 +00:00
#include <complex>
2012-08-28 16:16:12 +00:00
#include <sprout/config.hpp>
#include <sprout/array/array.hpp>
2012-08-28 16:16:12 +00:00
namespace sprout {
template<typename T>
class complex;
namespace detail {
2014-04-18 10:33:48 +00:00
template<typename Complex>
inline SPROUT_CONSTEXPR typename Complex::value_type
complex_norm(Complex const& x) {
2012-08-28 16:16:12 +00:00
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;
2012-08-28 16:16:12 +00:00
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::pointer reverse_iterator;
typedef typename array_type::pointer const_reverse_iterator;
public:
SPROUT_STATIC_CONSTEXPR size_type static_size = array_type::static_size;
2012-08-28 16:16:12 +00:00
private:
array_type elems_;
2012-08-28 16:16:12 +00:00
public:
2012-11-18 14:32:36 +00:00
SPROUT_CONSTEXPR complex(T const& re = T(), T const& im = T()) SPROUT_NOEXCEPT
: elems_{{re, im}}
2012-08-28 16:16:12 +00:00
{}
SPROUT_CXX14_CONSTEXPR complex(complex const&) = default;
2014-07-22 00:33:13 +00:00
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()}}
2012-08-28 16:16:12 +00:00
{}
2014-04-18 02:34:28 +00:00
SPROUT_CONSTEXPR T const& real() const SPROUT_NOEXCEPT {
return elems_[0];
2014-04-18 02:34:28 +00:00
}
SPROUT_CXX14_CONSTEXPR T& real() SPROUT_NOEXCEPT {
return elems_[0];
2012-08-28 16:16:12 +00:00
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR void real(T re) SPROUT_NOEXCEPT {
elems_[0] = re;
2012-08-28 16:16:12 +00:00
}
2014-04-18 02:34:28 +00:00
SPROUT_CONSTEXPR T const& imag() const SPROUT_NOEXCEPT {
return elems_[1];
2014-04-18 02:34:28 +00:00
}
SPROUT_CXX14_CONSTEXPR T& imag() SPROUT_NOEXCEPT {
return elems_[1];
2012-08-28 16:16:12 +00:00
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR void imag(T im) SPROUT_NOEXCEPT {
elems_[1] = im;
2012-08-28 16:16:12 +00:00
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator=(T const& rhs) SPROUT_NOEXCEPT {
real() = rhs;
imag() = T();
2012-08-28 16:16:12 +00:00
return *this;
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator+=(T const& rhs) SPROUT_NOEXCEPT {
real() += rhs;
2012-08-28 16:16:12 +00:00
return *this;
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator-=(T const& rhs) SPROUT_NOEXCEPT {
real() -= rhs;
2012-08-28 16:16:12 +00:00
return *this;
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator*=(T const& rhs) SPROUT_NOEXCEPT {
real() *= rhs;
imag() *= rhs;
2012-08-28 16:16:12 +00:00
return *this;
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator/=(T const& rhs) SPROUT_NOEXCEPT {
real() /= rhs;
imag() /= rhs;
2012-08-28 16:16:12 +00:00
return *this;
}
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator=(complex const& rhs) SPROUT_NOEXCEPT {
real() = rhs.real();
imag() = rhs.imag();
2013-10-29 10:15:52 +00:00
return *this;
}
2012-08-28 16:16:12 +00:00
template<typename X>
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator=(complex<X> const& rhs) SPROUT_NOEXCEPT {
real() = rhs.real();
imag() = rhs.imag();
2012-08-28 16:16:12 +00:00
return *this;
}
template<typename X>
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator+=(complex<X> const& rhs) SPROUT_NOEXCEPT {
real() += rhs.real();
imag() += rhs.imag();
2012-08-28 16:16:12 +00:00
return *this;
}
template<typename X>
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator-=(complex<X> const& rhs) SPROUT_NOEXCEPT {
real() -= rhs.real();
imag() -= rhs.imag();
2012-08-28 16:16:12 +00:00
return *this;
}
template<typename X>
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator*=(complex<X> const& rhs) SPROUT_NOEXCEPT {
2012-10-05 15:58:56 +00:00
return *this = complex(
real() * rhs.real() - imag() * rhs.imag(),
real() * rhs.imag() + imag() * rhs.real()
2012-08-28 16:16:12 +00:00
);
}
template<typename X>
2013-10-29 10:15:52 +00:00
SPROUT_CXX14_CONSTEXPR complex& operator/=(complex<X> const& rhs) SPROUT_NOEXCEPT {
2012-08-28 16:16:12 +00:00
T n = sprout::detail::complex_norm(rhs);
2012-10-05 15:58:56 +00:00
return *this = complex(
(real() * rhs.real() + imag() * rhs.imag()) / n,
(imag() * rhs.real() - real() * rhs.imag()) / n
2012-08-28 16:16:12 +00:00
);
}
// 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();
}
2014-07-22 00:33:13 +00:00
template<typename U>
SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator std::complex<U>() const SPROUT_NOEXCEPT {
return std::complex<U>(real(), imag());
}
2012-08-28 16:16:12 +00:00
};
template<typename T>
SPROUT_CONSTEXPR_OR_CONST typename sprout::complex<T>::size_type sprout::complex<T>::static_size;
2012-08-28 16:16:12 +00:00
} // namespace sprout
#endif // #ifndef SPROUT_COMPLEX_COMPLEX_HPP