mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-06-15 00:16:11 +08:00
new site
This commit is contained in:
parent
05087a303d
commit
baffc57197
90
.github/workflows/pages.yml
vendored
Normal file
90
.github/workflows/pages.yml
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
name: Deploy GitHub Pages
|
||||
|
||||
# Builds the docs/ site, substitutes the latest release tag into the HTML,
|
||||
# then deploys the result to GitHub Pages. Runs on:
|
||||
# - any push to main that touches docs/, this workflow, or CMakeLists.txt
|
||||
# - every published release (so a new tag refreshes the site)
|
||||
# - manual dispatch from the Actions tab
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "docs/**"
|
||||
- ".github/workflows/pages.yml"
|
||||
- "CMakeLists.txt"
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
# Required permissions for the deploy-pages action.
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Avoid concurrent deploys; let the latest one win.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build site
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
# Needed so the git-tag fallback can find release tags.
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: Resolve latest release version
|
||||
id: version
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Prefer the latest published GitHub release.
|
||||
tag="$(gh release view --repo ${{ github.repository }} --json tagName --jq .tagName 2>/dev/null || true)"
|
||||
if [ -z "${tag:-}" ]; then
|
||||
# Fall back to the newest semver-looking git tag.
|
||||
tag="$(git tag --sort=-v:refname | grep -E '^v?[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1 || true)"
|
||||
fi
|
||||
if [ -z "${tag:-}" ]; then
|
||||
# Last-resort fallback: read version from CMakeLists.txt.
|
||||
tag="v$(grep -E 'project\(fast_float VERSION' CMakeLists.txt | sed -E 's/.*VERSION ([0-9.]+).*/\1/')"
|
||||
fi
|
||||
# Strip a leading "v" — the template uses bare semver after "v".
|
||||
version="${tag#v}"
|
||||
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
||||
echo "Resolved version: ${version} (tag ${tag})"
|
||||
|
||||
- name: Substitute version into HTML
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version='${{ steps.version.outputs.version }}'
|
||||
# In-place replace every {{VERSION}} occurrence under docs/.
|
||||
find docs -type f \( -name '*.html' -o -name '*.md' -o -name '*.css' -o -name '*.js' \) \
|
||||
-exec sed -i "s/{{VERSION}}/${version}/g" {} +
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: docs
|
||||
|
||||
deploy:
|
||||
name: Deploy to GitHub Pages
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Deploy
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
0
docs/.nojekyll
Normal file
0
docs/.nojekyll
Normal file
25
docs/README.md
Normal file
25
docs/README.md
Normal file
@ -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.
|
||||
116
docs/assets/app.js
Normal file
116
docs/assets/app.js
Normal file
@ -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;
|
||||
}
|
||||
})();
|
||||
15
docs/assets/logo.svg
Normal file
15
docs/assets/logo.svg
Normal file
@ -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>
|
||||
|
After Width: | Height: | Size: 663 B |
454
docs/assets/style.css
Normal file
454
docs/assets/style.css
Normal file
@ -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; }
|
||||
}
|
||||
349
docs/index.html
Normal file
349
docs/index.html
Normal file
@ -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/cdn-release@11.10.0/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 & 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 <iostream>
|
||||
#include <string>
|
||||
|
||||
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 << "parsing failure\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::cout << "parsed the number " << result << '\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/cdn-release@11.10.0/build/highlight.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/build/languages/cmake.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.10.0/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>
|
||||
Loading…
x
Reference in New Issue
Block a user