/*============================================================================= Copyright (c) 2011-2016 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 #include #include namespace sprout { template class complex; namespace detail { template 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 class complex { private: typedef sprout::array 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 SPROUT_CONSTEXPR complex(complex const& other) SPROUT_NOEXCEPT : elems_{{other.real(), other.imag()}} {} template SPROUT_CONSTEXPR complex(std::complex 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 SPROUT_CXX14_CONSTEXPR complex& operator=(complex const& rhs) SPROUT_NOEXCEPT { real() = rhs.real(); imag() = rhs.imag(); return *this; } template SPROUT_CXX14_CONSTEXPR complex& operator+=(complex const& rhs) SPROUT_NOEXCEPT { real() += rhs.real(); imag() += rhs.imag(); return *this; } template SPROUT_CXX14_CONSTEXPR complex& operator-=(complex const& rhs) SPROUT_NOEXCEPT { real() -= rhs.real(); imag() -= rhs.imag(); return *this; } template SPROUT_CXX14_CONSTEXPR complex& operator*=(complex const& rhs) SPROUT_NOEXCEPT { return *this = complex( real() * rhs.real() - imag() * rhs.imag(), real() * rhs.imag() + imag() * rhs.real() ); } template SPROUT_CXX14_CONSTEXPR complex& operator/=(complex 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 SPROUT_EXPLICIT_CONVERSION SPROUT_CONSTEXPR operator std::complex() const SPROUT_NOEXCEPT { return std::complex(real(), imag()); } }; template SPROUT_CONSTEXPR_OR_CONST typename sprout::complex::size_type sprout::complex::static_size; } // namespace sprout #endif // #ifndef SPROUT_COMPLEX_COMPLEX_HPP