Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fast_float for openSUSE:Factory 
checked in at 2026-06-02 19:46:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fast_float (Old)
 and      /work/SRC/openSUSE:Factory/.fast_float.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fast_float"

Tue Jun  2 19:46:52 2026 rev:8 rq:1356525 version:8.2.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/fast_float/fast_float.changes    2026-05-16 
19:23:56.388599867 +0200
+++ /work/SRC/openSUSE:Factory/.fast_float.new.1937/fast_float.changes  
2026-06-02 19:47:13.284886581 +0200
@@ -1,0 +2,10 @@
+Tue Jun  2 04:17:12 UTC 2026 - Jan Engelhardt <[email protected]>
+
+- Update to release 8.2.6
+  * Unrolled the integer-part digit scan (straight-line for the
+    common 1-5 digit case).
+  * Added a 4-digit SWAR follow-up to loop_parse_if_eight_digits.
+  * Parallelized the exhaustive float32 sweeps across hardware
+    threads.
+
+-------------------------------------------------------------------

Old:
----
  fast_float-8.2.5.tar.gz

New:
----
  fast_float-8.2.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fast_float.spec ++++++
--- /var/tmp/diff_new_pack.Vt05CL/_old  2026-06-02 19:47:14.048918226 +0200
+++ /var/tmp/diff_new_pack.Vt05CL/_new  2026-06-02 19:47:14.052918392 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           fast_float
-Version:        8.2.5
+Version:        8.2.6
 Release:        0
 Summary:        Re-implementation of std::from_chars for parsing strings into 
