// Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_COUNT_BiTS_Hh_ #define DLIB_COUNT_BiTS_Hh_ #include "../algs.h" #include namespace dlib { // ---------------------------------------------------------------------------------------- template < typename T > T count_bits ( T v ) /*! requires - T is an unsigned integral type ensures - returns the number of bits in v which are set to 1. !*/ { COMPILE_TIME_ASSERT(is_unsigned_type::value && sizeof(T) <= 8); // This bit of bit trickery is from: // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSet64 v = v - ((v >> 1) & (T)~(T)0/3); v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3); v = (v + (v >> 4)) & (T)~(T)0/255*15; return (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * CHAR_BIT; } // ---------------------------------------------------------------------------------------- template < typename T > T hamming_distance ( const T& a, const T& b ) /*! requires - T is an unsigned integral type ensures - returns the number of bits which differ between a and b. !*/ { return count_bits(a^b); } // ---------------------------------------------------------------------------------------- template < typename T > T hamming_distance ( const std::pair& a, const std::pair& b ) /*! requires - T is an unsigned integral type or a std::pair that, recursively, eventually contains unsigned integral types. ensures - returns the number of bits which differ between a and b. !*/ { return hamming_distance(a.first,b.first) + hamming_distance(a.second, b.second); } // ---------------------------------------------------------------------------------------- } #endif // DLIB_COUNT_BiTS_Hh_