File indexing completed on 2025-09-17 08:33:43
0001 #ifndef BOOST_HASH2_DIGEST_HPP_INCLUDED
0002 #define BOOST_HASH2_DIGEST_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/hash2/detail/memcpy.hpp>
0009 #include <boost/hash2/detail/memcmp.hpp>
0010 #include <boost/assert.hpp>
0011 #include <boost/config.hpp>
0012 #include <string>
0013 #include <iosfwd>
0014 #include <cstddef>
0015
0016 namespace boost
0017 {
0018 namespace hash2
0019 {
0020
0021 template<std::size_t N> class digest
0022 {
0023 private:
0024
0025 unsigned char data_[ N ] = {};
0026
0027 public:
0028
0029
0030
0031 digest() = default;
0032
0033 BOOST_CXX14_CONSTEXPR digest( unsigned char const (&v)[ N ] ) noexcept
0034 {
0035 detail::memcpy( data_, v, N );
0036 }
0037
0038
0039
0040 using value_type = unsigned char;
0041 using reference = unsigned char&;
0042 using const_reference = unsigned char const&;
0043 using iterator = unsigned char*;
0044 using const_iterator = unsigned char const*;
0045 using size_type = std::size_t;
0046 using difference_type = std::ptrdiff_t;
0047
0048 BOOST_CXX14_CONSTEXPR iterator begin() noexcept { return data_; }
0049 constexpr const_iterator begin() const noexcept { return data_; }
0050
0051 BOOST_CXX14_CONSTEXPR iterator end() noexcept { return data_ + N; }
0052 constexpr const_iterator end() const noexcept { return data_ + N; }
0053
0054
0055
0056 BOOST_CXX14_CONSTEXPR unsigned char* data() noexcept { return data_; }
0057 constexpr unsigned char const* data() const noexcept { return data_; }
0058
0059 constexpr size_type size() const noexcept { return N; }
0060 constexpr size_type max_size() const noexcept { return N; }
0061
0062
0063
0064 BOOST_CXX14_CONSTEXPR reference operator[]( std::size_t i ) { BOOST_ASSERT( i < N ); return data_[ i ]; }
0065 BOOST_CXX14_CONSTEXPR const_reference operator[]( std::size_t i ) const { BOOST_ASSERT( i < N ); return data_[ i ]; }
0066
0067 BOOST_CXX14_CONSTEXPR reference front() noexcept { return data_[ 0 ]; }
0068 constexpr const_reference front() const noexcept { return data_[ 0 ]; }
0069
0070 BOOST_CXX14_CONSTEXPR reference back() noexcept { return data_[ N-1 ]; }
0071 constexpr const_reference back() const noexcept { return data_[ N-1 ]; }
0072 };
0073
0074
0075
0076 template<std::size_t N> BOOST_CXX14_CONSTEXPR bool operator==( digest<N> const& a, digest<N> const& b ) noexcept
0077 {
0078 return detail::memcmp( a.data(), b.data(), N ) == 0;
0079 }
0080
0081 template<std::size_t N> BOOST_CXX14_CONSTEXPR bool operator!=( digest<N> const& a, digest<N> const& b ) noexcept
0082 {
0083 return !( a == b );
0084 }
0085
0086
0087
0088 template<std::size_t N> BOOST_CXX14_CONSTEXPR char* to_chars( digest<N> const& v, char* first, char* last ) noexcept
0089 {
0090 if( last - first < static_cast<std::ptrdiff_t>( 2 * N ) )
0091 {
0092 return nullptr;
0093 }
0094
0095 constexpr char digits[] = "0123456789abcdef";
0096
0097 for( std::size_t i = 0; i < N; ++i )
0098 {
0099 first[ i*2 + 0 ] = digits[ v[i] >> 4 ];
0100 first[ i*2 + 1 ] = digits[ v[i] & 0x0F ];
0101 }
0102
0103 return first + N * 2;
0104 }
0105
0106 template<std::size_t N, std::size_t M> BOOST_CXX14_CONSTEXPR void to_chars( digest<N> const& v, char (&w)[ M ] ) noexcept
0107 {
0108 static_assert( M >= 2 * N + 1, "Output buffer not large enough" );
0109 *to_chars( v, w, w + M ) = 0;
0110 }
0111
0112
0113
0114 template<std::size_t N> std::ostream& operator<<( std::ostream& os, digest<N> const& v )
0115 {
0116 char tmp[ 2*N+1 ];
0117 to_chars( v, tmp );
0118
0119 os << tmp;
0120 return os;
0121 }
0122
0123
0124
0125 template<std::size_t N> std::string to_string( digest<N> const& v )
0126 {
0127 char tmp[ 2*N+1 ];
0128 to_chars( v, tmp );
0129
0130 return std::string( tmp, 2*N );
0131 }
0132
0133 }
0134 }
0135
0136 #endif