<?php

declare(strict_types=1);

namespace Evulmastah\Bitset;

use Evulmastah\Bitset\Exception\BitsetException;

class Bitset implements BitsetInterface
{
    private $set = [];

    /**
     * @throws BitsetException
     */
    public static function fromString(string $string): BitsetInterface
    {
        if (!preg_match('/[0|1]$/', $string)) {
            throw BitsetException::invalidStringException($string);
        }

        if (strlen($string) > 8 * PHP_INT_SIZE - 1) {
            throw BitsetException::numberOutOfRange();
        }

        $self = new self();

        foreach (str_split($string) as $bit) {
            $self->set[] = $bit === '1';
        }

        $self->set = array_reverse($self->set);

        return $self;
    }

    public static function fromNumber(int $number): BitsetInterface
    {
        $self = new self();

        while ($number > 0) {
            $self->set[] = ($number & 1) === 1;
            $number >>= 1;
        }

        return $self;
    }

    public function toString(): string
    {
        return implode(
            array_map(function ($isSet) {
                return $isSet ? '1' : '0';
            }, array_reverse($this->set))
        );
    }

    public function toNumber(): int
    {
        $number = 0;
        foreach ($this->set as $index => $isSet) {
            if ($isSet) {
                $number += (1 << $index);
            }
        }

        return $number;
    }

    public function count(): int
    {
        return array_sum($this->set);
    }

    public function test(int $index): bool
    {
        return $this->set[$index] ?? false;
    }

    public function all(): bool
    {
        return count(array_filter($this->set)) === count($this->set);
    }

    public function any(): bool
    {
        return array_sum($this->set) > 0;
    }

    public function none(): bool
    {
        return array_sum($this->set) === 0;
    }

    public function set(int $index, bool $isSet): void
    {
        $bitsCount = count($this->set);
        if ($index > $bitsCount) {
            $this->set = array_merge(
                $this->set,
                array_fill($bitsCount, $index - $bitsCount, false)
            );
        }

        $this->set[$index] = $isSet;
    }

    public function reset(): void
    {
        $this->set = [];
    }

    public function flip(): void
    {
        $this->set = array_map(function ($isSet) {
            return !$isSet;
        }, $this->set);
    }
}

The entries are the properties of their respective owners.
Powered by Flask, SQLAlchemy, Pygments and Bootstrap.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.