Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12736: crc table init at compile time
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-11-08 02:48:35
#12736: crc table init at compile time
-------------------------------+---------------------------
Reporter: ajax16384@⦠| Owner: Daryle Walker
Type: Feature Requests | Status: new
Milestone: To Be Determined | Component: crc
Version: Boost 1.61.0 | Severity: Optimization
Resolution: | Keywords:
-------------------------------+---------------------------
Comment (by zh):
https://github.com/hhggit/crc/commit/69910bbdb2cc43841bf33df3eebd22ca0b088e39
{{{
diff --git a/include/boost/crc.hpp b/include/boost/crc.hpp
old mode 100644
new mode 100755
index 6be5aa1..43bb819
--- a/include/boost/crc.hpp
+++ b/include/boost/crc.hpp
@@ -17,6 +17,9 @@
#include <boost/limits.hpp> // for std::numeric_limits
+#if __cplusplus >= 201402L
+#include <utility>
+#endif
// The type of CRC parameters that can go in a template should be related
// on the CRC's bit count. This macro expresses that type in a compact
@@ -299,13 +302,13 @@ namespace detail
{
typedef typename boost::uint_t<Bits>::fast value_type;
- static value_type reflect( value_type x );
+ BOOST_CXX14_CONSTEXPR static value_type reflect( value_type x
);
}; // boost::detail::reflector
// Function that reflects its argument
template < std::size_t Bits >
- typename reflector<Bits>::value_type
+ BOOST_CXX14_CONSTEXPR typename reflector<Bits>::value_type
reflector<Bits>::reflect
(
typename reflector<Bits>::value_type x
@@ -347,7 +350,7 @@ namespace detail
#if defined(__EDG_VERSION__) && __EDG_VERSION__ <= 243
static const least sig_bits = (~( ~( 0ul ) << Bits )) ;
#else
- BOOST_STATIC_CONSTANT( least, sig_bits = (~( ~(least( 0u )) <<
Bits )) );
+ BOOST_STATIC_CONSTANT( least, sig_bits = least(~( least(~(least(
0u ))) << Bits )) );
#endif
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 &&
__GNUC_PATCHLEVEL__ == 2
// Work around a weird bug that ICEs the compiler in build_c_cast
@@ -451,6 +454,56 @@ namespace detail
}; // boost::detail::mask_uint_t
#endif
+#if __cplusplus >= 201402L
+ template <std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool
Reflect, typename value_type, typename masking_type>
+ constexpr static value_type calc_table(unsigned char dividend) {
+ // factor-out constants to avoid recalculation
+ value_type const fast_hi_bit = masking_type::high_bit_fast;
+ unsigned char const byte_hi_bit = 1u << (CHAR_BIT - 1u);
+ value_type remainder = 0;
+
+ // go through all the dividend's bits
+ for ( unsigned char mask = byte_hi_bit; mask; mask >>= 1 )
+ {
+ // check if divisor fits
+ if ( crc_helper<CHAR_BIT, Reflect>::reflect(dividend) & mask )
+ {
+ remainder ^= fast_hi_bit;
+ }
+
+ // do polynominal division
+ if ( remainder & fast_hi_bit )
+ {
+ remainder <<= 1;
+ remainder ^= TruncPoly;
+ }
+ else
+ {
+ remainder <<= 1;
+ }
+ }
+
+ return crc_helper<Bits, Reflect>::reflect( remainder );
+ }
+
+ template <std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool
Reflect, typename Table >
+ struct crc_table_generator {
+ typedef mask_uint_t<Bits> masking_type;
+ typedef typename masking_type::fast value_type;
+
+ Table table_;
+
+ constexpr value_type operator[](int i) const {return table_[i];}
+
+ template<typename T, T...Is>
+ constexpr crc_table_generator(std::integer_sequence<T, Is...>)
+ : table_{(calc_table<Bits, TruncPoly, Reflect, value_type,
masking_type>(Is))...}
+ {}
+ constexpr crc_table_generator()
+ :
crc_table_generator(std::make_index_sequence<sizeof(Table)/sizeof(value_type)>())
+ {}
+ };
+#endif
// CRC table generator
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool
Reflect >
@@ -472,12 +525,22 @@ namespace detail
typedef value_type table_type[ byte_combos ];
#endif
- static void init_table();
+#if __cplusplus >= 201402L
+ typedef crc_table_generator<Bits, TruncPoly, Reflect, table_type>
generator_type;
+ constexpr static generator_type table_{};
+#else
+ static void init_table();
- static table_type table_;
+ static table_type table_;
+#endif
}; // boost::detail::crc_table_t
+#if __cplusplus >= 201402L
+ template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool
Reflect >
+ constexpr typename crc_table_t<Bits, TruncPoly,
Reflect>::generator_type
+ crc_table_t<Bits, TruncPoly, Reflect>::table_;
+#else
// CRC table generator static data member definition
// (Some compilers [Borland C++] require the initializer to be
present.)
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly, bool
Reflect >
@@ -534,6 +597,7 @@ namespace detail
did_init = true;
}
+#endif
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// Align the msb of the remainder to a byte
@@ -570,7 +634,7 @@ namespace detail
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// Possibly reflect a remainder
- static value_type reflect( value_type x )
+ BOOST_CONSTEXPR static value_type reflect( value_type x )
{ return detail::reflector<Bits>::reflect( x ); }
// Compare a byte to the remainder's highest byte
@@ -607,7 +671,7 @@ namespace detail
typedef typename uint_t<Bits>::fast value_type;
// Possibly reflect a remainder
- static value_type reflect( value_type x )
+ BOOST_CONSTEXPR static value_type reflect( value_type x )
{ return x; }
// Compare a byte to the remainder's highest byte
@@ -839,7 +903,9 @@ BOOST_CRC_OPTIMAL_NAME::crc_optimal
)
: rem_( helper_type::reflect(init_rem) )
{
+#if __cplusplus < 201402L
crc_table_type::init_table();
+#endif
}
template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly,
@@ -1059,8 +1125,9 @@ augmented_crc
typename masking_type::fast rem = initial_remainder;
byte_type const * const b = static_cast<byte_type const *>(
buffer );
byte_type const * const e = b + byte_count;
-
+#if __cplusplus < 201402L
crc_table_type::init_table();
+#endif
for ( byte_type const * p = b ; p < e ; ++p )
{
// Use the current top byte as the table index to the next
}}}
-- Ticket URL: <https://svn.boost.org/trac10/boost/ticket/12736#comment:2> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-11-08 02:54:31 UTC