Line data Source code
1 : /* GRAPHITE2 LICENSING
2 :
3 : Copyright 2012, SIL International
4 : All rights reserved.
5 :
6 : This library is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU Lesser General Public License as published
8 : by the Free Software Foundation; either version 2.1 of License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should also have received a copy of the GNU Lesser General Public
17 : License along with this library in the file named "LICENSE".
18 : If not, write to the Free Software Foundation, 51 Franklin Street,
19 : Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20 : internet at http://www.fsf.org/licenses/lgpl.html.
21 :
22 : Alternatively, the contents of this file may be used under the terms of the
23 : Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 : License, as published by the Free Software Foundation, either version 2
25 : of the License or (at your option) any later version.
26 : */
27 : #pragma once
28 :
29 : namespace graphite2
30 : {
31 :
32 :
33 : #if defined GRAPHITE2_BUILTINS && (defined __GNUC__ || defined __clang__)
34 :
35 : template<typename T>
36 : inline unsigned int bit_set_count(T v)
37 : {
38 : return __builtin_popcount(v);
39 : }
40 :
41 : template<>
42 : inline unsigned int bit_set_count(int16 v)
43 : {
44 : return __builtin_popcount(static_cast<uint16>(v));
45 : }
46 :
47 : template<>
48 : inline unsigned int bit_set_count(int8 v)
49 : {
50 : return __builtin_popcount(static_cast<uint8>(v));
51 : }
52 :
53 : template<>
54 : inline unsigned int bit_set_count(unsigned long v)
55 : {
56 : return __builtin_popcountl(v);
57 : }
58 :
59 : template<>
60 : inline unsigned int bit_set_count(signed long v)
61 : {
62 : return __builtin_popcountl(v);
63 : }
64 :
65 : template<>
66 : inline unsigned int bit_set_count(unsigned long long v)
67 : {
68 : return __builtin_popcountll(v);
69 : }
70 :
71 : template<>
72 : inline unsigned int bit_set_count(signed long long v)
73 : {
74 : return __builtin_popcountll(v);
75 : }
76 : #else
77 :
78 : template<typename T>
79 0 : inline unsigned int bit_set_count(T v)
80 : {
81 0 : v = v - ((v >> 1) & T(~(0UL)/3)); // temp
82 0 : v = (v & T(~(0UL)/15*3)) + ((v >> 2) & T(~(0UL)/15*3)); // temp
83 0 : v = (v + (v >> 4)) & T(~(0UL)/255*15); // temp
84 0 : return (T)(v * T(~(0UL)/255)) >> (sizeof(T)-1)*8; // count
85 : }
86 :
87 : #endif
88 :
89 :
90 : template<int S>
91 0 : inline unsigned long _mask_over_val(unsigned long v)
92 : {
93 0 : v = _mask_over_val<S/2>(v);
94 0 : v |= v >> S*4;
95 0 : return v;
96 : }
97 :
98 : template<>
99 0 : inline unsigned long _mask_over_val<1>(unsigned long v)
100 : {
101 0 : v |= v >> 1;
102 0 : v |= v >> 2;
103 0 : v |= v >> 4;
104 0 : return v;
105 : }
106 :
107 : template<typename T>
108 0 : inline T mask_over_val(T v)
109 : {
110 0 : return _mask_over_val<sizeof(T)>(v);
111 : }
112 :
113 : template<typename T>
114 : inline unsigned long next_highest_power2(T v)
115 : {
116 : return _mask_over_val<sizeof(T)>(v-1)+1;
117 : }
118 :
119 : template<typename T>
120 0 : inline unsigned int log_binary(T v)
121 : {
122 0 : return bit_set_count(mask_over_val(v))-1;
123 : }
124 :
125 : template<typename T>
126 : inline T has_zero(const T x)
127 : {
128 : return (x - T(~T(0)/255)) & ~x & T(~T(0)/255*128);
129 : }
130 :
131 : template<typename T>
132 : inline T zero_bytes(const T x, unsigned char n)
133 : {
134 : const T t = T(~T(0)/255*n);
135 : return T((has_zero(x^t) >> 7)*n);
136 : }
137 :
138 : #if 0
139 : inline float float_round(float x, uint32 m)
140 : {
141 : *reinterpret_cast<unsigned int *>(&x) &= m;
142 : return *reinterpret_cast<float *>(&x);
143 : }
144 : #endif
145 :
146 : }
|