File size: 2,204 Bytes
9375c9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (C) 2013  Davis E. King ([email protected])
// 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 <climits>

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<T>::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<T,T>& a,
        const std::pair<T,T>& 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_