2323 */
2424class BitArray implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable
2525{
26+ private static $ count = [
27+ 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 ,
28+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,
29+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,
30+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
31+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,
32+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
33+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
34+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 ,
35+ 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,
36+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
37+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
38+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 ,
39+ 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,
40+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 ,
41+ 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 ,
42+ 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8
43+ ];
44+
2645 /**
2746 * @var string Underlying data
2847 *
@@ -51,118 +70,64 @@ protected function __construct($size)
5170 }
5271
5372 /**
54- * Create a new BitArray from an integer
55- *
56- * @param integer $size Size of the bitarray
73+ * Clone a bitarray
5774 *
58- * @return BitArray A new BitArray
75+ * @return void
5976 *
6077 * @since 1.0.0
6178 */
62- public static function fromInteger ( $ size )
79+ public function __clone ( )
6380 {
64- return new BitArray ( $ size );
81+ $ this -> data = str_repeat ( $ this -> data , 1 );
6582 }
6683
6784 /**
68- * Create a new BitArray from a traversable
69- *
70- * @param \Traversable $traversable A traversable and countable
85+ * Convert the object to a string
7186 *
72- * @return BitArray A new BitArray
87+ * @return string String representation of this object
7388 *
7489 * @since 1.0.0
7590 */
76- public static function fromTraversable ( $ traversable )
91+ public function __toString ( )
7792 {
78- $ bits = new BitArray (count ($ traversable ));
79- $ offset = 0 ;
80- $ ord = 0 ;
93+ $ string = str_repeat ('0 ' , $ this ->size );
8194
82- foreach ($ traversable as $ value )
95+ for ($ offset = 0 ; $ offset < $ this -> size ; $ offset ++ )
8396 {
84- if ($ value )
85- {
86- $ ord |= 1 << $ offset % 8 ;
87- }
88-
89- if ($ offset % 8 === 7 )
97+ if (ord ($ this ->data [(int ) ($ offset / 8 )]) & (1 << $ offset % 8 ))
9098 {
91- $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
92- $ ord = 0 ;
99+ $ string [$ offset ] = '1 ' ;
93100 }
94-
95- $ offset ++;
96- }
97-
98- if ($ offset % 8 !== 0 )
99- {
100- $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
101101 }
102102
103- return $ bits ;
103+ return $ string ;
104104 }
105105
106106 /**
107- * Create a new BitArray from a bit string
107+ * Magic get method
108108 *
109- * @param string $string A bit string
109+ * @param string $property The property
110110 *
111- * @return BitArray A new BitArray
111+ * @throws \RuntimeException If the property does not exist
112+ *
113+ * @return mixed The value associated to the property
112114 *
113115 * @since 1.0.0
114116 */
115- public static function fromString ( $ string )
117+ public function __get ( $ property )
116118 {
117- $ bits = new BitArray (strlen ($ string ));
118- $ ord = 0 ;
119-
120- for ($ offset = 0 ; $ offset < $ bits ->size ; $ offset ++)
121- {
122- if ($ string [$ offset ] !== '0 ' )
123- {
124- $ ord |= 1 << $ offset % 8 ;
125- }
126-
127- if ($ offset % 8 === 7 )
128- {
129- $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
130- $ ord = 0 ;
131- }
132- }
133-
134- if ($ offset % 8 !== 0 )
119+ switch ($ property )
135120 {
136- $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
121+ case 'size ' :
122+ return $ this ->size ;
123+ break ;
124+ case 'count ' :
125+ return $ this ->count ();
126+ break ;
127+ default :
128+ throw new \RuntimeException ('Undefined property ' );
129+ break ;
137130 }
138-
139- return $ bits ;
140- }
141-
142- /**
143- * Create a new BitArray from json
144- *
145- * @param string $json A json encoded value
146- *
147- * @return BitArray A new BitArray
148- *
149- * @since 1.0.0
150- */
151- public static function fromJson ($ json )
152- {
153- return self ::fromTraversable (json_decode ($ json ));
154- }
155-
156- /**
157- * Clone a bitarray
158- *
159- * @return void
160- *
161- * @since 1.0.0
162- */
163- public function __clone ()
164- {
165- $ this ->data = str_repeat ($ this ->data , 1 );
166131 }
167132
168133 /**
@@ -252,15 +217,22 @@ public function offsetUnset($offset)
252217 }
253218
254219 /**
255- * Return the size
220+ * Return the number of true bits
256221 *
257- * @return integer The size
222+ * @return integer The number of true bits
258223 *
259224 * @since 1.0.0
260225 */
261226 public function count ()
262227 {
263- return $ this ->size ;
228+ $ count = 0 ;
229+
230+ for ($ i = 0 , $ length = strlen ($ this ->data ); $ i < $ length ; $ i ++)
231+ {
232+ $ count += static ::$ count [ord ($ this ->data [$ i ])];
233+ }
234+
235+ return $ count ;
264236 }
265237
266238 /**
@@ -283,37 +255,130 @@ public function jsonSerialize()
283255 }
284256
285257 /**
286- * Convert the object to a string
258+ * Get an iterator
287259 *
288- * @return string String representation of this object
260+ * @return Iterator Iterator
289261 *
290262 * @since 1.0.0
291263 */
292- public function __toString ()
264+ public function getIterator ()
293265 {
294- $ string = str_repeat ('0 ' , $ this ->size );
266+ return new Iterator ($ this );
267+ }
295268
296- for ($ offset = 0 ; $ offset < $ this ->size ; $ offset ++)
269+ /**
270+ * Return the size
271+ *
272+ * @return integer The size
273+ *
274+ * @since 1.0.0
275+ */
276+ public function size ()
277+ {
278+ return $ this ->size ;
279+ }
280+
281+ /**
282+ * Create a new BitArray from an integer
283+ *
284+ * @param integer $size Size of the bitarray
285+ *
286+ * @return BitArray A new BitArray
287+ *
288+ * @since 1.0.0
289+ */
290+ public static function fromInteger ($ size )
291+ {
292+ return new BitArray ($ size );
293+ }
294+
295+ /**
296+ * Create a new BitArray from a traversable
297+ *
298+ * @param \Traversable $traversable A traversable and countable
299+ *
300+ * @return BitArray A new BitArray
301+ *
302+ * @since 1.0.0
303+ */
304+ public static function fromTraversable ($ traversable )
305+ {
306+ $ bits = new BitArray (count ($ traversable ));
307+ $ offset = 0 ;
308+ $ ord = 0 ;
309+
310+ foreach ($ traversable as $ value )
297311 {
298- if (ord ( $ this -> data [( int ) ( $ offset / 8 )]) & ( 1 << $ offset % 8 ) )
312+ if ($ value )
299313 {
300- $ string [ $ offset ] = ' 1 ' ;
314+ $ ord |= 1 << $ offset % 8 ;
301315 }
316+
317+ if ($ offset % 8 === 7 )
318+ {
319+ $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
320+ $ ord = 0 ;
321+ }
322+
323+ $ offset ++;
302324 }
303325
304- return $ string ;
326+ if ($ offset % 8 !== 0 )
327+ {
328+ $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
329+ }
330+
331+ return $ bits ;
305332 }
306333
307334 /**
308- * Get an iterator
335+ * Create a new BitArray from a bit string
309336 *
310- * @return Iterator Iterator
337+ * @param string $string A bit string
338+ *
339+ * @return BitArray A new BitArray
311340 *
312341 * @since 1.0.0
313342 */
314- public function getIterator ( )
343+ public static function fromString ( $ string )
315344 {
316- return new Iterator ($ this );
345+ $ bits = new BitArray (strlen ($ string ));
346+ $ ord = 0 ;
347+
348+ for ($ offset = 0 ; $ offset < $ bits ->size ; $ offset ++)
349+ {
350+ if ($ string [$ offset ] !== '0 ' )
351+ {
352+ $ ord |= 1 << $ offset % 8 ;
353+ }
354+
355+ if ($ offset % 8 === 7 )
356+ {
357+ $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
358+ $ ord = 0 ;
359+ }
360+ }
361+
362+ if ($ offset % 8 !== 0 )
363+ {
364+ $ bits ->data [(int ) ($ offset / 8 )] = chr ($ ord );
365+ }
366+
367+ return $ bits ;
368+ }
369+
370+ /**
371+ * Create a new BitArray from json
372+ *
373+ * @param string $json A json encoded value
374+ *
375+ * @return BitArray A new BitArray
376+ *
377+ * @since 1.0.0
378+ */
379+ public static function fromJson ($ json )
380+ {
381+ return self ::fromTraversable (json_decode ($ json ));
317382 }
318383
319384 /**
0 commit comments