/*============================================================================= Copyright (c) 2011-2017 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_CHECKSUM_SUM_HPP #define SPROUT_CHECKSUM_SUM_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace sprout { static_assert(CHAR_BIT == 8, "CHAR_BIT == 8"); // // sum_basic // template class sum_basic { static_assert(Bits % 8 == 0, "Bits % 8 == 0"); public: typedef typename sprout::detail::uint_t::least value_type; typedef sum_basic const const_type; typedef typename std::conditional< sizeof(std::size_t) < sizeof(value_type), value_type, std::size_t >::type sum_type; private: sum_type sum_; private: template SPROUT_CONSTEXPR sum_type calc_sum(InputIterator first, InputIterator last) const { return sprout::accumulate( sprout::make_bytes_iterator(first), sprout::make_bytes_iterator(last), sum_ ); } public: SPROUT_CONSTEXPR sum_basic() : sum_() {} sum_basic(sum_basic const&) = default; explicit SPROUT_CONSTEXPR sum_basic(sum_type sum) : sum_(sum) {} SPROUT_CXX14_CONSTEXPR void reset(sum_type new_sum = 0) { sum_ = new_sum; } SPROUT_CONSTEXPR sum_basic const process_byte(std::uint8_t byte) const { return c_process_byte(byte); } template SPROUT_CONSTEXPR sum_basic const process_block(InputIterator bytes_begin, InputIterator bytes_end) const { return c_process_block(bytes_begin, bytes_end); } template SPROUT_CONSTEXPR sum_basic const process_bytes(InputIterator buffer, std::size_t byte_count) const { return c_process_bytes(buffer, byte_count); } template SPROUT_CONSTEXPR sum_basic const process_range(InputRange const& bytes_range) const { return c_process_range(bytes_range); } SPROUT_CONSTEXPR sum_basic const c_process_byte(std::uint8_t byte) const { return sum_basic(sum_ + byte); } template SPROUT_CONSTEXPR sum_basic const c_process_block(InputIterator bytes_begin, InputIterator bytes_end) const { return sum_basic(calc_sum(bytes_begin, bytes_end)); } template SPROUT_CONSTEXPR sum_basic const c_process_bytes(InputIterator buffer, std::size_t byte_count) const { return c_process_block(buffer, sprout::next(buffer, byte_count)); } template SPROUT_CONSTEXPR sum_basic const c_process_range(InputRange const& bytes_range) const { return c_process_block(sprout::begin(bytes_range), sprout::end(bytes_range)); } SPROUT_CXX14_CONSTEXPR void process_byte(std::uint8_t byte) { sum_ += byte; } template SPROUT_CXX14_CONSTEXPR void process_block(InputIterator bytes_begin, InputIterator bytes_end) { sum_ = calc_sum(bytes_begin, bytes_end); } template SPROUT_CXX14_CONSTEXPR void process_bytes(InputIterator buffer, std::size_t byte_count) { process_block(buffer, sprout::next(buffer, byte_count)); } template SPROUT_CXX14_CONSTEXPR void process_range(InputRange const& bytes_range) { process_block(sprout::begin(bytes_range), sprout::end(bytes_range)); } SPROUT_CONSTEXPR value_type checksum() const { return static_cast(sum_ & sprout::numeric_limits::max()); } SPROUT_CONSTEXPR value_type operator()() const { return checksum(); } }; // // sum8 // sum16 // sum32 // typedef sprout::sum_basic<8> sum8; typedef sprout::sum_basic<16> sum16; typedef sprout::sum_basic<32> sum32; // // make_sum8 // template inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(ForwardIterator first, ForwardIterator last) { return sprout::sum8().c_process_block(first, last)(); } template inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(sprout::basic_string const& s) { return sprout::sum8().c_process_range(s)(); } inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(char const* s) { return sprout::sum8().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(wchar_t const* s) { return sprout::sum8().c_process_bytes(s, sprout::char_traits::length(s))(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(char16_t const* s) { return sprout::sum8().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum8::value_type make_sum8(char32_t const* s) { return sprout::sum8().c_process_bytes(s, sprout::char_traits::length(s))(); } #endif // // make_sum16 // template inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(ForwardIterator first, ForwardIterator last) { return sprout::sum16().c_process_block(first, last)(); } template inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(sprout::basic_string const& s) { return sprout::sum16().c_process_range(s)(); } inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(char const* s) { return sprout::sum16().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(wchar_t const* s) { return sprout::sum16().c_process_bytes(s, sprout::char_traits::length(s))(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(char16_t const* s) { return sprout::sum16().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum16::value_type make_sum16(char32_t const* s) { return sprout::sum16().c_process_bytes(s, sprout::char_traits::length(s))(); } #endif // // make_sum32 // template inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(ForwardIterator first, ForwardIterator last) { return sprout::sum32().c_process_block(first, last)(); } template inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(sprout::basic_string const& s) { return sprout::sum32().c_process_range(s)(); } inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(char const* s) { return sprout::sum32().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(wchar_t const* s) { return sprout::sum32().c_process_bytes(s, sprout::char_traits::length(s))(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(char16_t const* s) { return sprout::sum32().c_process_bytes(s, sprout::char_traits::length(s))(); } inline SPROUT_CONSTEXPR sprout::sum32::value_type make_sum32(char32_t const* s) { return sprout::sum32().c_process_bytes(s, sprout::char_traits::length(s))(); } #endif } // namespace sprout #if SPROUT_USE_USER_DEFINED_LITERALS namespace sprout { namespace literals { namespace checksum { // // _sum8 // inline SPROUT_CONSTEXPR sprout::sum8::value_type operator"" _sum8(char const* s, std::size_t size) { return sprout::sum8().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum8::value_type operator"" _sum8(wchar_t const* s, std::size_t size) { return sprout::sum8().c_process_bytes(s, size)(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum8::value_type operator"" _sum8(char16_t const* s, std::size_t size) { return sprout::sum8().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum8::value_type operator"" _sum8(char32_t const* s, std::size_t size) { return sprout::sum8().c_process_bytes(s, size)(); } #endif // // _sum16 // inline SPROUT_CONSTEXPR sprout::sum16::value_type operator"" _sum16(char const* s, std::size_t size) { return sprout::sum16().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum16::value_type operator"" _sum16(wchar_t const* s, std::size_t size) { return sprout::sum16().c_process_bytes(s, size)(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum16::value_type operator"" _sum16(char16_t const* s, std::size_t size) { return sprout::sum16().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum16::value_type operator"" _sum16(char32_t const* s, std::size_t size) { return sprout::sum16().c_process_bytes(s, size)(); } #endif // // _sum32 // inline SPROUT_CONSTEXPR sprout::sum32::value_type operator"" _sum32(char const* s, std::size_t size) { return sprout::sum32().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum32::value_type operator"" _sum32(wchar_t const* s, std::size_t size) { return sprout::sum32().c_process_bytes(s, size)(); } #if SPROUT_USE_UNICODE_LITERALS inline SPROUT_CONSTEXPR sprout::sum32::value_type operator"" _sum32(char16_t const* s, std::size_t size) { return sprout::sum32().c_process_bytes(s, size)(); } inline SPROUT_CONSTEXPR sprout::sum32::value_type operator"" _sum32(char32_t const* s, std::size_t size) { return sprout::sum32().c_process_bytes(s, size)(); } #endif } // namespace checksum using sprout::literals::checksum::operator"" _sum8; using sprout::literals::checksum::operator"" _sum16; using sprout::literals::checksum::operator"" _sum32; } // namespace literals using sprout::literals::checksum::operator"" _sum8; using sprout::literals::checksum::operator"" _sum16; using sprout::literals::checksum::operator"" _sum32; } // namespace sprout #endif // #if SPROUT_USE_USER_DEFINED_LITERALS #endif // #ifndef SPROUT_CHECKSUM_SUM_HPP