/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTL_XCOMPLEX_SEQUENCE_HPP #define XTL_XCOMPLEX_SEQUENCE_HPP #include #include #include #include "xclosure.hpp" #include "xcomplex.hpp" #include "xiterator_base.hpp" #include "xsequence.hpp" namespace xtl { /************************************ * Optimized 1-D xcomplex container * ************************************/ template class xcomplex_iterator; template class xcomplex_sequence { public: using container_type = C; using cvt = typename C::value_type; using value_type = xcomplex; using reference = xcomplex; using const_reference = xcomplex; using pointer = xclosure_pointer; using const_pointer = xclosure_pointer; using size_type = typename container_type::size_type; using difference_type = typename container_type::difference_type; using iterator = xcomplex_iterator; using const_iterator = xcomplex_iterator; using reverse_iterator = xcomplex_iterator; using const_reverse_iterator = xcomplex_iterator; bool empty() const noexcept; size_type size() const noexcept; size_type max_size() const noexcept; reference at(size_type i); const_reference at(size_type i) const; reference operator[](size_type i); const_reference operator[](size_type i) const; reference front(); const_reference front() const; reference back(); const_reference back() const; iterator begin() noexcept; iterator end() noexcept; const_iterator begin() const noexcept; const_iterator end() const noexcept; const_iterator cbegin() const noexcept; const_iterator cend() const noexcept; reverse_iterator rbegin() noexcept; reverse_iterator rend() noexcept; const_reverse_iterator rbegin() const noexcept; const_reverse_iterator rend() const noexcept; const_reverse_iterator crbegin() const noexcept; const_reverse_iterator crend() const noexcept; container_type real() && noexcept; container_type& real() & noexcept; const container_type& real() const & noexcept; container_type imag() && noexcept; container_type& imag() & noexcept; const container_type& imag() const & noexcept; protected: xcomplex_sequence() = default; xcomplex_sequence(size_type s); xcomplex_sequence(size_type s, const value_type& v); template xcomplex_sequence(size_type s, const xcomplex& v); xcomplex_sequence(std::initializer_list init); ~xcomplex_sequence() = default; xcomplex_sequence(const xcomplex_sequence&) = default; xcomplex_sequence& operator=(const xcomplex_sequence&) = default; xcomplex_sequence(xcomplex_sequence&&) = default; xcomplex_sequence& operator=(xcomplex_sequence&&) = default; container_type m_real; container_type m_imag; }; template bool operator==(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs); template bool operator!=(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs); /****************** * xcomplex_array * ******************/ template class xcomplex_array : public xcomplex_sequence, ieee_compliant> { public: using base_type = xcomplex_sequence, ieee_compliant>; using value_type = typename base_type::value_type; using size_type = typename base_type::size_type; xcomplex_array() = default; xcomplex_array(size_type s); xcomplex_array(size_type s, const value_type& v); template xcomplex_array(size_type s, const xcomplex& v); }; /******************* * xcomplex_vector * *******************/ template > class xcomplex_vector : public xcomplex_sequence, ieee_compliant> { public: using base_type = xcomplex_sequence, ieee_compliant>; using value_type = typename base_type::value_type; using size_type = typename base_type::size_type; xcomplex_vector() = default; xcomplex_vector(size_type s); xcomplex_vector(size_type s, const value_type& v); xcomplex_vector(std::initializer_list init); template xcomplex_vector(size_type s, const xcomplex& v); void resize(size_type); void resize(size_type, const value_type&); template void resize(size_type s, const xcomplex& v); }; /********************* * xcomplex_iterator * *********************/ template struct xcomplex_iterator_traits { using iterator_type = xcomplex_iterator; using value_type = xcomplex; using reference = xcomplex; using pointer = xclosure_pointer; using difference_type = typename IT::difference_type; }; template class xcomplex_iterator : public xrandom_access_iterator_base2> { public: using self_type = xcomplex_iterator; using base_type = xrandom_access_iterator_base2>; using value_type = typename base_type::value_type; using reference = typename base_type::reference; using pointer = typename base_type::pointer; using difference_type = typename base_type::difference_type; xcomplex_iterator() = default; xcomplex_iterator(IT it_real, IT it_imag); self_type& operator++(); self_type& operator--(); self_type& operator+=(difference_type n); self_type& operator-=(difference_type n); difference_type operator-(const self_type& rhs) const; reference operator*() const; pointer operator->() const; bool operator==(const self_type& rhs) const; private: IT m_it_real; IT m_it_imag; }; /************************************ * xcomplex_sequence implementation * ************************************/ template inline xcomplex_sequence::xcomplex_sequence(size_type s) : m_real(make_sequence(s)), m_imag(make_sequence(s)) { } template inline xcomplex_sequence::xcomplex_sequence(size_type s, const value_type& v) : m_real(make_sequence(s, v.real())), m_imag(make_sequence(s, v.imag())) { } template template inline xcomplex_sequence::xcomplex_sequence(size_type s, const xcomplex& v) : m_real(make_sequence(s, v.real())), m_imag(make_sequence(s, v.imag())) { } template inline xcomplex_sequence::xcomplex_sequence(std::initializer_list init) : m_real(make_sequence(init.size())), m_imag(make_sequence(init.size())) { std::transform(init.begin(), init.end(), m_real.begin(), [](const auto& v) { return v.real(); }); std::transform(init.begin(), init.end(), m_imag.begin(), [](const auto& v) { return v.imag(); }); } template inline bool xcomplex_sequence::empty() const noexcept { return m_real.empty(); } template inline auto xcomplex_sequence::size() const noexcept -> size_type { return m_real.size(); } template inline auto xcomplex_sequence::max_size() const noexcept -> size_type { return m_real.max_size(); } template inline auto xcomplex_sequence::at(size_type i) -> reference { return reference(m_real.at(i), m_imag.at(i)); } template inline auto xcomplex_sequence::at(size_type i) const -> const_reference { return const_reference(m_real.at(i), m_imag.at(i)); } template inline auto xcomplex_sequence::operator[](size_type i) -> reference { return reference(m_real[i], m_imag[i]); } template inline auto xcomplex_sequence::operator[](size_type i) const -> const_reference { return const_reference(m_real[i], m_imag[i]); } template inline auto xcomplex_sequence::front() -> reference { return reference(m_real.front(), m_imag.front()); } template inline auto xcomplex_sequence::front() const -> const_reference { return const_reference(m_real.front(), m_imag.front()); } template inline auto xcomplex_sequence::back() -> reference { return reference(m_real.back(), m_imag.back()); } template inline auto xcomplex_sequence::back() const -> const_reference { return const_reference(m_real.back(), m_imag.back()); } template inline auto xcomplex_sequence::begin() noexcept -> iterator { return iterator(m_real.begin(), m_imag.begin()); } template inline auto xcomplex_sequence::end() noexcept -> iterator { return iterator(m_real.end(), m_imag.end()); } template inline auto xcomplex_sequence::begin() const noexcept -> const_iterator { return cbegin(); } template inline auto xcomplex_sequence::end() const noexcept -> const_iterator { return cend(); } template inline auto xcomplex_sequence::cbegin() const noexcept -> const_iterator { return const_iterator(m_real.cbegin(), m_imag.cbegin()); } template inline auto xcomplex_sequence::cend() const noexcept -> const_iterator { return const_iterator(m_real.cend(), m_imag.cend()); } template inline auto xcomplex_sequence::rbegin() noexcept -> reverse_iterator { return reverse_iterator(m_real.rbegin(), m_imag.rbegin()); } template inline auto xcomplex_sequence::rend() noexcept -> reverse_iterator { return reverse_iterator(m_real.rend(), m_imag.rend()); } template inline auto xcomplex_sequence::rbegin() const noexcept -> const_reverse_iterator { return crbegin(); } template inline auto xcomplex_sequence::rend() const noexcept -> const_reverse_iterator { return crend(); } template inline auto xcomplex_sequence::crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(m_real.crbegin(), m_imag.crbegin()); } template inline auto xcomplex_sequence::crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(m_real.crend(), m_imag.crend()); } template inline auto xcomplex_sequence::real() && noexcept -> container_type { return m_real; } template inline auto xcomplex_sequence::real() & noexcept -> container_type& { return m_real; } template inline auto xcomplex_sequence::real() const & noexcept -> const container_type& { return m_real; } template inline auto xcomplex_sequence::imag() && noexcept -> container_type { return m_imag; } template inline auto xcomplex_sequence::imag() & noexcept -> container_type& { return m_imag; } template inline auto xcomplex_sequence::imag() const & noexcept -> const container_type& { return m_imag; } template inline bool operator==(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs) { return lhs.real() == rhs.real() && lhs.imag() == rhs.imag(); } template inline bool operator!=(const xcomplex_sequence& lhs, const xcomplex_sequence& rhs) { return !(lhs == rhs); } /********************************* * xcomplex_array implementation * *********************************/ template inline xcomplex_array::xcomplex_array(size_type s) : base_type(s) { } template inline xcomplex_array::xcomplex_array(size_type s, const value_type& v) : base_type(s, v) { } template template inline xcomplex_array::xcomplex_array(size_type s, const xcomplex& v) : base_type(s, v) { } /********************************** * xcomplex_vector implementation * **********************************/ template inline xcomplex_vector::xcomplex_vector(size_type s) : base_type(s) { } template inline xcomplex_vector::xcomplex_vector(size_type s, const value_type& v) : base_type(s, v) { } template template inline xcomplex_vector::xcomplex_vector(size_type s, const xcomplex& v) : base_type(s, v) { } template inline xcomplex_vector::xcomplex_vector(std::initializer_list init) : base_type(init) { } template void xcomplex_vector::resize(size_type s) { this->m_real.resize(s); this->m_imag.resize(s); } template void xcomplex_vector::resize(size_type s, const value_type& v) { this->m_real.resize(s, v.real()); this->m_imag.resize(s, v.imag()); } template template inline void xcomplex_vector::resize(size_type s, const xcomplex& v) { this->m_real.resize(s, v.real()); this->m_imag.resize(s, v.imag()); } /************************************ * xcomplex_iterator implementation * ************************************/ template inline xcomplex_iterator::xcomplex_iterator(IT it_real, IT it_imag) : m_it_real(it_real), m_it_imag(it_imag) { } template inline auto xcomplex_iterator::operator++() -> self_type& { ++m_it_real; ++m_it_imag; return *this; } template inline auto xcomplex_iterator::operator--() -> self_type& { --m_it_real; --m_it_imag; return *this; } template inline auto xcomplex_iterator::operator+=(difference_type n) -> self_type& { m_it_real += n; m_it_imag += n; return *this; } template inline auto xcomplex_iterator::operator-=(difference_type n) -> self_type& { m_it_real -= n; m_it_imag -= n; return *this; } template inline auto xcomplex_iterator::operator-(const self_type& rhs) const -> difference_type { return m_it_real - rhs.m_it_real; } template inline auto xcomplex_iterator::operator*() const -> reference { return reference(*m_it_real, *m_it_imag); } template inline auto xcomplex_iterator::operator->() const -> pointer { return pointer(operator*()); } template inline bool xcomplex_iterator::operator==(const self_type& rhs) const { return m_it_real == rhs.m_it_real && m_it_imag == rhs.m_it_imag; } } #endif