Skip to content

Commit 0f994d4

Browse files
authored
speed up TrinaryLogic
1 parent cee7127 commit 0f994d4

File tree

1 file changed

+28
-28
lines changed

1 file changed

+28
-28
lines changed

src/TrinaryLogic.php

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,36 @@
3939
final class TrinaryLogic
4040
{
4141

42-
private const YES = 1;
43-
private const MAYBE = 0;
44-
private const NO = -1;
42+
private const YES = 3;
43+
private const MAYBE = 1;
44+
private const NO = 0;
4545

4646
/** @var self[] */
4747
private static array $registry = [];
4848

49+
private static self $YES;
50+
51+
private static self $MAYBE;
52+
53+
private static self $NO;
54+
4955
private function __construct(private int $value)
5056
{
5157
}
5258

5359
public static function createYes(): self
5460
{
55-
return self::$registry[self::YES] ??= new self(self::YES);
61+
return self::$YES ??= (self::$registry[self::YES] ??= new self(self::YES));
5662
}
5763

5864
public static function createNo(): self
5965
{
60-
return self::$registry[self::NO] ??= new self(self::NO);
66+
return self::$NO ??= (self::$registry[self::NO] ??= new self(self::NO));
6167
}
6268

6369
public static function createMaybe(): self
6470
{
65-
return self::$registry[self::MAYBE] ??= new self(self::MAYBE);
71+
return self::$MAYBE ??= (self::$registry[self::MAYBE] ??= new self(self::MAYBE));
6672
}
6773

6874
public static function createFromBoolean(bool $value): self
@@ -73,8 +79,7 @@ public static function createFromBoolean(bool $value): self
7379

7480
private static function create(int $value): self
7581
{
76-
self::$registry[$value] ??= new self($value);
77-
return self::$registry[$value];
82+
return self::$registry[$value] ??= new self($value);
7883
}
7984

8085
/**
@@ -113,17 +118,13 @@ public function toBooleanType(): BooleanType
113118
return new ConstantBooleanType($this->value === self::YES);
114119
}
115120

116-
public function and(self ...$operands): self
121+
public function and(?self $operand = null, self ...$rest): self
117122
{
118-
$min = $this->value;
119-
foreach ($operands as $operand) {
120-
if ($operand->value >= $min) {
121-
continue;
122-
}
123-
124-
$min = $operand->value;
123+
$min = $this->value & ($operand !== null ? $operand->value : self::YES);
124+
foreach ($rest as $restOperand) {
125+
$min &= $restOperand->value;
125126
}
126-
return self::create($min);
127+
return self::$registry[$min] ??= new self($min);
127128
}
128129

129130
/**
@@ -153,17 +154,13 @@ public function lazyAnd(
153154
return $this->and(...$results);
154155
}
155156

156-
public function or(self ...$operands): self
157+
public function or(?self $operand = null, self ...$rest): self
157158
{
158-
$max = $this->value;
159-
foreach ($operands as $operand) {
160-
if ($operand->value < $max) {
161-
continue;
162-
}
163-
164-
$max = $operand->value;
159+
$max = $this->value | ($operand !== null ? $operand->value : self::NO);
160+
foreach ($rest as $restOperand) {
161+
$max |= $restOperand->value;
165162
}
166-
return self::create($max);
163+
return self::$registry[$max] ??= new self($max);
167164
}
168165

169166
/**
@@ -247,7 +244,7 @@ public static function maxMin(self ...$operands): self
247244
throw new ShouldNotHappenException();
248245
}
249246
$operandValues = array_column($operands, 'value');
250-
return self::create(max($operandValues) > 0 ? 1 : min($operandValues));
247+
return self::create(max($operandValues) > self::MAYBE ? self::YES : min($operandValues));
251248
}
252249

253250
/**
@@ -275,7 +272,10 @@ public static function lazyMaxMin(
275272

276273
public function negate(): self
277274
{
278-
return self::create(-$this->value);
275+
// 0b11 >> 0 == 0b11 (3)
276+
// 0b11 >> 1 == 0b01 (1)
277+
// 0b11 >> 3 == 0b00 (0)
278+
return self::create(3 >> $this->value);
279279
}
280280

281281
public function equals(self $other): bool

0 commit comments

Comments
 (0)