diff --git a/sprout/detail/iterator.hpp b/sprout/detail/iterator.hpp index eb9b2a06..263f6ab2 100644 --- a/sprout/detail/iterator.hpp +++ b/sprout/detail/iterator.hpp @@ -7,6 +7,28 @@ namespace sprout { namespace detail { + namespace detail_ { + template + SPROUT_CONSTEXPR typename std::iterator_traits::difference_type distance( + Iterator first, + Iterator last + ) + { + return first == last + ? 0 + : 1 + sprout::detail::detail_::distance(sprout::next(first), last) + ; + } + template + SPROUT_CONSTEXPR typename std::iterator_traits::difference_type distance_impl( + Iterator first, + Iterator last + ) + { + using sprout::detail::detail_::distance; + return distance(first, last); + } + } // namespace detail_ // // distance // @@ -16,7 +38,7 @@ namespace sprout { Iterator last ) { - return first == last ? 0 : 1 + sprout::detail::distance(sprout::next(first), last); + return sprout::detail::detail_::distance_impl(first, last); } template @@ -43,7 +65,10 @@ namespace sprout { Iterator last ) { - return first == last ? 0 : sprout::detail::bidirectional_distance_impl(sprout::next(first), sprout::prev(first), last); + return first == last + ? 0 + : sprout::detail::bidirectional_distance_impl(sprout::next(first), sprout::prev(first), last) + ; } } // namespace detail } // namespace sprout diff --git a/sprout/fft/bitrev_table.hpp b/sprout/fft/bitrev_table.hpp new file mode 100644 index 00000000..1929212b --- /dev/null +++ b/sprout/fft/bitrev_table.hpp @@ -0,0 +1,8 @@ +#ifndef SPROUT_FFT_BITREV_TABLE_HPP +#define SPROUT_FFT_BITREV_TABLE_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_FFT_BITREV_TABLE_HPP diff --git a/sprout/fft/fit/bitrev_table.hpp b/sprout/fft/fit/bitrev_table.hpp new file mode 100644 index 00000000..b35ccd24 --- /dev/null +++ b/sprout/fft/fit/bitrev_table.hpp @@ -0,0 +1,41 @@ +#ifndef SPROUT_FFT_FIT_BITREV_TABLE_HPP +#define SPROUT_FFT_FIT_BITREV_TABLE_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace fit { + namespace detail { + template + SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm::type bitrev_table_impl( + Container const& cont, + typename sprout::fixed_container_traits::difference_type offset + ) + { + return sprout::sub_copy( + sprout::get_fixed(sprout::fixed::bitrev_table(cont)), + offset, + offset + sprout::size(cont) + ); + } + } // namespace detail + // + // bitrev_table + // + template + SPROUT_CONSTEXPR inline typename sprout::fit::result_of::algorithm::type bitrev_table( + Container const& cont + ) + { + return sprout::fit::detail::bitrev_table_impl(cont, sprout::fixed_begin_offset(cont)); + } + } // namespace fit +} // namespace sprout + +#endif // #ifndef SPROUT_FFT_FIT_BITREV_TABLE_HPP diff --git a/sprout/fft/fixed/bitrev_table.hpp b/sprout/fft/fixed/bitrev_table.hpp new file mode 100644 index 00000000..311e48eb --- /dev/null +++ b/sprout/fft/fixed/bitrev_table.hpp @@ -0,0 +1,64 @@ +#ifndef SPROUT_FFT_FIXED_BITREV_TABLE_HPP +#define SPROUT_FFT_FIXED_BITREV_TABLE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace fixed { + namespace detail { + template + SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type bitrev_table_impl( + Container const& cont, + sprout::index_tuple, + std::size_t bit_length, + typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size + ) + { + return sprout::remake_clone( + cont, + sprout::size(cont), + (Indexes >= offset && Indexes < offset + size + ? sprout::bit_reverse_in( + static_cast::value_type>(Indexes - offset), + bit_length + ) + : *sprout::next(sprout::fixed_begin(cont), Indexes) + )... + ); + } + } // namespace detail + // + // bitrev_table + // + template + SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type bitrev_table( + Container const& cont + ) + { + return sprout::fixed::detail::bitrev_table_impl( + cont, + typename sprout::index_range<0, sprout::fixed_container_traits::fixed_size>::type(), + sprout::empty(cont) + ? 0 + : sprout::bit_length(sprout::size(cont) - 1) + , + sprout::fixed_begin_offset(cont), + sprout::size(cont) + ); + } + } // namespace fixed + + using sprout::fixed::bitrev_table; +} // namespace sprout + +#endif // #ifndef SPROUT_FFT_FIXED_BITREV_TABLE_HPP diff --git a/sprout/integer/bit_length.hpp b/sprout/integer/bit_length.hpp new file mode 100644 index 00000000..c415e818 --- /dev/null +++ b/sprout/integer/bit_length.hpp @@ -0,0 +1,70 @@ +#ifndef SPROUT_INTEGER_BIT_LENGTH_HPP +#define SPROUT_INTEGER_BIT_LENGTH_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace detail { + SPROUT_STATIC_CONSTEXPR std::size_t bit_len_8_table[std::size_t(UCHAR_MAX) + 1] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 + }; + template + struct bit_len { + private: + SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size - 1; + SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT; + private: + template + SPROUT_CONSTEXPR IntType impl(IntType x, unsigned char i) const { + return bit_len_8_table[i] + ? bit_len_8_table[i] + next_size * CHAR_BIT + : sprout::detail::bit_len().template operator()(x) + ; + } + public: + template + SPROUT_CONSTEXPR IntType operator()(IntType x) const { + return impl(x, static_cast((x >> shift_bits) & UCHAR_MAX)); + } + }; + template<> + struct bit_len<1> { + public: + template + SPROUT_CONSTEXPR IntType operator()(IntType x) const { + return bit_len_8_table[static_cast(x & UCHAR_MAX)]; + } + }; + } // namespace detail + // + // bit_length + // + template + SPROUT_CONSTEXPR typename std::enable_if< + std::is_integral::value, + IntType + >::type bit_length(IntType x) { + return sprout::detail::bit_len().template operator()(x); + } +} // namespace sprout + +#endif // #ifndef SPROUT_INTEGER_BIT_LENGTH_HPP diff --git a/sprout/integer/bit_reverse.hpp b/sprout/integer/bit_reverse.hpp new file mode 100644 index 00000000..2367cbe3 --- /dev/null +++ b/sprout/integer/bit_reverse.hpp @@ -0,0 +1,81 @@ +#ifndef SPROUT_INTEGER_BIT_REVERSE_HPP +#define SPROUT_INTEGER_BIT_REVERSE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace detail { + SPROUT_STATIC_CONSTEXPR unsigned char bit_rev_8_table[std::size_t(UCHAR_MAX) + 1] = { + 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, + 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, + 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, + 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, + 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, + 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, + 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, + 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, + 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, + 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, + 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255 + }; + template + struct bit_rev { + private: + SPROUT_STATIC_CONSTEXPR std::size_t next_size = Size / 2; + SPROUT_STATIC_CONSTEXPR std::size_t shift_bits = next_size * CHAR_BIT; + public: + template + SPROUT_CONSTEXPR IntType operator()(IntType x) const { + return (sprout::detail::bit_rev().template operator()(x) << shift_bits) + | (sprout::detail::bit_rev().template operator()(x >> shift_bits)) + ; + } + }; + template<> + struct bit_rev<1> { + public: + template + SPROUT_CONSTEXPR IntType operator()(IntType x) const { + return sprout::detail::bit_rev_8_table[static_cast(x & UCHAR_MAX)]; + } + }; + } // namespace detail + // + // bit_reverse + // + template + SPROUT_CONSTEXPR typename std::enable_if< + std::is_integral::value, + IntType + >::type bit_reverse(IntType x) { + typedef typename std::make_unsigned::type unsigned_type; + return static_cast( + sprout::detail::bit_rev().template operator()(x) + ); + } + // + // bit_reverse_in + // + template + SPROUT_CONSTEXPR typename std::enable_if< + std::is_integral::value, + IntType + >::type bit_reverse_in(IntType x, std::size_t length) { + typedef typename std::make_unsigned::type unsigned_type; + return length <= sizeof(IntType) * CHAR_BIT + ? static_cast( + sprout::detail::bit_rev().template operator()(x) + >> (sizeof(IntType) * CHAR_BIT - length) + ) + : throw std::invalid_argument("invalid length") + ; + } +} // namespace sprout + +#endif // #ifndef SPROUT_INTEGER_BIT_REVERSE_HPP diff --git a/sprout/iterator/bytes_iterator.hpp b/sprout/iterator/bytes_iterator.hpp index e091368e..6167d8ef 100644 --- a/sprout/iterator/bytes_iterator.hpp +++ b/sprout/iterator/bytes_iterator.hpp @@ -99,16 +99,16 @@ namespace sprout { friend SPROUT_CONSTEXPR bool operator!=(bytes_iterator const& lhs, bytes_iterator const& rhs) { return !(lhs == rhs); } - friend bool operator<(bytes_iterator const& lhs, bytes_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<(bytes_iterator const& lhs, bytes_iterator const& rhs) { return lhs.it_ < rhs.it_ || lhs.it_ == rhs.it_ && lhs.i_ < rhs.i_; } - friend bool operator>(bytes_iterator const& lhs, bytes_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>(bytes_iterator const& lhs, bytes_iterator const& rhs) { return rhs < lhs; } - friend bool operator<=(bytes_iterator const& lhs, bytes_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<=(bytes_iterator const& lhs, bytes_iterator const& rhs) { return !(rhs < lhs); } - friend bool operator>=(bytes_iterator const& lhs, bytes_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>=(bytes_iterator const& lhs, bytes_iterator const& rhs) { return !(lhs < rhs); } SPROUT_CONSTEXPR reference operator*() const { @@ -153,7 +153,7 @@ namespace sprout { SPROUT_CONSTEXPR reference operator[](difference_type n) const { return *(*this + n); } - friend difference_type operator-(bytes_iterator const& lhs, bytes_iterator const& rhs) { + friend SPROUT_CONSTEXPR difference_type operator-(bytes_iterator const& lhs, bytes_iterator const& rhs) { return (lhs.it_ - rhs.it_) * traits_type::size() + (lhs.i_ - rhs.i_); } friend SPROUT_CONSTEXPR bytes_iterator operator+(difference_type n, bytes_iterator const& it) { diff --git a/sprout/iterator/index_iterator.hpp b/sprout/iterator/index_iterator.hpp index 919526ce..ca5b32f7 100644 --- a/sprout/iterator/index_iterator.hpp +++ b/sprout/iterator/index_iterator.hpp @@ -101,16 +101,16 @@ namespace sprout { friend SPROUT_CONSTEXPR bool operator!=(index_iterator const& lhs, index_iterator const& rhs) { return !(lhs == rhs); } - friend bool operator<(index_iterator const& lhs, index_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<(index_iterator const& lhs, index_iterator const& rhs) { return lhs.index_ < rhs.index_; } - friend bool operator>(index_iterator const& lhs, index_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>(index_iterator const& lhs, index_iterator const& rhs) { return rhs < lhs; } - friend bool operator<=(index_iterator const& lhs, index_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<=(index_iterator const& lhs, index_iterator const& rhs) { return !(rhs < lhs); } - friend bool operator>=(index_iterator const& lhs, index_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>=(index_iterator const& lhs, index_iterator const& rhs) { return !(lhs < rhs); } SPROUT_CONSTEXPR reference operator*() const { @@ -158,7 +158,7 @@ namespace sprout { SPROUT_CONSTEXPR reference operator[](difference_type n) const { return holder_.get()[index_ + n]; } - friend difference_type operator-(index_iterator const& lhs, index_iterator const& rhs) { + friend SPROUT_CONSTEXPR difference_type operator-(index_iterator const& lhs, index_iterator const& rhs) { return static_cast(lhs.index_) - static_cast(rhs.index_); } friend SPROUT_CONSTEXPR index_iterator operator+(difference_type n, index_iterator const& it) { @@ -213,4 +213,22 @@ namespace sprout { } } // namespace sprout + + +#include + +namespace sprout { + // + // distance + // + template + SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type distance( + sprout::index_iterator first, + sprout::index_iterator last + ) + { + return last - first; + } +} // namespace sprout + #endif // #ifndef SPROUT_ITERATOR_INDEX_ITERATOR_HPP diff --git a/sprout/iterator/reverse_iterator.hpp b/sprout/iterator/reverse_iterator.hpp index 5cf6a6c9..4a94bddf 100644 --- a/sprout/iterator/reverse_iterator.hpp +++ b/sprout/iterator/reverse_iterator.hpp @@ -123,7 +123,7 @@ namespace sprout { return !(lhs == rhs); } template - bool operator<( + SPROUT_CONSTEXPR bool operator<( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs ) @@ -131,7 +131,7 @@ namespace sprout { return lhs.base() < rhs.base(); } template - bool operator>( + SPROUT_CONSTEXPR bool operator>( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs ) @@ -139,7 +139,7 @@ namespace sprout { return rhs < lhs; } template - bool operator<=( + SPROUT_CONSTEXPR bool operator<=( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs ) @@ -147,7 +147,7 @@ namespace sprout { return !(rhs < lhs); } template - bool operator>=( + SPROUT_CONSTEXPR bool operator>=( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs ) @@ -155,7 +155,7 @@ namespace sprout { return !(lhs < rhs); } template - auto operator-( + SPROUT_CONSTEXPR auto operator-( sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs ) -> decltype(lhs.current - rhs.current) diff --git a/sprout/iterator/value_iterator.hpp b/sprout/iterator/value_iterator.hpp index 4ca1c194..9ea787b8 100644 --- a/sprout/iterator/value_iterator.hpp +++ b/sprout/iterator/value_iterator.hpp @@ -84,16 +84,16 @@ namespace sprout { friend SPROUT_CONSTEXPR bool operator!=(value_iterator const& lhs, value_iterator const& rhs) { return !(lhs == rhs); } - friend bool operator<(value_iterator const& lhs, value_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<(value_iterator const& lhs, value_iterator const& rhs) { return lhs.count_ > rhs.count_; } - friend bool operator>(value_iterator const& lhs, value_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>(value_iterator const& lhs, value_iterator const& rhs) { return rhs < lhs; } - friend bool operator<=(value_iterator const& lhs, value_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator<=(value_iterator const& lhs, value_iterator const& rhs) { return !(rhs < lhs); } - friend bool operator>=(value_iterator const& lhs, value_iterator const& rhs) { + friend SPROUT_CONSTEXPR bool operator>=(value_iterator const& lhs, value_iterator const& rhs) { return !(lhs < rhs); } SPROUT_CONSTEXPR reference operator*() const { @@ -147,7 +147,7 @@ namespace sprout { SPROUT_CONSTEXPR reference operator[](difference_type n) const { return holder_.get(); } - friend difference_type operator-(value_iterator const& lhs, value_iterator const& rhs) { + friend SPROUT_CONSTEXPR difference_type operator-(value_iterator const& lhs, value_iterator const& rhs) { return rhs.count_ - lhs.count_; } friend SPROUT_CONSTEXPR value_iterator operator+(difference_type n, value_iterator const& it) { @@ -202,4 +202,22 @@ namespace sprout { } } // namespace sprout + + +#include + +namespace sprout { + // + // distance + // + template + SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type distance( + sprout::value_iterator first, + sprout::value_iterator last + ) + { + return last - first; + } +} // namespace sprout + #endif // #ifndef SPROUT_ITERATOR_VALUE_ITERATOR_HPP diff --git a/sprout/numeric/fixed/adjacent_difference.hpp b/sprout/numeric/fixed/adjacent_difference.hpp index 84cdb64b..bc5b9fcc 100644 --- a/sprout/numeric/fixed/adjacent_difference.hpp +++ b/sprout/numeric/fixed/adjacent_difference.hpp @@ -11,61 +11,6 @@ namespace sprout { namespace fixed { namespace detail { - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_3( - Result const& result, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_3( - Result const& result, - Args const&... args - ) - { - return adjacent_difference_impl_3(result, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return first != last && sizeof...(Args) < static_cast(offset) - ? adjacent_difference_impl_2(sprout::next(first), last, result, *first, offset, args..., *first - value) - : adjacent_difference_impl_3(result, args...) - ; - } template SPROUT_CONSTEXPR inline typename std::enable_if< sprout::fixed_container_traits::fixed_size == sizeof...(Args), @@ -74,7 +19,8 @@ namespace sprout { InputIterator first, InputIterator last, Result const& result, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { @@ -88,25 +34,44 @@ namespace sprout { InputIterator first, InputIterator last, Result const& result, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { - return sizeof...(Args) < static_cast(offset) - ? adjacent_difference_impl_1(first, last, result, offset, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))) - : first != last - ? adjacent_difference_impl_2(sprout::next(first), last, result, *first, offset + sprout::size(result), args..., *first) - : adjacent_difference_impl_3(result, args...) + return first != last && sizeof...(Args) < size + ? adjacent_difference_impl_1(sprout::next(first), last, result, size, *first, args..., *first - value) + : sprout::detail::container_complate(result, args...) ; } template - SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type adjacent_difference_impl( + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size == 0, + typename sprout::fixed::result_of::algorithm::type + >::type adjacent_difference_impl( InputIterator first, InputIterator last, - Result const& result + Result const& result, + typename sprout::fixed_container_traits::size_type size ) { - return adjacent_difference_impl_1(first, last, result, sprout::fixed_begin_offset(result)); + return sprout::remake_clone(result, sprout::size(result)); + } + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size != 0, + typename sprout::fixed::result_of::algorithm::type + >::type adjacent_difference_impl_1( + InputIterator first, + InputIterator last, + Result const& result, + typename sprout::fixed_container_traits::size_type size + ) + { + return first != last + ? adjacent_difference_impl_1(sprout::next(first), last, result, size, *first, *first) + : sprout::detail::container_complate(result) + ; } } // namespace detail // @@ -119,67 +84,10 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::adjacent_difference_impl(first, last, result); + return sprout::fixed::detail::adjacent_difference_impl(first, last, result, sprout::size(result)); } namespace detail { - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_3( - Result const& result, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_3( - Result const& result, - Args const&... args - ) - { - return adjacent_difference_impl_3(result, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - BinaryOperation binary_op, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type adjacent_difference_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - BinaryOperation binary_op, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return first != last && sizeof...(Args) < static_cast(offset) - ? adjacent_difference_impl_2(sprout::next(first), last, result, binary_op, *first, offset, args..., binary_op(*first, value)) - : adjacent_difference_impl_3(result, args...) - ; - } template SPROUT_CONSTEXPR inline typename std::enable_if< sprout::fixed_container_traits::fixed_size == sizeof...(Args), @@ -189,7 +97,8 @@ namespace sprout { InputIterator last, Result const& result, BinaryOperation binary_op, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { @@ -204,26 +113,46 @@ namespace sprout { InputIterator last, Result const& result, BinaryOperation binary_op, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { - return sizeof...(Args) < static_cast(offset) - ? adjacent_difference_impl_1(first, last, result, binary_op, offset, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))) - : first != last - ? adjacent_difference_impl_2(sprout::next(first), last, result, binary_op, *first, offset + sprout::size(result), args..., *first) - : adjacent_difference_impl_3(result, args...) + return first != last && sizeof...(Args) < size + ? adjacent_difference_impl_1(sprout::next(first), last, result, binary_op, size, *first, args..., binary_op(*first, value)) + : sprout::detail::container_complate(result, args...) ; } template - SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type adjacent_difference_impl( + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size == 0, + typename sprout::fixed::result_of::algorithm::type + >::type adjacent_difference_impl( InputIterator first, InputIterator last, Result const& result, - BinaryOperation binary_op + BinaryOperation binary_op, + typename sprout::fixed_container_traits::size_type size ) { - return adjacent_difference_impl_1(first, last, result, binary_op, sprout::fixed_begin_offset(result)); + return sprout::remake_clone(result, sprout::size(result)); + } + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size != 0, + typename sprout::fixed::result_of::algorithm::type + >::type adjacent_difference_impl_1( + InputIterator first, + InputIterator last, + Result const& result, + BinaryOperation binary_op, + typename sprout::fixed_container_traits::size_type size + ) + { + return first != last + ? adjacent_difference_impl_1(sprout::next(first), last, result, binary_op, size, *first, *first) + : sprout::detail::container_complate(result) + ; } } // namespace detail // @@ -237,7 +166,7 @@ namespace sprout { BinaryOperation binary_op ) { - return sprout::fixed::detail::adjacent_difference_impl(first, last, result, binary_op); + return sprout::fixed::detail::adjacent_difference_impl(first, last, result, binary_op, sprout::size(result)); } } // namespace fixed diff --git a/sprout/numeric/fixed/partial_sum.hpp b/sprout/numeric/fixed/partial_sum.hpp index 0005e127..306889b7 100644 --- a/sprout/numeric/fixed/partial_sum.hpp +++ b/sprout/numeric/fixed/partial_sum.hpp @@ -11,70 +11,16 @@ namespace sprout { namespace fixed { namespace detail { - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_3( - Result const& result, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_3( - Result const& result, - Args const&... args - ) - { - return partial_sum_impl_3(result, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))); - } template SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return first != last && sizeof...(Args) < static_cast(offset) - ? partial_sum_impl_2(sprout::next(first), last, result, value + *first, offset, args..., value) - : partial_sum_impl_3(result, args..., value) - ; - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), + sprout::fixed_container_traits::fixed_size == sizeof...(Args) + 1, typename sprout::fixed::result_of::algorithm::type >::type partial_sum_impl_1( InputIterator first, InputIterator last, Result const& result, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { @@ -82,31 +28,50 @@ namespace sprout { } template SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), + sprout::fixed_container_traits::fixed_size != sizeof...(Args) + 1, typename sprout::fixed::result_of::algorithm::type >::type partial_sum_impl_1( InputIterator first, InputIterator last, Result const& result, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { - return sizeof...(Args) < static_cast(offset) - ? partial_sum_impl_1(first, last, result, offset, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))) - : first != last - ? partial_sum_impl_2(sprout::next(first), last, result, *first, offset + sprout::size(result), args...) - : partial_sum_impl_3(result, args...) + return first != last && sizeof...(Args) + 1 < size + ? partial_sum_impl_1(sprout::next(first), last, result, size, value + *first, args..., value) + : sprout::detail::container_complate(result, args..., value) ; } template - SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type partial_sum_impl( + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size == 0, + typename sprout::fixed::result_of::algorithm::type + >::type partial_sum_impl( InputIterator first, InputIterator last, - Result const& result + Result const& result, + typename sprout::fixed_container_traits::size_type size ) { - return partial_sum_impl_1(first, last, result, sprout::fixed_begin_offset(result)); + return sprout::remake_clone(result, sprout::size(result)); + } + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size != 0, + typename sprout::fixed::result_of::algorithm::type + >::type partial_sum_impl_1( + InputIterator first, + InputIterator last, + Result const& result, + typename sprout::fixed_container_traits::size_type size + ) + { + return first != last + ? partial_sum_impl_1(sprout::next(first), last, result, size, *first) + : sprout::detail::container_complate(result) + ; } } // namespace detail // @@ -119,77 +84,21 @@ namespace sprout { Result const& result ) { - return sprout::fixed::detail::partial_sum_impl(first, last, result); + return sprout::fixed::detail::partial_sum_impl(first, last, result, sprout::size(result)); } namespace detail { - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_3( - Result const& result, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_3( - Result const& result, - Args const&... args - ) - { - return partial_sum_impl_3(result, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))); - } template SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - BinaryOperation binary_op, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return sprout::remake_clone(result, sprout::size(result), args...); - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), - typename sprout::fixed::result_of::algorithm::type - >::type partial_sum_impl_2( - InputIterator first, - InputIterator last, - Result const& result, - BinaryOperation binary_op, - typename sprout::fixed_container_traits::value_type const& value, - typename sprout::fixed_container_traits::difference_type offset, - Args const&... args - ) - { - return first != last && sizeof...(Args) < static_cast(offset) - ? partial_sum_impl_2(sprout::next(first), last, result, binary_op, binary_op(value, *first), offset, args..., value) - : partial_sum_impl_3(result, args..., value) - ; - } - template - SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size == sizeof...(Args), + sprout::fixed_container_traits::fixed_size == sizeof...(Args) + 1, typename sprout::fixed::result_of::algorithm::type >::type partial_sum_impl_1( InputIterator first, InputIterator last, Result const& result, BinaryOperation binary_op, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { @@ -197,33 +106,53 @@ namespace sprout { } template SPROUT_CONSTEXPR inline typename std::enable_if< - sprout::fixed_container_traits::fixed_size != sizeof...(Args), + sprout::fixed_container_traits::fixed_size != sizeof...(Args) + 1, typename sprout::fixed::result_of::algorithm::type >::type partial_sum_impl_1( InputIterator first, InputIterator last, Result const& result, BinaryOperation binary_op, - typename sprout::fixed_container_traits::difference_type offset, + typename sprout::fixed_container_traits::size_type size, + typename sprout::fixed_container_traits::value_type const& value, Args const&... args ) { - return sizeof...(Args) < static_cast(offset) - ? partial_sum_impl_1(first, last, result, binary_op, offset, args..., *sprout::next(sprout::fixed_begin(result), sizeof...(Args))) - : first != last - ? partial_sum_impl_2(sprout::next(first), last, result, binary_op, *first, offset + sprout::size(result), args...) - : partial_sum_impl_3(result, args...) + return first != last && sizeof...(Args) + 1 < size + ? partial_sum_impl_1(sprout::next(first), last, result, size, binary_op(value, *first), args..., value) + : sprout::detail::container_complate(result, args..., value) ; } template - SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm::type partial_sum_impl( + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size == 0, + typename sprout::fixed::result_of::algorithm::type + >::type partial_sum_impl( InputIterator first, InputIterator last, Result const& result, - BinaryOperation binary_op + BinaryOperation binary_op, + typename sprout::fixed_container_traits::size_type size ) { - return partial_sum_impl_1(first, last, result, binary_op, sprout::fixed_begin_offset(result)); + return sprout::remake_clone(result, sprout::size(result)); + } + template + SPROUT_CONSTEXPR inline typename std::enable_if< + sprout::fixed_container_traits::fixed_size != 0, + typename sprout::fixed::result_of::algorithm::type + >::type partial_sum_impl_1( + InputIterator first, + InputIterator last, + Result const& result, + BinaryOperation binary_op, + typename sprout::fixed_container_traits::size_type size + ) + { + return first != last + ? partial_sum_impl_1(sprout::next(first), last, result, binary_op, size, *first) + : sprout::detail::container_complate(result) + ; } } // namespace detail // @@ -237,7 +166,7 @@ namespace sprout { BinaryOperation binary_op ) { - return sprout::fixed::detail::partial_sum_impl(first, last, result, binary_op); + return sprout::fixed::detail::partial_sum_impl(first, last, result, binary_op, sprout::size(result)); } } // namespace fixed diff --git a/testspr/print.hpp b/testspr/print.hpp index 998f3f3a..6a7cfae3 100644 --- a/testspr/print.hpp +++ b/testspr/print.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -17,14 +18,30 @@ namespace testspr { } template void print(Range const& range) { - print(sprout::begin(range), sprout::end(range)); + testspr::print(sprout::begin(range), sprout::end(range)); + } + + // + // print_ln + // + template + static void print_ln(T const& t) { + std::cout << t << std::endl; + } + + // + // print_bits + // + template + static void print_bits(T const& t) { + testspr::print_ln(std::bitset(t).template to_string()); } // // print_hl // void print_hl() { - std::cout << "--------------------------------------------------------------------------------" << std::endl; + testspr::print_ln("--------------------------------------------------------------------------------"); } } // namespace testspr