#ifndef SPROUT_ITERATOR_TRIANGLE_ITERATOR_HPP #define SPROUT_ITERATOR_TRIANGLE_ITERATOR_HPP #include #include #include #include #include #include #include #include #include #include namespace sprout { // // triangle_iterator // template class triangle_iterator : public std::iterator< std::random_access_iterator_tag, Value, std::ptrdiff_t, Value*, Value > { public: typedef std::random_access_iterator_tag iterator_category; typedef Value value_type; typedef std::ptrdiff_t difference_type; typedef value_type* pointer; typedef value_type reference; private: difference_type index_; value_type frequency_; value_type amplitude_; value_type phase_; private: explicit SPROUT_CONSTEXPR triangle_iterator(triangle_iterator const& other, difference_type index) : index_(index) , frequency_(other.frequency_) , amplitude_(other.amplitude_) , phase_(other.phase_) {} public: SPROUT_CONSTEXPR triangle_iterator() : index_() , frequency_(1) , amplitude_(1) , phase_(0) {} triangle_iterator(triangle_iterator const&) = default; explicit SPROUT_CONSTEXPR triangle_iterator( difference_type index, value_type const& frequency = 1, value_type const& amplitude = 1, value_type const& phase = 0 ) : index_(index) , frequency_(frequency) , amplitude_(amplitude) , phase_(phase) {} template SPROUT_CONSTEXPR triangle_iterator(triangle_iterator const& it) : index_(it.index_) , frequency_(it.frequency_) , amplitude_(it.amplitude_) , phase_(it.phase_) {} template triangle_iterator& operator=(triangle_iterator const& it) { triangle_iterator temp(it); temp.swap(*this); return *this; } SPROUT_CONSTEXPR difference_type index() const { return index_; } SPROUT_CONSTEXPR value_type const& frequency() const { return frequency_; } SPROUT_CONSTEXPR value_type const& amplitude() const { return amplitude_; } SPROUT_CONSTEXPR value_type const& phase() const { return phase_; } SPROUT_CONSTEXPR reference operator*() const { return amplitude_ == 0 ? 0 : amplitude_ * sprout::fixed::detail::triangle_value(frequency_ * value_type(index_) + phase_) ; } SPROUT_CONSTEXPR pointer operator->() const { return &operator*()(); } triangle_iterator& operator++() { ++index_; return *this; } triangle_iterator operator++(int) { triangle_iterator result(*this); ++index_; return result; } triangle_iterator& operator--() { --index_; return *this; } triangle_iterator operator--(int) { triangle_iterator temp(*this); --index_; return temp; } SPROUT_CONSTEXPR triangle_iterator operator+(difference_type n) const { return triangle_iterator(*this, index_ + n); } SPROUT_CONSTEXPR triangle_iterator operator-(difference_type n) const { return triangle_iterator(*this, index_ - n); } triangle_iterator& operator+=(difference_type n) { triangle_iterator temp(*this, index_ + n); temp.swap(*this); return *this; } triangle_iterator& operator-=(difference_type n) { triangle_iterator temp(*this, index_ - n); temp.swap(*this); return *this; } SPROUT_CONSTEXPR reference operator[](difference_type n) const { return amplitude_ == 0 ? 0 : amplitude_ * sprout::fixed::detail::triangle_value(frequency_ * value_type(index_ + n) + phase_) ; } SPROUT_CONSTEXPR triangle_iterator next() const { return triangle_iterator(*this, index_ + 1); } SPROUT_CONSTEXPR triangle_iterator prev() const { return triangle_iterator(*this, index_ - 1); } void swap(triangle_iterator& other) SPROUT_NOEXCEPT { sprout::swap(index_, other.index_); sprout::swap(frequency_, other.frequency_); sprout::swap(amplitude_, other.amplitude_); sprout::swap(phase_, other.phase_); } }; template inline SPROUT_CONSTEXPR bool operator==( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return lhs.index() == rhs.index(); } template inline SPROUT_CONSTEXPR bool operator!=( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return !(lhs == rhs); } template inline SPROUT_CONSTEXPR bool operator<( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return lhs.index() < rhs.index(); } template inline SPROUT_CONSTEXPR bool operator>( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return rhs < lhs; } template inline SPROUT_CONSTEXPR bool operator<=( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return !(rhs < lhs); } template inline SPROUT_CONSTEXPR bool operator>=( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return !(lhs < rhs); } template inline SPROUT_CONSTEXPR typename sprout::triangle_iterator::difference_type operator-( sprout::triangle_iterator const& lhs, sprout::triangle_iterator const& rhs ) { return lhs.index() - rhs.index(); } template inline SPROUT_CONSTEXPR sprout::triangle_iterator operator+( typename sprout::triangle_iterator::difference_type n, sprout::triangle_iterator const& it ) { return it + n; } // // swap // template inline void swap(sprout::triangle_iterator& lhs, sprout::triangle_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { lhs.swap(rhs); } // // iterator_distance // template inline SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type iterator_distance(sprout::triangle_iterator first, sprout::triangle_iterator last) { return last - first; } // // iterator_next // template inline SPROUT_CONSTEXPR sprout::triangle_iterator iterator_next(sprout::triangle_iterator const& it) { return it.next(); } template inline SPROUT_CONSTEXPR sprout::triangle_iterator iterator_next(sprout::triangle_iterator const& it, typename sprout::triangle_iterator::difference_type n) { return it + n; } // // iterator_prev // template inline SPROUT_CONSTEXPR sprout::triangle_iterator iterator_prev(sprout::triangle_iterator const& it) { return it.prev(); } template inline SPROUT_CONSTEXPR sprout::triangle_iterator iterator_prev(sprout::triangle_iterator const& it, typename sprout::triangle_iterator::difference_type n) { return it - n; } } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_TRIANGLE_ITERATOR_HPP