numbers
 License:        Apache-2.0 OR BSL-1.0 OR MIT

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.Vt05CL/_old  2026-06-02 19:47:14.108920712 +0200
+++ /var/tmp/diff_new_pack.Vt05CL/_new  2026-06-02 19:47:14.112920877 +0200
@@ -1,5 +1,5 @@
-mtime: 1778813088
-commit: 3c9f1c465ed439d5dc9e19b94dbecb93ffd7b85c65fde2ccd507fd4949d76351
+mtime: 1780373873
+commit: e339164932ee4eedc02db4a90ed76a617baf4e844b3025f7a06ad5431876cbd4
 url: https://src.opensuse.org/jengelh/fast_float
 revision: master
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-06-02 06:17:53.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ fast_float-8.2.5.tar.gz -> fast_float-8.2.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/.github/workflows/pages.yml 
new/fast_float-8.2.6/.github/workflows/pages.yml
--- old/fast_float-8.2.5/.github/workflows/pages.yml    1970-01-01 
01:00:00.000000000 +0100
+++ new/fast_float-8.2.6/.github/workflows/pages.yml    2026-06-02 
00:07:41.000000000 +0200
@@ -0,0 +1,64 @@
+name: Deploy GitHub Pages
+
+on:
+  push:
+    branches: [main]
+    paths:
+      - "docs/**"
+      - ".github/workflows/pages.yml"
+      - "CMakeLists.txt"
+  release:
+    types: [published]
+  workflow_dispatch:
+
+permissions:
+  contents: write      # Changed: need write to push to gh-pages
+  pages: read          # No longer needed for deploy-pages
+  id-token: none
+
+concurrency:
+  group: "pages"
+  cancel-in-progress: false
+
+jobs:
+  deploy:
+    name: Deploy to gh-pages
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v6
+        with:
+          fetch-depth: 0
+          fetch-tags: true
+
+      - name: Resolve latest release version
+        id: version
+        env:
+          GH_TOKEN: ${{ github.token }}
+        run: |
+          set -euo pipefail
+          tag="$(gh release view --repo ${{ github.repository }} --json 
tagName --jq .tagName 2>/dev/null || true)"
+          if [ -z "${tag:-}" ]; then
+            tag="$(git tag --sort=-v:refname | grep -E 
'^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)"
+          fi
+          if [ -z "${tag:-}" ]; then
+            tag="v$(grep -E 'project\(fast_float VERSION' CMakeLists.txt | sed 
-E 's/.*VERSION ([0-9.]+).*/\1/')"
+          fi
+          version="${tag#v}"
+          echo "tag=${tag}" >> "$GITHUB_OUTPUT"
+          echo "version=${version}" >> "$GITHUB_OUTPUT"
+          echo "Resolved version: ${version}"
+
+      - name: Substitute version into HTML
+        run: |
+          version='${{ steps.version.outputs.version }}'
+          find docs -type f \( -name '*.html' -o -name '*.md' -o -name '*.css' 
-o -name '*.js' \) \
+            -exec sed -i "s/{{VERSION}}/${version}/g" {} +
+
+      - name: Deploy to gh-pages branch
+        uses: JamesIves/github-pages-deploy-action@v4
+        with:
+          branch: gh-pages
+          folder: docs
+          clean: true
+          commit-message: "Deploy docs for version ${{ 
steps.version.outputs.version }}"
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/CMakeLists.txt 
new/fast_float-8.2.6/CMakeLists.txt
--- old/fast_float-8.2.5/CMakeLists.txt 2026-04-16 20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/CMakeLists.txt 2026-06-02 00:07:41.000000000 +0200
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION 3.14)
 
 
-project(fast_float VERSION 8.2.5 LANGUAGES CXX)
+project(fast_float VERSION 8.2.6 LANGUAGES CXX)
 set(FASTFLOAT_CXX_STANDARD 11 CACHE STRING "the C++ standard to use for 
fastfloat")
 set(CMAKE_CXX_STANDARD ${FASTFLOAT_CXX_STANDARD})
 option(FASTFLOAT_TEST "Enable tests" OFF)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/README.md 
new/fast_float-8.2.6/README.md
--- old/fast_float-8.2.5/README.md      2026-04-16 20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/README.md      2026-06-02 00:07:41.000000000 +0200
@@ -441,7 +441,6 @@
 * [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's
   web browser),
 * [DuckDB](https://duckdb.org),
-* [Redis](https://github.com/redis/redis) and 
[Valkey](https://github.com/valkey-io/valkey),
 * [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied
   the number parsing speed by two or three times,
 * [Google Jsonnet](https://github.com/google/jsonnet),
@@ -455,15 +454,6 @@
 has a derived implementation that is inherited by the [Ladybird
 Browser](https://github.com/LadybirdBrowser/ladybird).
 
-The fast_float library provides a performance similar to that of the
-[fast_double_parser](https://github.com/lemire/fast_double_parser) library but
-using an updated algorithm reworked from the ground up, and while offering an
-API more in line with the expectations of C++ programmers. The
-fast_double_parser library is part of the [Microsoft LightGBM machine-learning
-framework](https://github.com/microsoft/LightGBM).
-
-
-
 Packages
 ------
 
@@ -541,7 +531,7 @@
 FetchContent_Declare(
   fast_float
   GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
-  GIT_TAG tags/v8.2.5
+  GIT_TAG tags/v8.2.6
   GIT_SHALLOW TRUE)
 
 FetchContent_MakeAvailable(fast_float)
@@ -557,7 +547,7 @@
 CPMAddPackage(
   NAME fast_float
   GITHUB_REPOSITORY "fastfloat/fast_float"
-  GIT_TAG v8.2.5)
+  GIT_TAG v8.2.6)
 ```
 
 ## Using as single header
@@ -569,7 +559,7 @@
 
 You may directly download automatically generated single-header files:
 
-<https://github.com/fastfloat/fast_float/releases/download/v8.2.5/fast_float.h>
+<https://github.com/fastfloat/fast_float/releases/download/v8.2.6/fast_float.h>
 
 ## Benchmarking
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/docs/README.md 
new/fast_float-8.2.6/docs/README.md
--- old/fast_float-8.2.5/docs/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/fast_float-8.2.6/docs/README.md 2026-06-02 00:07:41.000000000 +0200
@@ -0,0 +1,25 @@
+# fast_float website
+
+The source for <https://fastfloat.github.io/fast_float/>.
+
+Static HTML, CSS, and a small JS file — no build step required. To preview
+locally, serve this directory with any static file server, for example:
+
+```bash
+python3 -m http.server -d docs 8080
+# then open http://localhost:8080/
+```
+
+## How the version number stays current
+
+The displayed release version is kept fresh by two independent mechanisms:
+
+1. **Build-time substitution.** The `Deploy GitHub Pages` workflow
+   (`.github/workflows/pages.yml`) replaces every occurrence of the literal
+   `{{VERSION}}` in `index.html` with the latest GitHub release tag before
+   publishing. The workflow runs on every push to `main` that touches
+   `docs/**`, on every published release, and can be dispatched manually.
+
+2. **Client-side refresh.** `assets/app.js` queries the GitHub Releases API
+   on page load and overwrites any element marked with `data-version`. This
+   means visitors see the very latest tag even between deploys.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/docs/assets/app.js 
new/fast_float-8.2.6/docs/assets/app.js
--- old/fast_float-8.2.5/docs/assets/app.js     1970-01-01 01:00:00.000000000 
+0100
+++ new/fast_float-8.2.6/docs/assets/app.js     2026-06-02 00:07:41.000000000 
+0200
@@ -0,0 +1,116 @@
+(function () {
+  "use strict";
+
+  // ---------- Theme toggle ----------
+  const root = document.documentElement;
+  const storedTheme = localStorage.getItem("ff-theme");
+  if (storedTheme === "light" || storedTheme === "dark") {
+    root.setAttribute("data-theme", storedTheme);
+  }
+  const toggle = document.getElementById("theme-toggle");
+  if (toggle) {
+    toggle.addEventListener("click", function () {
+      const current =
+        root.getAttribute("data-theme") ||
+        (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : 
"light");
+      const next = current === "dark" ? "light" : "dark";
+      root.setAttribute("data-theme", next);
+      localStorage.setItem("ff-theme", next);
+    });
+  }
+
+  // ---------- Copy-to-clipboard on code blocks ----------
+  document.querySelectorAll("pre > code").forEach(function (code) {
+    const pre = code.parentElement;
+    if (!pre || pre.querySelector(".copy-btn")) return;
+    const btn = document.createElement("button");
+    btn.className = "copy-btn";
+    btn.type = "button";
+    btn.textContent = "Copy";
+    btn.setAttribute("aria-label", "Copy code to clipboard");
+    btn.addEventListener("click", function () {
+      const text = code.innerText;
+      const done = function () {
+        btn.textContent = "Copied";
+        btn.classList.add("copied");
+        setTimeout(function () {
+          btn.textContent = "Copy";
+          btn.classList.remove("copied");
+        }, 1400);
+      };
+      if (navigator.clipboard && navigator.clipboard.writeText) {
+        navigator.clipboard.writeText(text).then(done, function () {
+          fallbackCopy(text);
+          done();
+        });
+      } else {
+        fallbackCopy(text);
+        done();
+      }
+    });
+    pre.appendChild(btn);
+  });
+
+  function fallbackCopy(text) {
+    const ta = document.createElement("textarea");
+    ta.value = text;
+    ta.style.position = "fixed";
+    ta.style.opacity = "0";
+    document.body.appendChild(ta);
+    ta.select();
+    try { document.execCommand("copy"); } catch (e) { /* ignore */ }
+    document.body.removeChild(ta);
+  }
+
+  // ---------- Live version refresh from GitHub Releases ----------
+  // The build-time workflow substitutes {{VERSION}} in the HTML; this
+  // additionally refreshes the displayed version in the browser so the
+  // site always reflects the very latest release without redeploying.
+  const versionNodes = document.querySelectorAll("[data-version]");
+  const downloadLink = document.getElementById("download-latest");
+  if (versionNodes.length === 0) return;
+
+  // Don't refetch more than once per hour per visitor.
+  const CACHE_KEY = "ff-latest-release";
+  const CACHE_TTL = 60 * 60 * 1000;
+  let cached = null;
+  try {
+    const raw = localStorage.getItem(CACHE_KEY);
+    if (raw) {
+      const parsed = JSON.parse(raw);
+      if (parsed && parsed.ts && Date.now() - parsed.ts < CACHE_TTL) {
+        cached = parsed;
+      }
+    }
+  } catch (e) { /* ignore */ }
+
+  if (cached && cached.tag) {
+    applyVersion(cached.tag, cached.url);
+  } else {
+    fetch("https://api.github.com/repos/fastfloat/fast_float/releases/latest";, 
{
+      headers: { Accept: "application/vnd.github+json" },
+    })
+      .then(function (r) { return r.ok ? r.json() : null; })
+      .then(function (data) {
+        if (!data || !data.tag_name) return;
+        try {
+          localStorage.setItem(
+            CACHE_KEY,
+            JSON.stringify({ ts: Date.now(), tag: data.tag_name, url: 
data.html_url })
+          );
+        } catch (e) { /* ignore */ }
+        applyVersion(data.tag_name, data.html_url);
+      })
+      .catch(function () { /* offline / rate limited — keep build-time value 
*/ });
+  }
+
+  function applyVersion(tag, url) {
+    const clean = tag.replace(/^v/, "");
+    versionNodes.forEach(function (el) {
+      // Preserve a leading "v" if the original text used one.
+      const wasV = (el.textContent || "").trim().startsWith("v");
+      el.textContent = (wasV ? "v" : "") + clean;
+    });
+    if (downloadLink && url) downloadLink.href = url;
+  }
+})();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/docs/assets/logo.svg 
new/fast_float-8.2.6/docs/assets/logo.svg
--- old/fast_float-8.2.5/docs/assets/logo.svg   1970-01-01 01:00:00.000000000 
+0100
+++ new/fast_float-8.2.6/docs/assets/logo.svg   2026-06-02 00:07:41.000000000 
+0200
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 64 64" width="64" 
height="64">
+  <defs>
+    <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
+      <stop offset="0%" stop-color="#2563eb"/>
+      <stop offset="100%" stop-color="#0ea5e9"/>
+    </linearGradient>
+  </defs>
+  <rect x="2" y="2" width="60" height="60" rx="14" fill="url(#g)"/>
+  <path d="M16 44 L28 20 L36 36 L44 28 L52 44"
+        fill="none" stroke="#ffffff" stroke-width="4"
+        stroke-linecap="round" stroke-linejoin="round"/>
+  <circle cx="28" cy="20" r="2.5" fill="#ffffff"/>
+  <circle cx="36" cy="36" r="2.5" fill="#ffffff"/>
+  <circle cx="44" cy="28" r="2.5" fill="#ffffff"/>
+</svg>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/docs/assets/style.css 
new/fast_float-8.2.6/docs/assets/style.css
--- old/fast_float-8.2.5/docs/assets/style.css  1970-01-01 01:00:00.000000000 
+0100
+++ new/fast_float-8.2.6/docs/assets/style.css  2026-06-02 00:07:41.000000000 
+0200
@@ -0,0 +1,454 @@
+:root {
+  --bg: #ffffff;
+  --bg-alt: #f7f8fb;
+  --surface: #ffffff;
+  --text: #0f172a;
+  --text-muted: #475569;
+  --border: #e2e8f0;
+  --accent: #2563eb;
+  --accent-strong: #1d4ed8;
+  --accent-soft: rgba(37, 99, 235, 0.10);
+  --grad-from: #2563eb;
+  --grad-to: #0ea5e9;
+  --code-bg: #0f172a;
+  --code-text: #e2e8f0;
+  --shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px rgba(15, 23, 42, 
0.06);
+  --radius: 12px;
+  --radius-sm: 8px;
+  --maxw: 1100px;
+}
+
+:root[data-theme="dark"] {
+  --bg: #0b1020;
+  --bg-alt: #0f172a;
+  --surface: #121a2e;
+  --text: #e6edf7;
+  --text-muted: #94a3b8;
+  --border: #1f2a44;
+  --accent: #60a5fa;
+  --accent-strong: #93c5fd;
+  --accent-soft: rgba(96, 165, 250, 0.14);
+  --grad-from: #60a5fa;
+  --grad-to: #22d3ee;
+  --code-bg: #060a17;
+  --code-text: #e6edf7;
+  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
+}
+
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) {
+    --bg: #0b1020;
+    --bg-alt: #0f172a;
+    --surface: #121a2e;
+    --text: #e6edf7;
+    --text-muted: #94a3b8;
+    --border: #1f2a44;
+    --accent: #60a5fa;
+    --accent-strong: #93c5fd;
+    --accent-soft: rgba(96, 165, 250, 0.14);
+    --grad-from: #60a5fa;
+    --grad-to: #22d3ee;
+    --code-bg: #060a17;
+    --code-text: #e6edf7;
+    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
+  }
+}
+
+* { box-sizing: border-box; }
+
+html { scroll-behavior: smooth; }
+
+body {
+  margin: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 
"Helvetica Neue", Arial, "Noto Sans", sans-serif;
+  font-size: 16px;
+  line-height: 1.6;
+  color: var(--text);
+  background: var(--bg);
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+a { color: var(--accent); text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+code, pre {
+  font-family: "SF Mono", Menlo, Consolas, "Liberation Mono", "Roboto Mono", 
monospace;
+  font-size: 0.92em;
+}
+:not(pre) > code {
+  background: var(--accent-soft);
+  color: var(--accent-strong);
+  padding: 0.12em 0.4em;
+  border-radius: 4px;
+  font-size: 0.88em;
+}
+
+pre {
+  background: var(--code-bg);
+  color: var(--code-text);
+  padding: 1.1rem 1.2rem;
+  border-radius: var(--radius);
+  overflow-x: auto;
+  margin: 1rem 0 1.5rem;
+  position: relative;
+  box-shadow: var(--shadow);
+  font-size: 0.88rem;
+  line-height: 1.55;
+}
+pre code { background: transparent; color: inherit; padding: 0; }
+/* highlight.js applies its own background — keep our pre styling */
+pre code.hljs { background: transparent; padding: 0; }
+
+.copy-btn {
+  position: absolute;
+  top: 8px;
+  right: 8px;
+  background: rgba(255, 255, 255, 0.08);
+  color: var(--code-text);
+  border: 1px solid rgba(255, 255, 255, 0.12);
+  border-radius: 6px;
+  padding: 4px 10px;
+  font-size: 0.75rem;
+  cursor: pointer;
+  opacity: 0;
+  transition: opacity 0.15s ease, background 0.15s ease;
+}
+pre:hover .copy-btn { opacity: 1; }
+.copy-btn:hover { background: rgba(255, 255, 255, 0.15); }
+.copy-btn.copied { background: rgba(34, 197, 94, 0.25); border-color: rgba(34, 
197, 94, 0.5); }
+
+.container {
+  max-width: var(--maxw);
+  margin: 0 auto;
+  padding: 0 1.25rem;
+}
+
+.skip {
+  position: absolute; left: -9999px;
+  background: var(--accent); color: white;
+  padding: 0.6rem 1rem; border-radius: 0 0 6px 0;
+}
+.skip:focus { left: 0; top: 0; }
+
+/* Header */
+.site-header {
+  position: sticky;
+  top: 0;
+  z-index: 50;
+  backdrop-filter: saturate(180%) blur(12px);
+  -webkit-backdrop-filter: saturate(180%) blur(12px);
+  background: color-mix(in srgb, var(--bg) 80%, transparent);
+  border-bottom: 1px solid var(--border);
+}
+.nav {
+  display: flex;
+  align-items: center;
+  gap: 1.25rem;
+  height: 60px;
+}
+.brand {
+  display: inline-flex;
+  align-items: center;
+  gap: 0.55rem;
+  font-weight: 700;
+  color: var(--text);
+  text-decoration: none;
+}
+.brand img { display: block; }
+.primary-nav {
+  display: flex;
+  gap: 1.2rem;
+  margin-left: 1rem;
+  flex: 1;
+}
+.primary-nav a {
+  color: var(--text-muted);
+  font-size: 0.92rem;
+  font-weight: 500;
+}
+.primary-nav a:hover { color: var(--text); text-decoration: none; }
+.nav-actions { display: flex; align-items: center; gap: 0.5rem; }
+
+.ghost-btn {
+  display: inline-flex; align-items: center; gap: 0.4rem;
+  padding: 0.45rem 0.8rem;
+  border: 1px solid var(--border);
+  border-radius: 8px;
+  color: var(--text);
+  font-size: 0.9rem;
+  background: var(--surface);
+  transition: border-color 0.15s, background 0.15s;
+}
+.ghost-btn:hover { border-color: var(--accent); text-decoration: none; }
+
+.theme-toggle {
+  width: 36px; height: 36px;
+  display: inline-flex; align-items: center; justify-content: center;
+  border: 1px solid var(--border);
+  border-radius: 8px;
+  background: var(--surface);
+  color: var(--text);
+  cursor: pointer;
+}
+.theme-toggle .i-moon { display: none; }
+.theme-toggle .i-sun { display: block; }
+:root[data-theme="dark"] .theme-toggle .i-sun,
+@media (prefers-color-scheme: dark) {
+  :root:not([data-theme="light"]) .theme-toggle .i-sun { display: none; }
+  :root:not([data-theme="light"]) .theme-toggle .i-moon { display: block; }
+}
+:root[data-theme="dark"] .theme-toggle .i-sun { display: none; }
+:root[data-theme="dark"] .theme-toggle .i-moon { display: block; }
+:root[data-theme="light"] .theme-toggle .i-sun { display: block; }
+:root[data-theme="light"] .theme-toggle .i-moon { display: none; }
+
+/* Hero */
+.hero {
+  padding: 5rem 0 4rem;
+  background:
+    radial-gradient(1200px 480px at 50% -10%, var(--accent-soft), transparent 
70%),
+    var(--bg);
+  border-bottom: 1px solid var(--border);
+}
+.eyebrow {
+  display: inline-block;
+  font-size: 0.78rem;
+  font-weight: 600;
+  letter-spacing: 0.04em;
+  text-transform: uppercase;
+  color: var(--accent);
+  background: var(--accent-soft);
+  padding: 0.3rem 0.7rem;
+  border-radius: 999px;
+  margin-bottom: 1.25rem;
+}
+.hero h1 {
+  font-size: clamp(2rem, 4.6vw, 3.6rem);
+  line-height: 1.1;
+  margin: 0 0 1.25rem;
+  font-weight: 800;
+  letter-spacing: -0.02em;
+}
+.grad {
+  background: linear-gradient(90deg, var(--grad-from), var(--grad-to));
+  -webkit-background-clip: text;
+  background-clip: text;
+  color: transparent;
+}
+.lede {
+  font-size: 1.15rem;
+  color: var(--text-muted);
+  max-width: 720px;
+  margin: 0 0 2rem;
+}
+.lede strong { color: var(--text); }
+
+.cta-row { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-bottom: 
1.75rem; }
+
+.btn {
+  display: inline-flex; align-items: center; gap: 0.5rem;
+  padding: 0.7rem 1.1rem;
+  border-radius: 10px;
+  font-weight: 600;
+  font-size: 0.95rem;
+  border: 1px solid var(--border);
+  background: var(--surface);
+  color: var(--text);
+  cursor: pointer;
+  transition: transform 0.05s ease, border-color 0.15s, background 0.15s;
+}
+.btn:hover { text-decoration: none; border-color: var(--accent); }
+.btn:active { transform: translateY(1px); }
+.btn.primary {
+  background: var(--accent);
+  border-color: var(--accent);
+  color: white;
+  box-shadow: 0 6px 20px rgba(37, 99, 235, 0.25);
+}
+.btn.primary:hover { background: var(--accent-strong); border-color: 
var(--accent-strong); }
+.btn.ghost { background: transparent; }
+.btn code { background: rgba(255, 255, 255, 0.18); color: inherit; padding: 
0.1em 0.45em; border-radius: 4px; }
+.btn:not(.primary) code { background: var(--accent-soft); color: 
var(--accent-strong); }
+
+.hero-meta {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 0.6rem 1rem;
+  align-items: center;
+  font-size: 0.9rem;
+  color: var(--text-muted);
+}
+.badge {
+  display: inline-flex; align-items: center; gap: 0.5rem;
+  padding: 0.3rem 0.7rem;
+  border: 1px solid var(--border);
+  border-radius: 999px;
+  background: var(--surface);
+}
+.badge code { background: transparent; color: var(--text); padding: 0; }
+.badge .dot {
+  width: 8px; height: 8px; border-radius: 50%;
+  background: #22c55e;
+  box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.18);
+}
+.meta-link { color: var(--text-muted); }
+.meta-link:hover { color: var(--accent); }
+
+/* Sections */
+.section { padding: 4.5rem 0; }
+.section.alt { background: var(--bg-alt); border-top: 1px solid var(--border); 
border-bottom: 1px solid var(--border); }
+.section h2 {
+  font-size: clamp(1.6rem, 3vw, 2.2rem);
+  margin: 0 0 0.5rem;
+  letter-spacing: -0.01em;
+}
+.section h3 { margin: 1.75rem 0 0.6rem; font-size: 1.1rem; }
+.section-lede { color: var(--text-muted); max-width: 720px; margin: 0 0 2rem; }
+
+/* Grid cards */
+.grid { display: grid; gap: 1rem; }
+.grid.features { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
+.grid.install { grid-template-columns: 1fr; }
+
+.card {
+  background: var(--surface);
+  border: 1px solid var(--border);
+  border-radius: var(--radius);
+  padding: 1.4rem 1.4rem 1.5rem;
+  box-shadow: var(--shadow);
+  transition: transform 0.12s ease, border-color 0.15s;
+}
+.card:hover { transform: translateY(-2px); border-color: var(--accent); }
+.card h3 { margin: 0 0 0.5rem; font-size: 1.05rem; }
+.card p, .card ul { margin: 0; color: var(--text-muted); font-size: 0.95rem; }
+.card pre { margin: 0.6rem 0 0; font-size: 0.82rem; }
+
+.bullets { padding-left: 1.1rem; }
+.bullets li { margin: 0.2rem 0; }
+
+/* Benchmarks */
+.bench {
+  background: var(--surface);
+  border: 1px solid var(--border);
+  border-radius: var(--radius);
+  padding: 1.5rem;
+  box-shadow: var(--shadow);
+}
+.bench-row {
+  display: grid;
+  grid-template-columns: 160px 1fr;
+  align-items: center;
+  gap: 0.9rem;
+  margin: 0.55rem 0;
+}
+.bench-label { font-weight: 600; color: var(--text); font-size: 0.95rem; }
+.bench-bar {
+  background: var(--bg-alt);
+  border-radius: 6px;
+  overflow: hidden;
+  height: 28px;
+  position: relative;
+}
+.bench-fill {
+  display: inline-flex;
+  align-items: center;
+  height: 100%;
+  width: var(--w, 0%);
+  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 35%, 
transparent), color-mix(in srgb, var(--accent) 55%, transparent));
+  color: var(--text);
+  padding: 0 0.7rem;
+  border-radius: 6px;
+  font-variant-numeric: tabular-nums;
+  font-size: 0.85rem;
+  font-weight: 600;
+  white-space: nowrap;
+}
+.bench-fill.primary {
+  background: linear-gradient(90deg, var(--grad-from), var(--grad-to));
+  color: white;
+}
+
+@media (max-width: 600px) {
+  .bench-row { grid-template-columns: 1fr; gap: 0.3rem; }
+}
+
+.repro {
+  margin-top: 1.25rem;
+  border: 1px solid var(--border);
+  border-radius: var(--radius-sm);
+  background: var(--surface);
+  padding: 0.4rem 1rem;
+}
+.repro summary {
+  cursor: pointer;
+  padding: 0.5rem 0;
+  font-weight: 600;
+  color: var(--text-muted);
+}
+.repro[open] summary { color: var(--text); }
+.repro pre { margin: 0.5rem 0 0.75rem; }
+
+/* Users list */
+.users {
+  list-style: none;
+  padding: 0;
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+  gap: 0.6rem 1rem;
+}
+.users li {
+  padding: 0.7rem 0.9rem;
+  border: 1px solid var(--border);
+  border-radius: var(--radius-sm);
+  background: var(--surface);
+  font-size: 0.92rem;
+  color: var(--text-muted);
+}
+.users li strong { color: var(--text); margin-right: 0.35rem; }
+.aside { color: var(--text-muted); margin-top: 1.5rem; font-size: 0.92rem; }
+
+.papers { list-style: none; padding: 0; }
+.papers li {
+  padding: 1rem 1.2rem;
+  border: 1px solid var(--border);
+  border-radius: var(--radius-sm);
+  background: var(--surface);
+  margin-bottom: 0.7rem;
+}
+
+/* Footer */
+.site-footer {
+  background: var(--bg-alt);
+  border-top: 1px solid var(--border);
+  padding: 3rem 0 2rem;
+  color: var(--text-muted);
+  font-size: 0.92rem;
+  margin-top: 2rem;
+}
+.footer-grid {
+  display: grid;
+  grid-template-columns: 1.5fr 1fr 1fr;
+  gap: 2rem;
+  margin-bottom: 2rem;
+}
+.site-footer h4 { color: var(--text); font-size: 0.95rem; margin: 0 0 0.6rem; }
+.site-footer ul { list-style: none; padding: 0; margin: 0; }
+.site-footer li { margin: 0.25rem 0; }
+.subfoot {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-top: 1.5rem;
+  border-top: 1px solid var(--border);
+  flex-wrap: wrap;
+  gap: 0.5rem;
+}
+.subfoot code { background: var(--surface); color: var(--text); border: 1px 
solid var(--border); }
+
+@media (max-width: 720px) {
+  .primary-nav { display: none; }
+  .footer-grid { grid-template-columns: 1fr; gap: 1.5rem; }
+  .hero { padding: 3rem 0 2.5rem; }
+  .section { padding: 3rem 0; }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/docs/index.html 
new/fast_float-8.2.6/docs/index.html
--- old/fast_float-8.2.5/docs/index.html        1970-01-01 01:00:00.000000000 
+0100
+++ new/fast_float-8.2.6/docs/index.html        2026-06-02 00:07:41.000000000 
+0200
@@ -0,0 +1,349 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <title>fast_float — parse floating-point numbers at a gigabyte per 
second</title>
+  <meta name="description" content="A header-only C++ library for fast and 
exact parsing of floating-point and integer numbers. Used by GCC, Chromium, 
WebKit, LLVM, Apache Arrow, DuckDB, Redis, and more." />
+  <meta name="theme-color" content="#0f172a" />
+
+  <meta property="og:title" content="fast_float — parse floats at 1 GB/s" />
+  <meta property="og:description" content="A header-only C++ library for fast 
and exact floating-point and integer parsing." />
+  <meta property="og:type" content="website" />
+  <meta property="og:url" content="https://fastfloat.github.io/fast_float/"; />
+  <meta name="twitter:card" content="summary_large_image" />
+
+  <link rel="icon" type="image/svg+xml" href="assets/logo.svg" />
+  <link rel="stylesheet" href="assets/style.css" />
+  <link rel="stylesheet" 
href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/github-dark.min.css";
 />
+</head>
+<body>
+  <a class="skip" href="#main">Skip to content</a>
+
+  <header class="site-header">
+    <div class="container nav">
+      <a class="brand" href="./">
+        <img src="assets/logo.svg" alt="" width="32" height="32" />
+        <span>fast_float</span>
+      </a>
+      <nav class="primary-nav" aria-label="Primary">
+        <a href="#features">Features</a>
+        <a href="#performance">Performance</a>
+        <a href="#quickstart">Quick start</a>
+        <a href="#users">Users</a>
+        <a href="#install">Install</a>
+      </nav>
+      <div class="nav-actions">
+        <a class="ghost-btn" href="https://github.com/fastfloat/fast_float"; 
aria-label="GitHub repository">
+          <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" 
aria-hidden="true"><path d="M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 
10.91.58.1.79-.25.79-.56v-2c-3.2.7-3.88-1.37-3.88-1.37-.52-1.33-1.27-1.69-1.27-1.69-1.04-.71.08-.7.08-.7
 1.15.08 1.76 1.18 1.76 1.18 1.03 1.76 2.7 1.25 
3.36.96.1-.74.4-1.25.73-1.54-2.55-.29-5.24-1.28-5.24-5.7 0-1.26.45-2.29 
1.18-3.1-.12-.29-.51-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11 11 0 0 1 5.78 
0c2.2-1.49 3.17-1.18 3.17-1.18.62 1.59.23 2.76.11 3.05.74.81 1.18 1.84 1.18 3.1 
0 4.43-2.69 5.4-5.25 5.69.41.36.78 1.07.78 2.16v3.2c0 .31.21.67.8.56A11.5 11.5 
0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5z"/></svg>
+          <span>GitHub</span>
+        </a>
+        <button class="theme-toggle" id="theme-toggle" aria-label="Toggle 
color theme" title="Toggle theme">
+          <svg class="i-sun" width="18" height="18" viewBox="0 0 24 24" 
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" 
aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 
4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 
6.34l1.41-1.41"/></svg>
+          <svg class="i-moon" width="18" height="18" viewBox="0 0 24 24" 
fill="currentColor" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 
0 0 0 21 12.79z"/></svg>
+        </button>
+      </div>
+    </div>
+  </header>
+
+  <main id="main">
+    <section class="hero">
+      <div class="container">
+        <span class="eyebrow">C++11 · header-only · triple-licensed</span>
+        <h1>Parse floating-point numbers <span class="grad">at a gigabyte per 
second</span>.</h1>
+        <p class="lede">
+          <strong>fast_float</strong> is a header-only C++ implementation of
+          <code>std::from_chars</code> for <code>float</code>, 
<code>double</code>, and integer types.
+          Exact IEEE rounding, no allocations, no exceptions — often 
<strong>many times faster</strong>
+          than your standard library.
+        </p>
+        <div class="cta-row">
+          <a class="btn primary" href="#quickstart">Get started</a>
+          <a class="btn" href="https://github.com/fastfloat/fast_float";>View 
on GitHub</a>
+          <a class="btn ghost" 
href="https://github.com/fastfloat/fast_float/releases/latest"; 
id="download-latest">
+            Download <code class="version-tag" data-version>v{{VERSION}}</code>
+          </a>
+        </div>
+        <div class="hero-meta">
+          <span class="badge" id="release-badge">
+            <span class="dot"></span> Latest release: <code 
data-version>v{{VERSION}}</code>
+          </span>
+          <a class="meta-link" 
href="https://github.com/fastfloat/fast_float/blob/main/LICENSE-APACHE";>Apache 
2.0</a>
+          <a class="meta-link" 
href="https://github.com/fastfloat/fast_float/blob/main/LICENSE-MIT";>MIT</a>
+          <a class="meta-link" 
href="https://github.com/fastfloat/fast_float/blob/main/LICENSE-BOOST";>Boost</a>
+        </div>
+      </div>
+    </section>
+
+    <section id="features" class="section">
+      <div class="container">
+        <h2>Why fast_float?</h2>
+        <p class="section-lede">A drop-in <code>from_chars</code> built for 
performance-critical code paths.</p>
+        <div class="grid features">
+          <article class="card">
+            <h3>Blazing fast</h3>
+            <p>Often <strong>4× faster</strong> than the best competitor and 
many times faster than typical standard-library implementations. Sustains 
<strong>1 GB/s</strong> on commodity hardware.</p>
+          </article>
+          <article class="card">
+            <h3>Exact rounding</h3>
+            <p>Returns the closest IEEE 754 <code>float</code> or 
<code>double</code> with round-to-nearest, ties-to-even — bit-for-bit 
correct.</p>
+          </article>
+          <article class="card">
+            <h3>Header-only</h3>
+            <p>Just drop in <code>fast_float.h</code> or use it via CMake, 
Conan, vcpkg, xmake, or Homebrew. Requires only C++11.</p>
+          </article>
+          <article class="card">
+            <h3>No surprises</h3>
+            <p>Does not allocate, does not throw, locale-independent. The 
interface mirrors C++17 <code>std::from_chars</code>.</p>
+          </article>
+          <article class="card">
+            <h3>Integers too</h3>
+            <p>Parses every standard integer type in bases 2–36, plus 
<code>bool</code>. The same fast, allocation-free interface.</p>
+          </article>
+          <article class="card">
+            <h3>Unicode &amp; formats</h3>
+            <p>UTF-8, UTF-16, and UTF-32 inputs. JSON, Fortran, and custom 
decimal separators via <code>from_chars_advanced</code>.</p>
+          </article>
+          <article class="card">
+            <h3>constexpr-ready</h3>
+            <p>In C++20, parse strings at compile time with 
<code>consteval</code> — zero runtime cost.</p>
+          </article>
+          <article class="card">
+            <h3>Portable</h3>
+            <p>Visual Studio, GCC, Clang, MSYS2. Linux, macOS, FreeBSD, 
Windows. x86-64, ARM, RISC-V, s390x. 32-bit and 64-bit.</p>
+          </article>
+        </div>
+      </div>
+    </section>
+
+    <section id="performance" class="section alt">
+      <div class="container">
+        <h2>Performance</h2>
+        <p class="section-lede">
+          Parsing random floating-point numbers, measured in megabytes per 
second
+          (higher is better). Source: project benchmark suite on a typical 
x86-64 box.
+        </p>
+
+        <div class="bench">
+          <div class="bench-row">
+            <span class="bench-label">fast_float</span>
+            <div class="bench-bar"><span class="bench-fill primary" 
style="--w: 100%">1042 MB/s</span></div>
+          </div>
+          <div class="bench-row">
+            <span class="bench-label">abseil</span>
+            <div class="bench-bar"><span class="bench-fill" style="--w: 
41%">430 MB/s</span></div>
+          </div>
+          <div class="bench-row">
+            <span class="bench-label">netlib</span>
+            <div class="bench-bar"><span class="bench-fill" style="--w: 
26%">271 MB/s</span></div>
+          </div>
+          <div class="bench-row">
+            <span class="bench-label">double-conversion</span>
+            <div class="bench-bar"><span class="bench-fill" style="--w: 
22%">225 MB/s</span></div>
+          </div>
+          <div class="bench-row">
+            <span class="bench-label">strtod</span>
+            <div class="bench-bar"><span class="bench-fill" style="--w: 
18%">191 MB/s</span></div>
+          </div>
+        </div>
+
+        <details class="repro">
+          <summary>Reproduce these numbers</summary>
+<pre data-lang="bash"><code>cmake -B build -D FASTFLOAT_BENCHMARKS=ON
+cmake --build build
+./build/benchmarks/benchmark</code></pre>
+        </details>
+      </div>
+    </section>
+
+    <section id="quickstart" class="section">
+      <div class="container">
+        <h2>Quick start</h2>
+        <p class="section-lede">Parse a <code>double</code> from a string in 
three lines.</p>
+
+<pre data-lang="cpp"><code>#include "fast_float/fast_float.h"
+#include &lt;iostream&gt;
+#include &lt;string&gt;
+
+int main() {
+  std::string input = "3.1416 xyz ";
+  double result;
+  auto answer = fast_float::from_chars(input.data(),
+                                       input.data() + input.size(),
+                                       result);
+  if (answer.ec != std::errc()) {
+    std::cerr &lt;&lt; "parsing failure\n";
+    return EXIT_FAILURE;
+  }
+  std::cout &lt;&lt; "parsed the number " &lt;&lt; result &lt;&lt; '\n';
+}</code></pre>
+
+        <h3>Integers in any base (2–36)</h3>
+<pre data-lang="cpp"><code>uint64_t value;
+std::string hex = "4f0cedc95a718c";
+auto r = fast_float::from_chars(hex.data(), hex.data() + hex.size(), value, 
16);
+// value == 22250738585072012</code></pre>
+
+        <h3>UTF-16 input</h3>
+<pre data-lang="cpp"><code>std::u16string input = u"3.1416 xyz ";
+double result;
+auto r = fast_float::from_chars(input.data(), input.data() + input.size(), 
result);</code></pre>
+
+        <h3>Comma as decimal separator, Fortran, or JSON</h3>
+<pre data-lang="cpp"><code>// "3,1416" — French-style
+fast_float::parse_options opts{fast_float::chars_format::general, ','};
+fast_float::from_chars_advanced(s.data(), s.data() + s.size(), result, opts);
+
+// "1d+4" — Fortran exponent
+opts = {fast_float::chars_format::fortran};
+
+// strict JSON per RFC 8259
+opts = {fast_float::chars_format::json};</code></pre>
+
+        <h3>C++20: parse at compile time</h3>
+<pre data-lang="cpp"><code>consteval double parse(std::string_view s) {
+  double v;
+  auto r = fast_float::from_chars(s.data(), s.data() + s.size(), v);
+  return r.ec == std::errc() ? v : -1.0;
+}
+constexpr double pi = parse("3.1415");  // computed at compile 
time</code></pre>
+      </div>
+    </section>
+
+    <section id="install" class="section alt">
+      <div class="container">
+        <h2>Install</h2>
+        <p class="section-lede">Pick the workflow that matches your 
project.</p>
+
+        <div class="grid install">
+          <article class="card">
+            <h3>CMake <code>FetchContent</code></h3>
+<pre data-lang="cmake"><code>FetchContent_Declare(
+  fast_float
+  GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
+  GIT_TAG tags/v{{VERSION}}
+  GIT_SHALLOW TRUE)
+FetchContent_MakeAvailable(fast_float)
+target_link_libraries(myprogram PUBLIC fast_float)</code></pre>
+          </article>
+
+          <article class="card">
+            <h3>CPM</h3>
+<pre data-lang="cmake"><code>CPMAddPackage(
+  NAME fast_float
+  GITHUB_REPOSITORY "fastfloat/fast_float"
+  GIT_TAG v{{VERSION}})</code></pre>
+          </article>
+
+          <article class="card">
+            <h3>Single header</h3>
+            <p>Download a pre-amalgamated header — no build system 
required.</p>
+<pre data-lang="bash"><code>curl -LO 
https://github.com/fastfloat/fast_float/releases/download/v{{VERSION}}/fast_float.h</code></pre>
+          </article>
+
+          <article class="card">
+            <h3>Package managers</h3>
+            <ul class="bullets">
+              <li><a 
href="https://conan.io/center/recipes/fast_float";>Conan</a></li>
+              <li><a 
href="https://formulae.brew.sh/formula/fast_float";>Homebrew</a> — <code>brew 
install fast_float</code></li>
+              <li><a href="https://xmake.io";>xmake</a></li>
+              <li>Fedora — <code>dnf install fast_float-devel</code></li>
+              <li><a 
href="https://repology.org/project/fast-float/versions";>More 
distributions</a></li>
+            </ul>
+          </article>
+        </div>
+      </div>
+    </section>
+
+    <section id="users" class="section">
+      <div class="container">
+        <h2>Trusted by</h2>
+        <p class="section-lede">fast_float ships inside compilers, browsers, 
databases, and more.</p>
+        <ul class="users">
+          <li><strong>GCC</strong> — backs <code>std::from_chars</code> since 
version 12</li>
+          <li><strong>Chromium</strong> — Chrome, Edge, and Opera</li>
+          <li><strong>WebKit</strong> — Safari</li>
+          <li><strong>Ladybird</strong> — independent browser engine</li>
+          <li><strong>DuckDB</strong> — in-process analytical database</li>
+          <li><strong>Apache Arrow</strong> — 2–3× faster number parsing</li>
+          <li><strong>ClickHouse</strong> — OLAP database</li>
+          <li><strong>MySQL</strong></li>
+          <li><strong>Boost.JSON</strong></li>
+          <li><strong>Blender</strong></li>
+          <li><strong>Google Jsonnet</strong></li>
+        </ul>
+        <p class="aside">
+          Ports and bindings exist for
+          <a href="https://github.com/aldanor/fast-float-rust/";>Rust</a>,
+          <a href="https://github.com/wrandelshofer/FastDoubleParser";>Java</a>,
+          <a href="https://github.com/CarlVerret/csFastFloat";>C#</a>,
+          <a href="https://github.com/kolemannix/ffc.h";>C</a>, and
+          <a href="https://github.com/eddelbuettel/rcppfastfloat";>R</a>.
+        </p>
+      </div>
+    </section>
+
+    <section id="papers" class="section alt">
+      <div class="container">
+        <h2>The research behind it</h2>
+        <ul class="papers">
+          <li>
+            Daniel Lemire,
+            <a href="https://arxiv.org/abs/2101.11408";><strong>Number Parsing 
at a Gigabyte per Second</strong></a>.
+            <em>Software: Practice and Experience</em> 51(8), 2021.
+          </li>
+          <li>
+            Noble Mushtak, Daniel Lemire,
+            <a href="https://arxiv.org/abs/2212.06644";><strong>Fast Number 
Parsing Without Fallback</strong></a>.
+            <em>Software: Practice and Experience</em> 53(7), 2023.
+          </li>
+        </ul>
+      </div>
+    </section>
+  </main>
+
+  <footer class="site-footer">
+    <div class="container footer-grid">
+      <div>
+        <strong>fast_float</strong>
+        <p>Triple-licensed under Apache 2.0, MIT, and Boost. Use it however 
you like.</p>
+      </div>
+      <div>
+        <h4>Project</h4>
+        <ul>
+          <li><a href="https://github.com/fastfloat/fast_float";>GitHub 
repository</a></li>
+          <li><a 
href="https://github.com/fastfloat/fast_float/releases";>Releases</a></li>
+          <li><a href="https://github.com/fastfloat/fast_float/issues";>Issue 
tracker</a></li>
+          <li><a 
href="https://github.com/fastfloat/fast_float/blob/main/SECURITY.md";>Security 
policy</a></li>
+        </ul>
+      </div>
+      <div>
+        <h4>Learn more</h4>
+        <ul>
+          <li><a href="https://arxiv.org/abs/2101.11408";>Number Parsing at a 
Gigabyte per Second</a></li>
+          <li><a href="https://www.youtube.com/watch?v=AVXgvlMeIm4";>Go Systems 
2020 talk</a></li>
+          <li><a 
href="https://github.com/fastfloat/fast_float/blob/main/README.md";>README</a></li>
+        </ul>
+      </div>
+    </div>
+    <div class="container subfoot">
+      <span>Current release <code data-version>v{{VERSION}}</code></span>
+      <span>Maintained by the <a 
href="https://github.com/fastfloat";>fast_float</a> contributors.</span>
+    </div>
+  </footer>
+
+  <script 
src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js";></script>
+  <script 
src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/cmake.min.js";></script>
+  <script 
src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/languages/bash.min.js";></script>
+  <script>
+    // Promote each <pre data-lang="X"> to a Highlight.js language class
+    // on its inner <code>, then highlight everything.
+    document.querySelectorAll("pre[data-lang]").forEach(function (pre) {
+      var code = pre.querySelector("code");
+      if (code && !code.className) code.className = "language-" + 
pre.dataset.lang;
+    });
+    hljs.highlightAll();
+  </script>
+  <script src="assets/app.js"></script>
+</body>
+</html>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/include/fast_float/ascii_number.h 
new/fast_float-8.2.6/include/fast_float/ascii_number.h
--- old/fast_float-8.2.5/include/fast_float/ascii_number.h      2026-04-16 
20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/include/fast_float/ascii_number.h      2026-06-02 
00:07:41.000000000 +0200
@@ -266,6 +266,21 @@
             p)); // in rare cases, this will overflow, but that's ok
     p += 8;
   }
