Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:33:42

0001 #ifndef BOOST_HASH2_DETAIL_WRITE_HPP_INCLUDED
0002 #define BOOST_HASH2_DETAIL_WRITE_HPP_INCLUDED
0003 
0004 // Copyright 2017, 2018, 2024 Peter Dimov
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <boost/hash2/endian.hpp>
0009 #include <boost/hash2/detail/is_constant_evaluated.hpp>
0010 #include <boost/config.hpp>
0011 #include <type_traits>
0012 #include <cstdint>
0013 #include <cstring>
0014 
0015 namespace boost
0016 {
0017 namespace hash2
0018 {
0019 namespace detail
0020 {
0021 
0022 // little endian
0023 
0024 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write16le( unsigned char* p, std::uint16_t v ) noexcept
0025 {
0026     if( !detail::is_constant_evaluated() && endian::native == endian::little )
0027     {
0028         std::memcpy( p, &v, sizeof(v) );
0029     }
0030     else
0031     {
0032         p[0] = static_cast<unsigned char>( v & 0xFF );
0033         p[1] = static_cast<unsigned char>( ( v >> 8 ) & 0xFF );
0034     }
0035 }
0036 
0037 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write32le( unsigned char* p, std::uint32_t v ) noexcept
0038 {
0039     if( !detail::is_constant_evaluated() && endian::native == endian::little )
0040     {
0041         std::memcpy( p, &v, sizeof(v) );
0042     }
0043     else
0044     {
0045         p[0] = static_cast<unsigned char>( v & 0xFF );
0046         p[1] = static_cast<unsigned char>( ( v >>  8 ) & 0xFF );
0047         p[2] = static_cast<unsigned char>( ( v >> 16 ) & 0xFF );
0048         p[3] = static_cast<unsigned char>( ( v >> 24 ) & 0xFF );
0049     }
0050 }
0051 
0052 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write64le( unsigned char* p, std::uint64_t v ) noexcept
0053 {
0054     if( !detail::is_constant_evaluated() && endian::native == endian::little )
0055     {
0056         std::memcpy( p, &v, sizeof(v) );
0057     }
0058     else
0059     {
0060         p[0] = static_cast<unsigned char>( v & 0xFF );
0061         p[1] = static_cast<unsigned char>( ( v >>  8 ) & 0xFF );
0062         p[2] = static_cast<unsigned char>( ( v >> 16 ) & 0xFF );
0063         p[3] = static_cast<unsigned char>( ( v >> 24 ) & 0xFF );
0064         p[4] = static_cast<unsigned char>( ( v >> 32 ) & 0xFF );
0065         p[5] = static_cast<unsigned char>( ( v >> 40 ) & 0xFF );
0066         p[6] = static_cast<unsigned char>( ( v >> 48 ) & 0xFF );
0067         p[7] = static_cast<unsigned char>( ( v >> 56 ) & 0xFF );
0068     }
0069 }
0070 
0071 // big endian
0072 
0073 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write16be( unsigned char* p, std::uint16_t v ) noexcept
0074 {
0075     p[0] = static_cast<unsigned char>( ( v >> 8 ) & 0xFF );
0076     p[1] = static_cast<unsigned char>( v & 0xFF );
0077 }
0078 
0079 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write32be( unsigned char* p, std::uint32_t v ) noexcept
0080 {
0081     p[0] = static_cast<unsigned char>( ( v >> 24 ) & 0xFF );
0082     p[1] = static_cast<unsigned char>( ( v >> 16 ) & 0xFF );
0083     p[2] = static_cast<unsigned char>( ( v >>  8 ) & 0xFF );
0084     p[3] = static_cast<unsigned char>( v & 0xFF );
0085 }
0086 
0087 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write64be( unsigned char* p, std::uint64_t v ) noexcept
0088 {
0089     p[0] = static_cast<unsigned char>( ( v >> 56 ) & 0xFF );
0090     p[1] = static_cast<unsigned char>( ( v >> 48 ) & 0xFF );
0091     p[2] = static_cast<unsigned char>( ( v >> 40 ) & 0xFF );
0092     p[3] = static_cast<unsigned char>( ( v >> 32 ) & 0xFF );
0093     p[4] = static_cast<unsigned char>( ( v >> 24 ) & 0xFF );
0094     p[5] = static_cast<unsigned char>( ( v >> 16 ) & 0xFF );
0095     p[6] = static_cast<unsigned char>( ( v >>  8 ) & 0xFF );
0096     p[7] = static_cast<unsigned char>( v & 0xFF );
0097 }
0098 
0099 // any endian
0100 
0101 // template<class T> BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void write( T v, endian e, unsigned char (&w)[ sizeof(T) ] ) noexcept;
0102 
0103 template<class T>
0104 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR
0105 typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 1, void>::type
0106 write( T v, endian /*e*/, unsigned char (&w)[ sizeof(T) ] ) noexcept
0107 {
0108     w[ 0 ] = static_cast<unsigned char>( v );
0109 }
0110 
0111 template<class T>
0112 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR
0113 typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 2, void>::type
0114 write( T v, endian e, unsigned char (&w)[ sizeof(T) ] ) noexcept
0115 {
0116     if( e == endian::little )
0117     {
0118         write16le( w, static_cast<std::uint16_t>( v ) );
0119     }
0120     else
0121     {
0122         write16be( w, static_cast<std::uint16_t>( v ) );
0123     }
0124 }
0125 
0126 template<class T>
0127 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR
0128 typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 4, void>::type
0129 write( T v, endian e, unsigned char (&w)[ sizeof(T) ] ) noexcept
0130 {
0131     if( e == endian::little )
0132     {
0133         write32le( w, static_cast<std::uint32_t>( v ) );
0134     }
0135     else
0136     {
0137         write32be( w, static_cast<std::uint32_t>( v ) );
0138     }
0139 }
0140 
0141 template<class T>
0142 BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR
0143 typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 8, void>::type
0144 write( T v, endian e, unsigned char (&w)[ sizeof(T) ] ) noexcept
0145 {
0146     if( e == endian::little )
0147     {
0148         write64le( w, static_cast<std::uint64_t>( v ) );
0149     }
0150     else
0151     {
0152         write64be( w, static_cast<std::uint64_t>( v ) );
0153     }
0154 }
0155 
0156 } // namespace detail
0157 } // namespace hash2
0158 } // namespace boost
0159 
0160 #endif // #ifndef BOOST_HASH2_DETAIL_WRITE_HPP_INCLUDED