final public static function byOrdinal(int $ordinal)
    {
        if (!isset(self::$names[static::class])) {
            self::detectConstants(static::class);
        }

        if (!isset(self::$names[static::class][$ordinal])) {
            throw new InvalidArgumentException(\sprintf(
                'Invalid ordinal number %s, must between 0 and %s',
                $ordinal,
                \count(self::$names[static::class]) - 1
            ));
        }

        $name = self::$names[static::class][$ordinal];
        if (isset(self::$instances[static::class][$name])) {
            return self::$instances[static::class][$name];
        }

        return self::$instances[static::class][$name] = new static(self::$constants[static::class][$name], $ordinal);
    }