+  // Consume a remaining 4-7 digit run in a single SWAR step instead of
+  // byte-by-byte (reuses the existing 4-digit helpers). The parsed result is
+  // identical either way. Gated to clang: on gcc the extra 4-digit check
+  // regresses inputs whose remainder is shorter than 4 digits (it becomes pure
+  // overhead there); clang does not show that.
+#if defined(__clang__)
+  if ((pend - p) >= 4) {
+    uint32_t const val4 = read4_to_u32(p);
+    if (is_made_of_four_digits_fast(val4)) {
+      i = i * 10000 +
+          parse_four_digits_unrolled(val4); // may overflow, that's ok
+      p += 4;
+    }
+  }
+#endif
 }
 
 enum class parse_error {
@@ -354,13 +369,36 @@
 
   uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
 
-  while ((p != pend) && is_integer(*p)) {
-    // a multiplication by 10 is cheaper than an arbitrary integer
-    // multiplication
-    i = 10 * i +
-        uint64_t(*p -
-                 UC('0')); // might overflow, we will handle the overflow later
+  // Straight-line unroll of the integer-part scan: most integer parts are
+  // 1-5 digits, so peeling the first iterations eliminates the loop back-edge
+  // for the common case. Semantics are identical to the original `while` loop:
+  // i = 10*i + digit, advancing p.
+  if ((p != pend) && is_integer(*p)) {
+    i = uint64_t(*p - UC('0'));
     ++p;
+    if ((p != pend) && is_integer(*p)) {
+      i = 10 * i + uint64_t(*p - UC('0'));
+      ++p;
+      if ((p != pend) && is_integer(*p)) {
+        i = 10 * i + uint64_t(*p - UC('0'));
+        ++p;
+        if ((p != pend) && is_integer(*p)) {
+          i = 10 * i + uint64_t(*p - UC('0'));
+          ++p;
+          if ((p != pend) && is_integer(*p)) {
+            i = 10 * i + uint64_t(*p - UC('0'));
+            ++p;
+            while ((p != pend) && is_integer(*p)) {
+              // a multiplication by 10 is cheaper than an arbitrary integer
+              // multiplication
+              i = 10 * i +
+                  uint64_t(*p - UC('0')); // might overflow, handled later
+              ++p;
+            }
+          }
+        }
+      }
+    }
   }
   UC const *const end_of_integer_part = p;
   int64_t digit_count = int64_t(end_of_integer_part - start_digits);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/include/fast_float/float_common.h 
new/fast_float-8.2.6/include/fast_float/float_common.h
--- old/fast_float-8.2.5/include/fast_float/float_common.h      2026-04-16 
20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/include/fast_float/float_common.h      2026-06-02 
00:07:41.000000000 +0200
@@ -18,7 +18,7 @@
 
 #define FASTFLOAT_VERSION_MAJOR 8
 #define FASTFLOAT_VERSION_MINOR 2
-#define FASTFLOAT_VERSION_PATCH 5
+#define FASTFLOAT_VERSION_PATCH 6
 
 #define FASTFLOAT_STRINGIZE_IMPL(x) #x
 #define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/tests/CMakeLists.txt 
new/fast_float-8.2.6/tests/CMakeLists.txt
--- old/fast_float-8.2.5/tests/CMakeLists.txt   2026-04-16 20:39:03.000000000 
+0200
+++ new/fast_float-8.2.6/tests/CMakeLists.txt   2026-06-02 00:07:41.000000000 
+0200
@@ -4,6 +4,10 @@
 
 include(FetchContent)
 
+# Some tests (the exhaustive sweeps) parallelize across std::thread.
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
 option(SYSTEM_DOCTEST "Use system copy of doctest" OFF)
 option(FASTFLOAT_SUPPLEMENTAL_TESTS "Run supplemental tests" ON)
 
@@ -49,6 +53,7 @@
       target_compile_options(${TEST_NAME} PUBLIC -Wsign-compare -Wshadow 
-Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wsign-conversion)
     endif()
     target_link_libraries(${TEST_NAME} PUBLIC fast_float supplemental-data)
+    target_link_libraries(${TEST_NAME} PUBLIC Threads::Threads)
     if (NOT SYSTEM_DOCTEST)
       target_link_libraries(${TEST_NAME} PUBLIC doctest)
     else ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/tests/exhaustive32.cpp 
new/fast_float-8.2.6/tests/exhaustive32.cpp
--- old/fast_float-8.2.5/tests/exhaustive32.cpp 2026-04-16 20:39:03.000000000 
+0200
+++ new/fast_float-8.2.6/tests/exhaustive32.cpp 2026-06-02 00:07:41.000000000 
+0200
@@ -8,6 +8,8 @@
 #include <iostream>
 #include <limits>
 #include <system_error>
+#include <thread>
+#include <vector>
 
 template <typename T> char *to_string(T d, char *buffer) {
   auto written = std::snprintf(buffer, 64, "%.*e",
@@ -15,47 +17,59 @@
   return buffer + written;
 }
 
-void allvalues() {
+// Checks a single 32-bit word (interpreted as a float); aborts on a mismatch.
+void check_word(uint32_t word) {
   char buffer[64];
-  for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
-    float v;
-    if ((w % 1048576) == 0) {
-      std::cout << ".";
-      std::cout.flush();
+  float v;
+  memcpy(&v, &word, sizeof(v));
+
+  char const *string_end = to_string(v, buffer);
+  float result_value;
+  auto result = fast_float::from_chars(buffer, string_end, result_value);
+  // Starting with version 4.0 for fast_float, we return result_out_of_range
+  // if the value is either too small (too close to zero) or too large
+  // (effectively infinity). So std::errc::result_out_of_range is normal for
+  // well-formed input strings.
+  if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) 
{
+    std::cerr << "parsing error ? " << buffer << std::endl;
+    abort();
+  }
+  if (std::isnan(v)) {
+    if (!std::isnan(result_value)) {
+      std::cerr << "not nan" << buffer << std::endl;
+      abort();
     }
-    uint32_t word = uint32_t(w);
-    memcpy(&v, &word, sizeof(v));
+  } else if (copysign(1, result_value) != copysign(1, v)) {
+    std::cerr << "I got " << std::hexfloat << result_value
+              << " but I was expecting " << v << std::endl;
+    abort();
+  } else if (result_value != v) {
+    std::cerr << "no match ? " << buffer << std::endl;
+    std::cout << "started with " << std::hexfloat << v << std::endl;
+    std::cout << "got back " << std::hexfloat << result_value << std::endl;
+    std::cout << std::dec;
+    abort();
+  }
+}
 
-    {
-      char const *string_end = to_string(v, buffer);
-      float result_value;
-      auto result = fast_float::from_chars(buffer, string_end, result_value);
-      // Starting with version 4.0 for fast_float, we return 
result_out_of_range
-      // if the value is either too small (too close to zero) or too large
-      // (effectively infinity). So std::errc::result_out_of_range is normal 
for
-      // well-formed input strings.
-      if (result.ec != std::errc() &&
-          result.ec != std::errc::result_out_of_range) {
-        std::cerr << "parsing error ? " << buffer << std::endl;
-        abort();
-      }
-      if (std::isnan(v)) {
-        if (!std::isnan(result_value)) {
-          std::cerr << "not nan" << buffer << std::endl;
-          abort();
-        }
-      } else if (copysign(1, result_value) != copysign(1, v)) {
-        std::cerr << "I got " << std::hexfloat << result_value
-                  << " but I was expecting " << v << std::endl;
-        abort();
-      } else if (result_value != v) {
-        std::cerr << "no match ? " << buffer << std::endl;
-        std::cout << "started with " << std::hexfloat << v << std::endl;
-        std::cout << "got back " << std::hexfloat << result_value << std::endl;
-        std::cout << std::dec;
-        abort();
+// Sweeps the whole 2^32 float space, split across hardware threads (the values
+// are independent); check_word() aborts on the first mismatch.
+void allvalues() {
+  unsigned int nthreads = std::thread::hardware_concurrency();
+  if (nthreads == 0) {
+    nthreads = 1;
+  }
+  std::vector<std::thread> workers;
+  workers.reserve(nthreads);
+  for (unsigned int t = 0; t < nthreads; t++) {
+    workers.emplace_back([t, nthreads]() {
+      for (uint64_t w = t; w <= 0xFFFFFFFF; w += nthreads) {
+        check_word(uint32_t(w));
       }
-    }
+    });
+  }
+  for (std::thread &worker : workers) {
+    worker.join();
   }
   std::cout << std::endl;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/tests/exhaustive32_64.cpp 
new/fast_float-8.2.6/tests/exhaustive32_64.cpp
--- old/fast_float-8.2.5/tests/exhaustive32_64.cpp      2026-04-16 
20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/tests/exhaustive32_64.cpp      2026-06-02 
00:07:41.000000000 +0200
@@ -1,6 +1,7 @@
 
 #include "fast_float/fast_float.h"
 
+#include <atomic>
 #include <cassert>
 #include <cmath>
 #include <cstdio>
@@ -9,6 +10,8 @@
 #include <limits>
 #include <string>
 #include <system_error>
+#include <thread>
+#include <vector>
 
 template <typename T> char *to_string(T d, char *buffer) {
   auto written = std::snprintf(buffer, 64, "%.*e",
@@ -45,25 +48,38 @@
   return true;
 }
 
+// Sweeps the whole 2^32 float space (widened to double), split across hardware
+// threads (the values are independent); stops at the first mismatch.
 void all_32bit_values() {
-  char buffer[64];
-  for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
-    float v32;
-    if ((w % 1048576) == 0) {
-      std::cout << ".";
-      std::cout.flush();
-    }
-    uint32_t word = uint32_t(w);
-    memcpy(&v32, &word, sizeof(v32));
-    double v = v32;
-
-    {
-      char const *string_end = to_string(v, buffer);
-      std::string s(buffer, size_t(string_end - buffer));
-      if (!basic_test_64bit(s, v)) {
-        return;
+  unsigned int nthreads = std::thread::hardware_concurrency();
+  if (nthreads == 0) {
+    nthreads = 1;
+  }
+  std::atomic<bool> ok{true};
+  std::vector<std::thread> workers;
+  workers.reserve(nthreads);
+  for (unsigned int t = 0; t < nthreads; t++) {
+    workers.emplace_back([t, nthreads, &ok]() {
+      char buffer[64];
+      for (uint64_t w = t;
+           w <= 0xFFFFFFFF && ok.load(std::memory_order_relaxed);
+           w += nthreads) {
+        float v32;
+        uint32_t word = uint32_t(w);
+        memcpy(&v32, &word, sizeof(v32));
+        double v = v32;
+
+        char const *string_end = to_string(v, buffer);
+        std::string s(buffer, size_t(string_end - buffer));
+        if (!basic_test_64bit(s, v)) {
+          ok.store(false, std::memory_order_relaxed);
+          return;
+        }
       }
-    }
+    });
+  }
+  for (std::thread &worker : workers) {
+    worker.join();
   }
   std::cout << std::endl;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fast_float-8.2.5/tests/exhaustive32_midpoint.cpp 
new/fast_float-8.2.6/tests/exhaustive32_midpoint.cpp
--- old/fast_float-8.2.5/tests/exhaustive32_midpoint.cpp        2026-04-16 
20:39:03.000000000 +0200
+++ new/fast_float-8.2.6/tests/exhaustive32_midpoint.cpp        2026-06-02 
00:07:41.000000000 +0200
@@ -1,5 +1,6 @@
 #include "fast_float/fast_float.h"
 
+#include <atomic>
 #include <cassert>
 #include <cmath>
 #include <cstdio>
@@ -7,6 +8,8 @@
 #include <iostream>
 #include <limits>
 #include <stdexcept>
+#include <thread>
+#include <vector>
 
 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
 // Anything at all that is related to cygwin, msys and so forth will
@@ -74,84 +77,105 @@
   }
 }
 
-bool allvalues() {
+// Checks a single 32-bit word (interpreted as a float). Returns true if the
+// parser agrees with the reference, false (after logging) on a mismatch.
+bool check_word(uint32_t word) {
   char buffer[64];
-  for (uint64_t w = 0; w <= 0xFFFFFFFF; w++) {
-    float v;
-    if ((w % 1048576) == 0) {
-      std::cout << ".";
-      std::cout.flush();
+  float v;
+  memcpy(&v, &word, sizeof(v));
+  if (!std::isfinite(v)) {
+    return true;
+  }
+  float nextf = std::nextafterf(v, INFINITY);
+  if (copysign(1, v) != copysign(1, nextf)) {
+    return true;
+  }
+  if (!std::isfinite(nextf)) {
+    return true;
+  }
+  double v1{v};
+  assert(float(v1) == v);
+  double v2{nextf};
+  assert(float(v2) == nextf);
+  double midv{v1 + (v2 - v1) / 2};
+  float expected_midv = float(midv);
+
+  char const *string_end = to_string(midv, buffer);
+  float str_answer;
+  strtof_from_string(buffer, str_answer);
+
+  float result_value;
+  auto result = fast_float::from_chars(buffer, string_end, result_value);
+  // Starting with version 4.0 for fast_float, we return result_out_of_range
+  // if the value is either too small (too close to zero) or too large
+  // (effectively infinity). So std::errc::result_out_of_range is normal for
+  // well-formed input strings.
+  if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) 
{
+    std::cerr << "parsing error ? " << buffer << std::endl;
+    return false;
+  }
+  if (std::isnan(v)) {
+    if (!std::isnan(result_value)) {
+      std::cerr << "not nan" << buffer << std::endl;
+      std::cerr << "v " << std::hexfloat << v << std::endl;
+      std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
+      std::cerr << "midv " << std::hexfloat << midv << std::endl;
+      std::cerr << "expected_midv " << std::hexfloat << expected_midv
+                << std::endl;
+      return false;
     }
-    uint32_t word = uint32_t(w);
-    memcpy(&v, &word, sizeof(v));
-    if (std::isfinite(v)) {
-      float nextf = std::nextafterf(v, INFINITY);
-      if (copysign(1, v) != copysign(1, nextf)) {
-        continue;
-      }
-      if (!std::isfinite(nextf)) {
-        continue;
-      }
-      double v1{v};
-      assert(float(v1) == v);
-      double v2{nextf};
-      assert(float(v2) == nextf);
-      double midv{v1 + (v2 - v1) / 2};
-      float expected_midv = float(midv);
-
-      char const *string_end = to_string(midv, buffer);
-      float str_answer;
-      strtof_from_string(buffer, str_answer);
-
-      float result_value;
-      auto result = fast_float::from_chars(buffer, string_end, result_value);
-      // Starting with version 4.0 for fast_float, we return 
result_out_of_range
-      // if the value is either too small (too close to zero) or too large
-      // (effectively infinity). So std::errc::result_out_of_range is normal 
for
-      // well-formed input strings.
-      if (result.ec != std::errc() &&
-          result.ec != std::errc::result_out_of_range) {
-        std::cerr << "parsing error ? " << buffer << std::endl;
-        return false;
-      }
-      if (std::isnan(v)) {
-        if (!std::isnan(result_value)) {
-          std::cerr << "not nan" << buffer << std::endl;
-          std::cerr << "v " << std::hexfloat << v << std::endl;
-          std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
-          std::cerr << "midv " << std::hexfloat << midv << std::endl;
-          std::cerr << "expected_midv " << std::hexfloat << expected_midv
-                    << std::endl;
-          return false;
+  } else if (copysign(1, result_value) != copysign(1, v)) {
+    std::cerr << buffer << std::endl;
+    std::cerr << "v " << std::hexfloat << v << std::endl;
+    std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
+    std::cerr << "midv " << std::hexfloat << midv << std::endl;
+    std::cerr << "expected_midv " << std::hexfloat << expected_midv
+              << std::endl;
+    std::cerr << "I got " << std::hexfloat << result_value
+              << " but I was expecting " << v << std::endl;
+    return false;
+  } else if (result_value != str_answer) {
+    std::cerr << "no match ? " << buffer << std::endl;
+    std::cerr << "v " << std::hexfloat << v << std::endl;
+    std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
+    std::cerr << "midv " << std::hexfloat << midv << std::endl;
+    std::cerr << "expected_midv " << std::hexfloat << expected_midv
+              << std::endl;
+    std::cout << "started with " << std::hexfloat << midv << std::endl;
+    std::cout << "round down to " << std::hexfloat << str_answer << std::endl;
+    std::cout << "got back " << std::hexfloat << result_value << std::endl;
+    std::cout << std::dec;
+    return false;
+  }
+  return true;
+}
+
+// Sweeps the whole 2^32 float space, split across hardware threads (the values
+// are independent). Returns false as soon as any word mismatches.
+bool allvalues() {
+  unsigned int nthreads = std::thread::hardware_concurrency();
+  if (nthreads == 0) {
+    nthreads = 1;
+  }
+  std::atomic<bool> ok{true};
+  std::vector<std::thread> workers;
+  workers.reserve(nthreads);
+  for (unsigned int t = 0; t < nthreads; t++) {
+    workers.emplace_back([t, nthreads, &ok]() {
+      for (uint64_t w = t;
+           w <= 0xFFFFFFFF && ok.load(std::memory_order_relaxed);
+           w += nthreads) {
+        if (!check_word(uint32_t(w))) {
+          ok.store(false, std::memory_order_relaxed);
+          return;
         }
-      } else if (copysign(1, result_value) != copysign(1, v)) {
-        std::cerr << buffer << std::endl;
-        std::cerr << "v " << std::hexfloat << v << std::endl;
-        std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
-        std::cerr << "midv " << std::hexfloat << midv << std::endl;
-        std::cerr << "expected_midv " << std::hexfloat << expected_midv
-                  << std::endl;
-        std::cerr << "I got " << std::hexfloat << result_value
-                  << " but I was expecting " << v << std::endl;
-        return false;
-      } else if (result_value != str_answer) {
-        std::cerr << "no match ? " << buffer << std::endl;
-        std::cerr << "v " << std::hexfloat << v << std::endl;
-        std::cerr << "v2 " << std::hexfloat << v2 << std::endl;
-        std::cerr << "midv " << std::hexfloat << midv << std::endl;
-        std::cerr << "expected_midv " << std::hexfloat << expected_midv
-                  << std::endl;
-        std::cout << "started with " << std::hexfloat << midv << std::endl;
-        std::cout << "round down to " << std::hexfloat << str_answer
-                  << std::endl;
-        std::cout << "got back " << std::hexfloat << result_value << std::endl;
-        std::cout << std::dec;
-        return false;
       }
-    }
+    });
   }
-  std::cout << std::endl;
-  return true;
+  for (std::thread &worker : workers) {
+    worker.join();
+  }
+  return ok.load();
 }
 
 inline void Assert(bool Assertion) {

Reply via email to