diff --git a/build-preview.sh b/build-preview.sh new file mode 100755 index 0000000..0687d24 --- /dev/null +++ b/build-preview.sh @@ -0,0 +1,95 @@ +#!/bin/sh +# Build preview site from website-v2-docs and swap in boostlook-v3.css +# +# Usage: +# ./build-preview.sh # build lib docs + site docs, sync into preview/ +# ./build-preview.sh --css-only # just rebuild CSS and swap it in +# ./build-preview.sh --serve # just start the local server + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +DOCS_DIR="$SCRIPT_DIR/../website-v2-docs" +BOOST_DIR="$HOME/boost" +PREVIEW_DIR="$SCRIPT_DIR/preview" +BUILD_DIR="$DOCS_DIR/build" +PORT=8000 + +css_swap() { + echo "Swapping boostlook-v3.css into preview..." + cp "$SCRIPT_DIR/boostlook-v3.css" "$PREVIEW_DIR/_/css/boostlook.css" +} + +serve() { + echo "Serving preview at http://localhost:$PORT/" + open "http://localhost:$PORT/" + cd "$PREVIEW_DIR" + python3 -m http.server "$PORT" +} + +if [ "$1" = "--serve" ]; then + serve + exit 0 +fi + +if [ ! -d "$DOCS_DIR" ]; then + echo "Error: website-v2-docs not found at $DOCS_DIR" + exit 1 +fi + +if [ ! -d "$BOOST_DIR" ]; then + echo "Error: boost superproject not found at $BOOST_DIR" + exit 1 +fi + +# Rebuild CSS from sources +echo "Building boostlook-v3.css..." +sh "$SCRIPT_DIR/build-css.sh" + +if [ "$1" = "--css-only" ]; then + css_swap + echo "Done (CSS only)." + exit 0 +fi + +# Build library docs +echo "Building library docs..." +cd "$DOCS_DIR" +sh libdoc.sh develop + +# Build site docs +echo "Building site docs..." +sh sitedoc.sh develop + +# Sync capy library docs into preview/capy/ +echo "Syncing capy docs into preview..." +mkdir -p "$PREVIEW_DIR/capy" +rsync -a --delete "$BUILD_DIR/lib/doc/capy/" "$PREVIEW_DIR/capy/" + +# Sync UI assets (fonts, JS, images) +echo "Syncing UI assets..." +rsync -a "$BUILD_DIR/lib/doc/_/" "$PREVIEW_DIR/_/" + +# Sync site docs +echo "Syncing site docs..." +for dir in user-guide contributor-guide formal-reviews; do + if [ -d "$BUILD_DIR/$dir" ]; then + rsync -a "$BUILD_DIR/$dir/" "$PREVIEW_DIR/$dir/" + fi +done + +# Build charconv (asciidoctor + b2) +echo "Building charconv docs..." +cp "$SCRIPT_DIR/boostlook-v3.css" "$BOOST_DIR/tools/boostlook/boostlook.css" +cd "$BOOST_DIR/libs/charconv/doc" +"$BOOST_DIR/b2" html_ +mkdir -p "$PREVIEW_DIR/charconv" +cp "$BOOST_DIR/libs/charconv/doc/html/charconv.html" "$PREVIEW_DIR/charconv/index.html" + +# Swap in our CSS +css_swap + +echo "Done. Preview ready at preview/" + +# Start local server +serve diff --git a/netlify.toml b/netlify.toml index c35c28c..e92579d 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,3 +1,3 @@ [build] publish = "preview/" - command = "rm preview/_/css/boostlook.css && cp boostlook-v3.css preview/_/css/boostlook.css" + command = "rm preview/_/css/boostlook.css && cp boostlook-v3.css preview/_/css/boostlook.css" \ No newline at end of file diff --git a/preview/_/css/boostlook.css b/preview/_/css/boostlook.css deleted file mode 120000 index ba7e560..0000000 --- a/preview/_/css/boostlook.css +++ /dev/null @@ -1 +0,0 @@ -../../../boostlook-v3.css \ No newline at end of file diff --git a/preview/_/css/boostlook.css b/preview/_/css/boostlook.css new file mode 100644 index 0000000..e86977c --- /dev/null +++ b/preview/_/css/boostlook.css @@ -0,0 +1,5012 @@ +/** + * Boost Look v3 — Development Build + * New design and development for the Boost C++ Libraries website (boost.io), + * in collaboration with MetaLab. + * Built from modular sources in src/css/ via build-css.sh + * Note: boostlook.css remains the current production stylesheet. + * License: BSL-1.0 + */ + +/** + * File Structure Overview (src/css/): + * 00-header.css - License, file overview + * 01-variables.css - Root CSS custom properties, spacing, typography, icons + * 02-themes.css - Light/dark theme variable mappings + * 03-fonts.css - @font-face declarations (Noto Sans, Monaspace) + * 04-reset.css - CSS reset (box-sizing, margins, defaults) + * 05-global-typography.css - Base container, headings h1-h6, heading anchors + * 06-global-links.css - Paragraph styling, links, footnotes + * 07-global-code.css - Code blocks, inline code, syntax highlighting (hljs) + * 08-global-components.css - Quotes, pagination, admonitions, lists, edit-page link + * 09-global-tables-images.css - Tables, image styles + * 10-scrollbars.css - Scrollbar styling (Firefox + WebKit) + * 11-template-layout.css - Template-specific scrolling, iframe, TOC common styles + * 12-asciidoctor.css - AsciiDoctor-specific styles, Rouge syntax highlighting + * 13-antora.css - Antora navigation, toolbar, breadcrumbs, tabs, search + * 14-quickbook.css - Quickbook legacy wrapper, titles, TOC, tables, footer + * 15-readme.css - Library README styles + * 16-responsive-toc.css - AsciiDoctor responsive TOC layout (768px → 1920px) + */ + +/** + * Template Structure: + * The framework supports these main documentation templates: + * + * 1. AsciiDoctor Template: + * example: https://www.boost.io/doc/libs/1_87_0/libs/charconv/doc/html/charconv.html + *
+ *
+ *

Title

+ *
+ * + *
    TOC Links
+ *
+ *
+ *
+ *
Content Sections
+ *
+ * + *
+ * + * 2. Antora Template: + * example: https://www.boost.io/doc/libs/1_87_0/doc/antora/url/index.html + *
+ * + *
+ *
+ *
Breadcrumbs and Spirit Nav
+ *

Title

+ *
Content Sections
+ *
+ *
+ * + *
+ * + * 3. Quickbook Template: + * example: https://www.boost.io/doc/libs/1_87_0/doc/html/accumulators.html + *
+ *
Navigation
+ *
+ *
Title and information
+ *
Table of Contents
+ *
Footer
+ *
+ *
+ * + * 4. README Template: + * example: https://www.boost.io/library/1.87.0/beast/ + *
ReadMe Content
+ */ + +/** + * Design Philosophy: + * - Consistent styling across different documentation templates + * - Responsive design with mobile-first approach + * - Dark/Light theme support + * - Accessible typography and color schemes + * - Modern scrolling and navigation experience + */ + +/** + * Framework Selector Conventions + * + * The framework uses the following selector prefixes: + * + * 1. .boostlook + * - Primary selector for cross-template styles + * - Applies to all documentation formats + * - Used for common components and layouts + * + * 2. .boostlook:not(:has(.doc)), + * .boostlook#boost-legacy-docs-wrapper - (DEPRECATED), + * .boostlook#antora-template-wrapper, + * div.source-docs-antora.boostlook:not(:has(>.boostlook)) - (Fallback) + * - Specific to legacy Quickbook templates + * - Maintains backward compatibility + * - Handles specialized Quickbook formatting + * + * 3. .boostlook#libraryReadMe + * - Dedicated to README template styling + * - Optimized for library documentation + * - Ensures consistent README presentation + */ + +/*----------------- Root Variables - Start -----------------*/ + +/* Root CSS Variables + * Defines core design tokens used throughout the framework. + * Organized into: + * 1. General Variables - Global settings used across themes + * 2. Color System - Comprehensive color palette including brand, state, and UI colors + * 3. Typography - Font sizes, line heights, and text styling variables + * 4. Spacing System - Padding, margins, and layout spacing tokens + * 5. Icons - SVG icon definitions for light and dark themes + * 6. Responsive Design - Mobile-first breakpoint variables + */ + +:root { + /* General Variables - Core design tokens for all themes */ + --bl-primary-color: rgb(255, 159, 0); /* Boost's signature orange color */ + + /*----------------- New Look Variables Start -----------------*/ + /* New Look Primitives */ + /* Colors Primary (Grey) */ + --colors-primary-0: #ffffff; + --colors-primary-50: #f5f6f8; + --colors-primary-100: #e4e7ea; + --colors-primary-200: #c7cccf; + --colors-primary-300: #afb3b6; + --colors-primary-400: #949a9e; + --colors-primary-500: #798086; + --colors-primary-600: #62676b; + --colors-primary-650: #585A64; + --colors-primary-700: #494d50; + --colors-primary-800: #393b3f; + --colors-primary-900: #18191b; + --colors-primary-950: #0d0e0f; + + /* Colors Brand Shades */ + --colors-brand-orange-100: #ffeaca; + --colors-brand-orange-200: #ffd897; + --colors-brand-orange-400: #ffb030; + --colors-brand-orange-500: #ff9f00; + --colors-brand-orange-600: #cd7e00; + --colors-brand-orange-900: #352000; + + /* Colors Negative Shades */ + --colors-negative-50: #fdf1f3ff; + --colors-negative-100: #ffe6ea; + --colors-negative-200: #ffcad2; + --colors-negative-300: #fe9aab; + --colors-negative-400: #f9677f; + --colors-negative-500: #eb3856; + --colors-negative-600: #bc233c; + --colors-negative-700: #8d1529; + --colors-negative-800: #600d1b; + --colors-negative-950: #1d0408; + + /* Colors Positive Shades */ + --colors-positive-50: #f0fef7ff; + --colors-positive-100: #def7eb; + --colors-positive-200: #bdeed6; + --colors-positive-300: #9ce6c2; + --colors-positive-400: #7bddad; + --colors-positive-500: #5ad599; + --colors-positive-600: #48ac7b; + --colors-positive-700: #36825d; + --colors-positive-800: #255940; + --colors-positive-950: #0a1b13; + + /* Colors Warning Shades */ + --colors-warning-0: rgba(255, 248, 243, 0.5); + --colors-warning-100: #ffefe2; + --colors-warning-200: #ffd4b3; + --colors-warning-300: #feb780; + --colors-warning-400: #ff9442; + --colors-warning-500: #fd760f; + --colors-warning-600: #c25909; + --colors-warning-700: #914104; + --colors-warning-800: #5d2a02; + --colors-warning-950: #1f0e01; + + /* Colors Secondary (Blue) */ + --colors-secondary-0: #f6fafd; + --colors-secondary-50: #daeef9; + --colors-secondary-100: #c2e2f4; + --colors-secondary-200: #92cbe9; + --colors-secondary-300: #62b3dd; + --colors-secondary-400: #329cd2; + --colors-secondary-500: #0284c7; + --colors-secondary-600: #026a9f; + --colors-secondary-700: #014f77; + --colors-secondary-800: #013550; + --colors-secondary-850: #01283c; + --colors-secondary-900: #001a28; + --colors-secondary-950: #000d14; + + /* Atom One Dark Theme Colors */ + --atom-one-dark-bg: #282c34; + --atom-one-dark-text: #abb2bf; + --atom-one-dark-keyword: #c678dd; + --atom-one-dark-operator: #e06c75; + --atom-one-dark-constant: #56b6c2; + --atom-one-dark-class: #e6c07b; + + /* Atom One Light Theme Colors */ + --atom-one-light-bg: #fafafa; + --atom-one-light-text: #383a42; + --atom-one-light-keyword: #a626a4; + --atom-one-light-operator: #e45649; + --atom-one-light-constant: #0184bb; + --atom-one-light-class: #c18401; + + /* Colour Primitives — Accent */ + --colors-accent-weak-teal: #C9F2EE; + --colors-accent-weak-yellow: #F8EBA9; + --colors-accent-weak-green: #E4E4C0; + --colors-accent-strong-teal: #64DACE; + --colors-accent-strong-yellow: #F5D039; + --colors-accent-strong-green: #CACA62; + + /* Colour Primitives — Syntax */ + --colors-syntax-weak-blue: #38DDFF; + --colors-syntax-weak-green: #72FE92; + --colors-syntax-weak-yellow: #FFF173; + --colors-syntax-weak-pink: #F358C0; + --colors-syntax-weak-grey: #A3A3A3; + --colors-syntax-strong-blue: #1345E8; + --colors-syntax-strong-green: #289D30; + --colors-syntax-strong-yellow: #A3A38C; + --colors-syntax-strong-pink: #D31FA7; + --colors-syntax-strong-grey: #9E9E9E; + + /* Colour Primitives — Error */ + --colors-error-weak: #FDF2F2; + --colors-error-strong: #D32F2F; + --colors-error-mid: #FF3B30; + + /* Colors Other */ + --colors-primary-150: #d5d7d9; + --colors-primary-850: #2a2c30; + --colors-overlay-overlay-white-40: rgba(255 255 255 / 0.4); + --colors-overlay-overlay-black-40: rgba(13 14 15 / 0.4); + --colors-overlay-overlay-white-64: rgba(255 255 255 / 0.64); + --colors-overlay-overlay-black-64: rgba(13 14 15 / 0.64); + --colors-overlay-overlay-white-88: rgba(255 255 255 / 0.88); + --colors-overlay-overlay-black-88: rgba(13 14 15 / 0.88); + + /* Spacings And Sizes */ + --spacing-size-size-0: 0rem; + --spacing-size-4xs: 0.125rem; + --spacing-size-3xs: 0.25rem; + --spacing-size-2xs: 0.5rem; + --spacing-size-xs: 0.75rem; + --spacing-size-sm: 1rem; + --spacing-size-md: 1.125rem; + --spacing-size-2md: 1.3rem; + --spacing-size-lg: 1.5rem; + --spacing-size-xl: 2rem; + --spacing-size-2xl: 2.5rem; + --spacing-size-3xl: 3rem; + --main-container: 90rem; + + /* Corner Radius — Metalab 2.0 Primitives */ + --corner-radius-xs: 0.125rem; + --corner-radius-s: 0.25rem; + --corner-radius-m: 0.375rem; + --corner-radius-l: 0.5rem; + --corner-radius-xl: 0.75rem; + --corner-radius-xxl: 1rem; + + /* New Look Typography */ + --font-family-body: "Noto Sans", system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; + --font-family-code: "Monaspace Neon", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* Metalab 2.0 Size Primitives (Desktop / Mobile) */ + /* XS: 12px / 10px */ + /* Small: 14px / 12px */ + /* Base: 16px / 14px */ + /* Medium:18px / 16px */ + /* Large: 24px / 20px */ + /* XL: 32px / 24px */ + /* 2XL: 40px / 28px */ + /* 3XL: 64px / 32px */ + /* 4XL: 72px / 40px */ + --font-size-3xs: 0.625rem; + --font-size-2xs: 0.75rem; + --font-size-xs: 0.875rem; + --font-size-sm: 1rem; + --font-size-2sm: 1.2rem; + --font-size-md: 1.125rem; + --font-size-lg: 1.25rem; + --font-size-2md: 1.3rem; + --font-size-xl: 1.5rem; + --font-size-2xl: 1.75rem; + --font-size-3xl: 2rem; + --font-size-4xl: 2.5rem; + --font-size-5xl: 3rem; + --font-size-6xl: 4.5rem; + --font-line-height-xs: 0.75rem; + --font-line-height-sm: 1rem; + --font-line-height-md: 1.25rem; + --font-line-height-lg: 1.5rem; + --font-line-height-xl: 1.75rem; + --font-line-height-2xl: 2rem; + --font-line-height-3xl: 2.5rem; + --font-line-height-4xl: 3rem; + + /* New Look Icons */ + /* Themed Headings Anchor Icon */ + --icon-anchor-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%3E%3Cg%20clip-path%3D%22url(%23clip0_618_10452)%22%3E%3Cpath%20d%3D%22M13.2084%202.77855C11.8904%201.46053%209.75343%201.46053%208.43541%202.77855L6.31409%204.89987L5.4302%204.01599L7.55152%201.89467C9.3577%200.0884953%2012.2861%200.0884955%2014.0923%201.89467C15.8984%203.70085%2015.8984%206.62923%2014.0923%208.43541L11.9709%2010.5567L11.0871%209.67284L13.2084%207.55152C14.5264%206.2335%2014.5264%204.09657%2013.2084%202.77855Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M2.77855%2013.2084C4.09657%2014.5264%206.23351%2014.5264%207.55153%2013.2084L9.67285%2011.0871L10.5567%2011.9709L8.43541%2014.0923C6.62923%2015.8984%203.70085%2015.8984%201.89467%2014.0923C0.0884953%2012.2861%200.0884953%209.3577%201.89467%207.55152L4.01599%205.4302L4.89987%206.31409L2.77855%208.43541C1.46053%209.75343%201.46053%2011.8904%202.77855%2013.2084Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M10.5567%206.31409C10.8008%206.07001%2010.8008%205.67428%2010.5567%205.4302C10.3126%205.18613%209.91692%205.18613%209.67284%205.4302L5.4302%209.67284C5.18613%209.91692%205.18613%2010.3127%205.4302%2010.5567C5.67428%2010.8008%206.07001%2010.8008%206.31409%2010.5567L10.5567%206.31409Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fg%3E%3Cdefs%3E%3CclipPath%20id%3D%22clip0_618_10452%22%3E%3Crect%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22white%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3C%2Fsvg%3E"); + --icon-anchor-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%3E%3Cg%20clip-path%3D%22url(%23clip0_618_7189)%22%3E%3Cpath%20d%3D%22M13.2084%202.77855C11.8904%201.46053%209.75343%201.46053%208.43541%202.77855L6.31409%204.89987L5.4302%204.01599L7.55152%201.89467C9.3577%200.0884953%2012.2861%200.0884955%2014.0923%201.89467C15.8984%203.70085%2015.8984%206.62923%2014.0923%208.43541L11.9709%2010.5567L11.0871%209.67284L13.2084%207.55152C14.5264%206.2335%2014.5264%204.09657%2013.2084%202.77855Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M2.77855%2013.2084C4.09657%2014.5264%206.23351%2014.5264%207.55153%2013.2084L9.67285%2011.0871L10.5567%2011.9709L8.43541%2014.0923C6.62923%2015.8984%203.70085%2015.8984%201.89467%2014.0923C0.0884953%2012.2861%200.0884953%209.3577%201.89467%207.55152L4.01599%205.4302L4.89987%206.31409L2.77855%208.43541C1.46053%209.75343%201.46053%2011.8904%202.77855%2013.2084Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M10.5567%206.31409C10.8008%206.07001%2010.8008%205.67428%2010.5567%205.4302C10.3126%205.18613%209.91692%205.18613%209.67284%205.4302L5.4302%209.67284C5.18613%209.91692%205.18613%2010.3127%205.4302%2010.5567C5.67428%2010.8008%206.07001%2010.8008%206.31409%2010.5567L10.5567%206.31409Z%22%20fill%3D%22white%22%2F%3E%3C%2Fg%3E%3Cdefs%3E%3CclipPath%20id%3D%22clip0_618_7189%22%3E%3Crect%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22white%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3C%2Fsvg%3E"); + + /* Themed Left Arrow Icon */ + --icon-arrow-left-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M12.5303%204.46967C12.8232%204.76256%2012.8232%205.23744%2012.5303%205.53033L6.81066%2011.25H19C19.4142%2011.25%2019.75%2011.5858%2019.75%2012C19.75%2012.4142%2019.4142%2012.75%2019%2012.75H6.81066L12.5303%2018.4697C12.8232%2018.7626%2012.8232%2019.2374%2012.5303%2019.5303C12.2374%2019.8232%2011.7626%2019.8232%2011.4697%2019.5303L4.46967%2012.5303C4.17678%2012.2374%204.17678%2011.7626%204.46967%2011.4697L11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-arrow-left-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M12.5303%204.46967C12.8232%204.76256%2012.8232%205.23744%2012.5303%205.53033L6.81066%2011.25H19C19.4142%2011.25%2019.75%2011.5858%2019.75%2012C19.75%2012.4142%2019.4142%2012.75%2019%2012.75H6.81066L12.5303%2018.4697C12.8232%2018.7626%2012.8232%2019.2374%2012.5303%2019.5303C12.2374%2019.8232%2011.7626%2019.8232%2011.4697%2019.5303L4.46967%2012.5303C4.17678%2012.2374%204.17678%2011.7626%204.46967%2011.4697L11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967Z%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed Right Arrow Icon */ + --icon-arrow-right-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967L19.5303%2011.4697C19.8232%2011.7626%2019.8232%2012.2374%2019.5303%2012.5303L12.5303%2019.5303C12.2374%2019.8232%2011.7626%2019.8232%2011.4697%2019.5303C11.1768%2019.2374%2011.1768%2018.7626%2011.4697%2018.4697L17.1893%2012.75H5C4.58579%2012.75%204.25%2012.4142%204.25%2012C4.25%2011.5858%204.58579%2011.25%205%2011.25H17.1893L11.4697%205.53033C11.1768%205.23744%2011.1768%204.76256%2011.4697%204.46967Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-arrow-right-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967L19.5303%2011.4697C19.8232%2011.7626%2019.8232%2012.2374%2019.5303%2012.5303L12.5303%2019.5303C12.2374%2019.8232%2011.7626%2019.8232%2011.4697%2019.5303C11.1768%2019.2374%2011.1768%2018.7626%2011.4697%2018.4697L17.1893%2012.75H5C4.58579%2012.75%204.25%2012.4142%204.25%2012C4.25%2011.5858%204.58579%2011.25%205%2011.25H17.1893L11.4697%205.53033C11.1768%205.23744%2011.1768%204.76256%2011.4697%204.46967Z%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed Up Arrow Icon */ + --icon-arrow-up-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M19.5303%2012.5303C19.2374%2012.8232%2018.7626%2012.8232%2018.4697%2012.5303L12.75%206.81066L12.75%2019C12.75%2019.4142%2012.4142%2019.75%2012%2019.75C11.5858%2019.75%2011.25%2019.4142%2011.25%2019L11.25%206.81066L5.53033%2012.5303C5.23744%2012.8232%204.76256%2012.8232%204.46967%2012.5303C4.17678%2012.2374%204.17678%2011.7626%204.46967%2011.4697L11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967L19.5303%2011.4697C19.8232%2011.7626%2019.8232%2012.2374%2019.5303%2012.5303Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-arrow-up-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M19.5303%2012.5303C19.2374%2012.8232%2018.7626%2012.8232%2018.4697%2012.5303L12.75%206.81066L12.75%2019C12.75%2019.4142%2012.4142%2019.75%2012%2019.75C11.5858%2019.75%2011.25%2019.4142%2011.25%2019L11.25%206.81066L5.53033%2012.5303C5.23744%2012.8232%204.76256%2012.8232%204.46967%2012.5303C4.17678%2012.2374%204.17678%2011.7626%204.46967%2011.4697L11.4697%204.46967C11.7626%204.17678%2012.2374%204.17678%2012.5303%204.46967L19.5303%2011.4697C19.8232%2011.7626%2019.8232%2012.2374%2019.5303%2012.5303Z%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed Clipboard Icon */ + --icon-clipboard-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M4.8%203.75C4.52152%203.75%204.25445%203.86062%204.05754%204.05754C3.86062%204.25445%203.75%204.52152%203.75%204.8V12.9C3.75%2013.1785%203.86062%2013.4455%204.05754%2013.6425C4.25445%2013.8394%204.52152%2013.95%204.8%2013.95H5.7C6.11421%2013.95%206.45%2014.2858%206.45%2014.7C6.45%2015.1142%206.11421%2015.45%205.7%2015.45H4.8C4.1237%2015.45%203.4751%2015.1813%202.99688%2014.7031C2.51866%2014.2249%202.25%2013.5763%202.25%2012.9V4.8C2.25%204.1237%202.51866%203.4751%202.99688%202.99688C3.4751%202.51866%204.1237%202.25%204.8%202.25H12.9C13.5763%202.25%2014.2249%202.51866%2014.7031%202.99688C15.1813%203.4751%2015.45%204.1237%2015.45%204.8V5.7C15.45%206.11421%2015.1142%206.45%2014.7%206.45C14.2858%206.45%2013.95%206.11421%2013.95%205.7V4.8C13.95%204.52152%2013.8394%204.25445%2013.6425%204.05754C13.4455%203.86062%2013.1785%203.75%2012.9%203.75H4.8ZM11.1%2010.05C10.5201%2010.05%2010.05%2010.5201%2010.05%2011.1V19.2C10.05%2019.7799%2010.5201%2020.25%2011.1%2020.25H19.2C19.7799%2020.25%2020.25%2019.7799%2020.25%2019.2V11.1C20.25%2010.5201%2019.7799%2010.05%2019.2%2010.05H11.1ZM8.55%2011.1C8.55%209.69167%209.69167%208.55%2011.1%208.55H19.2C20.6083%208.55%2021.75%209.69167%2021.75%2011.1V19.2C21.75%2020.6083%2020.6083%2021.75%2019.2%2021.75H11.1C9.69167%2021.75%208.55%2020.6083%208.55%2019.2V11.1Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-clipboard-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M4.8%203.75C4.52152%203.75%204.25445%203.86062%204.05754%204.05754C3.86062%204.25445%203.75%204.52152%203.75%204.8V12.9C3.75%2013.1785%203.86062%2013.4455%204.05754%2013.6425C4.25445%2013.8394%204.52152%2013.95%204.8%2013.95H5.7C6.11421%2013.95%206.45%2014.2858%206.45%2014.7C6.45%2015.1142%206.11421%2015.45%205.7%2015.45H4.8C4.1237%2015.45%203.4751%2015.1813%202.99688%2014.7031C2.51866%2014.2249%202.25%2013.5763%202.25%2012.9V4.8C2.25%204.1237%202.51866%203.4751%202.99688%202.99688C3.4751%202.51866%204.1237%202.25%204.8%202.25H12.9C13.5763%202.25%2014.2249%202.51866%2014.7031%202.99688C15.1813%203.4751%2015.45%204.1237%2015.45%204.8V5.7C15.45%206.11421%2015.1142%206.45%2014.7%206.45C14.2858%206.45%2013.95%206.11421%2013.95%205.7V4.8C13.95%204.52152%2013.8394%204.25445%2013.6425%204.05754C13.4455%203.86062%2013.1785%203.75%2012.9%203.75H4.8ZM11.1%2010.05C10.5201%2010.05%2010.05%2010.5201%2010.05%2011.1V19.2C10.05%2019.7799%2010.5201%2020.25%2011.1%2020.25H19.2C19.7799%2020.25%2020.25%2019.7799%2020.25%2019.2V11.1C20.25%2010.5201%2019.7799%2010.05%2019.2%2010.05H11.1ZM8.55%2011.1C8.55%209.69167%209.69167%208.55%2011.1%208.55H19.2C20.6083%208.55%2021.75%209.69167%2021.75%2011.1V19.2C21.75%2020.6083%2020.6083%2021.75%2019.2%2021.75H11.1C9.69167%2021.75%208.55%2020.6083%208.55%2019.2V11.1Z%22%20fill%3D%22%23FFFFFF%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed Home Icon */ + --icon-home-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M10.1192%203.23498C11.177%202.24329%2012.823%202.24329%2013.8808%203.23498L19.8808%208.85998C20.4354%209.37986%2020.75%2010.1061%2020.75%2010.8662V18.9997C20.75%2019.9662%2019.9665%2020.7497%2019%2020.7497H15C14.5858%2020.7497%2014.25%2020.414%2014.25%2019.9997V15.9998C14.25%2015.8617%2014.1381%2015.7498%2014%2015.7498H10C9.86193%2015.7498%209.75%2015.8617%209.75%2015.9998V19.9997C9.75%2020.414%209.41421%2020.7497%209%2020.7497H5C4.0335%2020.7497%203.25%2019.9662%203.25%2018.9997V10.8662C3.25%2010.1061%203.56462%209.37986%204.11916%208.85998L10.1192%203.23498ZM12.8549%204.32929C12.3741%203.87852%2011.6259%203.87852%2011.1451%204.32929L5.14507%209.95429C4.89301%2010.1906%204.75%2010.5207%204.75%2010.8662V18.9997C4.75%2019.1378%204.86193%2019.2497%205%2019.2497H8.25V15.9998C8.25%2015.0333%209.0335%2014.2498%2010%2014.2498H14C14.9665%2014.2498%2015.75%2015.0333%2015.75%2015.9998V19.2497H19C19.1381%2019.2497%2019.25%2019.1378%2019.25%2018.9997V10.8662C19.25%2010.5207%2019.107%2010.1906%2018.8549%209.95429L12.8549%204.32929Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-home-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M10.1192%203.23523C11.177%202.24353%2012.823%202.24353%2013.8808%203.23523L19.8808%208.86023C20.4354%209.38011%2020.75%2010.1063%2020.75%2010.8665V19C20.75%2019.9665%2019.9665%2020.75%2019%2020.75H15C14.5858%2020.75%2014.25%2020.4142%2014.25%2020V16C14.25%2015.8619%2014.1381%2015.75%2014%2015.75H10C9.86193%2015.75%209.75%2015.8619%209.75%2016V20C9.75%2020.4142%209.41421%2020.75%209%2020.75H5C4.0335%2020.75%203.25%2019.9665%203.25%2019V10.8665C3.25%2010.1063%203.56462%209.38011%204.11916%208.86023L10.1192%203.23523ZM12.8549%204.32953C12.3741%203.87876%2011.6259%203.87876%2011.1451%204.32953L5.14507%209.95453C4.89301%2010.1908%204.75%2010.5209%204.75%2010.8665V19C4.75%2019.1381%204.86193%2019.25%205%2019.25H8.25V16C8.25%2015.0335%209.0335%2014.25%2010%2014.25H14C14.9665%2014.25%2015.75%2015.0335%2015.75%2016V19.25H19C19.1381%2019.25%2019.25%2019.1381%2019.25%2019V10.8665C19.25%2010.5209%2019.107%2010.1908%2018.8549%209.95453L12.8549%204.32953Z%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed File Icon */ + --icon-file-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M5%2011.5H10V10.5H5V11.5Z%22%20fill%3D%22%2362676B%22%2F%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M4%201.5C3.17157%201.5%202.5%202.17157%202.5%203V13C2.5%2013.8284%203.17157%2014.5%204%2014.5H12C12.8284%2014.5%2013.5%2013.8284%2013.5%2013V6.41421C13.5%206.01639%2013.342%205.63486%2013.0607%205.35355L9.64645%201.93934C9.36514%201.65803%208.98361%201.5%208.58579%201.5H4ZM3.5%203C3.5%202.72386%203.72386%202.5%204%202.5H8.58579C8.71839%202.5%208.84557%202.55268%208.93934%202.64645L12.3536%206.06066C12.4473%206.15443%2012.5%206.28161%2012.5%206.41421V13C12.5%2013.2761%2012.2761%2013.5%2012%2013.5H4C3.72386%2013.5%203.5%2013.2761%203.5%2013V3Z%22%20fill%3D%22%2362676B%22%2F%3E%3C%2Fsvg%3E"); + --icon-file-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M5%2011.5H10V10.5H5V11.5Z%22%20fill%3D%22%23949A9E%22%2F%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M4%201.5C3.17157%201.5%202.5%202.17157%202.5%203V13C2.5%2013.8284%203.17157%2014.5%204%2014.5H12C12.8284%2014.5%2013.5%2013.8284%2013.5%2013V6.41421C13.5%206.01639%2013.342%205.63486%2013.0607%205.35355L9.64645%201.93934C9.36514%201.65803%208.98361%201.5%208.58579%201.5H4ZM3.5%203C3.5%202.72386%203.72386%202.5%204%202.5H8.58579C8.71839%202.5%208.84557%202.55268%208.93934%202.64645L12.3536%206.06066C12.4473%206.15443%2012.5%206.28161%2012.5%206.41421V13C12.5%2013.2761%2012.2761%2013.5%2012%2013.5H4C3.72386%2013.5%203.5%2013.2761%203.5%2013V3Z%22%20fill%3D%22%23949A9E%22%2F%3E%3C%2Fsvg%3E"); + + /* Themed Menu Icon */ + --icon-menu-light: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M3%206C3.55228%206%204%205.55228%204%205C4%204.44772%203.55228%204%203%204C2.44772%204%202%204.44772%202%205C2%205.55228%202.44772%206%203%206Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M22%205.75H6V4.25H22V5.75Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M22%2012.75H6V11.25H22V12.75Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M16%2019.75H6V18.25H16V19.75Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M4%2012C4%2012.5523%203.55228%2013%203%2013C2.44772%2013%202%2012.5523%202%2012C2%2011.4477%202.44772%2011%203%2011C3.55228%2011%204%2011.4477%204%2012Z%22%20fill%3D%22%2318191B%22%2F%3E%3Cpath%20d%3D%22M3%2020C3.55228%2020%204%2019.5523%204%2019C4%2018.4477%203.55228%2018%203%2018C2.44772%2018%202%2018.4477%202%2019C2%2019.5523%202.44772%2020%203%2020Z%22%20fill%3D%22%2318191B%22%2F%3E%3C%2Fsvg%3E"); + --icon-menu-dark: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%3E%3Cpath%20d%3D%22M3%206C3.55228%206%204%205.55228%204%205C4%204.44772%203.55228%204%203%204C2.44772%204%202%204.44772%202%205C2%205.55228%202.44772%206%203%206Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M22%205.75H6V4.25H22V5.75Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M22%2012.75H6V11.25H22V12.75Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M16%2019.75H6V18.25H16V19.75Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M4%2012C4%2012.5523%203.55228%2013%203%2013C2.44772%2013%202%2012.5523%202%2012C2%2011.4477%202.44772%2011%203%2011C3.55228%2011%204%2011.4477%204%2012Z%22%20fill%3D%22white%22%2F%3E%3Cpath%20d%3D%22M3%2020C3.55228%2020%204%2019.5523%204%2019C4%2018.4477%203.55228%2018%203%2018C2.44772%2018%202%2018.4477%202%2019C2%2019.5523%202.44772%2020%203%2020Z%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E"); + + /* New Look Responsive Mobile First */ + /* Spacing — Metalab 2.0 (mobile) */ + /* xs: 2/2, s: 4/4, default: 8/6, medium: 12/8, large: 16/12, xl: 24/16, xxl: 32/20 */ + --spacing-default: 0.375rem; + --spacing-medium: 0.5rem; + --spacing-large: 0.75rem; + --spacing-xl: 1rem; + --spacing-xxl: 1.25rem; + + /* Corner Radius — Metalab 2.0 (mobile) */ + --radius-xs: var(--corner-radius-xs); + --radius-s: 0.1875rem; + --radius-m: var(--corner-radius-s); + --radius-l: var(--corner-radius-m); + --radius-xl: 0.625rem; + --radius-xxl: var(--corner-radius-xl); + + --leftbar-paddings-leftbar-padding-sm: var(--spacing-size-sm); + --leftbar-paddings-leftbar-padding-md: var(--spacing-size-md); + --leftbar-paddings-leftbar-padding-0: var(--spacing-size-size-0); + --leftbar-paddings-leftbar-padding-lg: var(--spacing-size-lg); + --padding-padding-lg: var(--spacing-size-md); + --padding-padding-sm: var(--spacing-size-xs); + --padding-padding-2sm: var(--spacing-size-2md); + --padding-padding-xs: var(--spacing-size-xs); + --padding-padding-2xs: var(--spacing-size-2xs); + --padding-padding-3xs: var(--spacing-size-3xs); + --padding-padding-xl: var(--spacing-size-xl); + --leftbar-paddings-leftbar-padding-4xs: var(--spacing-size-4xs); + --leftbar-paddings-leftbar-padding-2xs: var(--spacing-size-2xs); + --leftbar-paddings-leftbar-padding-3xs: var(--spacing-size-3xs); + --padding-padding-md: var(--spacing-size-sm); + --main-margin: var(--spacing-size-sm); + --main-max-width-leftbar: 0rem; + --main-content-width: 54rem; + --icons-24: 1.5rem; + --icons-20: 1.25rem; + --icons-16: 1rem; + --icons-12: 0.75rem; + + /* Typography */ + --typography-font-size-3xs: var(--font-size-3xs); + --typography-font-size-2xs: var(--font-size-2xs); + --typography-font-size-xs: var(--font-size-xs); + --typography-font-size-sm: var(--font-size-xs); + --typography-font-size-md: var(--font-size-sm); + --typography-font-size-2md: var(--font-size-2sm); + --typography-font-size-lg: var(--font-size-md); + --typography-font-size-xl: var(--font-size-lg); + --typography-font-size-2xl: var(--font-size-xl); + --typography-font-size-3xl: var(--font-size-2xl); + --typography-font-size-4xl: var(--font-size-3xl); + --typography-font-size-5xl: var(--font-size-4xl); + + /* Heading — Metalab 2.0 (mobile) */ + --typography-font-size-h1: var(--font-size-2xl); + --typography-font-size-h2: var(--font-size-lg); + --typography-font-size-h3: var(--font-size-sm); + --typography-font-size-h4: var(--font-size-xs); + + --typography-line-height-xs: var(--font-line-height-xs); + --typography-line-height-sm: var(--font-line-height-sm); + --typography-line-height-md: var(--font-line-height-md); + --typography-line-height-lg: var(--font-line-height-md); + --typography-line-height-xl: var(--font-line-height-lg); + --typography-line-height-2xl: var(--font-line-height-lg); + --typography-line-height-3xl: var(--font-line-height-2xl); + --typography-line-height-4xl: var(--font-line-height-3xl); + /*----------------- New Look Variables End -----------------*/ +} + +/*----------------- New Look Responsive Desktop Start -----------------*/ +@media (min-width: 768px) { + :root { + /* Spacing — Metalab 2.0 (desktop) */ + --spacing-default: var(--spacing-size-2xs); + --spacing-medium: var(--spacing-size-xs); + --spacing-large: var(--spacing-size-sm); + --spacing-xl: var(--spacing-size-lg); + --spacing-xxl: var(--spacing-size-xl); + + /* Corner Radius — Metalab 2.0 (desktop) */ + --radius-xs: var(--corner-radius-xs); + --radius-s: var(--corner-radius-s); + --radius-m: var(--corner-radius-m); + --radius-l: var(--corner-radius-l); + --radius-xl: var(--corner-radius-xl); + --radius-xxl: var(--corner-radius-xxl); + + --leftbar-paddings-leftbar-padding-sm: var(--spacing-size-sm); + --leftbar-paddings-leftbar-padding-md: var(--spacing-size-md); + --leftbar-paddings-leftbar-padding-0: var(--spacing-size-size-0); + --leftbar-paddings-leftbar-padding-lg: var(--spacing-size-lg); + --padding-padding-lg: var(--spacing-size-lg); + --padding-padding-sm: var(--spacing-size-sm); + --padding-padding-xs: var(--spacing-size-xs); + --padding-padding-2xs: var(--spacing-size-2xs); + --padding-padding-3xs: var(--spacing-size-3xs); + --leftbar-paddings-leftbar-padding-4xs: var(--spacing-size-4xs); + --leftbar-paddings-leftbar-padding-2xs: var(--spacing-size-2xs); + --leftbar-paddings-leftbar-padding-3xs: var(--spacing-size-3xs); + --padding-padding-md: var(--spacing-size-md); + --main-margin: var(--spacing-size-xl); + --main-max-width-leftbar: 18.25rem; + --icons-24: 1.5rem; + --icons-20: 1.25rem; + --icons-16: 1rem; + --icons-12: 0.75rem; + + /* Typography */ + --typography-font-size-3xs: var(--font-size-3xs); + --typography-font-size-2xs: var(--font-size-2xs); + --typography-font-size-xs: var(--font-size-xs); + --typography-font-size-sm: var(--font-size-sm); + --typography-font-size-md: var(--font-size-md); + --typography-font-size-2md: var(--font-size-2md); + --typography-font-size-lg: var(--font-size-lg); + --typography-font-size-xl: var(--font-size-xl); + --typography-font-size-2xl: var(--font-size-2xl); + --typography-font-size-3xl: var(--font-size-3xl); + --typography-font-size-4xl: var(--font-size-4xl); + --typography-font-size-5xl: var(--font-size-5xl); + --typography-line-height-xs: var(--font-line-height-xs); + --typography-line-height-sm: var(--font-line-height-sm); + --typography-line-height-md: var(--font-line-height-md); + --typography-line-height-lg: var(--font-line-height-lg); + --typography-line-height-xl: var(--font-line-height-xl); + --typography-line-height-2xl: var(--font-line-height-2xl); + --typography-line-height-3xl: var(--font-line-height-3xl); + --typography-line-height-4xl: var(--font-line-height-4xl); + + /* Heading — Metalab 2.0 (desktop) */ + --typography-font-size-h1: var(--font-size-3xl); + --typography-font-size-h2: var(--font-size-lg); + --typography-font-size-h3: var(--font-size-md); + --typography-font-size-h4: var(--font-size-sm); + } +} + +@media (min-width: 990px) { + :root { + --main-max-width-leftbar: 21.25rem; + --main-margin: var(--spacing-size-3xl); + } +} + +/*----------------- New Look Responsive Desktop End -----------------*/ + +/*----------------- Root Variables - End -----------------*/ + +/*----------------- HTML Variables - Start -----------------*/ + +/** + * HTML Theme Variables + * These variables are applied to the HTML element and control the active theme. + * The framework supports two themes: + * 1. Light Theme (default) + * 2. Dark Theme (activated by html.dark class) + */ + +/* Light Theme (Default) Configuration */ +html { + /*----------------- New Look Variables Start -----------------*/ + --icon-anchor: var(--icon-anchor-light); + --icon-arrow-left: var(--icon-arrow-left-light); + --icon-arrow-right: var(--icon-arrow-right-light); + --icon-arrow-up: var(--icon-arrow-up-light); + --icon-clipboard: var(--icon-clipboard-light); + --icon-home: var(--icon-home-light); + --icon-file: var(--icon-file-light); + --icon-menu: var(--icon-menu-light); + + --text-buttons-button-label-primary-default: var(--colors-primary-0); + --text-buttons-button-label-secondary-default: var(--colors-primary-900); + --text-buttons-button-label-inactive: var(--colors-primary-500); + + --text-main-text-primary: var(--colors-primary-900); + --text-main-text-link-blue-secondary: var(--colors-secondary-500); + --text-main-text-link-blue-tetriary: var(--colors-secondary-400); + --text-main-text-body-secondary: var(--colors-primary-700); + --text-main-text-body-quaternary: var(--colors-primary-400); + --text-main-text-body-tetriary: var(--colors-primary-600); + --text-main-text-body-primary: var(--colors-primary-650); + --text-main-text-link-blue: var(--colors-secondary-600); + + --text-states-text-warning-tetriary: var(--colors-warning-600); + --text-states-text-warning-secondary: var(--colors-warning-500); + --text-states-text-positive-secondary: var(--colors-positive-500); + --text-states-text-positive-tetriary: var(--colors-positive-600); + --text-states-text-negative-secondary: var(--colors-negative-500); + --text-states-text-negative-tetriary: var(--colors-negative-600); + --text-states-text-warning: var(--colors-warning-400); + --text-states-text-positive: var(--colors-positive-400); + --text-states-text-negative: var(--colors-negative-400); + --text-states-text-additional: var(--colors-secondary-400); + --text-states-text-additional-secondary: var(--colors-secondary-500); + --text-states-text-additional-tetriary: var(--colors-secondary-600); + + --text-code-red: var(--atom-one-light-operator); + --text-code-green: var(--colors-syntax-strong-green); + --text-code-blue: var(--colors-syntax-strong-blue); + --text-code-yellow: var(--colors-syntax-strong-yellow); + --text-code-pink: var(--colors-syntax-strong-pink); + --text-code-grey: var(--colors-syntax-strong-grey); + --text-code-purple: var(--atom-one-light-keyword); + --text-code-turquoise: var(--atom-one-light-constant); + --text-code-neutral: var(--atom-one-light-text); + --text-code-navy: var(--atom-one-light-class); + + --surface-background-states-surface-error-weak: var(--colors-error-weak); + --text-states-text-error-strong: var(--colors-error-strong); + --text-states-text-error-mid: var(--colors-error-mid); + + --surface-accent-teal-weak: var(--colors-accent-weak-teal); + --surface-accent-yellow-weak: var(--colors-accent-weak-yellow); + --surface-accent-green-weak: var(--colors-accent-weak-green); + --surface-accent-teal-strong: var(--colors-accent-strong-teal); + --surface-accent-yellow-strong: var(--colors-accent-strong-yellow); + --surface-accent-green-strong: var(--colors-accent-strong-green); + + --surface-button-button-bg-secondary-ta-default: var(--colors-brand-orange-400); + --surface-button-button-bg-primary-default: var(--colors-secondary-700); + --surface-button-button-bg-primary-pressed: var(--colors-secondary-700); + --surface-button-button-bg-primary-inactive: var(--colors-primary-200); + --surface-button-button-bg-secondary-cta-hover: var(--colors-brand-orange-500); + --surface-button-button-bg-primary-hover: var(--colors-secondary-800); + --surface-button-button-bg-secondary-cta-pressed: var(--colors-brand-orange-400); + --surface-button-button-bg-secondary-cta-inactive: var(--colors-primary-200); + + --surface-page: #F7FDFE; + --surface-background-main-base-primary: var(--surface-page); + --surface-background-main-surface-primary: var(--colors-primary-50); + --surface-background-main-surface-secondary: var(--colors-primary-100); + --surface-background-main-surface-tetriary: var(--colors-primary-150); + --surface-background-main-surface-blue-primary: var(--colors-secondary-0); + --surface-background-main-surface-blue-secondary: var(--colors-secondary-50); + --surface-background-main-surface-blue-tetriary: var(--colors-secondary-100); + --surface-background-main-surface-blue-quaternary: var(--colors-secondary-200); + --surface-background-main-surface-transparent: var(--colors-overlay-overlay-white-64); + --surface-background-main-surface-transparent-inverse: var(--colors-overlay-overlay-black-40); + --surface-background-main-surface-transparent-secondary: var(--colors-overlay-overlay-white-88); + + --surface-background-states-surface-warning-primary: var(--colors-warning-0); + --surface-background-states-surface-warning-secondary: var(--colors-warning-100); + --surface-background-states-surface-warning-tetriary: var(--colors-warning-200); + --surface-background-states-surface-warning-quaternary: var(--colors-warning-300); + --surface-background-states-surface-positive-primary: var(--colors-positive-50); + --surface-background-states-surface-positive-secondary: var(--colors-positive-100); + --surface-background-states-surface-positive-tetriary: var(--colors-positive-200); + --surface-background-states-surface-positive-quaternary: var(--colors-positive-300); + --surface-background-states-surface-negative-primary: var(--colors-negative-50); + --surface-background-states-surface-negative-secondary: var(--colors-negative-100); + --surface-background-states-surface-negative-tetriary: var(--colors-negative-200); + --surface-background-states-surface-negative-quaternary: var(--colors-negative-300); + --surface-background-states-surface-additional-secondary: var(--colors-secondary-100); + --surface-background-states-surface-additional-tetriary: var(--colors-secondary-200); + --surface-background-states-surface-additional-quaternary: var(--colors-secondary-300); + + --surface-icons-icon-primary: var(--colors-primary-900); + --surface-icons-icon-button-primary: var(--colors-primary-0); + --surface-icons-icon-button-secondary: var(--colors-primary-900); + --surface-icons-icon-button-inactive: var(--colors-primary-500); + --surface-icons-icon-secondary: var(--colors-primary-600); + --surface-icons-icon-quaternary: var(--colors-primary-200); + --surface-icons-icon-cta: var(--colors-brand-orange-500); + --surface-icons-icon-hover: var(--colors-brand-orange-400); + --surface-icons-icon-tetriary: var(--colors-primary-400); + --surface-icons-icon-warning: var(--colors-warning-600); + --surface-icons-icon-positive: var(--colors-positive-600); + --surface-icons-icon-negative: var(--colors-negative-600); + --surface-icons-icon-brand-orange: var(--colors-brand-orange-600); + --surface-icons-icon-blue: var(--colors-secondary-600); + --surface-icons-icon-blue-light: var(--colors-secondary-200); + + --border-border-primary: var(--colors-primary-100); + --border-border-secondary: var(--colors-primary-150); + --border-border-tetriary: var(--colors-primary-300); + --border-border-quaternary: var(--colors-primary-600); + --border-border-active: var(--colors-primary-900); + --border-border-brand-orange: var(--colors-brand-orange-200); + --border-border-warning: var(--colors-warning-200); + --border-border-positive: var(--colors-positive-200); + --border-border-negative: var(--colors-negative-200); + --border-border-blue: var(--colors-secondary-200); + --border-border-blue-primary: var(--colors-secondary-100); + --border-border-blue-hover: var(--colors-secondary-400); + + /*----------------- New Look Variables End -----------------*/ +} + +/* Dark Theme Configuration */ +html.dark { + /*----------------- New Look Variables Dark Mode Start -----------------*/ + --icon-anchor: var(--icon-anchor-dark); + --icon-arrow-left: var(--icon-arrow-left-dark); + --icon-arrow-right: var(--icon-arrow-right-dark); + --icon-arrow-up: var(--icon-arrow-up-dark); + --icon-clipboard: var(--icon-clipboard-dark); + --icon-home: var(--icon-home-dark); + --icon-file: var(--icon-file-dark); + --icon-menu: var(--icon-menu-dark); + + --text-buttons-button-label-primary-default: var(--colors-primary-0); + --text-buttons-button-label-secondary-default: var(--colors-primary-950); + --text-buttons-button-label-inactive: var(--colors-primary-500); + + --text-main-text-primary: var(--colors-primary-0); + --text-main-text-link-blue-secondary: var(--colors-secondary-500); + --text-main-text-link-blue-tetriary: var(--colors-secondary-600); + --text-main-text-link-blue: var(--colors-secondary-400); + --text-main-text-body-secondary: var(--colors-primary-200); + --text-main-text-body-tetriary: var(--colors-primary-300); + --text-main-text-body-quaternary: var(--colors-primary-600); + --text-main-text-body-primary: var(--colors-primary-50); + + --text-states-text-warning-tetriary: var(--colors-warning-400); + --text-states-text-warning-secondary: var(--colors-warning-500); + --text-states-text-warning: var(--colors-warning-600); + --text-states-text-positive-secondary: var(--colors-positive-500); + --text-states-text-positive-tetriary: var(--colors-positive-400); + --text-states-text-positive: var(--colors-positive-600); + --text-states-text-negative-secondary: var(--colors-negative-500); + --text-states-text-negative-tetriary: var(--colors-negative-400); + --text-states-text-negative: var(--colors-negative-600); + --text-states-text-additional: var(--colors-secondary-600); + --text-states-text-additional-secondary: var(--colors-secondary-500); + --text-states-text-additional-tetriary: var(--colors-secondary-400); + + --text-code-red: var(--atom-one-dark-operator); + --text-code-green: var(--colors-syntax-weak-green); + --text-code-blue: var(--colors-syntax-weak-blue); + --text-code-yellow: var(--colors-syntax-weak-yellow); + --text-code-pink: var(--colors-syntax-weak-pink); + --text-code-grey: var(--colors-syntax-weak-grey); + --text-code-purple: var(--atom-one-dark-keyword); + --text-code-turquoise: var(--atom-one-dark-constant); + --text-code-neutral: var(--atom-one-dark-text); + --text-code-navy: var(--atom-one-dark-class); + + --surface-background-states-surface-error-weak: var(--colors-error-strong); + --text-states-text-error-strong: var(--colors-error-mid); + --text-states-text-error-mid: var(--colors-error-mid); + + --surface-accent-teal-weak: var(--colors-accent-strong-teal); + --surface-accent-yellow-weak: var(--colors-accent-strong-yellow); + --surface-accent-green-weak: var(--colors-accent-strong-green); + --surface-accent-teal-strong: var(--colors-accent-weak-teal); + --surface-accent-yellow-strong: var(--colors-accent-weak-yellow); + --surface-accent-green-strong: var(--colors-accent-weak-green); + + --surface-button-button-bg-secondary-ta-default: var(--colors-brand-orange-500); + --surface-button-button-bg-primary-default: var(--colors-secondary-800); + --surface-button-button-bg-primary-pressed: var(--colors-secondary-800); + --surface-button-button-bg-primary-inactive: var(--colors-primary-800); + --surface-button-button-bg-secondary-cta-hover: var(--colors-brand-orange-400); + --surface-button-button-bg-primary-hover: var(--colors-secondary-700); + --surface-button-button-bg-secondary-cta-pressed: var(--colors-brand-orange-500); + --surface-button-button-bg-secondary-cta-inactive: var(--colors-primary-800); + + --surface-page: var(--colors-primary-950); + --surface-background-main-base-primary: var(--surface-page); + --surface-background-main-surface-primary: var(--colors-primary-900); + --surface-background-main-surface-secondary: var(--colors-primary-850); + --surface-background-main-surface-tetriary: var(--colors-primary-800); + --surface-background-main-surface-blue-primary: var(--colors-secondary-900); + --surface-background-main-surface-blue-secondary: var(--colors-secondary-900); + --surface-background-main-surface-blue-tetriary: var(--colors-secondary-850); + --surface-background-main-surface-blue-quaternary: var(--colors-secondary-800); + --surface-background-main-surface-transparent: var(--colors-overlay-overlay-black-64); + --surface-background-main-surface-transparent-inverse: var(--colors-overlay-overlay-white-40); + --surface-background-main-surface-transparent-secondary: var(--colors-overlay-overlay-black-88); + + --surface-background-states-surface-warning-primary: var(--colors-warning-950); + --surface-background-states-surface-warning-secondary: var(--colors-warning-950); + --surface-background-states-surface-warning-tetriary: var(--colors-warning-800); + --surface-background-states-surface-warning-quaternary: var(--colors-warning-700); + --surface-background-states-surface-positive-primary: var(--colors-positive-950); + --surface-background-states-surface-positive-secondary: var(--colors-positive-950); + --surface-background-states-surface-positive-tetriary: var(--colors-positive-800); + --surface-background-states-surface-positive-quaternary: var(--colors-positive-700); + --surface-background-states-surface-negative-primary: var(--colors-negative-950); + --surface-background-states-surface-negative-secondary: var(--colors-negative-950); + --surface-background-states-surface-negative-tetriary: var(--colors-negative-800); + --surface-background-states-surface-negative-quaternary: var(--colors-negative-700); + --surface-background-states-surface-additional-secondary: var(--colors-secondary-950); + --surface-background-states-surface-additional-tetriary: var(--colors-secondary-800); + --surface-background-states-surface-additional-quaternary: var(--colors-secondary-700); + + --surface-icons-icon-primary: var(--colors-primary-0); + --surface-icons-icon-button-primary: var(--colors-primary-0); + --surface-icons-icon-button-secondary: var(--colors-primary-950); + --surface-icons-icon-button-inactive: var(--colors-primary-600); + --surface-icons-icon-secondary: var(--colors-primary-400); + --surface-icons-icon-quaternary: var(--colors-primary-600); + --surface-icons-icon-cta: var(--colors-brand-orange-500); + --surface-icons-icon-hover: var(--colors-brand-orange-600); + --surface-icons-icon-warning: var(--colors-warning-400); + --surface-icons-icon-positive: var(--colors-positive-400); + --surface-icons-icon-negative: var(--colors-negative-400); + --surface-icons-icon-brand-orange: var(--colors-brand-orange-400); + --surface-icons-icon-blue: var(--colors-secondary-400); + --surface-icons-icon-blue-light: var(--colors-secondary-700); + + --border-border-primary: var(--colors-primary-850); + --border-border-secondary: var(--colors-primary-800); + --border-border-tetriary: var(--colors-primary-700); + --border-border-quaternary: var(--colors-primary-500); + --border-border-active: var(--colors-primary-0); + --border-border-brand-orange: var(--colors-brand-orange-900); + --border-border-warning: var(--colors-warning-800); + --border-border-positive: var(--colors-positive-800); + --border-border-negative: var(--colors-negative-800); + --border-border-blue: var(--colors-secondary-700); + --border-border-blue-primary: var(--colors-secondary-850); + --border-border-blue-hover: var(--colors-secondary-500); + + /*----------------- New Look Variables Dark Mode Start -----------------*/ +} + +/*----------------- HTML Variables - End -----------------*/ + +/* Override for Antora default styles */ +html:has(.boostlook) { + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-size: 1rem; + height: 100%; + scroll-behavior: smooth; +} + +/*----------------- Font-Face Declarations start -----------------*/ + +/** + * Typography Configuration + * The framework uses Noto Sans family as its primary font system: + * 1. Noto Sans Display: Main text font with variable weight support + * 2. Monaspace Neon: Monospace font for code blocks + * + * Font Loading Strategy: + * - Multiple source paths for resilient loading + * - Variable fonts for optimal performance + * - Font-display: block to prevent FOIT (Flash of Invisible Text) + */ + +/* Noto Sans Display - Regular */ +@font-face { + font-family: "Noto Sans"; + font-style: normal; + font-weight: 100 900; + font-stretch: 62.5% 100%; + font-variation-settings: "wght" 400, "wdth" 62.5; + font-display: block; + src: url("../font/NotoSansDisplay.ttf") format("truetype"), + url("/static/font/notosans.woff2") format("woff2"), + url("../../../../tools/boostlook/notosans.woff2") format("woff2"), + url("https://cppalliance.org/fonts/NotoSansDisplay.ttf") format("truetype"); + size-adjust: 100%; + ascent-override: 92%; + descent-override: 22%; + line-gap-override: 0%; +} + +/* Noto Sans Display - Italic */ +@font-face { + font-family: "Noto Sans"; + font-style: italic; + font-weight: 100 900; + font-stretch: 62.5% 100%; + font-variation-settings: "wght" 400, "wdth" 62.5; + font-display: block; + src: url("../font/NotoSansDisplay-Italic.ttf") format("truetype"), + url("/static/font/notosans_ext.woff2") format("woff2"), + url("../../../../tools/boostlook/notosans_ext.woff2") format("woff2"), + url("https://cppalliance.org/fonts/NotoSansDisplay-Italic.ttf") format("truetype"); + size-adjust: 100%; + ascent-override: 92%; + descent-override: 22%; + line-gap-override: 0%; +} + +/* Monaspace Neon - Regular */ +@font-face { + font-family: "Monaspace Neon"; + font-style: normal; + font-weight: 400; + font-display: block; + src: url("../font/MonaspaceNeonFrozen-Regular.ttf") format("truetype"), + url("/static/font/MonaspaceNeon-Var.woff2") format("woff2"), + url("../../../../tools/boostlook/MonaspaceNeon-Var.woff2") format("woff2"), + url("https://cppalliance.org/fonts/MonaspaceNeon-Var.woff2") format("woff2"); + size-adjust: 100%; + ascent-override: 92%; + descent-override: 22%; + line-gap-override: 0%; +} + +/* Monaspace Xenon - Italic */ +@font-face { + font-family: "Monaspace Xenon"; + font-style: italic; + font-weight: 400; + font-display: block; + src: url("../font/MonaspaceXenonFrozen-Italic.ttf") format("truetype"), + url("/static/font/MonaspaceXenon-Var.woff2") format("woff2"), + url("../../../../tools/boostlook/MonaspaceXenon-Var.woff2") format("woff2"), + url("https://cppalliance.org/fonts/MonaspaceXenon-Var.woff2") format("woff2"); + size-adjust: 100%; + ascent-override: 92%; + descent-override: 22%; + line-gap-override: 0%; +} + +/*----------------- Font-Face Declarations end -----------------*/ + +/*----------------- CSS Reset start -----------------*/ + +/** + * Modern CSS Reset + * A minimal CSS reset that: + * 1. Uses the modern box-sizing model + * 2. Removes default margins + * 3. Improves text rendering + * 4. Ensures responsive media elements + * 5. Normalizes form elements + * 6. Prevents text overflow issues + * 7. Provides a proper stacking context + * 8. Resets legacy table and adjacent element styles + */ + +/* Box sizing rules */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +/* Remove default margin */ +* { + margin: 0; +} + +html body { + margin: 0; +} + +/* Body defaults */ +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; + margin: 0; + /* Improves text rendering on WebKit */ +} + +/* Media elements */ +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; + /* Responsive media elements */ +} + +/* Form elements */ +input, +button, +textarea, +select { + font: inherit; + /* Inherit typography */ +} + +/* Text elements */ +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; + /* Prevent text overflow */ +} + +body :not(pre):not([class^="L"]) > code { + /* overrides builtin colors */ + color: var(--text-code-neutral, #0d0e0f); + border: 0; + background-color: unset; +} + +/* Stacking context */ +#root, +#__next { + isolation: isolate; + /* Create new stacking context */ +} + +/* Reset Legacy Table and Next to Table Element Styles */ +.boostlook .tablecontainer, +.boostlook .tablecontainer + *, +.boostlook :not(.tablecontainer) > table.tableblock, +.boostlook :not(.tablecontainer) > table.tableblock + *, +.boostlook .doc .tablecontainer, +.boostlook .doc .tablecontainer + *, +.boostlook .doc :not(.tablecontainer) > table.tableblock, +.boostlook .doc :not(.tablecontainer) > table.tableblock + *, +.boostlook.boostlook:not(:has(.doc)) table.table, +.boostlook.boostlook:not(:has(.doc)) table.table + * { + margin: revert; +} + +.boostlook .underline:has(> code:only-child) { + text-decoration-line: none; +} + +/*----------------- CSS Reset end -----------------*/ + +/*----------------- Global Styles for .boostlook start -----------------*/ + +/** + * Global Styles for .boostlook + * Core styles that apply to all .boostlook containers regardless of template. + * These styles establish: + * 1. Base container styling + * 2. Typography hierarchy and spacing + * 3. Link appearances and interactions + * 4. Code block formatting and syntax highlighting + * 5. List and table styles + * 6. Special block elements (quotes, admonitions, etc.) + * 7. Pagination and navigation elements + * 8. Layout structure and spacing + */ + +/* Base Container */ +.boostlook { + font-family: var(--font-family-body, "Noto Sans") !important; + font-variation-settings: "wght" 400, "wdth" 95; + line-height: 120%; + letter-spacing: -0.01em; + color: var(--text-main-text-body-secondary, #585A64); + background: var(--surface-background-main-base-primary, #fff); +} + +/* Typography Hierarchy + * Establishes consistent heading sizes and spacing + * while maintaining proper visual hierarchy + */ +.boostlook h1, +.boostlook .doc h1, +.boostlook h2, +.boostlook .doc h2, +.boostlook h3, +.boostlook .doc h3, +.boostlook h4, +.boostlook .doc h4, +.boostlook h5, +.boostlook .doc h5, +.boostlook h6, +.boostlook .doc h6 { + color: var(--text-main-text-primary, #050816); + display: block; + font-family: var(--font-family-body, "Noto Sans"); + line-height: 100%; + margin-top: var(--padding-padding-lg, 1.5rem); + margin-bottom: 0.5rem; + font-weight: 500; + font-variation-settings: "wght" 500, "wdth" 87.5; + position: relative; +} + +/* Heading Sizes — Metalab 2.0 */ +/* h1: Display/Desktop/Medium/3XL */ +.boostlook h1, +.boostlook .doc h1 { + font-size: var(--typography-font-size-h1, 2rem); + letter-spacing: -0.01em; +} + +/* h2: Display/Desktop/Medium/Large */ +.boostlook h2, +.boostlook .doc h2 { + font-size: var(--typography-font-size-h2, 1.25rem); + letter-spacing: -0.01em; +} + +/* h3: Display/Desktop/Medium/M */ +.boostlook h3, +.boostlook .doc h3 { + font-size: var(--typography-font-size-h3, 1.125rem); + letter-spacing: -0.01em; +} + +/* h4: Display/Desktop/Medium/Base */ +.boostlook h4, +.boostlook .doc h4 { + font-size: var(--typography-font-size-h4, 1rem); + letter-spacing: -0.16px; +} + +/* h5 */ +.boostlook h5, +.boostlook .doc h5 { + font-size: var(--font-size-xs, 0.875rem); + letter-spacing: -0.14px; +} + +/* h6 */ +.boostlook h6, +.boostlook .doc h6 { + font-size: var(--font-size-2xs, 0.75rem); + letter-spacing: -0.12px; +} + +/* Document-specific headings adjustments */ +.boostlook .doc h2:not(.discrete) { + /* website-v2-doc styles overrides */ + margin-left: 0; + padding-left: 0; + border-bottom: revert; + margin-right: revert; + padding: revert; +} + +.boostlook h2:has(+ .sectionbody > .sect2:first-child > h3), +.boostlook .doc h2:has(+ .sectionbody > .sect2:first-child > h3) { + margin-bottom: 0; +} + +.boostlook h3:has(+ .sect3 > h4:first-child), +.boostlook .doc h2:has(+ .sect3 > h4:first-child) { + margin-bottom: 0; +} + +/* Override default docs site css */ +.boostlook .doc .dlist, +.boostlook .doc .exampleblock, +.boostlook .doc .hdlist, +.boostlook .doc .imageblock, +.boostlook .doc .listingblock, +.boostlook .doc .literalblock, +.boostlook .doc .olist, +.boostlook .doc .paragraph, +.boostlook .doc .partintro, +.boostlook .doc .quoteblock, +.boostlook .doc .sidebarblock, +.boostlook .doc .tabs, +.boostlook .doc .ulist, +.boostlook .doc .verseblock, +.boostlook .doc .videoblock, +.boostlook .doc details, +.boostlook .doc hr { + margin: revert; +} + +/* Anchor positioning within headings */ +.boostlook .doc h1:has(.anchor), +.boostlook .doc h2:has(.anchor), +.boostlook .doc h3:has(.anchor), +.boostlook .doc h4:has(.anchor), +.boostlook .doc h5:has(.anchor), +.boostlook .doc h6:has(.anchor), +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) { + display: inline-block; + /* Anchor width and spacing compensation */ + padding-right: 3rem; +} + +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href] { + text-decoration: none; + color: inherit; +} + +/* Heading Anchors */ +.boostlook .doc h1 .anchor, +.boostlook .doc h2 .anchor, +.boostlook .doc h3 .anchor, +.boostlook .doc h4 .anchor, +.boostlook .doc h5 .anchor, +.boostlook .doc h6 .anchor, +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[id], +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href]:before { + position: absolute; + top: 50%; + right: 0; + display: flex; + align-items: center; + justify-content: center; + margin-left: revert; + width: 2rem; + height: 2rem; + border: 1px; + visibility: hidden; + opacity: 0; + text-decoration: none; + border-radius: var(--spacing-size-lg, 1.5rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + background: var(--surface-background-main-base-primary, #fff); + transform: translateY(-50%); + transition: all 0.2s ease; +} + +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[id] { + visibility: visible; +} +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href]:before { + content: ""; +} + +.boostlook .doc h1 .anchor::before, +.boostlook .doc h2 .anchor::before, +.boostlook .doc h3 .anchor::before, +.boostlook .doc h4 .anchor::before, +.boostlook .doc h5 .anchor::before, +.boostlook .doc h6 .anchor::before, +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href]:after { + content: var(--icon-anchor); + display: block; + line-height: 1; + opacity: 0.6; + transition: opacity 0.3s ease; +} + +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href]:after { + position: absolute; + top: 50%; + right: 0; + width: 2rem; + height: 2rem; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + visibility: hidden; + line-height: 0; + transform: translateY(-50%); + transition: all 0.2s ease; +} + +.doc h1:hover .anchor, +.doc h2:hover .anchor, +.doc h3:hover .anchor, +.doc h4:hover .anchor, +.doc h5:hover .anchor, +.doc h6:hover .anchor, +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]):hover a[href]:before { + opacity: 1; + visibility: visible; +} + +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]):hover a[href]:after { + opacity: 0.6; + visibility: visible; +} + +.boostlook .doc h1 .anchor:hover, +.boostlook .doc h2 .anchor:hover, +.boostlook .doc h3 .anchor:hover, +.boostlook .doc h4 .anchor:hover, +.boostlook .doc h5 .anchor:hover, +.boostlook .doc h6 .anchor:hover, +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]:hover) a[href]:before { + border-color: var(--border-border-blue, #92cbe9); +} + +.boostlook .doc h1 .anchor:active, +.boostlook .doc h2 .anchor:active, +.boostlook .doc h3 .anchor:active, +.boostlook .doc h4 .anchor:active, +.boostlook .doc h5 .anchor:active, +.boostlook .doc h6 .anchor:active, +.boostlook :where(h1, h2, h3, h4, h5, h6):has(> a[id]):has(> a[href]) a[href]:active:before { + border-color: var(--border-border-blue, #92cbe9); + background: var(--surface-background-main-surface-blue-secondary, #daeef9); +} + +.boostlook .doc h1 .anchor:hover::before, +.boostlook .doc h2 .anchor:hover::before, +.boostlook .doc h3 .anchor:hover::before, +.boostlook .doc h4 .anchor:hover::before, +.boostlook .doc h5 .anchor:hover::before, +.boostlook .doc h6 .anchor:hover::before { + opacity: 1; +} + +/* Paragraph Styling — Metalab 2.0: Sans/Desktop/Regular/Base/Tight */ +.boostlook p { + padding-top: initial !important; + padding-bottom: initial !important; + color: var(--text-main-text-body-secondary, #585A64); + font-size: var(--typography-font-size-sm, 1rem); + line-height: 120%; + letter-spacing: -0.16px; +} + +/* Components margins */ +.boostlook .paragraph + .paragraph { + margin-top: var(--padding-padding-md, 1rem); +} + +.boostlook:not(:has(.doc)) .section > p + p, +.boostlook:not(:has(.doc)) .chapter > p + p, +.boostlook div.blockquote blockquote p + p, +.boostlook#libraryReadMe > p:not(:first-child) + p, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > p + p, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > p + p, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > p + p { + margin-top: var(--padding-padding-3xs, 0.25rem); +} +.boostlook #content .admonitionblock + .tabs, +.boostlook .paragraph + .tabs { + margin-top: var(--spacing-size-2md, 1.3rem); +} + +.boostlook #content .paragraph + .admonitionblock, +.boostlook #content .tabs + .paragraph, +.boostlook #content .colist + .paragraph, +.boostlook #content .admonitionblock + .admonitionblock, +.boostlook #content .olist + .admonitionblock, +.boostlook #content .olist + .paragraph, +.boostlook:not(:has(.doc)) div.orderedlist + p, +.boostlook:not(:has(.doc)) p + div.orderedlist, +.boostlook:not(:has(.doc)) .itemizedlist + p, +.boostlook:not(:has(.doc)) div.itemizedlist:has(+ a[id^="bind"]) + a + *, +.boostlook:not(:has(.doc)) div.table:has(+ .table-break) + .table-break + *, +.boostlook #content .paragraph + .olist, +.boostlook #content .ulist + .admonitionblock, +.boostlook #content .ulist + .paragraph, +.boostlook #content .colist + .admonitionblock, +.boostlook #content .admonitionblock + .paragraph, +.boostlook #content .paragraph + table.tableblock, +.boostlook.boostlook:not(:has(.doc)) p + table.table, +.boostlook.boostlook:not(:has(.doc)) p + .informaltable, +.boostlook #content table.tableblock + .paragraph, +.boostlook #content table.tableblock + .admonitionblock, +.boostlook:not(:has(.doc)) .informaltable + p, +.boostlook #content .imageblock + .paragraph, +.boostlook:not(:has(.doc)) .inlinemediaobject + p, +.boostlook:not(:has(.doc)) p:has(> .inlinemediaobject:only-child) + p, +.boostlook#libraryReadMe > p + table, +.boostlook#libraryReadMe > table + p, +.boostlook#libraryReadMe > ul + p, +.boostlook#libraryReadMe .literalblock + .paragraph, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]) + p, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class]) + p, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class]) + p { + margin-top: var(--padding-padding-xs, 0.75rem); +} + +.boostlook #content .dlist + .paragraph, +.boostlook #content .dlist + .listingblock, +.boostlook:not(:has(.doc)) div.blockquote + p, +.boostlook:not(:has(.doc)) .variablelist + p { + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook h2 + .tabs, +.boostlook .doc h2 + .tabs, +.boostlook h3 + .tabs, +.boostlook .doc h3 + .tabs, +.boostlook h4 + .tabs, +.boostlook .doc h4 + .tabs, +.boostlook h5 + .tabs, +.boostlook .doc h5 + .tabs, +.boostlook h5 + .tabs, +.boostlook .doc h6 + .tabs { + margin-top: var(--padding-padding-sm, 0.75rem); +} + +.boostlook #content .sectionbody .olist:first-child, +.boostlook:not(:has(.doc)) .section div.orderedlist:first-child { + margin-top: var(--padding-padding-3xs, 0.25rem); +} + +.boostlook .olist .imageblock .content, +.boostlook .ulist .imageblock .content { + margin-bottom: var(--padding-padding-xs, 0.75rem); +} + +/* Special paragraph cases */ +.boostlook table p, +.boostlook ul p { + margin: 0; +} + +/* Link Styling */ +.boostlook a, +.boostlook .doc a { + color: var(--text-main-text-link-blue, #026a9f); + text-decoration: none; + transition: color 0.3s ease; +} + +/* Link Hover States */ +.boostlook a:hover, +.boostlook .doc a:hover { + color: var(--text-states-text-warning, #FF9442); + cursor: pointer; +} + +/* Emphasis within code */ +.boostlook code em, +.boostlook code i, +.boostlook pre em, +.boostlook pre i { + font-family: "Monaspace Xenon", monospace; + font-size: inherit; + font-style: italic; +} + +.boostlook em { + font-family: inherit; + font-size: inherit; + font-style: italic; +} + +/* Text Emphasis */ +.boostlook b, +.boostlook strong { + font-variation-settings: "wght" 600, "wdth" 87.5; + text-shadow: none; +} + +/* Comments within code (inline and blocks) */ +.boostlook code span.c, +.boostlook code span.ch, +.boostlook code span.cm, +.boostlook code span.cp, +.boostlook code span.cpf, +.boostlook code span.c1, +.boostlook code span.cs, +.boostlook code span.comment { + font-family: "Monaspace Xenon", monospace; + font-style: italic; +} + +/* Code Block Styling */ +.boostlook .doc .listingblock, +.boostlook .listingblock { + position: relative; +} + +.boostlook .doc .listingblock code, +.boostlook .listingblock code { + display: initial; +} + +.boostlook .hljs { + background: transparent; +} + +.boostlook code { + font-family: var(--font-family-code, "Monaspace Neon"), monospace; +} + +.boostlook table thead code { + background: inherit; +} + +.boostlook pre code, +.boostlook pre code.hljs, +.boostlook .doc .content pre code, +.boostlook .doc pre.highlight code { + font-size: var(--typography-font-size-xs, 0.875rem); + font-feature-settings: "calt" 1, "liga" 0; + line-height: var(--typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + color: var(--text-main-text-primary, #18191b); + padding: revert; + border: none; +} + +.boostlook pre code .conum[data-value]::after, +.boostlook pre code.hljs .conum[data-value]::after, +.boostlook .doc .content pre code .conum[data-value]::after, +.boostlook .doc pre.highlight code .conum[data-value]::after { + content: "("attr(data-value)")"; +} + +.boostlook pre:not(:has(> code)), +.boostlook pre:not(:has(> code)):has(p, span) { + font-size: var(--typography-font-size-xs, 0.875rem); + line-height: var(--typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +.boostlook pre, +.boostlook pre.rouge, +.boostlook .doc .content pre, +.boostlook .doc pre.highlight, +.boostlook .doc .listingblock pre:not(.highlight), +.boostlook .doc .literalblock pre +.boostlook .literalblock pre, +.boostlook .listingblock > .content > pre, +.boostlook .listingblock > .content > pre:not(.highlight), +.boostlook .literalblock > .content > pre:not(.highlight), +.boostlook .exampleblock > .content, +.boostlook .sidebarblock { + padding: var(--spacing-size-xs, 0.75rem) var(--spacing-size-sm, 1rem); + background: var(--atom-one-light-bg, #fafafa) !important; + border-radius: var(--radius-xxl, 1rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + box-shadow: none; +} + +.boostlook .sidebarblock { + margin-top: 20px; + border: 1px solid var(--border-border-secondary, #d5d7d9); +} + +/* Dark theme code block background */ +html.dark .boostlook pre, +html.dark .boostlook pre.rouge, +html.dark .boostlook .doc .content pre, +html.dark .boostlook .doc pre.highlight, +html.dark .boostlook .doc .listingblock pre:not(.highlight), +html.dark .boostlook .doc .literalblock pre, +html.dark .boostlook#libraryReadMe > pre:not(:last-child), +html.dark .boostlook#libraryReadMe div.highlight:has(> pre):not(:is(dd pre, td pre)), +html.dark .boostlook .doc .literalblock pre, +html.dark .boostlook .literalblock pre, +html.dark .boostlook .literalblock > .content > pre:not(.highlight), +html.dark .boostlook .listingblock > .content > pre, +html.dark .boostlook .sidebarblock, +html.dark .boostlook .exampleblock > .content, +html.dark .boostlook .listingblock > .content > pre { + background: var(--atom-one-dark-bg, #282c34) !important; +} + +.boostlook .doc pre { + padding: initial; +} + +.boostlook .content:has(> pre), +.boostlook .content:has(> pre.highlight) { + border-radius: 0; + /*border: 1px solid var(--border-border-secondary, #d5d7d9);*/ + background: none; +} + +.boostlook pre.programlisting, +.boostlook pre.synopsis, +.boostlook pre.literallayout, +.boostlook#libraryReadMe > pre { + border: 1px solid var(--border-border-secondary, #d5d7d9); +} + +/* Code Block Regular Title */ +.boostlook .doc .listingblock .title, +.boostlook .listingblock .title { + color: var(--text-main-text-body-primary, #2a2c30); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + font-variation-settings: "wght" 600, "wdth" 87.5; + line-height: var(--typography-line-height-md, 1.25rem); + letter-spacing: unset; + padding-bottom: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook .doc .listingblock .title a, +.boostlook .listingblock .title a { + font: inherit; + text-decoration: none; +} + +/* Code Block Title With File Name. + * Applies only if codeblock has child with class .toolbox + * and it`s title doesn`t includes any other elems as children +*/ +.boostlook .doc .listingblock:has(.source-toolbox) .title:not(:has(a, span, p, code, pre)), +.boostlook .listingblock:has(.source-toolbox) .title:not(:has(a, span, p, code, pre)) { + position: absolute; + top: 1px; + height: 2rem; + max-width: calc(100% - 5rem); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 0; + padding-left: var(--spacing-size-sm); + display: flex; + align-items: center; + gap: var(--spacing-size-2xs, 0.5rem); + color: var(--text-main-text-body-tetriary, #62676b); + font-family: "Noto Sans"; + font-size: var(--typography-font-size-2xs, 0.75rem); + font-style: normal; + line-height: var(--typography-line-height-sm, 1rem); + letter-spacing: var(--spacing-size-size-0, 0rem); + z-index: 1; + display: none; +} + +.boostlook .doc .listingblock:has(.source-toolbox) .title:not(:has(a, span, p, code, pre))::before, +.boostlook .listingblock:has(.source-toolbox) .title:not(:has(a, span, p, code, pre))::before { + content: var(--icon-file); + line-height: 0; +} + +/* Code Block Margins */ +.boostlook .listingblock:has(> .content > pre), +.boostlook .listingblock:has(> .content > pre.highlight), +.boostlook:not(:has(.doc)) pre.programlisting, +.boostlook:not(:has(.doc)) pre.synopsis, +.boostlook#libraryReadMe > pre, +.boostlook#libraryReadMe .literalblock:has(pre), +.boostlook#libraryReadMe div.highlight:has(> pre) { + margin: 0; + border: none; + background-color: transparent; + padding:0; +} + +/* Apply left margin only if code block not in definition block or in table */ +.boostlook:not(:has(.doc)) pre.programlisting:not(:is(dd pre, td pre)), +.boostlook:not(:has(.doc)) pre.synopsis:not(:is(dd pre, td pre)), +.boostlook#libraryReadMe > pre:not(:is(dd pre, td pre)), +.boostlook#libraryReadMe .literalblock:has(pre):not(:is(dd pre, td pre)), +.boostlook#libraryReadMe div.highlight:has(> pre):not(:is(dd pre, td pre)) { + /*margin-left: var(--spacing-size-xl);*/ + /*border: 1px solid var(--border-border-secondary, #d5d7d9);*/ + background: var(--atom-one-light-bg, #fafafa); + margin-top: var(--padding-padding-xs, 0.75rem); +} + +.boostlook#libraryReadMe .literalblock:has(pre):not(:is(dd pre, td pre)) { + margin-left: var(--spacing-size-xl); + border: 1px solid var(--border-border-secondary, #d5d7d9); +} +.boostlook .olist.arabic > ol > li .listingblock:has(> .content > pre):not(:is(dd pre, td pre)), +.boostlook:not(:has(.doc)) .orderedlist > ol > li .listingblock:has(> .content > pre.highlight):not(:is(dd pre, td pre)) { + margin-left: 0; +} + +.boostlook .listingblock:has(> .content > pre):not(:is(dd pre, td pre)):has(.title) { + border: none; + background: none; +} + +.boostlook .listingblock:has(> .content > pre):not(:last-child), +.boostlook .listingblock:has(> .content > pre.highlight):not(:last-child), +.boostlook:not(:has(.doc)) pre.programlisting:not(:last-child), +.boostlook:not(:has(.doc)) pre.synopsis:not(:last-child), +.boostlook#libraryReadMe > pre:not(:last-child) { + margin-bottom: var(--padding-padding-xs, 0.75rem); +} + +.boostlook .content:has(> pre):has(> .source-toolbox) { + position: relative; + display: flex; + flex-direction: column-reverse; +} + +.boostlook .highlight pre, +.boostlook .content:has(> pre) pre.highlight, +.boostlook .literalblock > .content > pre:not(.highlight) { + border: 1px solid var(--border-border-primary, #e4e7ea); + border-radius: var(--radius-xxl, 1rem); +} +.boostlook .content:has(> pre):has(> .source-toolbox) pre { + /*border: 1px solid var(--border-border-secondary, #d5d7d9);*/ + /*border-radius: var(--spacing-size-2xs, 0.5rem);*/ +} + +.boostlook .content:has(> pre):has(> .source-toolbox) .source-toolbox { + position: static; + order: 0; + display: flex; + visibility: visible; + top: unset; + right: unset; + color: var(--text-main-text-body-tetriary, #62676b); + font-family: inherit; + z-index: 1; + padding: var(--article-article-compressing-from-12-8--, 0.5rem) var(--spacing-size-sm, 1rem); + /*min-height: 2rem;*/ + height: 0; + max-height: 0; + min-height: 0; + padding: 0; + /*margin-top: -1px;*/ +} + +.boostlook .content:has(> pre):has(> .source-toolbox):not(:has(.source-lang)) .source-toolbox { + min-height: 0; + height: 0; + padding: 0 !important; + margin-bottom: -1px; +} +.boostlook .content:has(> pre):has(> .source-toolbox):not(:has(.source-lang)) .source-toolbox .copy-button { + top: 0.25rem; +} +.boostlook .content:has(> pre):has(> .source-toolbox) .source-lang { + color: var(--text-main-text-body-quaternary, #949a9e); + text-align: right; + font-family: "Noto Sans"; + font-size: var(--typography-font-size-2xs, 0.75rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + text-transform: uppercase; + margin-left: auto; + display: none; +} +.boostlook .content:has(> pre):has(> .source-toolbox) .source-lang::after { + content: none; +} + +/* Code Block Copy to Clipboard Icon */ +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-button { + position: absolute; + top: 2.25rem; + right: 0.25rem; + display: flex; + flex-direction: column; + align-items: center; + color: inherit; + outline: none; + font-size: inherit; + line-height: inherit; + width: 2rem; + height: 2rem; + padding: var(--spacing-size-3xs, 0.25rem); + border-radius: var(--spacing-size-2xs, 0.5rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + background: var(--surface-background-main-surface-primary, #f5f6f8); + opacity: 0; + visibility: hidden; + transition: all 0.2s ease; +} + +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-button:hover { + border: 1px solid var(--border-border-blue, #92cbe9); +} + +.boostlook .content:has(> pre):has(> .source-toolbox):hover .copy-button { + opacity: 1; + visibility: visible; +} + +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-button img { + display: none; +} + +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-button::before { + content: var(--icon-clipboard); + width: var(--icons-24, 1.5rem); + height: var(--icons-24, 1.5rem); + aspect-ratio: 1/1; +} + +/* Code Block Copied Toast */ +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-toast { + flex: none; + position: relative; + display: inline-flex; + justify-content: center; + padding: var(--padding-padding-3xs, 0.25rem) var(--padding-padding-xs, 0.75rem); + flex-direction: column; + align-items: center; + margin-top: 1em; + background: var(--surface-background-main-surface-primary, #f5f6f8); + border-radius: var(--spacing-size-2xs, 0.5rem); + border: 1px solid var(--border-border-secondary, #d5d7d9); + color: var(--text-main-text-primary, #18191b); + cursor: auto; + opacity: 0; + transition: opacity 0.5s ease 0.5s; +} + +.boostlook .content:has(> pre):has(> .source-toolbox) .copy-toast::after { + content: url("data:image/svg+xml,%3Csvg%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M6%2011.95L11.6569%206.2931L6%200.636243L0.343146%206.2931L6%2011.95Z%22%20fill%3D%22%23F5F6F8%22%2F%3E%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M0.343146%206.2931L6%200.636243L11.6569%206.2931L10.9497%207.0002L6%202.05046L1.05025%207.0002L0.343146%206.2931Z%22%20fill%3D%22%23E4E7EA%22%2F%3E%3C%2Fsvg%3E"); + position: absolute; + top: -62%; + width: 1em; + height: 1em; + border: unset; + border-left-color: unset; + transform: unset; + transform-origin: unset; + color: var(--text-main-text-primary, #18191b); + text-align: center; + font-size: var(--typography-font-size-sm, 1rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); /* 150% */ +} + +/* Code Styling */ +.boostlook p code:not(:has(> code)), +.boostlook li code:not(:has(> code)), +.boostlook .doc p code:not(:has(> code)), +.boostlook .doc .colist > table code:not(:has(> code)) { + display: inline; + color: var(--text-code-neutral, #0d0e0f); + font-size: 0.88em; + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-md); + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +.boostlook p:not(:is(table p)) code:not(:has(> code)), +.boostlook li code:not(:has(> code)), +.boostlook .doc p:not(:is(table p)) code:not(:has(> code)), +.boostlook .doc .colist > table code:not(:has(> code)) { + border-radius: unset; + padding: unset; + /* border: 1px solid var(--border-border-secondary, #d5d7d9); */ + background: transparent !important; +} + +/* Code Links */ +.boostlook p:not(:is(table p)) a code, +.boostlook li:not(:is(table li)) a code, +.boostlook .doc p:not(:is(table p)) a code, +.boostlook .doc table a code, +.boostlook .doc .colist > table a code, +.boostlook code:has(> a:first-child:last-child), +.boostlook code:has(> a:only-child), +.boostlook p:not(:is(table p)) code:has(> a:first-child:last-child), +.boostlook p:not(:is(table p)) code:has(> a:only-child), +.boostlook li:not(:is(table li)) code:has(> a:first-child:last-child), +.boostlook li:not(:is(table li)) code:has(> a:only-child), +.boostlook .doc p:not(:is(table p)) code:has(> a:first-child:last-child), +.boostlook .doc p:not(:is(table p)) code:has(> a:only-child), +.boostlook .doc .colist > table code:has(> a:first-child:last-child), +.boostlook .doc .colist > table code:has(> a:only-child) { + /* transition: all 0.2s ease; */ + border-radius: unset; + border: none; + background: transparent !important; + color: inherit; +} + +/* Applies to links in code in case where only one link tag inside code */ +/* .boostlook code:not(.tableblock code, .table code):has(> a:first-child:last-child) a, +.boostlook code:not(.tableblock code, .table code):has(> a:only-child) a, +.boostlook p code:not(.tableblock code, .table code):has(> a:first-child:last-child) a, +.boostlook p code:not(.tableblock code, .table code):has(> a:only-child) a, +.boostlook li code:not(.tableblock code, .table code):has(> a:first-child:last-child) a, +.boostlook li code:not(.tableblock code, .table code):has(> a:only-child) a, +.boostlook .doc p code:not(.tableblock code, .table code):has(> a:first-child:last-child) a, +.boostlook .doc p code:not(.tableblock code, .table code):has(> a:only-child) a, +.boostlook .doc .colist > table code:has(> a:first-child:last-child) a, +.boostlook .doc .colist > table code:has(> a:only-child) a { + text-decoration: none; + font: inherit; + color: inherit; +} */ + +/* .boostlook .doc table.tableblock code a, +.boostlook:not(:has(.doc)) table.table code a { */ +/* text-decoration-color: transparent; */ +/* color: var(--text-code-blue, #329cd2); */ +/* line-height: var(--typography-line-height-lg, 1.5rem); */ +/* } */ + +/* Code Link Hover States */ +/* .boostlook p:not(:is(table p)) a:hover code, +.boostlook li a:hover code, +.boostlook .doc p:not(:is(table p)) a:hover code, +.boostlook .doc table a:hover code, +.boostlook .doc .colist > table a:hover code, +.boostlook p:not(:is(table p)) code:has(> a:first-child:last-child):hover, +.boostlook p:not(:is(table p)) code:has(> a:only-child):hover, +.boostlook li code:has(> a:first-child:last-child):hover, +.boostlook li code:has(> a:only-child):hover, +.boostlook .doc p:not(:is(table p)) code:has(> a:first-child:last-child):hover, +.boostlook .doc p:not(:is(table p)) code:has(> a:only-child):hover, +.boostlook .doc .colist > table code:has(> a:first-child:last-child):hover, +.boostlook .doc .colist > table code:has(> a:only-child):hover { + border-color: var(--border-border-blue-hover, #329cd2); + background: var(--surface-background-main-surface-blue-tetriary, #c2e2f4) !important; +} */ + +.boostlook a:hover code { + color: inherit; +} + +.boostlook .doc table.tableblock code:hover a, +.boostlook:not(:has(.doc)) table.table code:hover a, +.boostlook .doc table.tableblock code a:focus-visible, +.boostlook:not(:has(.doc)) table.table code a:focus-visible { + text-decoration-color: var(--border-border-blue, #92cbe9); +} + +/* Syntax Highlighting — Figma mapping: + * Blue (#1345E8 / #38DDFF) — types & keywords (int, void, const, class, namespace…) + * Green (#289D30 / #72FE92) — function names, strings + * Yellow(#A3A38C / #FFF173) — punctuation, numbers, attributes + * Pink (#D31FA7 / #F358C0) — preprocessor, special identifiers + * Grey (#9E9E9E / #A3A3A3) — comments + * Text (--text-main-text-body-primary) — plain identifiers + */ + +/* Keywords & types → Blue */ +.boostlook .hljs-keyword, +.boostlook .hljs-selector-tag, +.boostlook .hljs-subst, +.boostlook .hljs-type, +.boostlook pre span.k, +.boostlook pre span.kc, +.boostlook pre span.kd, +.boostlook pre span.kn, +.boostlook pre span.kp, +.boostlook pre span.kr, +.boostlook pre span.kt, +.boostlook pre span.keyword, +.boostlook pre span.property { + color: var(--text-code-blue, #1345E8); +} + +/* Function names & titles → Green */ +.boostlook .hljs-title, +.boostlook .hljs-section, +.boostlook .hljs-selector-id { + color: var(--text-code-green, #289D30); +} + +/* Identifiers → neutral text */ +.boostlook pre span.n, +.boostlook pre span.na, +.boostlook pre span.nb, +.boostlook pre span.bp, +.boostlook pre span.nc, +.boostlook pre span.no, +.boostlook pre span.nd, +.boostlook pre span.ni, +.boostlook pre span.ne, +.boostlook pre span.nf, +.boostlook pre span.py, +.boostlook pre span.nl, +.boostlook pre span.nn, +.boostlook pre span.nx, +.boostlook pre span.nt, +.boostlook pre span.nv, +.boostlook pre span.vc, +.boostlook pre span.vg, +.boostlook pre span.vi, +.boostlook pre span.identifier { + color: var(--text-main-text-body-primary, #2a2c30); +} + +/* Comments → Grey italic */ +.boostlook pre span.c, +.boostlook pre span.ch, +.boostlook pre span.cm, +.boostlook pre span.cp, +.boostlook pre span.cpf, +.boostlook pre span.c1, +.boostlook pre span.cs, +.boostlook pre span.sd, +.boostlook pre span.sh, +.boostlook pre span.comment, +.boostlook .hljs-comment, +.boostlook .cpp-comment, +.boostlook .hljs-quote, +.boostlook .hljs-bullet, +.boostlook .hljs-code { + color: var(--text-code-grey, #9E9E9E); + font-family: "Monaspace Xenon", monospace; + font-style: italic; +} + +/* Built-in functions → Green (like function names) */ +.boostlook .hljs-built_in { + color: var(--text-code-green, #289D30); +} + +/* Strings → Green */ +.boostlook pre span.s, +.boostlook pre span.sa, +.boostlook pre span.sb, +.boostlook pre span.dl, +.boostlook pre span.s2, +.boostlook pre span.se, +.boostlook pre span.si, +.boostlook pre span.sx, +.boostlook pre span.sr, +.boostlook pre span.s1, +.boostlook pre span.ss, +.boostlook pre span.string, +.boostlook .hljs-doctag, +.boostlook .hljs-string, +.boostlook .hljs-addition { + color: var(--text-code-green, #289D30); +} + +/* Numbers, punctuation, attributes → Yellow */ +.boostlook .hljs-number { + color: var(--text-code-yellow, #A3A38C); +} + +/* Preprocessor / meta → Pink */ +.boostlook .hljs-meta { + color: var(--text-code-pink, #D31FA7); +} + +/* Deletion, misc → Red */ +.boostlook .hljs-deletion, +.boostlook .hljs-selector-class, +.boostlook .hljs-template-tag { + color: var(--text-code-red, #f9677f); +} + +.boostlook .hljs-attribute, +.boostlook .hljs-name, +.boostlook .hljs-tag { + color: var(--text-main-text-primary, #18191b); +} + +/* Syntax Defaults */ +.boostlook .hljs-attribute, +.boostlook .hljs-doctag, +.boostlook .hljs-keyword, +.boostlook .hljs-meta .hljs-keyword, +.boostlook .hljs-name, +.boostlook .hljs-selector-tag, +.boostlook .hljs-section, +.boostlook .hljs-title { + font-weight: inherit; +} + +/* Dark mode hljs overrides — beat site.css html.dark .hljs-* selectors */ +html.dark .boostlook .hljs-keyword, +html.dark .boostlook .hljs-selector-tag, +html.dark .boostlook .hljs-subst, +html.dark .boostlook .hljs-type { + color: var(--text-code-blue, #38DDFF); +} + +html.dark .boostlook .hljs-title, +html.dark .boostlook .hljs-section, +html.dark .boostlook .hljs-selector-id, +html.dark .boostlook .hljs-built_in { + color: var(--text-code-green, #72FE92); +} + +html.dark .boostlook .hljs-comment, +html.dark .boostlook .hljs-quote, +html.dark .boostlook .hljs-bullet, +html.dark .boostlook .hljs-code { + color: var(--text-code-grey, #A3A3A3); + font-style: italic; +} + +html.dark .boostlook .hljs-doctag, +html.dark .boostlook .hljs-string, +html.dark .boostlook .hljs-addition { + color: var(--text-code-green, #72FE92); +} + +html.dark .boostlook .hljs-number, +html.dark .boostlook .hljs-literal, +html.dark .boostlook .hljs-variable, +html.dark .boostlook .hljs-template-variable { + color: var(--text-code-yellow, #FFF173); +} + +html.dark .boostlook .hljs-meta { + color: var(--text-code-pink, #F358C0); +} + +html.dark .boostlook .hljs-deletion, +html.dark .boostlook .hljs-selector-class, +html.dark .boostlook .hljs-template-tag { + color: var(--text-code-red, #e06c75); +} + +html.dark .boostlook .hljs-attribute, +html.dark .boostlook .hljs-name, +html.dark .boostlook .hljs-tag { + color: var(--text-main-text-primary, #f5f6f8); +} + +/* Override cpp-highlight theme from site.css */ +.boostlook .doc pre.highlight code.cpp-highlight, +.boostlook pre.highlight code.cpp-highlight, +.boostlook code.cpp-highlight { + color: var(--text-main-text-body-primary, #050816); +} + +.boostlook .doc pre.highlight code.cpp-highlight .cpp-keyword, +.boostlook pre.highlight code.cpp-highlight .cpp-keyword, +.boostlook code.cpp-highlight .cpp-keyword { + color: var(--text-code-blue, #1345E8); +} + +.boostlook .doc pre.highlight code.cpp-highlight .cpp-string, +.boostlook pre.highlight code.cpp-highlight .cpp-string, +.boostlook code.cpp-highlight .cpp-string { + color: var(--text-code-green, #289D30); +} + +.boostlook .doc pre.highlight code.cpp-highlight .cpp-preprocessor, +.boostlook pre.highlight code.cpp-highlight .cpp-preprocessor, +.boostlook code.cpp-highlight .cpp-preprocessor { + color: var(--text-code-pink, #D31FA7); +} + +.boostlook .doc pre.highlight code.cpp-highlight .cpp-comment, +.boostlook pre.highlight code.cpp-highlight .cpp-comment, +.boostlook code.cpp-highlight .cpp-comment { + color: var(--text-code-grey, #9E9E9E); + font-family: "Monaspace Xenon", monospace; + font-style: italic; +} + +.boostlook .doc pre.highlight code.cpp-highlight .cpp-attribute, +.boostlook pre.highlight code.cpp-highlight .cpp-attribute, +.boostlook code.cpp-highlight .cpp-attribute { + color: var(--text-code-yellow, #A3A38C); +} + +/* Dark mode cpp-highlight overrides */ +html.dark .boostlook .doc pre.highlight code.cpp-highlight, +html.dark .boostlook pre.highlight code.cpp-highlight, +html.dark .boostlook code.cpp-highlight { + color: var(--text-main-text-primary, #f5f6f8); +} + +html.dark .boostlook .doc pre.highlight code.cpp-highlight .cpp-keyword, +html.dark .boostlook pre.highlight code.cpp-highlight .cpp-keyword, +html.dark .boostlook code.cpp-highlight .cpp-keyword { + color: var(--text-code-blue, #38DDFF); +} + +html.dark .boostlook .doc pre.highlight code.cpp-highlight .cpp-string, +html.dark .boostlook pre.highlight code.cpp-highlight .cpp-string, +html.dark .boostlook code.cpp-highlight .cpp-string { + color: var(--text-code-green, #72FE92); +} + +html.dark .boostlook .doc pre.highlight code.cpp-highlight .cpp-preprocessor, +html.dark .boostlook pre.highlight code.cpp-highlight .cpp-preprocessor, +html.dark .boostlook code.cpp-highlight .cpp-preprocessor { + color: var(--text-code-pink, #F358C0); +} + +html.dark .boostlook .doc pre.highlight code.cpp-highlight .cpp-comment, +html.dark .boostlook pre.highlight code.cpp-highlight .cpp-comment, +html.dark .boostlook code.cpp-highlight .cpp-comment { + color: var(--text-code-grey, #A3A3A3); + font-family: "Monaspace Xenon", monospace; + font-style: italic; +} + +html.dark .boostlook .doc pre.highlight code.cpp-highlight .cpp-attribute, +html.dark .boostlook pre.highlight code.cpp-highlight .cpp-attribute, +html.dark .boostlook code.cpp-highlight .cpp-attribute { + color: var(--text-code-yellow, #FFF173); +} + +/* Table Headings */ +.boostlook h6:has(+ table) { + margin-left: 1em; +} + +/* Quote Blocks */ +.boostlook .quoteblock, +.boostlook .doc .quoteblock, +.boostlook .verseblock, +.boostlook .doc .verseblock, +.boostlook div.blockquote { + padding: var(--padding-padding-md, 1.125rem) var(--padding-padding-lg, 1.5rem); + border-radius: var(--spacing-size-size-0, 0rem); + border-left: 2px solid var(--border-border-active, #18191b); + background: var(--surface-background-main-surface-primary, #f5f6f8); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-sm, 1rem); + line-height: var(--typography-line-height-lg, 1.5rem); +} + +/* Add intendation */ +.boostlook .sectionbody .quoteblock, +.boostlook .sectionbody .doc .quoteblock, +.boostlook .sectionbody .verseblock, +.boostlook .sectionbody .doc .verseblock, +.boostlook .sectionbody div.blockquote, +.boostlook .section .quoteblock, +.boostlook .section .doc .quoteblock, +.boostlook .section .verseblock, +.boostlook .section .doc .verseblock, +.boostlook .section div.blockquote { + margin-left: var(--spacing-size-xl, 2rem); +} + +.boostlook .quoteblock:not(:first-child), +.boostlook .doc .quoteblock:not(:first-child), +.boostlook .verseblock:not(:first-child), +.boostlook .doc .verseblock:not(:first-child), +.boostlook div.blockquote:not(:first-child) { + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook .quoteblock blockquote, +.boostlook .doc .quoteblock blockquote, +.boostlook .verseblock blockquote, +.boostlook .doc .verseblock blockquote, +.boostlook div.blockquote blockquote { + margin: 0; + font: inherit; + color: inherit; +} + +.boostlook .quoteblock blockquote .paragraph, +.boostlook .doc .quoteblock blockquote .paragraph, +.boostlook .verseblock blockquote .paragraph, +.boostlook .doc .verseblock blockquote .paragraph, +.boostlook div.blockquote blockquote p { + font: inherit; +} + +.boostlook .quoteblock blockquote p, +.boostlook .doc .quoteblock blockquote p, +.boostlook .verseblock blockquote p, +.boostlook .doc .verseblock blockquote p { + margin: 0; + font: inherit; + color: inherit; +} + +.boostlook .quoteblock blockquote:before { + content: none; +} + +/* Pagination */ +.boostlook nav.pagination { + border-top: revert; + line-height: initial; + margin: revert; + display: flex; + padding: var(--spacing-size-2xs, 0.5rem) var(--spacing-size-size-0, 0rem); + align-items: stretch; + gap: var(--spacing-size-2xs, 0.5rem); +} + +.boostlook nav.pagination > span { + display: flex; + flex-direction: column; + flex: 1 0 0; + backdrop-filter: blur(8px); + padding-right: revert; + padding-left: revert; + margin-left: revert; +} +.boostlook nav.pagination > span.next { + text-align: right; +} + +.boostlook nav.pagination span::before { + content: none !important; +} + +.boostlook nav.pagination > span a { + /* Container padding + two paddings of arrow icon container + arrow icon width + gap between arrow and content */ + --_arrow-based-padding: calc(var(--padding-padding-2xs) + (var(--spacing-size-3xs) * 2) + var(--icons-24) + var(--padding-padding-md)); + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + width: 100%; + height: 100%; + border-radius: var(--padding-padding-xs, 0.75rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + padding: var(--padding-padding-xs, 0.75rem); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-sm, 1rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); /* 150% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + text-decoration: none; + transition: background-color 0.3s ease; +} + +.boostlook nav.pagination > span:hover a { + background: var(--surface-background-main-surface-primary, #f5f6f8); + color: inherit; +} + +.boostlook nav.pagination > span.prev a { + padding-left: var(--_arrow-based-padding); +} +.boostlook nav.pagination > span.next a { + padding-right: var(--_arrow-based-padding); +} + +@media screen and (min-width: 990px) { + .boostlook nav.pagination > span a { + --_arrow-based-padding: calc(var(--padding-padding-2xs) + (var(--spacing-size-xs) * 2) + var(--icons-24) + var(--padding-padding-md)); + } +} + +.boostlook nav.pagination > span a::before { + width: auto; + position: static; + color: var(--text-main-text-body-quaternary, #949a9e); + font-size: var(--typography-font-size-2xs, 0.75rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + transform: revert; +} + +.boostlook nav.pagination > span.prev a::before { + content: "Previous"; +} +.boostlook nav.pagination > span.next a::before { + content: "Next"; +} + +.boostlook nav.pagination > span a::after { + --_arrow-size: calc((var(--spacing-size-3xs, 0.25rem) * 2) + var(--icons-24)); + position: absolute; + top: 50%; + display: flex; + width: var(--_arrow-size); + height: var(--_arrow-size); + align-items: center; + justify-content: center; + border: 1px solid transparent; + border-radius: var(--spacing-size-2xs, 0.5rem); + background: var(--surface-background-main-base-primary, #fff); + transition: all 0.2s ease; + transform: translateY(-50%); +} + +@media screen and (min-width: 990px) { + .boostlook nav.pagination > span a::after { + --_arrow-size: calc((var(--spacing-size-xs, 0.75rem) * 2) + var(--icons-24)); + } +} + +.boostlook nav.pagination > span.prev a::after { + content: var(--icon-arrow-left); + left: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook nav.pagination > span.next a::after { + content: var(--icon-arrow-right); + right: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook nav.pagination > span:hover a::after { + border-color: var(--border-border-blue, #92cbe9); + background: var(--surface-background-main-surface-blue-secondary, #daeef9); +} + +/* Admonitions */ +/* Admonitions — Metalab 2.0 */ +.boostlook #content .admonitionblock, +.boostlook:not(:has(.doc)) div.note, +.boostlook:not(:has(.doc)) div.tip, +.boostlook:not(:has(.doc)) div.important, +.boostlook:not(:has(.doc)) div.caution, +.boostlook:not(:has(.doc)) div.warning, +.boostlook:not(:has(.doc)) div.blurb, +.boostlook:not(:has(.doc)) p.blurb { + padding: var(--spacing-large, 1rem); + border-radius: var(--radius-xxl, 1rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + margin: revert; + background: var(--surface-background-main-base-primary, #fff); +} + +.boostlook #content li .admonitionblock, +.boostlook:not(:has(.doc)) li div.note, +.boostlook:not(:has(.doc)) li div.tip, +.boostlook:not(:has(.doc)) li div.important, +.boostlook:not(:has(.doc)) li div.caution, +.boostlook:not(:has(.doc)) li div.warning, +.boostlook:not(:has(.doc)) li div.blurb, +.boostlook:not(:has(.doc)) li p.blurb { + margin-left: 0; +} + +/* Readme Template Admonitionblock */ +.boostlook:not(:has(.doc)) .notices { + background-image: none !important; +} + +.boostlook #content .admonitionblock > table, +.boostlook:not(:has(.doc)) div.note > table, +.boostlook:not(:has(.doc)) div.tip > table, +.boostlook:not(:has(.doc)) div.important > table, +.boostlook:not(:has(.doc)) div.caution > table, +.boostlook:not(:has(.doc)) div.warning > table, +.boostlook:not(:has(.doc)) div.blurb > table, +.boostlook:not(:has(.doc)) p.blurb > table { + all: revert; + table-layout: fixed; + position: relative; + width: 100%; +} + +.boostlook #content .admonitionblock > table tr, +.boostlook:not(:has(.doc)) div.note tbody, +.boostlook:not(:has(.doc)) div.tip tbody, +.boostlook:not(:has(.doc)) div.important tbody, +.boostlook:not(:has(.doc)) div.caution tbody, +.boostlook:not(:has(.doc)) div.warning tbody, +.boostlook:not(:has(.doc)) div.blurb tbody, +.boostlook:not(:has(.doc)) p.blurb tbody, +.boostlook:not(:has(.doc)) .notices { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 12px; +} + +.boostlook #content .admonitionblock > table tr td { + padding: 0; + border: unset; +} + +.boostlook #content .admonitionblock > table tr td.icon, +.boostlook:not(:has(.doc)) div.note > table tr:first-child th, +.boostlook:not(:has(.doc)) div.tip > table tr:first-child th, +.boostlook:not(:has(.doc)) div.important > table tr:first-child th, +.boostlook:not(:has(.doc)) div.caution > table tr:first-child th, +.boostlook:not(:has(.doc)) div.warning > table tr:first-child th, +.boostlook:not(:has(.doc)) div.blurb > table tr:first-child th, +.boostlook:not(:has(.doc)) p.blurb > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices .heading { + display: flex; + align-items: center; + gap: var(--spacing-size-2xs, 0.5rem); + /* Removes legacy icon */ + background: transparent; +} + +.boostlook:not(:has(.doc)) .notices .heading { + margin: 0; +} + +.boostlook:not(:has(.doc)) div.note > table tr:first-child th, +.boostlook:not(:has(.doc)) div.tip > table tr:first-child th, +.boostlook:not(:has(.doc)) div.important > table tr:first-child th, +.boostlook:not(:has(.doc)) div.caution > table tr:first-child th, +.boostlook:not(:has(.doc)) div.warning > table tr:first-child th, +.boostlook:not(:has(.doc)) div.blurb > table tr:first-child th, +.boostlook:not(:has(.doc)) p.blurb > table tr:first-child th, +.boostlook:not(:has(.doc)) div.note > table tr:first-child th > *, +.boostlook:not(:has(.doc)) div.tip > table tr:first-child th > *, +.boostlook:not(:has(.doc)) div.important > table tr:first-child th > *, +.boostlook:not(:has(.doc)) div.caution > table tr:first-child th > *, +.boostlook:not(:has(.doc)) div.warning > table tr:first-child th > *, +.boostlook:not(:has(.doc)) div.blurb > table tr:first-child th > *, +.boostlook:not(:has(.doc)) p.blurb > table tr:first-child th > *, +.boostlook #content .admonitionblock > table tr td.icon > *, +.boostlook:not(:has(.doc)) .notices .heading { + color: var(--text-main-text-primary, #050816); + font-size: 1rem; + font-weight: 500; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: 100%; + letter-spacing: -0.16px; +} +.boostlook #content .admonitionblock > table tr td.icon > * { + padding: 0; + font-family: var(--font-family-body, "Noto Sans"); +} + +.boostlook #content .admonitionblock > table tr td.icon i.fa::after { + content: attr(title); +} + +.boostlook #content .admonitionblock > table tr td.content, + /* Leagcy Doc */ +.boostlook:not(:has(.doc)) div.note > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.note > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) div.tip > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.tip > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) div.important > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.important > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) div.caution > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.caution > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) div.warning > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.warning > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) div.blurp > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) div.blurp > table tr:not(:first-child) td p, +.boostlook:not(:has(.doc)) p.blurb > table tr:not(:first-child) td, +.boostlook:not(:has(.doc)) p.blurb > table tr:not(:first-child) td p, + /* Antora Template Correction*/ +.boostlook #content .admonitionblock > table tr td.content p, +.boostlook:not(:has(.doc)) .notices .message p { + color: var(--text-main-text-body-tetriary, #717378); + font-size: 0.75rem; + font-variation-settings: "wght" 400, "wdth" 87.5; + line-height: 135%; + letter-spacing: -0.12px; +} + +.boostlook:not(:has(.doc)) .notices .message { + margin: 0; +} + +.boostlook #content .admonitionblock > table code, +.boostlook:not(:has(.doc)) div.note > table code, +.boostlook:not(:has(.doc)) div.tip > table code, +.boostlook:not(:has(.doc)) div.important > table code, +.boostlook:not(:has(.doc)) div.caution > table code, +.boostlook:not(:has(.doc)) div.warning > table code, +.boostlook:not(:has(.doc)) div.blurb > table code, +.boostlook:not(:has(.doc)) p.blurb > table code { + margin: revert; + padding: 0; +} + +/* Note — Metalab 2.0: neutral card */ +.boostlook #content .admonitionblock.note, +.boostlook:not(:has(.doc)) div.note, +.boostlook:not(:has(.doc)) .notices.note { + border-color: var(--border-border-primary, #e4e7ea); + background-color: var(--surface-background-main-base-primary, #fff); +} + +.boostlook #content .admonitionblock.note > table tr td.icon > *, +.boostlook:not(:has(.doc)) div.note > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.note .heading { + color: var(--text-main-text-primary, #18191b); +} + +/* Tip */ +.boostlook #content .admonitionblock.tip, +.boostlook:not(:has(.doc)) div.tip, +.boostlook:not(:has(.doc)) .notices.tip { + border-color: var(--border-border-positive, #f8fefb); + background-color: var(--surface-background-states-surface-positive-primary, #f6fafd); +} +/* .boostlook #content .admonitionblock.tip > table tr td.icon, +.boostlook:not(:has(.doc)) div.tip > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.tip .heading { + background: var(--border-border-positive, #bdeed6); +} */ +.boostlook #content .admonitionblock.tip > table tr td.icon > *, +.boostlook:not(:has(.doc)) div.tip > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.tip .heading { + color: var(--text-main-text-primary, #18191b); +} + +/* Important */ +.boostlook #content .admonitionblock.important, +.boostlook #content .admonitionblock.caution, +.boostlook:not(:has(.doc)) div.important, +.boostlook:not(:has(.doc)) div.caution, +.boostlook:not(:has(.doc)) .notices.important { + border-color: var(--border-border-brand-orange, #ffd897); + background-color: var(--surface-background-states-surface-warning-primary, #fefcf9); +} +/* .boostlook #content .admonitionblock.important > table tr td.icon, +.boostlook #content .admonitionblock.caution > table tr td.icon, +.boostlook:not(:has(.doc)) div.important > table tr:first-child th, +.boostlook:not(:has(.doc)) div.caution > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.important { + background: var(--surface-background-states-surface-warning-tetriary, #ffd4b3); +} */ +.boostlook #content .admonitionblock.important > table tr td.icon > *, +.boostlook #content .admonitionblock.caution > table tr td.icon > *, +.boostlook:not(:has(.doc)) div.important > table tr:first-child th, +.boostlook:not(:has(.doc)) div.caution > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.important { + color: var(--text-main-text-primary, #18191b); +} + +/* Warning */ +.boostlook #content .admonitionblock.warning, +.boostlook:not(:has(.doc)) div.warning, +.boostlook:not(:has(.doc)) .notices.warning { + border-color: var(--border-border-negative, #ffcad2); + background-color: var(--surface-background-states-surface-negative-primary, #fdf1f3); +} +/* .boostlook #content .admonitionblock.warning > table tr td.icon, +.boostlook:not(:has(.doc)) div.warning > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.warning .heading { + background: var(--surface-background-states-surface-negative-tetriary, #ffcad2); +} */ +.boostlook #content .admonitionblock.warning > table tr td.icon > *, +.boostlook:not(:has(.doc)) div.warning > table tr:first-child th, +.boostlook:not(:has(.doc)) .notices.warning .heading { + color: var(--text-main-text-primary, #18191b); +} + +/* Dlist */ +/* Apply top margin only for root list */ +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist), +.boostlook .dlist dl dt:not(:first-child):not(.dlist .dlist), +.boostlook:not(:has(.doc)) .variablelist:not(:first-child):not(.variablelist .variablelist), +.boostlook:not(:has(.doc)) .variablelist dl dt:not(:first-child):not(.variablelist .variablelist) { + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) { + background-color: var(--surface-background-main-surface-blue-primary, #ebf4f9); + border: 1px solid transparent; /* var(--border-border-blue-primary, #c2e2f4) */ + padding: var(--padding-padding-xs, 0.75rem) var(--padding-padding-md, 1.125rem); + margin-left: var(--spacing-size-xl); +} + +.boostlook #content .colist.arabic > table > tbody > tr td .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) { + margin-left: 0; +} + +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) .hdlist1 { + font-size: var(--typography-font-size-sm, 1rem); + font-variation-settings: "wght" 600, "wdth" 62.5; + line-height: var(--typography-line-height-lg, 1.5rem); + letter-spacing: var(--spacing-size-size-0, 0rem); + font-weight: 600; + color: #000 !important; + /*margin-bottom: var(--spacing-size-2xs, 0.5rem);*/ +} +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) dd a:hover { + color: var(--text-states-text-warning, #FF9442); + cursor: pointer; +} +.boostlook #content .olist.arabic > ol > li table.tableblock:not(:first-child), +.boostlook #content .olist.arabic > ol > li .dlist:not(:first-child):not(.dlist .dlist) { + margin-left: 0; +} +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) dd a { + color: var(--text-main-text-link-blue, #026a9f); + text-decoration: none; + transition: color 0.3s ease; +} +.boostlook #content .dlist:not(:first-child):not(.dlist .dlist):has(.hdlist1) dd { + margin: 0; + padding: 0; + border: none; + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-xs, 0.875rem); + font-variation-settings: "wght" 400, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +.boostlook .dlist dl, +.boostlook:not(:has(.doc)) .variablelist dl { + display: flex; + flex-direction: column; + gap: var(--spacing-size-2xs, 0.5rem); +} + +/* Where is this used */ +.boostlook .dlist dl dt, +.boostlook:not(:has(.doc)) .variablelist dl dt { + display: block; + width: fit-content; + padding: initial; + border-radius: initial; + border: initial; + /* border-bottom-left-radius: unset; */ + background: initial; + color: var(--text-code-neutral, #0d0e0f); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + margin-bottom: 0; +} + +/* styles for nested list */ +.boostlook .dlist:is(.dlist .dlist) dl dt, +.boostlook:not(:has(.doc)) .variablelist:is(.variablelist .variablelist) dl dt { + font-size: var(--typography-font-size-sm, 1rem); +} + +.boostlook .dlist dl dt code, +.boostlook:not(:has(.doc)) .variablelist dl dt code { + border: none; + padding: 0; + background: transparent !important; +} + +.boostlook .dlist dl dt .term, +.boostlook:not(:has(.doc)) .variablelist dl dt .term { + font: inherit; + font-weight: inherit; +} + +.boostlook .dlist dl dt code, +.boostlook:not(:has(.doc)) .variablelist dl dt code { + font-variation-settings: "wght" 600, "wdth" 87.5; + font-family: var(--font-family-code, 'Monaspace Neon'); +} + +.boostlook .dlist dl dd, +.boostlook:not(:has(.doc)) .variablelist dl dd { + margin: unset; + margin-top: -1px; + padding: var(--padding-padding-2xs, 0.5rem) var(--padding-padding-sm, 1rem); + border-radius: var(--spacing-size-size-0, 0rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-xs, 0.875rem); + line-height: var(--typography-line-height-lg, 1.5rem); +} + +/* styles for nested list */ +.boostlook .dlist:is(.dlist .dlist) dl dd, +.boostlook:not(:has(.doc)) .variablelist:is(.variablelist .variablelist) dl dd { + border: none; + padding: initial; +} + +/* styles for block if it has nested list */ +.boostlook .dlist dl dd:has(>.dlist), +.boostlook:not(:has(.doc)) .variablelist dl dd:has(>.variablelist) { + padding: var(--padding-padding-sm, 1rem); +} + +/* apply margin only for top level list */ +.boostlook .dlist dl > dd:not(:is(dl dl dd)), +.boostlook:not(:has(.doc)) .variablelist dl > dd:not(:is(dl dl dd)) { + margin-left: var(--spacing-size-xl); +} + +.boostlook .dlist dl dd p, +.boostlook:not(:has(.doc)) .variablelist dl dd p { + font: inherit; + margin: 0; +} + +.boostlook .dlist dl dd em, +.boostlook:not(:has(.doc)) .variablelist dl dd em { + font: inherit; + font-variation-settings: "wght" 500, "wdth" 87.5; +} + +/* Edit Page Link */ +.boostlook .edit-this-page { + color: var(--text-main-text-body-quaternary, #949a9e); + text-align: right; + font-size: var(--typography-font-size-2xs, 0.75rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ + letter-spacing: var(--spacing-size-size-0, 0rem); + padding: 0 var(--padding-padding-2xs, 0.5rem); +} + +.boostlook .edit-this-page a { + all: inherit; +} + +/* Layout Structure */ +.boostlook #header, +.boostlook #content, +.boostlook #footer { + padding-left: var(--main-margin); + padding-right: var(--main-margin); +} + +.boostlook #header { + padding-top: 1.25rem; +} + +.boostlook #footer { + padding-top: var(--padding-padding-sm); + padding-bottom: var(--padding-padding-sm); + color: var(--text-main-text-body-quaternary, #949a9e); + font-size: var(--typography-font-size-xs); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Unordered Lists */ +/* Reset Legacy and Common */ +.boostlook .doc .dlist .dlist, +.boostlook .doc .dlist .olist, +.boostlook .doc .dlist .ulist, +.boostlook .doc .olist .dlist, +.boostlook .doc .olist .olist, +.boostlook .doc .olist .ulist, +.boostlook .doc .olist li + li, +.boostlook .doc .ulist .dlist, +.boostlook .doc .ulist .olist, +.boostlook .doc .ulist .ulist, +.boostlook .doc .ulist:not(.tablist) li + li, +.boostlook:not(:has(.doc)) div.orderedlist li + li { + margin-top: var(--padding-padding-3xs, 0.25rem); +} + +.boostlook:not(:has(.doc)) div.orderedlist div.orderedlist { + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook .doc .dlist .dlist, +.boostlook .doc .dlist .olist, +.boostlook .doc .dlist .ulist, +.boostlook .doc .olist .dlist, +.boostlook .doc .olist .olist, +.boostlook .doc .olist .ulist, +.boostlook .doc .ulist .dlist, +.boostlook .doc .ulist .olist, +.boostlook .doc .ulist .ulist, +.boostlook:not(:has(.doc)) div.orderedlist div.orderedlist { + margin-bottom: var(--padding-padding-2xs, 0.5rem); +} + +/* Default List */ +.boostlook div.itemizedlist:has(> ul.itemizedlist):not(:first-child), +.boostlook :not(div.itemizedlist) > ul.itemizedlist, +.boostlook .ulist:not(:first-child):not(.tablist), +.boostlook .ulist:not(:first-child).disc, +.boostlook#libraryReadMe ul:not(:first-child), + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class]), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class]) { + margin-top: var(--padding-padding-xs, 0.75rem); +} + +.boostlook ul.itemizedlist, +.boostlook .ulist:not(.tablist) > ul, +.boostlook .ulist.disc > ul, +.boostlook#libraryReadMe ul, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class]), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class]) { + list-style: none; + padding: 0; +} + +.boostlook ul.itemizedlist { + list-style: none !important; +} + +.boostlook ul.itemizedlist > li, +.boostlook .ulist:not(.tablist) > ul > li, +.boostlook .ulist.disc > ul > li, +.boostlook#libraryReadMe ul > li, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]) > li, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class])> li, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class])> li { + position: relative; + padding-left: 2rem; + line-height: var(--typography-line-height-lg, 1.5rem); +} + +.boostlook ul.itemizedlist > li, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content ul:not([class]) li, +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content ol:not([class]) li, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content ul:not([class]) li, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content ol:not([class]) li, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content ul:not([class]) li, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content ol:not([class]) li { + font: inherit; + line-height: var(--typography-line-height-lg, 1.5rem); +} + +.boostlook ul.itemizedlist > li + li, +.boostlook .ulist:not(.tablist) > ul > li + li, +.boostlook .ulist.disc > ul > li + li, +.boostlook#libraryReadMe ul > li + li, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]) > li + li, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class]) > li + li, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class]) > li + li { + margin-top: var(--padding-padding-3xs, 0.25rem); +} + +.boostlook ul.itemizedlist > li::before, +.boostlook .ulist:not(.tablist) > ul > li::before, +.boostlook .ulist.disc > ul > li::before, +.boostlook#libraryReadMe ul > li::before, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > ul:not([class]) > li::before, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > ul:not([class]) > li::before, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content > ul:not([class]) > li::before { + content: "\2022"; + position: absolute; + left: 0; + top: 0; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-main-text-primary, #18191b); +} + +/* Ordered Lists */ +.boostlook .olist.arabic > ol, +.boostlook .olist.loweralpha > ol, +.boostlook:not(:has(.doc)) .orderedlist > ol { + list-style: none; + counter-reset: list-counter; + padding-left: 0; + padding-bottom: 1rem; +} + +/* Arabic Ordered List */ +.boostlook .olist.arabic > ol > li, +.boostlook:not(:has(.doc)) .orderedlist > ol > li { + position: relative; + padding-left: 2rem; + counter-increment: list-counter; + line-height: var(--typography-line-height-lg, 1.5rem); +} + +.boostlook .olist.arabic > ol > li::before, +.boostlook:not(:has(.doc)) .orderedlist > ol > li::before { + content: counter(list-counter)"."; + position: absolute; + left: 0; + top: -4px; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-sm, 1rem); + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ +} + +.boostlook .olist.arabic > ol > li::after, +.boostlook:not(:has(.doc)) .orderedlist > ol > li::after { + content: ""; + position: absolute; + left: 1px; + top: 0px; + width: 30px; + height: 24px; + /*border: 1px solid var(--border-border-tetriary);*/ + /* Mask to make square brackets for marker to make it look like [ 01 ] */ + /*clip-path: polygon(0 0, 3px 0, 3px 3px, 27px 3px, 27px 0, 30px 0, 30px 24px, 27px 24px, 27px 21px, 3px 21px, 3px 24px, 0 24px);*/ +} + +/* LowerAlfa Ordered List */ +.boostlook .olist.loweralpha > ol > li { + position: relative; + padding-left: 2rem; + counter-increment: list-counter; + line-height: var(--typography-line-height-lg, 1.5rem); +} + +.boostlook .olist.loweralpha > ol > li::before { + content: counter(list-counter, lower-alpha) ". "; + position: absolute; + left: 0; + top: 0; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-xs, 0.875rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--Typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Conum */ +.boostlook .doc .conum[data-value] { + position: relative; + border: none; + border-radius: 100%; + display: inline-flex; + align-items: center; + justify-content: center; + font-family: "Noto Sans"; + font-style: normal; + font-variation-settings: "wght" 350, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); + font-size: var(--typography-font-size-sm, 1rem); + text-align: center; + width: 32px; + height: 32px; + letter-spacing: var(--spacing-size-size-0, 0rem); + text-indent: unset; + color: var(--text-main-text-primary, #18191b); + text-align: center; + /*background: var(--surface-background-main-surface-secondary, #e4e7ea);*/ +} +.boostlook .doc code .conum[data-value] { + background: transparent; + width: auto; + height: auto; + font-size: inherit; + font-family: inherit; + line-height: inherit; + color: var(--text-main-text-primary, #18191b); +} + +.boostlook .doc .conum[data-value]::after { + content: attr(data-value)"."; + font: inherit; +} + +.boostlook .doc .conum[data-value] + b { + display: none; +} + +/* Collist */ +.boostlook .colist.arabic { + margin: revert; +} +.boostlook .colist.arabic > table { + width: 100%; + border-collapse: collapse; + color: var(--text-main-text-body-primary); +} + +.boostlook .colist.arabic > table > tbody > tr td, +.boostlook .colist.arabic > table > tr td { + /* Reset Legacy */ + padding: revert; + padding-top: var(--padding-padding-3xs, 0.25rem); + padding-bottom: 0; + font-size: var(--typography-font-size-sm, 1rem); +} + +.boostlook .colist.arabic > table > tbody > tr > :first-child, +.boostlook .colist.arabic > table > tr > :first-child { + padding-left: 0; + padding-right: 0; + vertical-align: top; + /* to make first column fit its content */ + width: 1%; + white-space: nowrap; +} + +.boostlook .colist.arabic > table > tbody > tr > :first-child:has(.conum), +.boostlook .colist.arabic > table > tr > :first-child:has(.conum) { + padding-top: 0; +} + +/* Tables */ +/* Reset Antora Table Styles */ +.boostlook #content table.tableblock tr, +.boostlook #content table.tableblock td, +.boostlook #content table.tableblock th, +.boostlook #content table.tableblock thead, +.boostlook #content table.tableblock tbody, +.boostlook #content table.tableblock tfoot, +.boostlook #content table.tableblock caption, +.boostlook #content table.tableblock colgroup, +.boostlook #content table.tableblock col, +.boostlook #content table.tableblock, +.boostlook:not(:has(.doc)) table.table tr, +.boostlook:not(:has(.doc)) table.table td, +.boostlook:not(:has(.doc)) table.table th, +.boostlook:not(:has(.doc)) table.table thead, +.boostlook:not(:has(.doc)) table.table tbody, +.boostlook:not(:has(.doc)) table.table tfoot, +.boostlook:not(:has(.doc)) table.table caption, +.boostlook:not(:has(.doc)) table.table colgroup, +.boostlook:not(:has(.doc)) table.table col, +.boostlook:not(:has(.doc)) table.table, +.boostlook#libraryReadMe > table, +.boostlook#libraryReadMe > table tr, +.boostlook#libraryReadMe > table td, +.boostlook#libraryReadMe > table th, +.boostlook#libraryReadMe > table thead, +.boostlook#libraryReadMe > table tbody, +.boostlook#libraryReadMe > table tfoot, +.boostlook#libraryReadMe > table caption, +.boostlook#libraryReadMe > table colgroup, +.boostlook#libraryReadMe > table col { + all: unset; + display: revert; +} + + +.boostlook #content table.tableblock:not(:first-child), +.boostlook:not(:has(.doc)) .table:not(:first-child), +.boostlook#libraryReadMe > table:not(:first-child) { + margin-top: var(--padding-padding-xs, 0.75rem); +} + +.boostlook #content table.tableblock.stretch, +.boostlook:not(:has(.doc)) table.table, +.boostlook#libraryReadMe > table.stretch { + min-width: 100%; +} + +.boostlook #content table.tableblock caption, +.boostlook:not(:has(.doc)) div.table .title { + color: var(--text-main-text-body-primary, #2a2c30); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + font-variation-settings: "wght" 600, "wdth" 87.5; + line-height: var(--typography-line-height-md, 1.25rem); /* 142.857% */ + padding: 0; + padding-bottom: var(--padding-padding-2xs, 0.5rem); +} + +.boostlook #content table.tableblock caption > *, +.boostlook:not(:has(.doc)) div.table .title > * { + font: inherit; + font-variation-settings: "wght" 500, "wdth" 87.5; + text-decoration: none; +} + +.boostlook:not(:has(.doc)) div.table .title { + padding-bottom: var(--padding-padding-2xs, 0.5rem) !important; +} + +/* Table cells — Metalab 2.0 */ +.boostlook #content table.tableblock th, +.boostlook #content table.tableblock td, +.boostlook:not(:has(.doc)) table.table th, +.boostlook:not(:has(.doc)) table.table td, +.boostlook#libraryReadMe > table th, +.boostlook#libraryReadMe > table td { + padding: 12px 16px; + min-height: 28px; + text-align: left; + border-top: 1px solid var(--border-border-primary, #e4e7ea); + border-left: 1px solid var(--border-border-primary, #e4e7ea); +} + +.boostlook #content table.tableblock th:last-child, +.boostlook #content table.tableblock td:last-child, +.boostlook:not(:has(.doc)) table.table th:last-child, +.boostlook:not(:has(.doc)) table.table td:last-child, +.boostlook#libraryReadMe > table th:last-child, +.boostlook#libraryReadMe > table td:last-child { + border-right: 1px solid var(--border-border-primary, #e4e7ea); +} + +.boostlook #content table.tableblock tr:last-child td, +.boostlook:not(:has(.doc)) table.table tr:last-child td, +.boostlook#libraryReadMe > table tr:last-child td { + border-bottom: 1px solid var(--border-border-primary, #e4e7ea); +} + +.boostlook #content table.tableblock:has(thead) th:first-child, +.boostlook #content table.tableblock:not(:has(thead)) tr:first-child td:first-child, +.boostlook:not(:has(.doc)) table.table:has(thead) th:first-child, +.boostlook:not(:has(.doc)) table.table:not(:has(thead)) tr:first-child td:first-child, +.boostlook#libraryReadMe > table:has(thead) th:first-child, +.boostlook#libraryReadMe > table:not(:has(thead)) tr:first-child td:first-child { + /*border-top-left-radius: var(--spacing-size-2xs, 0.5rem);*/ +} + +.boostlook #content table.tableblock:has(thead) th:last-child, +.boostlook #content table.tableblock:not(:has(thead)) tr:first-child td:last-child, +.boostlook:not(:has(.doc)) table.table:has(thead) th:last-child, +.boostlook:not(:has(.doc)) table.table:not(:has(thead)) tr:first-child td:last-child, +.boostlook#libraryReadMe > table:has(thead) th:last-child, +.boostlook#libraryReadMe > table:not(:has(thead)) tr:first-child td:last-child { + /*border-top-right-radius: var(--spacing-size-2xs, 0.5rem);*/ +} + +.boostlook #content table.tableblock tr:last-child td:first-child, +.boostlook:not(:has(.doc)) table.table tr:last-child td:first-child, +.boostlook#libraryReadMe > table tr:last-child td:first-child { + /*border-bottom-left-radius: var(--spacing-size-2xs, 0.5rem);*/ +} + +.boostlook #content table.tableblock tr:last-child td:last-child, +.boostlook:not(:has(.doc)) table.table tr:last-child td:last-child, +.boostlook#libraryReadMe > table tr:last-child td:last-child { + /*border-bottom-right-radius: var(--spacing-size-2xs, 0.5rem);*/ +} + +/* Table header — Metalab 2.0: Surface-Mid bg */ +.boostlook #content table.tableblock th, +.boostlook #content table.tableblock th strong, +.boostlook:not(:has(.doc)) table.table th, +.boostlook:not(:has(.doc)) table.table th strong, +.boostlook#libraryReadMe > table th, +.boostlook#libraryReadMe > table th strong { + background: var(--surface-background-main-surface-primary, #f7f7f7); + color: var(--text-main-text-primary, #050816); + font-size: 0.75rem; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: 100%; + letter-spacing: -0.12px; +} + +/* Table data — Metalab 2.0: 12px, Text-Secondary */ +.boostlook #content table.tableblock td, +.boostlook:not(:has(.doc)) table.table td, +.boostlook#libraryReadMe > table td { + color: var(--text-main-text-body-secondary, #585A64); + font-size: 0.75rem; + font-style: normal; + line-height: 100%; + letter-spacing: -0.12px; +} + +.boostlook#libraryReadMe > table td { + vertical-align: middle; +} + +.boostlook #content table.tableblock td.valign-top, +.boostlook:not(:has(.doc)) table.table td.valign-top, +.boostlook#libraryReadMe > table td.valign-top { + vertical-align: top; +} + +.boostlook #content table.tableblock td.valign-bottom, +.boostlook:not(:has(.doc)) table.table td.valign-bottom, +.boostlook#libraryReadMe > table td.valign-bottom { + vertical-align: bottom; +} + +.boostlook #content table.tableblock td.valign-center, +.boostlook:not(:has(.doc)) table.table td.valign-center, +.boostlook#libraryReadMe > table td.valign-center { + vertical-align: middle; +} + +.boostlook #content table.tableblock td.halign-left, +.boostlook:not(:has(.doc)) table.table td.halign-left, +.boostlook#libraryReadMe > table td.halign-left { + text-align: left; +} + +.boostlook #content table.tableblock td.halign-center, +.boostlook:not(:has(.doc)) table.table td.halign-center, +.boostlook#libraryReadMe > table td.halign-center { + text-align: center; +} + +.boostlook #content table.tableblock th p, +.boostlook #content table.tableblock td p, +.boostlook:not(:has(.doc)) table.table th p, +.boostlook:not(:has(.doc)) table.table td p, +.boostlook#libraryReadMe > table th p, +.boostlook#libraryReadMe > table td p { + font: inherit; + color: inherit; +} + +.boostlook #content table.tableblock td strong, +.boostlook:not(:has(.doc)) table.table td strong, +.boostlook#libraryReadMe > table td strong { + font-variation-settings: "wght" 600, "wdth" 87.5; +} + +.boostlook #content table.tableblock td code, +.boostlook:not(:has(.doc)) table.table td code, +.boostlook#libraryReadMe > table td code { + background: transparent !important; + padding: 0; + border: none; +} + +.boostlook #content table.tableblock .footnotes tr td, +.boostlook:not(:has(.doc)) table.table .footnotes tr td { + border: none; + border-radius: 0; + padding: var(--padding-padding-xs) 0; +} + +/* Image Styles */ +.boostlook .doc .imageblock, +.boostlook .doc .videoblock { + display: flex; + flex-direction: column; + align-items: center; +} + +.boostlook:not(#libraryReadMe) .image:has(> img), +.boostlook .content:has(> img), +.boostlook .mediaobject:has(> embed) { + display: flex; + padding: var(--padding-padding-md, 1.125rem); + flex-direction: column; + justify-content: center; + align-items: center; + border-radius: var(--spacing-size-xs, 0.75rem); + background: var(--surface-background-main-surface-primary, #f5f6f8); + width: 100%; + margin-top: var(--padding-padding-xs, 0.75rem); +} + +.boostlook:not(#libraryReadMe) .image:has(> img), +.boostlook .content:has(> img) { + background-color: transparent; +} + +.boostlook:not(:has(.doc)) .inlinemediaobject:has(> img, > object) { + display: inline-block; + vertical-align: text-bottom; + line-height: 0; +} + +.doc ul.checklist p>i.fa-check-square-o:first-child, .doc ul.checklist p>i.fa-square-o:first-child { + display: none; +} + +.boostlook .doc .imageblock .content:has(img) { + background-color: transparent; + padding-left: 0; + padding-right: 0; +} + +/*----------------- Global Styles for .boostlook end -----------------*/ + +/* ----------- Scrollbars Styles Start ------------- */ + +/** + * + * Scrollbar Styling + * + * This stylesheet provides comprehensive scrollbar customization for different contexts. + * + * Features: + * 1. Global Scrollbar Styles: + * - Applies thin scrollbar width and custom colors to the HTML element. + * - Customizes scrollbar appearance for elements within the `.boostlook` class. + * + * 2. Media Query Adjustments: + * - For screens with a minimum width of 768px, further customizes scrollbar colors for specific elements. + * - Changes scrollbar thumb color on hover for better visibility. + * + * 3. Webkit Scrollbar Customization: + * - Sets the width and height of the scrollbar. + * - Customizes the scrollbar track and thumb with specific colors and border-radius. + * - Adjusts scrollbar appearance for elements within the `.boostlook` class and its descendants. + * + * 4. Hover Effects: + * - Changes the scrollbar thumb color on hover for better user interaction. + * + */ + +@supports (scrollbar-width: thin) { + /* HTML Matches its scroll background to content background */ + html { + scrollbar-width: thin; + scrollbar-color: var(--border-border-tetriary, #afb3b6) var(--surface-background-main-base-primary, #fff); + } + + .boostlook, + .boostlook *, + .boostlook pre, + .boostlook code, + .boostlook:has(:not(.doc)) div.table .table-contents { + scrollbar-width: thin; + scrollbar-color: var(--border-border-tetriary, #afb3b6) transparent; + } + + @media screen and (min-width: 768px) { + .boostlook pre, + .boostlook code, + .boostlook:has(:not(.doc)) div.table .table-contents { + scrollbar-width: thin; + scrollbar-color: transparent transparent; + } + + .boostlook pre:hover, + .boostlook code:hover, + .boostlook:has(:not(.doc)) div.table .table-contents:hover { + scrollbar-color: var(--border-border-tetriary, #afb3b6) transparent; + } + } +} + +html::-webkit-scrollbar, +.boostlook::-webkit-scrollbar, +.boostlook *::-webkit-scrollbar { + width: 8px !important; + height: 8px !important; +} + +html::-webkit-scrollbar-track { + background: var(--surface-background-main-base-primary, #fff); + border-radius: var(--spacing-size-2xs, 0.5rem); +} + +.boostlook::-webkit-scrollbar-track, +.boostlook *::-webkit-scrollbar-track, +.boostlook pre::-webkit-scrollbar-track, +.boostlook code::-webkit-scrollbar-track, +.boostlook:has(:not(.doc)) div.table .table-contents::-webkit-scrollbar-track { + width: 6px; + background: transparent; + border-radius: var(--spacing-size-2xs, 0.5rem); +} + +html::-webkit-scrollbar-thumb, +.boostlook::-webkit-scrollbar-thumb, +.boostlook *::-webkit-scrollbar-thumb, +.boostlook pre::-webkit-scrollbar-thumb, +.boostlook code::-webkit-scrollbar-thumb, +.boostlook:has(:not(.doc)) div.table .table-contents::-webkit-scrollbar-thumb { + width: 6px; + background: var(--border-border-tetriary, #afb3b6); +} + +@media screen and (min-width: 768px) { + .boostlook pre::-webkit-scrollbar-thumb, + .boostlook code::-webkit-scrollbar-thumb, + .boostlook:has(:not(.doc)) div.table .table-contents::-webkit-scrollbar-thumb { + background: transparent; + } + + .boostlook pre:hover::-webkit-scrollbar-thumb, + .boostlook code:hover::-webkit-scrollbar-thumb, + .boostlook:has(:not(.doc)) div.table .table-contents:hover:-webkit-scrollbar-thumb { + background-color: var(--border-border-tetriary, #afb3b6); + } +} + +.boostlook .doc pre, +.boostlook p code, +.boostlook table code, +.boostlook p tt, +.boostlook p kbd, +.boostlook p samp, +.boostlook p pre, +.boostlook:not(:has(.doc)) pre, +.boostlook code, +.boostlook pre code, +.boostlook .doc .content pre code, +.boostlook#libraryReadMe pre code { + overflow-x: auto; +} + +/* ----------- Scrollbars Styles End ------------- */ + +/* Template-specific Adjustments */ + +/* Hide root scrollbars for Antora template */ +html:has(.article > .boostlook) { + height: 100vh; + overflow: hidden; +} + +/* Iframe container scrollbar handling */ +html:has(#docsiframe) { + overflow-y: hidden; +} + +/* Chrome/Edge scrollbar for iframe container */ +html:has(#docsiframe)::-webkit-scrollbar { + width: 0; + height: 0; +} + +/* Antora template - Scrollable content area */ +.boostlook #content:has(> .doc) { + overflow-y: auto; +} + +/* Asciidoc template - Content overflow handling */ +.boostlook:has(#content > .sect1) { + overflow-y: auto; + height: 100vh; +} + +/* Table Container */ +.boostlook .content div:has(> table), +.boostlook .doc table.tableblock, +.boostlook #content .sect3:has(.tableblock) { + overflow-x: auto !important; +} + +/* Article Layout */ +.article.toc2.toc-left { + height: 100vh; + /* Simplified: always use offset behavior, never center */ + margin-left: var(--main-max-width-leftbar); + background: var(--surface-background-main-base-primary, #fff); + position: relative; + overflow-y: auto; +} + +/* TOC Common start */ +/* Background Colors */ +.boostlook #toc.toc2, +.boostlook #header:not(:has(.nav-container)), +.boostlook #content, +.boostlook #footer { + background: var(--surface-background-main-base-primary, #fff); +} +/* TOC Scrolling */ +.boostlook #toc.toc2 { + overflow-y: auto; + scrollbar-color: inherit; +} +/* TOC Positioning */ +.boostlook #toc.toc2, +#boost-legacy-docs-wrapper:not(:has(article.doc)) #toc.toc2.is-active, +#antora-template-wrapper:not(:has(article.doc)) #toc.toc2.is-active, +div.source-docs-antora.boostlook:not(:has(article.doc)):not(:has(> .boostlook)) #toc.toc2.is-active { + position: static; +} + +/* TOC Toggle Button */ +.boostlook #toggle-toc { + visibility: hidden; + height: 0; + width: 0; +} + +/* TOC Navigation Menu */ +.boostlook #toc ul, +.boostlook:not(:has(.doc)) div.toc dd { + margin: 0; + padding: 0 0 0 var(--leftbar-paddings-leftbar-padding-2xs, 0.5rem); + color: var(--text-main-text-body-secondary, #494d50); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + line-height: var(--typography-line-height-md, 1.25rem); + list-style: none; + box-sizing: border-box; + position: relative; + z-index: 0; +} + +.boostlook #toc .nav-menu > .nav-list, +.boostlook #toc .nav-menu > .nav-list > .nav-list, +.boostlook #toc > ul.sectlevel1 { + padding-left: 0; +} + +.boostlook .nav-menu .nav-list li, +.boostlook #toc > ul.sectlevel1 li:not(:has(> ul)), +.boostlook #toc > ul.sectlevel1 li:has(> ul) a, +.boostlook:not(:has(.doc)) div.toc dt { + position: relative; + padding: var(--leftbar-paddings-leftbar-padding-4xs, 0.125rem) var(--leftbar-paddings-leftbar-padding-3xs, 0.25rem); +} + +.boostlook .nav-menu .nav-list li:has(.nav-text), +.boostlook #toc > ul.sectlevel1 li:has(> ul):not(:first-of-type) { + margin-top: var(--leftbar-paddings-leftbar-padding-4xs, 0.125rem); +} + +.boostlook .nav-text, +.boostlook #toc > ul.sectlevel1 li:has(> ul) > a { + color: var(--text-main-text-body-quaternary, #949a9e); + font-size: var(--typography-font-size-2xs, 0.75rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Table of Contents Links */ +.boostlook #toc a, +.boostlook:not(:has(.doc)) div.toc a { + color: var(--text-main-text-body-secondary, #494d50); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + line-height: var(--typography-line-height-sm, 1rem); /* 142.857% */ + text-decoration: none; +} + +.boostlook #toc a:hover, +.boostlook #toc a:focus, +.boostlook #toc > ul.sectlevel1 li:has(> ul) > a:hover, +.boostlook #toc > ul.sectlevel1 li:has(> ul) > a:focus, +.boostlook:not(:has(.doc)) div.toc a:hover, +.boostlook:not(:has(.doc)) div.toc a:focus { + color: var(--text-main-text-link-blue-secondary, #0284c7); + text-decoration: none; +} +/* +.boostlook #toc .nav-link:visited:not(:hover), +.boostlook #toc .sectlevel1 li:not(:has(> ul)) a:visited:not(:hover), +.boostlook:not(:has(.doc)) div.toc a:visited:not(:hover) { + color: var(--text-main-text-link-viewed, #62b3dd); +} +*/ + +.boostlook .nav-list li[data-depth]:not([data-depth="1"]), +.boostlook #toc > ul.sectlevel1 ul[class*="sectlevel"] > li, +.boostlook:not(:has(.doc)) div.toc dd dt { + margin-left: calc(var(--leftbar-paddings-leftbar-padding-2xs) * -1); + padding-left: calc(var(--padding-padding-sm, 1rem) + var(--leftbar-paddings-leftbar-padding-2xs)); +} + +.boostlook .nav-list li[data-depth]:not([data-depth="1"])::before, +.boostlook #toc > ul.sectlevel1 ul[class*="sectlevel"] > li::before, +.boostlook:not(:has(.doc)) div.toc dd dt:before { + content: ""; + position: absolute; + left: var(--leftbar-paddings-leftbar-padding-2xs); + top: 0; + width: 1px; + height: 100%; + background: var(--border-border-secondary, #d5d7d9); +} + +.boostlook .nav-list li[data-depth]:not([data-depth="1"]):hover::before, +.boostlook #toc > ul.sectlevel1 li:not(:has(> ul)):hover::before, +.boostlook:not(:has(.doc)) div.toc dd dt:hover:before { + background-color: var(--border-border-blue-hover, #329cd2); + isolation: isolate; + z-index: 1; +} + +/* Navigation Menu Title */ +.boostlook #toc #toctitle, +.boostlook .nav-menu h3.title { + padding: var(--leftbar-paddings-leftbar-padding-3xs, 0.25rem); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-2xs, 0.75rem); + line-height: var(--typography-line-height-sm, 1rem); + letter-spacing: var(--spacing-size-size-0, 0rem); + font-variation-settings: "wght" 600, "wdth" 87.5; +} + +/* TOC code in links */ +.boostlook #toc a code, +.boostlook:not(:has(.doc)) div.toc a code { + /* slightly reduce code elements font size in side menu */ + font-size: 0.96em; + display: inline; + background: none !important; + padding: 0; + border: none; + color: inherit; + transition: none; +} + +/* Content */ +.boostlook #content .doc, +.boostlook #content > .sect1, +.boostlook #header > *, +.boostlook #footer > * { + max-width: var(--main-content-width); + margin-left: 0; +} + +.boostlook #preamble + .sect1, +.boostlook .doc .sect1 + .sect1 { + margin-top: revert; +} + +html:not(.is-clipped--nav):has(.boostlook) div#content { + display: block; + visibility: visible; +} + +html.is-clipped--nav:has(.boostlook) div#content { + display: none; + visibility: hidden; +} + +/* Responsive Design */ +@media screen and (min-width: 768px) { + .article.toc2.toc-left { + padding: 0 1rem 0 1rem; + } + + .boostlook #toggle-toc { + visibility: visible; + height: auto; + width: auto; + } + + .boostlook #toc.toc2 { + position: fixed; + width: var(--main-max-width-leftbar); + left: 0; + top: 0; + z-index: 1000; + height: 100vh; + padding: 0; + overflow-x: hidden; + overflow-y: auto; + border-right: 1px solid var(--border-border-primary, #e4e7ea); + visibility: visible; + } + + .boostlook #toc.toc2:not(.nav-container) { + padding: 1rem 1.5rem; + } + + .boostlook #toc.toc2:not(.nav-container):has(#toggle-toc) { + /* Extra left padding if toc toggle exists */ + padding: 1rem 1.5rem 1rem 2.2rem; + } + + + /* TOC Toggle Button */ + .boostlook #toggle-toc { + position: fixed; + top: 2rem; + left: 1rem; + background-color: var(--surface-background-main-base-primary); + box-shadow: 0 0px 3px var(--surface-background-main-surface-transparent-inverse); + border: 0; + padding: 0; + cursor: pointer; + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2224px%22%20viewBox%3D%220%20-960%20960%20960%22%20width%3D%2224px%22%20fill%3D%22%235f6368%22%3E%3Cpath%20d%3D%22M400-240l240-240-240-240-56%2056%20184%20184-184%20184%2056%2056Z%22%2F%3E%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: center; + border-radius: var(--radius-xxl, 1rem); + height: 2rem; + width: 2rem; + text-indent: -9999px; + z-index: 1001; + } + + /* Hidden TOC */ + html.toc-hidden .boostlook { + margin-left: 0; + } + + html.toc-hidden .boostlook #toggle-toc { + left: 2px; + } + + /* Visible TOC */ + html.toc-visible .boostlook #toggle-toc { + left: 2px; + background-color: var(--surface-background-main-base-primary); + } + + html.toc-visible .boostlook { + margin-left: 0; + } + + html.toc-hidden .boostlook #toc.toc2 { + visibility: hidden; + } + + html.toc-visible #toc.toc2 { + opacity: 1; + visibility: visible; + /* width: 250px; + padding-left: 1.5rem; */ + } + + /* TOC Shadow States */ + html.toc-visible:not(.toc-pinned) #toc.toc2 { + box-shadow: 4px 0 12px 0px rgba(0, 0, 0, 0.1); + } + + /* TOC Pin States */ + html.toc-visible.toc-pinned #toggle-toc { + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%2224px%22%20viewBox%3D%220%20-960%20960%20960%22%20width%3D%2224px%22%20fill%3D%22%235f6368%22%3E%3Cpath%20d%3D%22M560-240%20320-480l240-240%2056%2056-184%20184%20184%20184-56%2056Z%22%2F%3E%3C%2Fsvg%3E"); + } + + /* html.toc-visible.toc-pinned .boostlook { + margin-left: var(--main-max-width-leftbar); + } */ +} +/* TOC Common End */ + +/*----------------- Styles specific to AsciiDoctor content start -----------------*/ + +/** + * AsciiDoctor-Specific Styles + * Styles that apply specifically to content generated by AsciiDoctor. + * These styles handle: + * 1. Article layout and structure + * 2. Table of contents (TOC) styling + * 3. Content formatting + * 4. Responsive design adjustments + */ + +/* Header Adjustments */ +.boostlook #header > h1 { + margin-top: 0; +} + +.boostlook #header .author { + display: inline-block; + margin-top: var(--padding-padding-md, 1.125rem); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-lg, 1.25rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-xl, 1.75rem); + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Rouge Syntax Highlighting — matches Figma mapping */ +.boostlook pre.rouge .k, +.boostlook pre.rouge .kt { /* Keywords, types → Blue */ + color: var(--text-code-blue, #1345E8); +} +.boostlook pre.rouge .n, +.boostlook pre.rouge .nf { /* Names, identifiers, functions → Green */ + color: var(--text-code-green, #289D30); +} +.boostlook pre.rouge .o { /* Operators → Red */ + color: var(--text-code-red, #e45649); +} +.boostlook pre.rouge .s, +.boostlook pre.rouge .s1, +.boostlook pre.rouge .s2 { /* Strings → Green */ + color: var(--text-code-green, #289D30); +} +.boostlook pre.rouge .mi, +.boostlook pre.rouge .mf { /* Numbers → Yellow */ + color: var(--text-code-yellow, #A3A38C); +} +.boostlook pre.rouge .p { /* Punctuation → Yellow */ + color: var(--text-code-yellow, #A3A38C); +} +.boostlook pre.rouge .c, +.boostlook pre.rouge .c1, +.boostlook pre.rouge .cm { /* Comments → Grey */ + color: var(--text-code-grey, #9E9E9E); + font-family: "Monaspace Xenon", monospace; + font-style: italic; +} + +.boostlook pre.rouge code span { + font-style: normal; +} + +/*----------------- Styles specific to AsciiDoctor content end -----------------*/ + +/*----------------- Styles specific to Antora Templates start -----------------*/ + +/** + * Antora Template Styles + * Specific styles for Antora-generated documentation. + * These styles handle: + * 1. Header and navigation layout + * 2. Typography customization + * 3. Navigation menu structure + * 4. Content layout and formatting + * 5. Responsive design adaptations + */ + +/* Table of Contents */ +.boostlook .nav { + height: 100%; + padding: var(--spacing-size-sm, 1rem) var(--spacing-size-lg, 1.5rem); + position: static; + background-color: unset; + box-shadow: none; + height: auto; + overflow-y: auto; +} + +/* Toc Navigation */ +.boostlook #toc .nav-menu h3.title a { + color: inherit; + font: inherit; +} + +.boostlook #toc .nav-menu h3.title a:focus, +.boostlook #toc .nav-menu h3.title a:hover { + color: var(--text-main-text-link-blue-secondary, #0284c7); +} + +/* Navigation Menu */ +.boostlook .nav-panel-menu { + overflow: visible; +} + +.boostlook .nav-close { + display: none; +} + +.boostlook .nav-menu > .nav-list > .nav-list { + margin-left: 0; +} + +.boostlook .nav-list li[data-depth]:not([data-depth="1"]).is-current-page.is-active::before { + background-color: var(--text-main-text-primary, #18191b); +} + +/* Active Page Indicator */ +.boostlook .nav-list .is-current-page.is-active { + position: relative; + border-radius: var(--padding-padding-3xs, 0.25rem); + background: var(--surface-background-main-surface-blue-secondary, #daeef9); +} + +.boostlook #toc .nav-list .is-current-page.is-active > .nav-link { + color: var(--text-main-text-primary, #18191b); +} + +/* Header Layout */ +.boostlook #header:has(.nav-container) { + padding: 0; +} + +/* Typography */ +.boostlook .doc, +.boostlook .doc i { + font: inherit; +} +.boostlook .doc i { + color: inherit; +} + +/* TOC Container */ +.boostlook #toc.toc2.nav-container { + position: fixed; +} + +.boostlook #toc.toc2.nav-container.is-active { + position: static; + height: 100vh; + padding: 0; + overflow-y: auto; +} + +/* Nav Toggle */ +.boostlook #content .nav-toggle { + display: flex; + padding: var(--spacing-size-3xs, 0.25rem); + align-items: center; + border: none; + border-radius: var(--spacing-size-2xs, 0.5rem); + outline: none; + line-height: inherit; + height: unset; + width: unset; + margin-right: var(--padding-padding-xs, 0.5rem); + + background: var(--surface-background-main-base-primary, #fff); + background-size: auto; + background-position-x: auto; +} + +.boostlook #content .nav-toggle:before { + content: var(--icon-menu); + line-height: 0; +} + +@media screen and (min-width: 768px) { + .boostlook #content .nav-toggle { + display: none; + visibility: hidden; + } +} + +/* Layout */ +.boostlook .article .content { + gap: 1rem; +} + +.boostlook #content:has(.toc.sidebar) { + display: flex; +} + +.boostlook #footer:has(> script):not(:has(> div)) { + padding-top: 0; + padding-bottom: 0; +} + +/* Toolbar */ +.boostlook .toolbar { + position: static; + height: auto; + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--padding-padding-md, 1.125rem) 0; + color: var(--text-main-text-body-tetriary, #62676b); + background-color: transparent; + box-shadow: unset; +} + +.boostlook .toolbar + h1 { + margin-top: 0; +} + +/* Breadcrumbs */ +.boostlook .breadcrumbs { + display: block; + flex: 1 1; + padding: 0; + font-size: inherit; + line-height: revert; + overflow: auto; + scrollbar-width: none; + margin-right: var(--spacing-size-3xs); +} + +.boostlook .breadcrumbs::-webkit-scrollbar { + display: none; +} + +.boostlook .breadcrumbs ul { + display: flex; + flex-wrap: nowrap; + align-items: center; + margin: 0; + padding: 0; + list-style: none; + color: var(--text-main-text-body-tetriary, #62676b); + font-size: var(--typography-font-size-xs, 0.875rem); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +.boostlook .breadcrumbs ul li { + font: inherit; + display: flex; + align-items: center; + white-space: nowrap; +} + +@media screen and (max-width: 767px) { + .boostlook .breadcrumbs ul li:not(:first-child):not(:last-child) { + display: none; + } +} + +.boostlook .breadcrumbs ul li a { + font: inherit; + color: var(--text-main-text-link-blue-secondary, #0284c7); + text-decoration: none; + position: relative; +} + +.boostlook .breadcrumbs ul li a:hover { + text-decoration: underline; +} + +.boostlook .breadcrumbs ul li:first-of-type { + display: flex; + align-items: center; + padding: var(--spacing-size-3xs, 0.25rem); + margin-right: var(--padding-padding-xs, 0.75rem); + gap: var(--spacing-size-2xs, 0.5rem); + border-radius: var(--spacing-size-2xs, 0.5rem); + border: 1px solid var(--border-border-primary, #e4e7ea); + background: var(--surface-background-main-surface-primary, #f5f6f8); +} + +.boostlook .breadcrumbs ul li:first-of-type::after { + content: none; +} + +.boostlook .breadcrumbs ul li:first-of-type a { + display: flex; + align-items: center; + gap: var(--spacing-size-3xs, 0.25rem); + line-height: 0; + color: var(--text-main-text-primary, #18191b); + text-decoration: none; +} + +.boostlook .breadcrumbs ul li::after { + content: ""; + display: inline-block; + flex-shrink: 0; + flex-grow: 0; + width: 2px; + height: 2px; + border-radius: 50%; + background: var(--surface-icons-icon-tetriary, #949a9e); + padding: 0; + margin: 0 var(--spacing-size-2xs, 0.5rem); +} + +.boostlook .breadcrumbs ul li:first-of-type::after, +.boostlook .breadcrumbs ul li:last-of-type::after { + content: none; +} + +.boostlook .breadcrumbs ul li:first-of-type a svg { + display: none; +} + +.boostlook .breadcrumbs ul li:first-of-type a::before { + content: var(--icon-home); +} + +/* Spirit Navigation */ +.boostlook .toolbar .spirit-nav, +.boostlook:not(:has(.doc)) .spirit-nav { + display: flex; + align-items: center; + gap: 0.125rem; +} + +.boostlook .toolbar .spirit-nav .disabled, +.boostlook:not(:has(.doc)) .spirit-nav .disabled { + opacity: 0.35; + cursor: not-allowed; + pointer-events: none; +} + +.boostlook:not(:has(.doc)) .spirit-nav { + padding-top: var(--padding-padding-md, 1.125rem); + justify-content: flex-end; +} + +.boostlook .toolbar .spirit-nav a, +.boostlook:not(:has(.doc)) .spirit-nav a { + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-size-2xs, 0.5rem); + border-radius: var(--spacing-size-2xs, 0.5rem); + /* border: 1px solid var(--border-border-primary, #e4e7ea); */ + /* background: var(--surface-background-main-base-primary, #fff); */ + width: 32px; + height: 32px; + text-decoration: none; + padding: 0; + position: relative; + transition: all 0.2s ease; +} + +.boostlook .toolbar .spirit-nav a:hover, +.boostlook:not(:has(.doc)) .spirit-nav a:hover { + border: 1px solid var(--border-border-blue, #92cbe9); + background: var(--surface-background-main-surface-blue-secondary, #daeef9); +} + +.boostlook .toolbar .spirit-nav a span { + overflow: hidden; + position: relative; +} + +.boostlook:not(:has(.doc)) .spirit-nav a img { + display: none; + border-width: 0px; +} + +/* hide default icons if elemnts exists */ +.boostlook .toolbar .spirit-nav a span[title*="Previous"], +.boostlook .toolbar .spirit-nav a span[title*="Next"], +.boostlook .toolbar .spirit-nav a span[title*="Up"] { + color: transparent; + display: block; + width: 100%; + height: 100%; +} + +.boostlook .toolbar .spirit-nav a span[title*="Previous"]::after, +.boostlook .toolbar .spirit-nav a span[title*="Next"]::after, +.boostlook .toolbar .spirit-nav a span[title*="Up"]::after, +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey]::after { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + line-height: 0; +} + +.boostlook .toolbar .spirit-nav a span[title*="Previous"]::after, +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey="p"]::after { + content: var(--icon-arrow-left); +} +.boostlook .toolbar .spirit-nav a span[title*="Next"]::after, +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey="n"]::after { + content: var(--icon-arrow-right); +} +.boostlook .toolbar .spirit-nav a span[title*="Up"]::after, +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey="u"]::after { + content: var(--icon-arrow-up); +} +.boostlook .toolbar .spirit-nav a span[title*="Up"]::after, +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey="u"]::after { + content: var(--icon-arrow-up); +} + +.boostlook:not(:has(.doc)) .spirit-nav a[accesskey="h"]::after { + content: var(--icon-home); +} + +/* Tabs Elements */ +.boostlook .tabs .tabpanel { + border: revert; + padding: var(--padding-padding-xs, 0.75rem) 0; + background: transparent; +} + +.boostlook .tablist, +.boostlook .tabs .tabpanel { + border-bottom: 1px solid var(--border-border-primary, #e4e7ea); +} + +.boostlook .tablist > ul[role="tablist"] { + background-color: var(--surface-background-main-surface-primary, #f5f6f8); +} +.dark .boostlook .tablist > ul[role="tablist"] { + background-color: var(--surface-background-main-surface-primary, #18191b); +} +.boostlook .tablist > ul .tab { + position: relative; + display: flex; + padding: var(--padding-padding-2xs, 0.5rem) var(--padding-padding-md, 1.125rem); + justify-content: center; + align-items: center; + color: var(--text-main-text-body-tetriary, #62676b); + font-size: var(--typography-font-size-xs, 0.875rem); + line-height: var(--typography-line-height-md, 1.25rem); /* 142.857% */ + cursor: pointer; + border: none; + background: transparent; +} + +.boostlook .tabs.is-loading .tablist li:first-child::after, +.boostlook .tabs:not(.is-loading) .tablist li.is-selected::after { + content: ""; + display: block; + height: 1px; + position: absolute; + bottom: -1px; + left: 0; + right: 0; + border-bottom: 1px solid var(--text-main-text-primary, #18191b); +} + +.boostlook .tablist > ul .tab * { + color: inherit; +} + +.boostlook .tablist > ul .tab.is-selected, +.boostlook .tablist > ul .tab:hover { + color: var(--text-main-text-primary, #18191b); +} + +.boostlook .tablist.ulist > ul li + li { + margin-left: unset; +} + +.boostlook .tabs:not(.is-loading) .tablist .tab:not(.is-selected) { + background-color: transparent; +} + +/* Search Field Container */ +#search-field { + display: flex; + position: relative; +} + +/* Search Input */ +#search-input { + padding: 0.15rem 0.75rem 0.15rem 1.75rem !important; + border: 1px solid var(--border-border-secondary); + border-radius: var(--radius-m, 0.375rem); + background-color: var(--surface-background-main-surface-primary); + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: 0.35rem center; + background-size: 16px 16px; + color: var(--text-main-text-body-primary); + font-family: inherit; + font-size: 1rem !important; /* 16px minimum prevents iOS zoom on focus */ + transition: border-color 0.15s ease, box-shadow 0.15s ease; +} + +#search-input::placeholder { + color: var(--text-main-text-body-tetriary); +} + +#search-input:focus { + outline: none; + border-color: var(--border-border-blue-primary); + box-shadow: 0 0 0 3px var(--colors-secondary-50); +} + +#search-input:disabled { + background: var(--colors-primary-100); + color: var(--text-main-text-body-tetriary); + cursor: not-allowed; +} + +/* Results Dropdown */ +.search-result-dropdown-menu { + position: absolute; + z-index: 100; + top: 100%; + right: 0; + margin-top: var(--spacing-default, 0.5rem); + min-width: 400px; + border-radius: var(--radius-l, 0.5rem); + background: var(--surface-background-main-base-primary); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); +} + +.search-result-dataset { + padding: 0.5rem; + border: 1px solid var(--border-border-secondary); + border-radius: var(--radius-l, 0.5rem); + min-width: 580px; + max-height: calc(100vh - 6rem); + overflow: auto; +} + +/* Result Component Header */ +.search-result-component-header { + padding: 0.5rem 0.75rem; + margin: 0.25rem 0; + border-bottom: 1px solid var(--border-border-secondary); + color: var(--text-main-text-body-secondary); + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.025em; +} + +/* Result Item */ +.search-result-item { + display: flex; + margin: 0.25rem 0; + border-radius: var(--radius-m, 0.375rem); +} + +.search-result-item:hover { + background: var(--colors-primary-50); +} + +.search-result-item .no-result { + padding: 1rem; + color: var(--text-main-text-body-tetriary); + text-align: center; +} + +/* Result Document Title (Left Column) */ +.search-result-document-title { + width: 25%; + padding: 0.625rem 0.75rem; + border-right: 1px solid var(--border-border-secondary); + color: var(--text-main-text-body-tetriary); + font-size: 0.75rem; + text-align: right; +} + +/* Result Document Hit (Right Column) */ +.search-result-document-hit { + flex: 1; + color: var(--text-main-text-body-secondary); + font-size: 0.8125rem; +} + +.search-result-document-hit > a { + display: block; + padding: 0.5rem 0.75rem; + color: inherit; + text-decoration: none; +} + +.search-result-document-hit > a:hover { + background: transparent; +} + +.search-result-document-hit .search-result-section-title { + margin-bottom: 0.25rem; + color: var(--text-main-text-body-primary); + font-size: 0.875rem; + font-weight: 500; +} + +.search-result-document-hit .search-result-highlight { + padding: 0.1em 0.2em; + border-radius: var(--radius-xs, 0.125rem); + background: var(--colors-secondary-50); + color: var(--text-main-text-link-blue); + font-weight: 500; +} + +/* Search Responsive: Mobile (< 768px) */ +@media screen and (max-width: 767px) { + .boostlook .toolbar { + flex-wrap: wrap; + gap: 0.75rem; + } + + .search-container { + order: 99; + flex: 1 0 100%; + } + + #search-input { + width: 100% !important; + min-width: unset; + font-size: 1rem !important; /* Prevents iOS zoom on focus */ + } + + .search-result-dropdown-menu { + position: fixed; + top: 6rem; + left: 1rem; + right: 1rem; + min-width: unset; + max-width: unset; + width: auto; + } + + .search-result-dataset { + min-width: unset; + } +} + +/* Search Responsive: Tablet (768px - 1023px) */ +@media screen and (min-width: 768px) { + #search-input { + width: unset !important; + min-width: unset !important; + } + + .search-result-dropdown-menu { + position: fixed; + top: 4rem; + left: calc(var(--main-max-width-leftbar) + 1rem); + right: 1rem; + min-width: unset; + max-width: unset; + width: auto; + } + + .search-result-dataset { + min-width: unset; + } +} + +/* Search Responsive: Desktop (1024px+) */ +@media screen and (min-width: 1024px) { + #search-input { + min-width: 200px !important; + z-index: 1001; + } + + .search-result-dropdown-menu { + position: absolute; + top: 100%; + left: auto; + right: 0; + width: clamp(530px, 45vw, 600px); + } +} + +/*----------------- Styles specific to Antora Templates end -----------------*/ + +/*---------- Quickbook docs styling fixes -----------*/ + +/** + * Quickbook Documentation Styles + * Comprehensive styling for Quickbook-generated documentation, including: + * 1. Typography and heading hierarchy + * 2. Content blocks and spacing + * 3. Navigation and spirit-nav elements + * 4. Special elements (notes, tips, etc.) + * 5. Code and syntax highlighting + */ + +#boost-legacy-docs-wrapper:has(> .boostlook), +#antora-template-wrapper:has(> .boostlook), +div.source-docs-antora.boostlook:has(> .boostlook) { + /* CharConv template fix */ + margin: auto; +} + +/* Legacy boostlook container */ +.boostlook#boost-legacy-docs-wrapper, +.boostlook#antora-template-wrapper, +div.source-docs-antora.boostlook { + margin-top: 0; + max-width: unset; + overflow: hidden; + position: relative; + min-height: 100vh; +} + +.boostlook#boost-legacy-docs-wrapper > #header, +.boostlook#boost-legacy-docs-wrapper > #content, +.boostlook#boost-legacy-docs-wrapper > #footer, +.boostlook#boost-legacy-docs-wrapper > #footnotes, +.boostlook#antora-template-wrapper > #header, +.boostlook#antora-template-wrapper > #content, +.boostlook#antora-template-wrapper > #footer, +.boostlook#antora-template-wrapper > #footnotes, +div.source-docs-antora.boostlook > #header, +div.source-docs-antora.boostlook > #content, +div.source-docs-antora.boostlook > #footer, +div.source-docs-antora.boostlook > #footnotes { + /* width: auto; + max-width: unset; + margin-left: auto; */ + padding-left: unset; + padding-right: unset; +} + +/* Add Side margin for legacy boostlook container */ +#boost-legacy-docs-wrapper:not(:has(.doc)):not(:has(> .boostlook)), +#antora-template-wrapper:not(:has(.doc)):not(:has(> .boostlook)), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) { + padding: 0 var(--main-margin, 3rem); +} + +/* Title Block Common */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type { + margin-bottom: var(--padding-padding-md, 1.125rem); +} + +/* Title Styles */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type .title, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type .title, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type .title, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type .title, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type .title, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type .title { + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-2xl, 1.75rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-3xl, 2.5rem); + letter-spacing: var(--spacing-size-size-0, 0rem); + margin: 0; +} + +/* Title Author */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type .author, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type .author, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type .author, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type .author, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type .author, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type .author, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content .author, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content .author, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content .author { + margin: 0; + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-lg, 1.25rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-xl, 1.75rem); + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Top margin for first Author in title */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type div.author, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type div.author, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type div.author, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type div.author, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type div.author, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type div.author, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.author, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.author, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content div.author { + margin-top: var(--padding-padding-md, 1.125rem); +} + +/* Reduce top margin for next authors in authors group */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type .authorgroup div.author:not(:first-child), +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type .authorgroup div.author:not(:first-child), +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type .authorgroup div.author:not(:first-child), +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type .authorgroup div.author:not(:first-child), +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type .authorgroup div.author:not(:first-child), +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type .authorgroup div.author:not(:first-child) { + margin-top: var(--padding-padding-2xs); +} + +/* Remove Top Margin for next .copyright */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type div:has(div.author) + div:has(div.author) .author { + margin-top: var(--padding-padding-3xs); +} + +/* Title Copyright */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type .copyright, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type .copyright, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type .copyright, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type .copyright, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type .copyright, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type .copyright, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content .copyright, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content .copyright, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content .copyright { + color: var(--text-main-text-body-secondary, #494d50); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + line-height: var(--typography-line-height-lg, 1.5rem); + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +/* Remove Top Margin for next .copyright */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type div:has(.copyright) + div:has(.copyright) .copyright { + margin-top: 0; +} + +/* Title Legalnotice */ +.boostlook:not(:has(.doc)) > .section > .titlepage:first-of-type .legalnotice, +.boostlook:not(:has(.doc)) > .document > .titlepage:first-of-type .legalnotice, +.boostlook:not(:has(.doc)) > .refentry > .titlepage:first-of-type .legalnotice, +.boostlook:not(:has(.doc)) > .chapter > .titlepage:first-of-type .legalnotice, +.boostlook:not(:has(.doc)) > .book > .titlepage:first-of-type .legalnotice, +.boostlook:not(:has(.doc)) > .article > .titlepage:first-of-type .legalnotice, + /* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content .legalnotice, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content .legalnotice, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(>.boostlook)) > #content .legalnotice { + color: var(--text-main-text-body-primary, #2a2c30); + font-size: var(--typography-font-size-sm, 1rem); + font-style: normal; + line-height: var(--typography-line-height-lg, 1.5rem); + margin-top: var(--padding-padding-2xs, 0.5rem); +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content .legalnotice, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content .legalnotice, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content .legalnotice { + margin-bottom: var(--padding-padding-md, 1.125rem); +} + +/* Remove
s */ +.boostlook:not(:has(.doc)) .titlepage hr { + display: none; +} + +/* Table of Contents */ +.boostlook:not(:has(.doc)) div.toc { + color: var(--text-main-text-body-secondary, #494d50); + font-family: var(--font-family-body, "Noto Sans"); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + line-height: var(--typography-line-height-md, 1.25rem); + margin: 0; + margin-bottom: var(--padding-padding-md, 1.125rem); + padding: 0; + border: none; +} + +.boostlook:not(:has(.doc)) div.toc > p { + display: flex; + padding: var(--spacing-size-3xs, 0.25rem); + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-2xs, 0.75rem); + font-variation-settings: "wght" 600, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); /* 133.333% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +.boostlook:not(:has(.doc)) div.toc > p > * { + font: inherit; + color: inherit; +} + +.boostlook:not(:has(.doc)) div.toc .toc dt { + color: var(--text-main-text-body-secondary, #494d50); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + line-height: var(--typography-line-height-md, 1.25rem); +} + +.boostlook:not(:has(.doc)) div.toc dd dd { + padding-left: var(--leftbar-paddings-leftbar-padding-sm); +} + +/* Section Layout */ +.boostlook#boost-legacy-docs-wrapper:not(:has(.doc)):not(:has(> .boostlook)) > *, +.boostlook#antora-template-wrapper:not(:has(.doc)):not(:has(> .boostlook)) > *, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > * { + /* max-width: var(--main-content-width); + margin-left: inherit; + margin-right: inherit; */ + margin: 0 auto; +} + +/* hide footer spirit nav since it wasn't visible before */ +.boostlook:not(:has(.doc)) div:nth-of-type(4).spirit-nav, +.boostlook#boost-legacy-docs-wrapper div.spirit-nav:last-child, +.boostlook#antora-template-wrapper div.spirit-nav:last-child, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) div.spirit-nav:last-child { + display: none !important; +} + +/* hidden elems */ +.boostlook:not(:has(.doc)) > hr, +.boostlook:not(:has(.doc)) .table-break { + display: none; +} + +/* Content Blocks */ +.boostlook:not(:has(.doc)) .inlinemediaobject:has(> img):first-child:last-child { + margin: var(--padding-padding-xs, 0.75rem) 0; +} + +.boostlook :is(h1, h2, h3, h4, h5) code, +.boostlook .doc :is(h1, h2, h3, h4, h5) code { + background: transparent !important; + border: none; + font-size: 0.85em; + font-weight: 400; + color: inherit; + padding: 0; + display: initial; + transition: none; +} + +.boostlook:not(:has(.doc)) a:is(h1 a, h2 a, h3 a, h4 a, h5 a) code { + background: transparent !important; + border: none; + font-size: inherit; + color: inherit; + padding: 0; + display: initial; + transition: none; +} + +/* Special Blocks */ +/* hide legacy icon */ +.boostlook:not(:has(.doc)) div:not(.admonitionblock).note > table tr:first-child td, +.boostlook:not(:has(.doc)) div:not(.admonitionblock).tip > table tr:first-child td, +.boostlook:not(:has(.doc)) div:not(.admonitionblock).important > table tr:first-child td, +.boostlook:not(:has(.doc)) div:not(.admonitionblock).caution > table tr:first-child td, +.boostlook:not(:has(.doc)) div:not(.admonitionblock).warning > table tr:first-child td, +.boostlook:not(:has(.doc)) div:not(.admonitionblock).blurb > table tr:first-child td, +.boostlook:not(:has(.doc)) p.blurb > table tr:first-child td { + display: none; +} + +/* Special Blocks Margins */ +.boostlook:not(:has(.doc)) div.note, +.boostlook:not(:has(.doc)) div.tip, +.boostlook:not(:has(.doc)) div.important, +.boostlook:not(:has(.doc)) div.caution, +.boostlook:not(:has(.doc)) div.warning, +.boostlook:not(:has(.doc)) div.blurb, +.boostlook:not(:has(.doc)) p.blurb { + margin-top: var(--padding-padding-xs, 0.75rem); + margin-bottom: var(--padding-padding-2xs); +} + +.boostlook:not(:has(.doc)) .titlepage + div.note, +.boostlook:not(:has(.doc)) .titlepage + div.tip, +.boostlook:not(:has(.doc)) .titlepage + div.important, +.boostlook:not(:has(.doc)) .titlepage + div.caution, +.boostlook:not(:has(.doc)) .titlepage + div.warning, +.boostlook:not(:has(.doc)) .titlepage + div.blurb, +.boostlook:not(:has(.doc)) .titlepage + p.blurb { + margin-top: var(--padding-padding-2xs); +} + +/* Tables */ +/* Make div with Table display block */ +.boostlook:has(:not(.doc)) div.table { + display: block; +} + +/* Enable Horizontal Scroll */ +.boostlook:has(:not(.doc)) div.table .table-contents, +.boostlook:has(:not(.doc)) .informaltable:has(> .table) { + overflow: auto; +} + +/* References Table */ +/* This is specific selector for refences tables which containes many tables and only tables as direct children */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) { + display: flex; + flex-direction: column; + gap: var(--padding-padding-md, 1.125rem); + /* border: 2px solid red; */ +} + +/* Disable margins for all Headings inside table */ +.boostlook:has(:not(.doc)) .informaltable:has(> .table) :is(h1, h2, h3, h4, h5, h6) { + margin: 0; +} + +/* Table has inner table th */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) .table:has(.simplelist) th { + border: none; + padding: 0 0 var(--padding-padding-xs, 0.75rem) 0; + background: none; + color: var(--text-main-text-primary, #18191b); + font-size: var(--typography-font-size-md, 1.125rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-xl, 1.75rem); /* 155.556% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Disable global cell paddings */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) .table:has(.simplelist) > tbody > tr > td { + padding: 0; +} + +/* Add border radius to tbody first row */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) .table:has(.simplelist) tr:last-child td:first-child { + border-top-left-radius: var(--spacing-size-2xs, 0.5rem); + overflow: hidden; +} + +/* Add border radius to tbody first row */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) .table:has(.simplelist) tr:last-child td:last-child { + border-top-right-radius: var(--spacing-size-2xs, 0.5rem); + overflow: hidden; +} + +/* Select Inner Headings and make it look as table head */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) .table:has(.simplelist) tbody :is(h1, h2, h3, h4, h5, h6) { + padding: var(--padding-padding-3xs, 0.25rem) var(--padding-padding-2xs, 0.5rem); + gap: var(--spacing-size-xs, 0.75rem); + background: var(--surface-background-main-surface-primary, #f5f6f8); + color: var(--text-main-text-body-tetriary, #62676b); + font-size: var(--typography-font-size-xs, 0.875rem); + font-style: normal; + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-lg, 1.5rem); /* 171.429% */ + letter-spacing: var(--spacing-size-size-0, 0rem); +} + +/* Inner table styles */ +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) table.simplelist { + width: 100%; +} + +.boostlook:has(:not(.doc)) .informaltable:has(> table:nth-of-type(2)):not(:has(> *:not(table))) table.simplelist td { + border: none; + padding: var(--padding-padding-3xs, 0.25rem) var(--padding-padding-2xs, 0.5rem); +} + +/* Footnotes */ +.boostlook:has(:not(.doc)) .footnotes { + margin-top: var(--padding-padding-lg); + border-top: 1px solid var(--border-border-primary); +} + +.boostlook:has(:not(.doc)) .footnotes hr { + display: none; +} + +/* Copyright Footer */ +/* If Footer has no content than use it as bottom spacer */ +.boostlook .copyright-footer:empty { + padding-top: var(--main-margin); +} + +/* If Footer has content */ +.boostlook .copyright-footer:not(:empty) { + padding: var(--padding-padding-lg) 0; +} + +/* Footer Content */ +.boostlook:not(:has(.doc)) .copyright-footer { + color: var(--text-main-text-body-quaternary, #949a9e); + font-size: var(--typography-font-size-xs); + font-variation-settings: "wght" 500, "wdth" 87.5; + line-height: var(--typography-line-height-sm, 1rem); + letter-spacing: var(--spacing-size-size-0, 0rem); + text-align: left; +} + +/* Footer Content */ +.boostlook:not(:has(.doc)) .copyright-footer p { + text-align: inherit; + font-size: var(--typography-font-size-2xs); + color: var(--text-main-text-body-primary, #2a2c30); +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content hr, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content hr, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content hr { + display: none; +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.code-snippet, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.code-snippet, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content div.code-snippet { + position: relative; +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.highlight:has(> pre), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.highlight:has(> pre), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content div.highlight:has(> pre) { + margin: 0; + border: none; + padding: 0; +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.highlight:has(> pre) pre, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.highlight:has(> pre) pre, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content div.highlight:has(> pre) pre { + padding: var(--spacing-size-xs, 0.75rem) var(--spacing-size-sm, 1rem); + margin-top: var(--padding-padding-3xs, 0.25rem); +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > pre:not([class]), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > pre:not([class]), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content > pre:not([class]) { + margin-left: 0; + margin-right: 0; +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.code-snippet:has(pre):not(:last-child) pre:not([class]), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.code-snippet:has(pre):not(:last-child) pre:not([class]), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content div.code-snippet:has(pre):not(:last-child) pre:not([class]), +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content > pre:not([class]):not(:last-child), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content > pre:not([class]):not(:last-child), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content > pre:not([class]):not(:last-child), +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content div.code-snippet:not(:last-child) pre, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content div.code-snippet:not(:last-child) pre, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content div.code-snippet:not(:last-child) pre { + margin-bottom: var(--padding-padding-xs, 0.75rem); +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content + p:has(> small), +.boostlook:not(:has(.doc))#antora-template-wrapper > #content + p:has(> small), +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content + p:has(> small) { + padding: var(--padding-padding-lg) 0 !important; +} + +/* Outcome 2.2 Weird Template fix */ +.boostlook:not(:has(.doc))#boost-legacy-docs-wrapper > #content .footnotes, +.boostlook:not(:has(.doc))#antora-template-wrapper > #content .footnotes, +div.source-docs-antora.boostlook:not(:has(.doc)):not(:has(> .boostlook)) > #content .footnotes { + padding-top: var(--padding-padding-xs, 0.75rem); +} + +@media screen and (min-width: 768px) { + body.article:has(.boostlook#boost-legacy-docs-wrapper), + body.article:has(.boostlook#antora-template-wrapper), + body.article:has(div.source-docs-antora.boostlook) { + /* !important ovverides website own styles !important + * Adjust this to "padding: 0 1rem 0 1rem" + * when website container width will be used as in new look design + */ + padding: 0 !important; + } + + #boost-legacy-docs-wrapper .boostlook #toc.toc2, + #antora-template-wrapper .boostlook #toc.toc2, + div.source-docs-antora.boostlook:has(> .boostlook) .boostlook #toc.toc2 { + /* Adjust this to "max(1rem, 50% - 45rem)" + * when website container width will be used as in new look design + */ + left: max(0rem, 50% - 45rem); + } +} +/* TOC Common End */ + +/*----------------- Quickbook Documentation Styles end -----------------*/ + +/*----------------- Library README Styles start -----------------*/ + +.boostlook#libraryReadMe { + margin-left: 0; +} + +.boostlook#libraryReadMe > * { + max-width: unset; + margin-left: inherit; + margin-right: inherit; +} + +.boostlook#libraryReadMe > h1:first-child { + margin-top: 0; +} + +.boostlook#libraryReadMe div.highlight:has(> pre) { + background: transparent !important; +} + +.boostlook#libraryReadMe p:has(> a img ) { + display:flex; + flex-wrap:wrap; + justify-content: flex-start; + align-items: center; +} + +.boostlook#libraryReadMe p a:has(> img ) { + margin-left:.5rem; +} + +.boostlook#libraryReadMe > pre:not(:is(dd pre, td pre)) { + padding: var(--spacing-size-xs, 0.75rem) var(--spacing-size-sm, 1rem); + border: 1px solid var(--border-border-secondary, #d5d7d9); +} + +/*----------------- Library README Styles end -----------------*/ + +/*----------------- AsciiDoctor-Specific Responsive TOC Layout start -----------------*/ + +/* Prevent header/content/footer padding from jumping at 990px breakpoint */ +@media (min-width: 990px) { + :root { + --main-max-width-leftbar: 18.25rem; + --main-margin: var(--spacing-size-xl); + } +} + +/* === Tablet/Desktop: TOC Sidebar Layout (768px+) === */ +@media screen and (min-width: 768px) { + .boostlook #toc.toc2 { + position: fixed !important; + left: 0 !important; + width: var(--main-max-width-leftbar) !important; + top: 0 !important; + height: 100vh !important; + } + + .boostlook #toggle-toc { + position: fixed !important; + left: 1rem !important; + top: 2rem !important; + } + + .toc2 .boostlook:has(> #content .doc) { + margin-left: 0; + } + + html.toc-visible .boostlook { + margin-left: 0 !important; + } + + .article.toc2.toc-left { + max-width: none !important; + } + html:not(.toc-hidden, .toc-visible) .article.toc2.toc-left, + .toc-visible.toc-pinned .article.toc2.toc-left { + margin-left: var(--main-max-width-leftbar) !important; + } +} + +/* === Wide Screens: Expanded Content Width (1536px+) === */ +@media screen and (min-width: 1536px) { + :root { + --main-content-width: 1100px; + --main-content-left-spacing: 2rem; + } +} + +/* === Ultra-Wide Screens: Maximum content width (1920px+) === */ +@media screen and (min-width: 1920px) { + :root { + --main-content-width: 1300px; + --main-content-left-spacing: 4rem; + } + + .boostlook #content, + .boostlook #header > h1, + .boostlook #header .author { + margin-left: var(--main-content-left-spacing); + } +} + +/*----------------- AsciiDoctor-Specific Responsive TOC Layout end -----------------*/ diff --git a/preview/2.cpp20-coroutines/2.intro.html b/preview/capy/2.cpp20-coroutines/2.intro.html similarity index 100% rename from preview/2.cpp20-coroutines/2.intro.html rename to preview/capy/2.cpp20-coroutines/2.intro.html diff --git a/preview/2.cpp20-coroutines/2a.foundations.html b/preview/capy/2.cpp20-coroutines/2a.foundations.html similarity index 100% rename from preview/2.cpp20-coroutines/2a.foundations.html rename to preview/capy/2.cpp20-coroutines/2a.foundations.html diff --git a/preview/2.cpp20-coroutines/2b.syntax.html b/preview/capy/2.cpp20-coroutines/2b.syntax.html similarity index 100% rename from preview/2.cpp20-coroutines/2b.syntax.html rename to preview/capy/2.cpp20-coroutines/2b.syntax.html diff --git a/preview/2.cpp20-coroutines/2c.machinery.html b/preview/capy/2.cpp20-coroutines/2c.machinery.html similarity index 100% rename from preview/2.cpp20-coroutines/2c.machinery.html rename to preview/capy/2.cpp20-coroutines/2c.machinery.html diff --git a/preview/2.cpp20-coroutines/2d.advanced.html b/preview/capy/2.cpp20-coroutines/2d.advanced.html similarity index 100% rename from preview/2.cpp20-coroutines/2d.advanced.html rename to preview/capy/2.cpp20-coroutines/2d.advanced.html diff --git a/preview/3.concurrency/3.intro.html b/preview/capy/3.concurrency/3.intro.html similarity index 100% rename from preview/3.concurrency/3.intro.html rename to preview/capy/3.concurrency/3.intro.html diff --git a/preview/3.concurrency/3a.foundations.html b/preview/capy/3.concurrency/3a.foundations.html similarity index 100% rename from preview/3.concurrency/3a.foundations.html rename to preview/capy/3.concurrency/3a.foundations.html diff --git a/preview/3.concurrency/3b.synchronization.html b/preview/capy/3.concurrency/3b.synchronization.html similarity index 100% rename from preview/3.concurrency/3b.synchronization.html rename to preview/capy/3.concurrency/3b.synchronization.html diff --git a/preview/3.concurrency/3c.advanced.html b/preview/capy/3.concurrency/3c.advanced.html similarity index 100% rename from preview/3.concurrency/3c.advanced.html rename to preview/capy/3.concurrency/3c.advanced.html diff --git a/preview/3.concurrency/3d.patterns.html b/preview/capy/3.concurrency/3d.patterns.html similarity index 100% rename from preview/3.concurrency/3d.patterns.html rename to preview/capy/3.concurrency/3d.patterns.html diff --git a/preview/4.coroutines/4.intro.html b/preview/capy/4.coroutines/4.intro.html similarity index 100% rename from preview/4.coroutines/4.intro.html rename to preview/capy/4.coroutines/4.intro.html diff --git a/preview/4.coroutines/4a.tasks.html b/preview/capy/4.coroutines/4a.tasks.html similarity index 100% rename from preview/4.coroutines/4a.tasks.html rename to preview/capy/4.coroutines/4a.tasks.html diff --git a/preview/4.coroutines/4b.launching.html b/preview/capy/4.coroutines/4b.launching.html similarity index 100% rename from preview/4.coroutines/4b.launching.html rename to preview/capy/4.coroutines/4b.launching.html diff --git a/preview/4.coroutines/4c.executors.html b/preview/capy/4.coroutines/4c.executors.html similarity index 100% rename from preview/4.coroutines/4c.executors.html rename to preview/capy/4.coroutines/4c.executors.html diff --git a/preview/4.coroutines/4d.io-awaitable.html b/preview/capy/4.coroutines/4d.io-awaitable.html similarity index 99% rename from preview/4.coroutines/4d.io-awaitable.html rename to preview/capy/4.coroutines/4d.io-awaitable.html index b6d7d73..b69b866 100644 --- a/preview/4.coroutines/4d.io-awaitable.html +++ b/preview/capy/4.coroutines/4d.io-awaitable.html @@ -456,7 +456,7 @@ std::coroutine_handle<> await_suspend(std::coroutine_handle<> h);env→stop_token — A stop token for cooperative cancellation

  • -

    env→allocator — An optional allocator for frame allocation

    +

    env→frame_allocator — An optional frame allocator

  • diff --git a/preview/4.coroutines/4e.cancellation.html b/preview/capy/4.coroutines/4e.cancellation.html similarity index 100% rename from preview/4.coroutines/4e.cancellation.html rename to preview/capy/4.coroutines/4e.cancellation.html diff --git a/preview/4.coroutines/4f.composition.html b/preview/capy/4.coroutines/4f.composition.html similarity index 100% rename from preview/4.coroutines/4f.composition.html rename to preview/capy/4.coroutines/4f.composition.html diff --git a/preview/4.coroutines/4g.allocators.html b/preview/capy/4.coroutines/4g.allocators.html similarity index 100% rename from preview/4.coroutines/4g.allocators.html rename to preview/capy/4.coroutines/4g.allocators.html diff --git a/preview/5.buffers/5.intro.html b/preview/capy/5.buffers/5.intro.html similarity index 100% rename from preview/5.buffers/5.intro.html rename to preview/capy/5.buffers/5.intro.html diff --git a/preview/5.buffers/5a.overview.html b/preview/capy/5.buffers/5a.overview.html similarity index 100% rename from preview/5.buffers/5a.overview.html rename to preview/capy/5.buffers/5a.overview.html diff --git a/preview/5.buffers/5b.types.html b/preview/capy/5.buffers/5b.types.html similarity index 100% rename from preview/5.buffers/5b.types.html rename to preview/capy/5.buffers/5b.types.html diff --git a/preview/5.buffers/5c.sequences.html b/preview/capy/5.buffers/5c.sequences.html similarity index 100% rename from preview/5.buffers/5c.sequences.html rename to preview/capy/5.buffers/5c.sequences.html diff --git a/preview/5.buffers/5d.system-io.html b/preview/capy/5.buffers/5d.system-io.html similarity index 100% rename from preview/5.buffers/5d.system-io.html rename to preview/capy/5.buffers/5d.system-io.html diff --git a/preview/5.buffers/5e.algorithms.html b/preview/capy/5.buffers/5e.algorithms.html similarity index 100% rename from preview/5.buffers/5e.algorithms.html rename to preview/capy/5.buffers/5e.algorithms.html diff --git a/preview/5.buffers/5f.dynamic.html b/preview/capy/5.buffers/5f.dynamic.html similarity index 100% rename from preview/5.buffers/5f.dynamic.html rename to preview/capy/5.buffers/5f.dynamic.html diff --git a/preview/6.streams/6.intro.html b/preview/capy/6.streams/6.intro.html similarity index 100% rename from preview/6.streams/6.intro.html rename to preview/capy/6.streams/6.intro.html diff --git a/preview/6.streams/6a.overview.html b/preview/capy/6.streams/6a.overview.html similarity index 100% rename from preview/6.streams/6a.overview.html rename to preview/capy/6.streams/6a.overview.html diff --git a/preview/6.streams/6b.streams.html b/preview/capy/6.streams/6b.streams.html similarity index 100% rename from preview/6.streams/6b.streams.html rename to preview/capy/6.streams/6b.streams.html diff --git a/preview/6.streams/6c.sources-sinks.html b/preview/capy/6.streams/6c.sources-sinks.html similarity index 100% rename from preview/6.streams/6c.sources-sinks.html rename to preview/capy/6.streams/6c.sources-sinks.html diff --git a/preview/6.streams/6d.buffer-concepts.html b/preview/capy/6.streams/6d.buffer-concepts.html similarity index 100% rename from preview/6.streams/6d.buffer-concepts.html rename to preview/capy/6.streams/6d.buffer-concepts.html diff --git a/preview/6.streams/6e.algorithms.html b/preview/capy/6.streams/6e.algorithms.html similarity index 100% rename from preview/6.streams/6e.algorithms.html rename to preview/capy/6.streams/6e.algorithms.html diff --git a/preview/6.streams/6f.isolation.html b/preview/capy/6.streams/6f.isolation.html similarity index 100% rename from preview/6.streams/6f.isolation.html rename to preview/capy/6.streams/6f.isolation.html diff --git a/preview/7.examples/7.intro.html b/preview/capy/7.examples/7.intro.html similarity index 100% rename from preview/7.examples/7.intro.html rename to preview/capy/7.examples/7.intro.html diff --git a/preview/7.examples/7a.hello-task.html b/preview/capy/7.examples/7a.hello-task.html similarity index 100% rename from preview/7.examples/7a.hello-task.html rename to preview/capy/7.examples/7a.hello-task.html diff --git a/preview/7.examples/7b.producer-consumer.html b/preview/capy/7.examples/7b.producer-consumer.html similarity index 100% rename from preview/7.examples/7b.producer-consumer.html rename to preview/capy/7.examples/7b.producer-consumer.html diff --git a/preview/7.examples/7c.buffer-composition.html b/preview/capy/7.examples/7c.buffer-composition.html similarity index 100% rename from preview/7.examples/7c.buffer-composition.html rename to preview/capy/7.examples/7c.buffer-composition.html diff --git a/preview/7.examples/7d.mock-stream-testing.html b/preview/capy/7.examples/7d.mock-stream-testing.html similarity index 100% rename from preview/7.examples/7d.mock-stream-testing.html rename to preview/capy/7.examples/7d.mock-stream-testing.html diff --git a/preview/7.examples/7e.type-erased-echo.html b/preview/capy/7.examples/7e.type-erased-echo.html similarity index 100% rename from preview/7.examples/7e.type-erased-echo.html rename to preview/capy/7.examples/7e.type-erased-echo.html diff --git a/preview/7.examples/7f.timeout-cancellation.html b/preview/capy/7.examples/7f.timeout-cancellation.html similarity index 100% rename from preview/7.examples/7f.timeout-cancellation.html rename to preview/capy/7.examples/7f.timeout-cancellation.html diff --git a/preview/7.examples/7g.parallel-fetch.html b/preview/capy/7.examples/7g.parallel-fetch.html similarity index 100% rename from preview/7.examples/7g.parallel-fetch.html rename to preview/capy/7.examples/7g.parallel-fetch.html diff --git a/preview/7.examples/7h.custom-dynamic-buffer.html b/preview/capy/7.examples/7h.custom-dynamic-buffer.html similarity index 100% rename from preview/7.examples/7h.custom-dynamic-buffer.html rename to preview/capy/7.examples/7h.custom-dynamic-buffer.html diff --git a/preview/7.examples/7i.echo-server-corosio.html b/preview/capy/7.examples/7i.echo-server-corosio.html similarity index 100% rename from preview/7.examples/7i.echo-server-corosio.html rename to preview/capy/7.examples/7i.echo-server-corosio.html diff --git a/preview/7.examples/7j.stream-pipeline.html b/preview/capy/7.examples/7j.stream-pipeline.html similarity index 100% rename from preview/7.examples/7j.stream-pipeline.html rename to preview/capy/7.examples/7j.stream-pipeline.html diff --git a/preview/8.design/8.intro.html b/preview/capy/8.design/8.intro.html similarity index 100% rename from preview/8.design/8.intro.html rename to preview/capy/8.design/8.intro.html diff --git a/preview/8.design/8a.CapyLayering.html b/preview/capy/8.design/8a.CapyLayering.html similarity index 100% rename from preview/8.design/8a.CapyLayering.html rename to preview/capy/8.design/8a.CapyLayering.html diff --git a/preview/8.design/8b.Separation.html b/preview/capy/8.design/8b.Separation.html similarity index 100% rename from preview/8.design/8b.Separation.html rename to preview/capy/8.design/8b.Separation.html diff --git a/preview/8.design/8c.ReadStream.html b/preview/capy/8.design/8c.ReadStream.html similarity index 100% rename from preview/8.design/8c.ReadStream.html rename to preview/capy/8.design/8c.ReadStream.html diff --git a/preview/8.design/8d.ReadSource.html b/preview/capy/8.design/8d.ReadSource.html similarity index 100% rename from preview/8.design/8d.ReadSource.html rename to preview/capy/8.design/8d.ReadSource.html diff --git a/preview/8.design/8e.BufferSource.html b/preview/capy/8.design/8e.BufferSource.html similarity index 100% rename from preview/8.design/8e.BufferSource.html rename to preview/capy/8.design/8e.BufferSource.html diff --git a/preview/8.design/8f.WriteStream.html b/preview/capy/8.design/8f.WriteStream.html similarity index 100% rename from preview/8.design/8f.WriteStream.html rename to preview/capy/8.design/8f.WriteStream.html diff --git a/preview/8.design/8g.WriteSink.html b/preview/capy/8.design/8g.WriteSink.html similarity index 100% rename from preview/8.design/8g.WriteSink.html rename to preview/capy/8.design/8g.WriteSink.html diff --git a/preview/8.design/8h.BufferSink.html b/preview/capy/8.design/8h.BufferSink.html similarity index 100% rename from preview/8.design/8h.BufferSink.html rename to preview/capy/8.design/8h.BufferSink.html diff --git a/preview/8.design/8i.TypeEraseAwaitable.html b/preview/capy/8.design/8i.TypeEraseAwaitable.html similarity index 100% rename from preview/8.design/8i.TypeEraseAwaitable.html rename to preview/capy/8.design/8i.TypeEraseAwaitable.html diff --git a/preview/8.design/8j.any_buffer_sink.html b/preview/capy/8.design/8j.any_buffer_sink.html similarity index 100% rename from preview/8.design/8j.any_buffer_sink.html rename to preview/capy/8.design/8j.any_buffer_sink.html diff --git a/preview/8.design/8k.Executor.html b/preview/capy/8.design/8k.Executor.html similarity index 100% rename from preview/8.design/8k.Executor.html rename to preview/capy/8.design/8k.Executor.html diff --git a/preview/8.design/8l.RunApi.html b/preview/capy/8.design/8l.RunApi.html similarity index 100% rename from preview/8.design/8l.RunApi.html rename to preview/capy/8.design/8l.RunApi.html diff --git a/preview/8.design/8m.WhyNotCobalt.html b/preview/capy/8.design/8m.WhyNotCobalt.html similarity index 100% rename from preview/8.design/8m.WhyNotCobalt.html rename to preview/capy/8.design/8m.WhyNotCobalt.html diff --git a/preview/8.design/8n.WhyNotCobaltConcepts.html b/preview/capy/8.design/8n.WhyNotCobaltConcepts.html similarity index 100% rename from preview/8.design/8n.WhyNotCobaltConcepts.html rename to preview/capy/8.design/8n.WhyNotCobaltConcepts.html diff --git a/preview/8.design/8o.WhyNotTMC.html b/preview/capy/8.design/8o.WhyNotTMC.html similarity index 100% rename from preview/8.design/8o.WhyNotTMC.html rename to preview/capy/8.design/8o.WhyNotTMC.html diff --git a/preview/capy/index.html b/preview/capy/index.html new file mode 100644 index 0000000..e11f896 --- /dev/null +++ b/preview/capy/index.html @@ -0,0 +1,619 @@ + + + + + + + + + + + + + + Capy :: Boost Libraries Documentation + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Capy

    +
    +
    +
    +

    Capy abstracts away sockets, files, and asynchrony with type-erased streams and buffer sequences—code compiles fast because the implementation is hidden. It provides the framework for concurrent algorithms that transact in buffers of memory: networking, serial ports, console, timers, and any platform I/O. This is only possible because Capy is coroutine-only, enabling optimizations and ergonomics that hybrid approaches must sacrifice.

    +
    +
    +
    +
    +

    What This Library Does

    +
    +
    +
      +
    • +

      Lazy coroutine taskstask<T> with forward-propagating stop tokens and automatic cancellation

      +
    • +
    • +

      Buffer sequences — taken straight from Asio and improved

      +
    • +
    • +

      Stream conceptsReadStream, WriteStream, ReadSource, WriteSink, BufferSource, BufferSink

      +
    • +
    • +

      Type-erased streamsany_stream, any_read_stream, any_write_stream for fast compilation

      +
    • +
    • +

      Concurrency facilities — executors, strands, thread pools, when_all, when_any

      +
    • +
    • +

      Test utilities — mock streams, mock sources/sinks, error injection

      +
    • +
    +
    +
    +
    +
    +

    What This Library Does Not Do

    +
    +
    +
      +
    • +

      Networking — no sockets, acceptors, or DNS; that’s what Corosio provides

      +
    • +
    • +

      Protocols — no HTTP, WebSocket, or TLS; see the Http and Beast2 libraries

      +
    • +
    • +

      Platform event loops — no io_uring, IOCP, epoll, or kqueue; Capy is the layer above

      +
    • +
    • +

      Callbacks or futures — coroutine-only means no other continuation styles

      +
    • +
    • +

      Sender/receiver — Capy uses the IoAwaitable protocol, not std::execution

      +
    • +
    +
    +
    +
    +
    +

    Target Audience

    +
    +
    +
      +
    • +

      Users of Corosio — portable coroutine networking

      +
    • +
    • +

      Users of Http — sans-I/O HTTP/1.1 clients and servers

      +
    • +
    • +

      Users of Websocket — sans-I/O WebSocket

      +
    • +
    • +

      Users of Beast2 — high-level HTTP/WebSocket servers

      +
    • +
    • +

      Users of Burl — high-level HTTP client

      +
    • +
    +
    +
    +

    All of these are built on Capy. Understanding its concepts—tasks, buffer sequences, streams, executors—unlocks the full power of the stack.

    +
    +
    +
    +
    +

    Design Philosophy

    +
    +
    +
      +
    • +

      Use case first. Buffer sequences, stream concepts, executor affinity—these exist because I/O code needs them, not because they’re theoretically elegant.

      +
    • +
    • +

      Coroutines-only. No callbacks, futures, or sender/receiver. Hybrid support forces compromises; full commitment unlocks optimizations that adapted models cannot achieve.

      +
    • +
    • +

      Address the complaints of C++. Type erasure at boundaries, minimal dependencies, and hidden implementations keep builds fast and templates manageable.

      +
    • +
    +
    +
    +
    +
    +

    Requirements

    +
    +
    +

    Assumed Knowledge

    +
    +
      +
    • +

      C++20 coroutines, concepts, and ranges

      +
    • +
    • +

      Basic concurrent programming

      +
    • +
    +
    +
    +
    +

    Compiler Support

    +
    +
      +
    • +

      GCC 12+

      +
    • +
    • +

      Clang 17+

      +
    • +
    • +

      Apple-Clang (macOS 14+)

      +
    • +
    • +

      MSVC 14.34+

      +
    • +
    • +

      MinGW

      +
    • +
    +
    +
    +
    +

    Dependencies

    +
    +

    None. Capy is self-contained and does not require Boost.

    +
    +
    +
    +

    Linking

    +
    +

    Capy is a compiled library. Link against capy.

    +
    +
    +
    +
    +
    +

    Code Convention

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

    Unless otherwise specified, all code examples in this documentation assume the following:

    +
    +
    +
    +
    #include <boost/capy.hpp>
    +using namespace boost::capy;
    +
    +
    +
    +
    +
    +
    +
    +

    Quick Example

    +
    +
    +

    This example demonstrates a minimal coroutine that reads from a stream and echoes the data back:

    +
    +
    +
    +
    #include <boost/capy.hpp>
    +
    +using namespace boost::capy;
    +
    +task<> echo(any_stream& stream)
    +{
    +    char buf[1024];
    +    for(;;)
    +    {
    +        auto [ec, n] = co_await stream.read_some(mutable_buffer(buf));
    +        if(ec.failed())
    +            co_return;
    +        auto [wec, wn] = co_await write(stream, const_buffer(buf, n));
    +        if(wec.failed())
    +            co_return;
    +    }
    +}
    +
    +int main()
    +{
    +    thread_pool pool;
    +    // In a real application, you would obtain a stream from Corosio
    +    // and call: run_async(pool.get_executor())(echo(stream));
    +    return 0;
    +}
    +
    +
    +
    +

    The echo function accepts an any_stream&—a type-erased wrapper that works with any concrete stream implementation. The function reads data into a buffer, then writes it back. Both operations use co_await to suspend until the I/O completes.

    +
    +
    +

    The task<> return type (equivalent to task<void>) creates a lazy coroutine that does not start executing until awaited or launched with run_async.

    +
    +
    +
    +
    +

    Next Steps

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/quick-start.html b/preview/capy/quick-start.html similarity index 100% rename from preview/quick-start.html rename to preview/capy/quick-start.html diff --git a/preview/reference/boost.html b/preview/capy/reference/boost.html similarity index 100% rename from preview/reference/boost.html rename to preview/capy/reference/boost.html diff --git a/preview/reference/boost/capy.html b/preview/capy/reference/boost/capy.html similarity index 100% rename from preview/reference/boost/capy.html rename to preview/capy/reference/boost/capy.html diff --git a/preview/reference/boost/capy/BufferSink.html b/preview/capy/reference/boost/capy/BufferSink.html similarity index 100% rename from preview/reference/boost/capy/BufferSink.html rename to preview/capy/reference/boost/capy/BufferSink.html diff --git a/preview/reference/boost/capy/BufferSource.html b/preview/capy/reference/boost/capy/BufferSource.html similarity index 100% rename from preview/reference/boost/capy/BufferSource.html rename to preview/capy/reference/boost/capy/BufferSource.html diff --git a/preview/reference/boost/capy/ConstBufferSequence.html b/preview/capy/reference/boost/capy/ConstBufferSequence.html similarity index 100% rename from preview/reference/boost/capy/ConstBufferSequence.html rename to preview/capy/reference/boost/capy/ConstBufferSequence.html diff --git a/preview/reference/boost/capy/DynamicBuffer.html b/preview/capy/reference/boost/capy/DynamicBuffer.html similarity index 100% rename from preview/reference/boost/capy/DynamicBuffer.html rename to preview/capy/reference/boost/capy/DynamicBuffer.html diff --git a/preview/reference/boost/capy/DynamicBufferParam.html b/preview/capy/reference/boost/capy/DynamicBufferParam.html similarity index 100% rename from preview/reference/boost/capy/DynamicBufferParam.html rename to preview/capy/reference/boost/capy/DynamicBufferParam.html diff --git a/preview/reference/boost/capy/ExecutionContext.html b/preview/capy/reference/boost/capy/ExecutionContext.html similarity index 100% rename from preview/reference/boost/capy/ExecutionContext.html rename to preview/capy/reference/boost/capy/ExecutionContext.html diff --git a/preview/reference/boost/capy/Executor.html b/preview/capy/reference/boost/capy/Executor.html similarity index 100% rename from preview/reference/boost/capy/Executor.html rename to preview/capy/reference/boost/capy/Executor.html diff --git a/preview/reference/boost/capy/IoAwaitable.html b/preview/capy/reference/boost/capy/IoAwaitable.html similarity index 100% rename from preview/reference/boost/capy/IoAwaitable.html rename to preview/capy/reference/boost/capy/IoAwaitable.html diff --git a/preview/reference/boost/capy/IoAwaitableRange.html b/preview/capy/reference/boost/capy/IoAwaitableRange.html similarity index 100% rename from preview/reference/boost/capy/IoAwaitableRange.html rename to preview/capy/reference/boost/capy/IoAwaitableRange.html diff --git a/preview/reference/boost/capy/IoRunnable.html b/preview/capy/reference/boost/capy/IoRunnable.html similarity index 100% rename from preview/reference/boost/capy/IoRunnable.html rename to preview/capy/reference/boost/capy/IoRunnable.html diff --git a/preview/reference/boost/capy/MatchCondition.html b/preview/capy/reference/boost/capy/MatchCondition.html similarity index 100% rename from preview/reference/boost/capy/MatchCondition.html rename to preview/capy/reference/boost/capy/MatchCondition.html diff --git a/preview/reference/boost/capy/MutableBufferSequence.html b/preview/capy/reference/boost/capy/MutableBufferSequence.html similarity index 100% rename from preview/reference/boost/capy/MutableBufferSequence.html rename to preview/capy/reference/boost/capy/MutableBufferSequence.html diff --git a/preview/reference/boost/capy/ReadSource.html b/preview/capy/reference/boost/capy/ReadSource.html similarity index 100% rename from preview/reference/boost/capy/ReadSource.html rename to preview/capy/reference/boost/capy/ReadSource.html diff --git a/preview/reference/boost/capy/ReadStream.html b/preview/capy/reference/boost/capy/ReadStream.html similarity index 100% rename from preview/reference/boost/capy/ReadStream.html rename to preview/capy/reference/boost/capy/ReadStream.html diff --git a/preview/reference/boost/capy/Stream.html b/preview/capy/reference/boost/capy/Stream.html similarity index 100% rename from preview/reference/boost/capy/Stream.html rename to preview/capy/reference/boost/capy/Stream.html diff --git a/preview/reference/boost/capy/WriteSink.html b/preview/capy/reference/boost/capy/WriteSink.html similarity index 100% rename from preview/reference/boost/capy/WriteSink.html rename to preview/capy/reference/boost/capy/WriteSink.html diff --git a/preview/reference/boost/capy/WriteStream.html b/preview/capy/reference/boost/capy/WriteStream.html similarity index 100% rename from preview/reference/boost/capy/WriteStream.html rename to preview/capy/reference/boost/capy/WriteStream.html diff --git a/preview/reference/boost/capy/any_buffer_sink.html b/preview/capy/reference/boost/capy/any_buffer_sink.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink.html rename to preview/capy/reference/boost/capy/any_buffer_sink.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-06.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-06.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-06.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-07a.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-07a.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-07a.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-07a.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-07d.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-07d.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-07d.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-07d.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-08.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-08.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-08.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-08.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-0c9.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-0c9.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-0c9.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-0c9.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2constructor-0ca.html b/preview/capy/reference/boost/capy/any_buffer_sink/2constructor-0ca.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2constructor-0ca.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2constructor-0ca.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2conversion.html b/preview/capy/reference/boost/capy/any_buffer_sink/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2conversion.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2conversion.html diff --git a/preview/reference/boost/capy/any_buffer_sink/2destructor.html b/preview/capy/reference/boost/capy/any_buffer_sink/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/2destructor.html rename to preview/capy/reference/boost/capy/any_buffer_sink/2destructor.html diff --git a/preview/reference/boost/capy/any_buffer_sink/commit.html b/preview/capy/reference/boost/capy/any_buffer_sink/commit.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/commit.html rename to preview/capy/reference/boost/capy/any_buffer_sink/commit.html diff --git a/preview/reference/boost/capy/any_buffer_sink/commit_eof.html b/preview/capy/reference/boost/capy/any_buffer_sink/commit_eof.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/commit_eof.html rename to preview/capy/reference/boost/capy/any_buffer_sink/commit_eof.html diff --git a/preview/reference/boost/capy/any_buffer_sink/has_value.html b/preview/capy/reference/boost/capy/any_buffer_sink/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/has_value.html rename to preview/capy/reference/boost/capy/any_buffer_sink/has_value.html diff --git a/preview/reference/boost/capy/any_buffer_sink/operator_assign-02.html b/preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/operator_assign-02.html rename to preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-02.html diff --git a/preview/reference/boost/capy/any_buffer_sink/operator_assign-07.html b/preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-07.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/operator_assign-07.html rename to preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-07.html diff --git a/preview/reference/boost/capy/any_buffer_sink/operator_assign-0d.html b/preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-0d.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/operator_assign-0d.html rename to preview/capy/reference/boost/capy/any_buffer_sink/operator_assign-0d.html diff --git a/preview/reference/boost/capy/any_buffer_sink/prepare.html b/preview/capy/reference/boost/capy/any_buffer_sink/prepare.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/prepare.html rename to preview/capy/reference/boost/capy/any_buffer_sink/prepare.html diff --git a/preview/reference/boost/capy/any_buffer_sink/rebind.html b/preview/capy/reference/boost/capy/any_buffer_sink/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/rebind.html rename to preview/capy/reference/boost/capy/any_buffer_sink/rebind.html diff --git a/preview/reference/boost/capy/any_buffer_sink/write.html b/preview/capy/reference/boost/capy/any_buffer_sink/write.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/write.html rename to preview/capy/reference/boost/capy/any_buffer_sink/write.html diff --git a/preview/reference/boost/capy/any_buffer_sink/write_eof-08.html b/preview/capy/reference/boost/capy/any_buffer_sink/write_eof-08.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/write_eof-08.html rename to preview/capy/reference/boost/capy/any_buffer_sink/write_eof-08.html diff --git a/preview/reference/boost/capy/any_buffer_sink/write_eof-0b.html b/preview/capy/reference/boost/capy/any_buffer_sink/write_eof-0b.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/write_eof-0b.html rename to preview/capy/reference/boost/capy/any_buffer_sink/write_eof-0b.html diff --git a/preview/reference/boost/capy/any_buffer_sink/write_eof-0e.html b/preview/capy/reference/boost/capy/any_buffer_sink/write_eof-0e.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/write_eof-0e.html rename to preview/capy/reference/boost/capy/any_buffer_sink/write_eof-0e.html diff --git a/preview/reference/boost/capy/any_buffer_sink/write_some.html b/preview/capy/reference/boost/capy/any_buffer_sink/write_some.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_sink/write_some.html rename to preview/capy/reference/boost/capy/any_buffer_sink/write_some.html diff --git a/preview/reference/boost/capy/any_buffer_source.html b/preview/capy/reference/boost/capy/any_buffer_source.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source.html rename to preview/capy/reference/boost/capy/any_buffer_source.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-02.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-02.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-02.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-02.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-03.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-03.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-03.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-04.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-04.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-04.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-07.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-07.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-07.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-08.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-08.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-08.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-08.html diff --git a/preview/reference/boost/capy/any_buffer_source/2constructor-0c.html b/preview/capy/reference/boost/capy/any_buffer_source/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2constructor-0c.html rename to preview/capy/reference/boost/capy/any_buffer_source/2constructor-0c.html diff --git a/preview/reference/boost/capy/any_buffer_source/2conversion.html b/preview/capy/reference/boost/capy/any_buffer_source/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2conversion.html rename to preview/capy/reference/boost/capy/any_buffer_source/2conversion.html diff --git a/preview/reference/boost/capy/any_buffer_source/2destructor.html b/preview/capy/reference/boost/capy/any_buffer_source/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/2destructor.html rename to preview/capy/reference/boost/capy/any_buffer_source/2destructor.html diff --git a/preview/reference/boost/capy/any_buffer_source/consume.html b/preview/capy/reference/boost/capy/any_buffer_source/consume.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/consume.html rename to preview/capy/reference/boost/capy/any_buffer_source/consume.html diff --git a/preview/reference/boost/capy/any_buffer_source/has_value.html b/preview/capy/reference/boost/capy/any_buffer_source/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/has_value.html rename to preview/capy/reference/boost/capy/any_buffer_source/has_value.html diff --git a/preview/reference/boost/capy/any_buffer_source/operator_assign-02.html b/preview/capy/reference/boost/capy/any_buffer_source/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/operator_assign-02.html rename to preview/capy/reference/boost/capy/any_buffer_source/operator_assign-02.html diff --git a/preview/reference/boost/capy/any_buffer_source/operator_assign-08.html b/preview/capy/reference/boost/capy/any_buffer_source/operator_assign-08.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/operator_assign-08.html rename to preview/capy/reference/boost/capy/any_buffer_source/operator_assign-08.html diff --git a/preview/reference/boost/capy/any_buffer_source/operator_assign-0d.html b/preview/capy/reference/boost/capy/any_buffer_source/operator_assign-0d.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/operator_assign-0d.html rename to preview/capy/reference/boost/capy/any_buffer_source/operator_assign-0d.html diff --git a/preview/reference/boost/capy/any_buffer_source/pull.html b/preview/capy/reference/boost/capy/any_buffer_source/pull.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/pull.html rename to preview/capy/reference/boost/capy/any_buffer_source/pull.html diff --git a/preview/reference/boost/capy/any_buffer_source/read.html b/preview/capy/reference/boost/capy/any_buffer_source/read.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/read.html rename to preview/capy/reference/boost/capy/any_buffer_source/read.html diff --git a/preview/reference/boost/capy/any_buffer_source/read_some.html b/preview/capy/reference/boost/capy/any_buffer_source/read_some.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/read_some.html rename to preview/capy/reference/boost/capy/any_buffer_source/read_some.html diff --git a/preview/reference/boost/capy/any_buffer_source/rebind.html b/preview/capy/reference/boost/capy/any_buffer_source/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_buffer_source/rebind.html rename to preview/capy/reference/boost/capy/any_buffer_source/rebind.html diff --git a/preview/reference/boost/capy/any_executor.html b/preview/capy/reference/boost/capy/any_executor.html similarity index 100% rename from preview/reference/boost/capy/any_executor.html rename to preview/capy/reference/boost/capy/any_executor.html diff --git a/preview/reference/boost/capy/any_executor/2constructor-05.html b/preview/capy/reference/boost/capy/any_executor/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/any_executor/2constructor-05.html rename to preview/capy/reference/boost/capy/any_executor/2constructor-05.html diff --git a/preview/reference/boost/capy/any_executor/2constructor-0d6.html b/preview/capy/reference/boost/capy/any_executor/2constructor-0d6.html similarity index 100% rename from preview/reference/boost/capy/any_executor/2constructor-0d6.html rename to preview/capy/reference/boost/capy/any_executor/2constructor-0d6.html diff --git a/preview/reference/boost/capy/any_executor/2constructor-0d7.html b/preview/capy/reference/boost/capy/any_executor/2constructor-0d7.html similarity index 100% rename from preview/reference/boost/capy/any_executor/2constructor-0d7.html rename to preview/capy/reference/boost/capy/any_executor/2constructor-0d7.html diff --git a/preview/reference/boost/capy/any_executor/2constructor-0f.html b/preview/capy/reference/boost/capy/any_executor/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/any_executor/2constructor-0f.html rename to preview/capy/reference/boost/capy/any_executor/2constructor-0f.html diff --git a/preview/reference/boost/capy/any_executor/2conversion.html b/preview/capy/reference/boost/capy/any_executor/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_executor/2conversion.html rename to preview/capy/reference/boost/capy/any_executor/2conversion.html diff --git a/preview/reference/boost/capy/any_executor/context.html b/preview/capy/reference/boost/capy/any_executor/context.html similarity index 100% rename from preview/reference/boost/capy/any_executor/context.html rename to preview/capy/reference/boost/capy/any_executor/context.html diff --git a/preview/reference/boost/capy/any_executor/dispatch.html b/preview/capy/reference/boost/capy/any_executor/dispatch.html similarity index 100% rename from preview/reference/boost/capy/any_executor/dispatch.html rename to preview/capy/reference/boost/capy/any_executor/dispatch.html diff --git a/preview/reference/boost/capy/any_executor/on_work_finished.html b/preview/capy/reference/boost/capy/any_executor/on_work_finished.html similarity index 100% rename from preview/reference/boost/capy/any_executor/on_work_finished.html rename to preview/capy/reference/boost/capy/any_executor/on_work_finished.html diff --git a/preview/reference/boost/capy/any_executor/on_work_started.html b/preview/capy/reference/boost/capy/any_executor/on_work_started.html similarity index 100% rename from preview/reference/boost/capy/any_executor/on_work_started.html rename to preview/capy/reference/boost/capy/any_executor/on_work_started.html diff --git a/preview/reference/boost/capy/any_executor/operator_assign.html b/preview/capy/reference/boost/capy/any_executor/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/any_executor/operator_assign.html rename to preview/capy/reference/boost/capy/any_executor/operator_assign.html diff --git a/preview/reference/boost/capy/any_executor/operator_eq.html b/preview/capy/reference/boost/capy/any_executor/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/any_executor/operator_eq.html rename to preview/capy/reference/boost/capy/any_executor/operator_eq.html diff --git a/preview/reference/boost/capy/any_executor/post.html b/preview/capy/reference/boost/capy/any_executor/post.html similarity index 100% rename from preview/reference/boost/capy/any_executor/post.html rename to preview/capy/reference/boost/capy/any_executor/post.html diff --git a/preview/reference/boost/capy/any_executor/target_type.html b/preview/capy/reference/boost/capy/any_executor/target_type.html similarity index 100% rename from preview/reference/boost/capy/any_executor/target_type.html rename to preview/capy/reference/boost/capy/any_executor/target_type.html diff --git a/preview/reference/boost/capy/any_read_source.html b/preview/capy/reference/boost/capy/any_read_source.html similarity index 100% rename from preview/reference/boost/capy/any_read_source.html rename to preview/capy/reference/boost/capy/any_read_source.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-02.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-02.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-02.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-02.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-0a.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-0a.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-0a.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-0a.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-0b.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-0b.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-0b.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-0d.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-0d.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-0d.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-0d.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-0fc.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-0fc.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-0fc.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-0fc.html diff --git a/preview/reference/boost/capy/any_read_source/2constructor-0fd.html b/preview/capy/reference/boost/capy/any_read_source/2constructor-0fd.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2constructor-0fd.html rename to preview/capy/reference/boost/capy/any_read_source/2constructor-0fd.html diff --git a/preview/reference/boost/capy/any_read_source/2conversion.html b/preview/capy/reference/boost/capy/any_read_source/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2conversion.html rename to preview/capy/reference/boost/capy/any_read_source/2conversion.html diff --git a/preview/reference/boost/capy/any_read_source/2destructor.html b/preview/capy/reference/boost/capy/any_read_source/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/2destructor.html rename to preview/capy/reference/boost/capy/any_read_source/2destructor.html diff --git a/preview/reference/boost/capy/any_read_source/has_value.html b/preview/capy/reference/boost/capy/any_read_source/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/has_value.html rename to preview/capy/reference/boost/capy/any_read_source/has_value.html diff --git a/preview/reference/boost/capy/any_read_source/operator_assign-08.html b/preview/capy/reference/boost/capy/any_read_source/operator_assign-08.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/operator_assign-08.html rename to preview/capy/reference/boost/capy/any_read_source/operator_assign-08.html diff --git a/preview/reference/boost/capy/any_read_source/operator_assign-0b.html b/preview/capy/reference/boost/capy/any_read_source/operator_assign-0b.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/operator_assign-0b.html rename to preview/capy/reference/boost/capy/any_read_source/operator_assign-0b.html diff --git a/preview/reference/boost/capy/any_read_source/operator_assign-0e.html b/preview/capy/reference/boost/capy/any_read_source/operator_assign-0e.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/operator_assign-0e.html rename to preview/capy/reference/boost/capy/any_read_source/operator_assign-0e.html diff --git a/preview/reference/boost/capy/any_read_source/read.html b/preview/capy/reference/boost/capy/any_read_source/read.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/read.html rename to preview/capy/reference/boost/capy/any_read_source/read.html diff --git a/preview/reference/boost/capy/any_read_source/read_some.html b/preview/capy/reference/boost/capy/any_read_source/read_some.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/read_some.html rename to preview/capy/reference/boost/capy/any_read_source/read_some.html diff --git a/preview/reference/boost/capy/any_read_source/rebind.html b/preview/capy/reference/boost/capy/any_read_source/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_read_source/rebind.html rename to preview/capy/reference/boost/capy/any_read_source/rebind.html diff --git a/preview/reference/boost/capy/any_read_stream.html b/preview/capy/reference/boost/capy/any_read_stream.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream.html rename to preview/capy/reference/boost/capy/any_read_stream.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-004.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-004.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-004.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-004.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-007.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-007.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-007.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-007.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-01.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-01.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-01.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-080.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-080.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-080.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-080.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-08d.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-08d.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-08d.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-08d.html diff --git a/preview/reference/boost/capy/any_read_stream/2constructor-0c.html b/preview/capy/reference/boost/capy/any_read_stream/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2constructor-0c.html rename to preview/capy/reference/boost/capy/any_read_stream/2constructor-0c.html diff --git a/preview/reference/boost/capy/any_read_stream/2conversion.html b/preview/capy/reference/boost/capy/any_read_stream/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2conversion.html rename to preview/capy/reference/boost/capy/any_read_stream/2conversion.html diff --git a/preview/reference/boost/capy/any_read_stream/2destructor.html b/preview/capy/reference/boost/capy/any_read_stream/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/2destructor.html rename to preview/capy/reference/boost/capy/any_read_stream/2destructor.html diff --git a/preview/reference/boost/capy/any_read_stream/has_value.html b/preview/capy/reference/boost/capy/any_read_stream/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/has_value.html rename to preview/capy/reference/boost/capy/any_read_stream/has_value.html diff --git a/preview/reference/boost/capy/any_read_stream/operator_assign-04.html b/preview/capy/reference/boost/capy/any_read_stream/operator_assign-04.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/operator_assign-04.html rename to preview/capy/reference/boost/capy/any_read_stream/operator_assign-04.html diff --git a/preview/reference/boost/capy/any_read_stream/operator_assign-09.html b/preview/capy/reference/boost/capy/any_read_stream/operator_assign-09.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/operator_assign-09.html rename to preview/capy/reference/boost/capy/any_read_stream/operator_assign-09.html diff --git a/preview/reference/boost/capy/any_read_stream/operator_assign-0b.html b/preview/capy/reference/boost/capy/any_read_stream/operator_assign-0b.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/operator_assign-0b.html rename to preview/capy/reference/boost/capy/any_read_stream/operator_assign-0b.html diff --git a/preview/reference/boost/capy/any_read_stream/read_some.html b/preview/capy/reference/boost/capy/any_read_stream/read_some.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/read_some.html rename to preview/capy/reference/boost/capy/any_read_stream/read_some.html diff --git a/preview/reference/boost/capy/any_read_stream/rebind.html b/preview/capy/reference/boost/capy/any_read_stream/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_read_stream/rebind.html rename to preview/capy/reference/boost/capy/any_read_stream/rebind.html diff --git a/preview/reference/boost/capy/any_stream.html b/preview/capy/reference/boost/capy/any_stream.html similarity index 100% rename from preview/reference/boost/capy/any_stream.html rename to preview/capy/reference/boost/capy/any_stream.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-01.html b/preview/capy/reference/boost/capy/any_stream/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-01.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-01.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-0b.html b/preview/capy/reference/boost/capy/any_stream/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-0b.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-0b.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-0c.html b/preview/capy/reference/boost/capy/any_stream/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-0c.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-0c.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-0d3.html b/preview/capy/reference/boost/capy/any_stream/2constructor-0d3.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-0d3.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-0d3.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-0db.html b/preview/capy/reference/boost/capy/any_stream/2constructor-0db.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-0db.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-0db.html diff --git a/preview/reference/boost/capy/any_stream/2constructor-0f.html b/preview/capy/reference/boost/capy/any_stream/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2constructor-0f.html rename to preview/capy/reference/boost/capy/any_stream/2constructor-0f.html diff --git a/preview/reference/boost/capy/any_stream/2conversion.html b/preview/capy/reference/boost/capy/any_stream/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2conversion.html rename to preview/capy/reference/boost/capy/any_stream/2conversion.html diff --git a/preview/reference/boost/capy/any_stream/2destructor.html b/preview/capy/reference/boost/capy/any_stream/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_stream/2destructor.html rename to preview/capy/reference/boost/capy/any_stream/2destructor.html diff --git a/preview/reference/boost/capy/any_stream/has_value.html b/preview/capy/reference/boost/capy/any_stream/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_stream/has_value.html rename to preview/capy/reference/boost/capy/any_stream/has_value.html diff --git a/preview/reference/boost/capy/any_stream/operator_assign-02.html b/preview/capy/reference/boost/capy/any_stream/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/any_stream/operator_assign-02.html rename to preview/capy/reference/boost/capy/any_stream/operator_assign-02.html diff --git a/preview/reference/boost/capy/any_stream/operator_assign-06.html b/preview/capy/reference/boost/capy/any_stream/operator_assign-06.html similarity index 100% rename from preview/reference/boost/capy/any_stream/operator_assign-06.html rename to preview/capy/reference/boost/capy/any_stream/operator_assign-06.html diff --git a/preview/reference/boost/capy/any_stream/operator_assign-07.html b/preview/capy/reference/boost/capy/any_stream/operator_assign-07.html similarity index 100% rename from preview/reference/boost/capy/any_stream/operator_assign-07.html rename to preview/capy/reference/boost/capy/any_stream/operator_assign-07.html diff --git a/preview/reference/boost/capy/any_write_sink.html b/preview/capy/reference/boost/capy/any_write_sink.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink.html rename to preview/capy/reference/boost/capy/any_write_sink.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-01.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-01.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-01.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-02.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-02.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-02.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-02.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-04.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-04.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-04.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-07.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-07.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-07.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-0f7.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-0f7.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-0f7.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-0f7.html diff --git a/preview/reference/boost/capy/any_write_sink/2constructor-0f9.html b/preview/capy/reference/boost/capy/any_write_sink/2constructor-0f9.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2constructor-0f9.html rename to preview/capy/reference/boost/capy/any_write_sink/2constructor-0f9.html diff --git a/preview/reference/boost/capy/any_write_sink/2conversion.html b/preview/capy/reference/boost/capy/any_write_sink/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2conversion.html rename to preview/capy/reference/boost/capy/any_write_sink/2conversion.html diff --git a/preview/reference/boost/capy/any_write_sink/2destructor.html b/preview/capy/reference/boost/capy/any_write_sink/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/2destructor.html rename to preview/capy/reference/boost/capy/any_write_sink/2destructor.html diff --git a/preview/reference/boost/capy/any_write_sink/has_value.html b/preview/capy/reference/boost/capy/any_write_sink/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/has_value.html rename to preview/capy/reference/boost/capy/any_write_sink/has_value.html diff --git a/preview/reference/boost/capy/any_write_sink/operator_assign-08b.html b/preview/capy/reference/boost/capy/any_write_sink/operator_assign-08b.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/operator_assign-08b.html rename to preview/capy/reference/boost/capy/any_write_sink/operator_assign-08b.html diff --git a/preview/reference/boost/capy/any_write_sink/operator_assign-08d.html b/preview/capy/reference/boost/capy/any_write_sink/operator_assign-08d.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/operator_assign-08d.html rename to preview/capy/reference/boost/capy/any_write_sink/operator_assign-08d.html diff --git a/preview/reference/boost/capy/any_write_sink/operator_assign-0c.html b/preview/capy/reference/boost/capy/any_write_sink/operator_assign-0c.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/operator_assign-0c.html rename to preview/capy/reference/boost/capy/any_write_sink/operator_assign-0c.html diff --git a/preview/reference/boost/capy/any_write_sink/rebind.html b/preview/capy/reference/boost/capy/any_write_sink/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/rebind.html rename to preview/capy/reference/boost/capy/any_write_sink/rebind.html diff --git a/preview/reference/boost/capy/any_write_sink/write.html b/preview/capy/reference/boost/capy/any_write_sink/write.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/write.html rename to preview/capy/reference/boost/capy/any_write_sink/write.html diff --git a/preview/reference/boost/capy/any_write_sink/write_eof-05.html b/preview/capy/reference/boost/capy/any_write_sink/write_eof-05.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/write_eof-05.html rename to preview/capy/reference/boost/capy/any_write_sink/write_eof-05.html diff --git a/preview/reference/boost/capy/any_write_sink/write_eof-0b.html b/preview/capy/reference/boost/capy/any_write_sink/write_eof-0b.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/write_eof-0b.html rename to preview/capy/reference/boost/capy/any_write_sink/write_eof-0b.html diff --git a/preview/reference/boost/capy/any_write_sink/write_eof-0d.html b/preview/capy/reference/boost/capy/any_write_sink/write_eof-0d.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/write_eof-0d.html rename to preview/capy/reference/boost/capy/any_write_sink/write_eof-0d.html diff --git a/preview/reference/boost/capy/any_write_sink/write_some.html b/preview/capy/reference/boost/capy/any_write_sink/write_some.html similarity index 100% rename from preview/reference/boost/capy/any_write_sink/write_some.html rename to preview/capy/reference/boost/capy/any_write_sink/write_some.html diff --git a/preview/reference/boost/capy/any_write_stream.html b/preview/capy/reference/boost/capy/any_write_stream.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream.html rename to preview/capy/reference/boost/capy/any_write_stream.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-01.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-01.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-01.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-059.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-059.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-059.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-059.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-05e.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-05e.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-05e.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-05e.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-07.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-07.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-07.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-09.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-09.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-09.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-09.html diff --git a/preview/reference/boost/capy/any_write_stream/2constructor-0f.html b/preview/capy/reference/boost/capy/any_write_stream/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2constructor-0f.html rename to preview/capy/reference/boost/capy/any_write_stream/2constructor-0f.html diff --git a/preview/reference/boost/capy/any_write_stream/2conversion.html b/preview/capy/reference/boost/capy/any_write_stream/2conversion.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2conversion.html rename to preview/capy/reference/boost/capy/any_write_stream/2conversion.html diff --git a/preview/reference/boost/capy/any_write_stream/2destructor.html b/preview/capy/reference/boost/capy/any_write_stream/2destructor.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/2destructor.html rename to preview/capy/reference/boost/capy/any_write_stream/2destructor.html diff --git a/preview/reference/boost/capy/any_write_stream/has_value.html b/preview/capy/reference/boost/capy/any_write_stream/has_value.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/has_value.html rename to preview/capy/reference/boost/capy/any_write_stream/has_value.html diff --git a/preview/reference/boost/capy/any_write_stream/operator_assign-05.html b/preview/capy/reference/boost/capy/any_write_stream/operator_assign-05.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/operator_assign-05.html rename to preview/capy/reference/boost/capy/any_write_stream/operator_assign-05.html diff --git a/preview/reference/boost/capy/any_write_stream/operator_assign-0b.html b/preview/capy/reference/boost/capy/any_write_stream/operator_assign-0b.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/operator_assign-0b.html rename to preview/capy/reference/boost/capy/any_write_stream/operator_assign-0b.html diff --git a/preview/reference/boost/capy/any_write_stream/operator_assign-0c.html b/preview/capy/reference/boost/capy/any_write_stream/operator_assign-0c.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/operator_assign-0c.html rename to preview/capy/reference/boost/capy/any_write_stream/operator_assign-0c.html diff --git a/preview/reference/boost/capy/any_write_stream/rebind.html b/preview/capy/reference/boost/capy/any_write_stream/rebind.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/rebind.html rename to preview/capy/reference/boost/capy/any_write_stream/rebind.html diff --git a/preview/reference/boost/capy/any_write_stream/write_some.html b/preview/capy/reference/boost/capy/any_write_stream/write_some.html similarity index 100% rename from preview/reference/boost/capy/any_write_stream/write_some.html rename to preview/capy/reference/boost/capy/any_write_stream/write_some.html diff --git a/preview/reference/boost/capy/async_event.html b/preview/capy/reference/boost/capy/async_event.html similarity index 100% rename from preview/reference/boost/capy/async_event.html rename to preview/capy/reference/boost/capy/async_event.html diff --git a/preview/reference/boost/capy/async_event/2constructor-02.html b/preview/capy/reference/boost/capy/async_event/2constructor-02.html similarity index 100% rename from preview/reference/boost/capy/async_event/2constructor-02.html rename to preview/capy/reference/boost/capy/async_event/2constructor-02.html diff --git a/preview/reference/boost/capy/async_event/2constructor-06.html b/preview/capy/reference/boost/capy/async_event/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/async_event/2constructor-06.html rename to preview/capy/reference/boost/capy/async_event/2constructor-06.html diff --git a/preview/reference/boost/capy/async_event/2constructor-0b.html b/preview/capy/reference/boost/capy/async_event/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/async_event/2constructor-0b.html rename to preview/capy/reference/boost/capy/async_event/2constructor-0b.html diff --git a/preview/reference/boost/capy/async_event/clear.html b/preview/capy/reference/boost/capy/async_event/clear.html similarity index 100% rename from preview/reference/boost/capy/async_event/clear.html rename to preview/capy/reference/boost/capy/async_event/clear.html diff --git a/preview/reference/boost/capy/async_event/is_set.html b/preview/capy/reference/boost/capy/async_event/is_set.html similarity index 100% rename from preview/reference/boost/capy/async_event/is_set.html rename to preview/capy/reference/boost/capy/async_event/is_set.html diff --git a/preview/reference/boost/capy/async_event/operator_assign.html b/preview/capy/reference/boost/capy/async_event/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/async_event/operator_assign.html rename to preview/capy/reference/boost/capy/async_event/operator_assign.html diff --git a/preview/reference/boost/capy/async_event/set.html b/preview/capy/reference/boost/capy/async_event/set.html similarity index 100% rename from preview/reference/boost/capy/async_event/set.html rename to preview/capy/reference/boost/capy/async_event/set.html diff --git a/preview/reference/boost/capy/async_event/wait.html b/preview/capy/reference/boost/capy/async_event/wait.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait.html rename to preview/capy/reference/boost/capy/async_event/wait.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/2constructor-002.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-002.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/2constructor-002.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-002.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/2constructor-00b.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-00b.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/2constructor-00b.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-00b.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/2constructor-01.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/2constructor-01.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-01.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/2constructor-06.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/2constructor-06.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/2constructor-06.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/2destructor.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/2destructor.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/2destructor.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/2destructor.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/await_ready.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/await_ready.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/await_ready.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/await_ready.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/await_resume.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/await_resume.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/await_resume.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/await_resume.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/await_suspend.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/await_suspend.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/await_suspend.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-02.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-02.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-02.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-06.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-06.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-06.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-06.html diff --git a/preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-0e.html b/preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-0e.html similarity index 100% rename from preview/reference/boost/capy/async_event/wait_awaiter/operator_assign-0e.html rename to preview/capy/reference/boost/capy/async_event/wait_awaiter/operator_assign-0e.html diff --git a/preview/reference/boost/capy/async_mutex.html b/preview/capy/reference/boost/capy/async_mutex.html similarity index 100% rename from preview/reference/boost/capy/async_mutex.html rename to preview/capy/reference/boost/capy/async_mutex.html diff --git a/preview/reference/boost/capy/async_mutex/2constructor-01.html b/preview/capy/reference/boost/capy/async_mutex/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/2constructor-01.html rename to preview/capy/reference/boost/capy/async_mutex/2constructor-01.html diff --git a/preview/reference/boost/capy/async_mutex/2constructor-03.html b/preview/capy/reference/boost/capy/async_mutex/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/2constructor-03.html rename to preview/capy/reference/boost/capy/async_mutex/2constructor-03.html diff --git a/preview/reference/boost/capy/async_mutex/2constructor-0a.html b/preview/capy/reference/boost/capy/async_mutex/2constructor-0a.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/2constructor-0a.html rename to preview/capy/reference/boost/capy/async_mutex/2constructor-0a.html diff --git a/preview/reference/boost/capy/async_mutex/is_locked.html b/preview/capy/reference/boost/capy/async_mutex/is_locked.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/is_locked.html rename to preview/capy/reference/boost/capy/async_mutex/is_locked.html diff --git a/preview/reference/boost/capy/async_mutex/lock.html b/preview/capy/reference/boost/capy/async_mutex/lock.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock.html rename to preview/capy/reference/boost/capy/async_mutex/lock.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-05.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-05.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-05.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-061.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-061.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-061.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-061.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-063.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-063.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-063.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-063.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-0b.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/2constructor-0b.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2constructor-0b.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/2destructor.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2destructor.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/2destructor.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/2destructor.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/await_ready.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_ready.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/await_ready.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_ready.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/await_resume.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_resume.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/await_resume.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_resume.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/await_suspend.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/await_suspend.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/await_suspend.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-06.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-06.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-06.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-06.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0b.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0b.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0b.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0b.html diff --git a/preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0f.html b/preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0f.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0f.html rename to preview/capy/reference/boost/capy/async_mutex/lock_awaiter/operator_assign-0f.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2constructor-04.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2constructor-04.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-04.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0a.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0a.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0a.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0a.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0e.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0e.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0e.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0e.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0f93.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0f93.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0f93.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0f93.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0f9d.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0f9d.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2constructor-0f9d.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2constructor-0f9d.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/2destructor.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/2destructor.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/2destructor.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/2destructor.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-05.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-05.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-05.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-05.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-0a.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-0a.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-0a.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-0a.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-0f.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-0f.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard/operator_assign-0f.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard/operator_assign-0f.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard_awaiter.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard_awaiter.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard_awaiter/2constructor.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/2constructor.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard_awaiter/2constructor.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/2constructor.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_ready.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_ready.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_ready.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_ready.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_resume.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_resume.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_resume.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_resume.html diff --git a/preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_suspend.html b/preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/lock_guard_awaiter/await_suspend.html rename to preview/capy/reference/boost/capy/async_mutex/lock_guard_awaiter/await_suspend.html diff --git a/preview/reference/boost/capy/async_mutex/operator_assign.html b/preview/capy/reference/boost/capy/async_mutex/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/operator_assign.html rename to preview/capy/reference/boost/capy/async_mutex/operator_assign.html diff --git a/preview/reference/boost/capy/async_mutex/scoped_lock.html b/preview/capy/reference/boost/capy/async_mutex/scoped_lock.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/scoped_lock.html rename to preview/capy/reference/boost/capy/async_mutex/scoped_lock.html diff --git a/preview/reference/boost/capy/async_mutex/unlock.html b/preview/capy/reference/boost/capy/async_mutex/unlock.html similarity index 100% rename from preview/reference/boost/capy/async_mutex/unlock.html rename to preview/capy/reference/boost/capy/async_mutex/unlock.html diff --git a/preview/reference/boost/capy/awaitable_decomposes_to.html b/preview/capy/reference/boost/capy/awaitable_decomposes_to.html similarity index 100% rename from preview/reference/boost/capy/awaitable_decomposes_to.html rename to preview/capy/reference/boost/capy/awaitable_decomposes_to.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-00.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-00.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-00.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-00.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-06.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-06.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-06.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-0b.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/2constructor-0b.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2constructor-0b.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/2destructor.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2destructor.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/2destructor.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/2destructor.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/capacity.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/capacity.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/capacity.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/capacity.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/commit.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/commit.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/commit.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/commit.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/const_buffers_type.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/const_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/const_buffers_type.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/const_buffers_type.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/consume.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/consume.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/consume.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/consume.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/data.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/data.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/data.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/data.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/is_dynamic_buffer_adapter.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/is_dynamic_buffer_adapter.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/is_dynamic_buffer_adapter.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/is_dynamic_buffer_adapter.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/max_size.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/max_size.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/max_size.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/max_size.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/mutable_buffers_type.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/mutable_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/mutable_buffers_type.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/mutable_buffers_type.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/operator_assign.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/operator_assign.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/operator_assign.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/prepare.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/prepare.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/prepare.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/prepare.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/size.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/size.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/size.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/size.html diff --git a/preview/reference/boost/capy/basic_string_dynamic_buffer/string_type.html b/preview/capy/reference/boost/capy/basic_string_dynamic_buffer/string_type.html similarity index 100% rename from preview/reference/boost/capy/basic_string_dynamic_buffer/string_type.html rename to preview/capy/reference/boost/capy/basic_string_dynamic_buffer/string_type.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0d8.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0d8.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0d8.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0d8.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-05.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-05.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-05.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0c.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0c.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0c.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0e.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0e.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0e.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2constructor-0e.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2destructor.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2destructor.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/2destructor.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/2destructor.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/capacity.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/capacity.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/capacity.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/capacity.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/commit.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/commit.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/commit.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/commit.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/const_buffers_type.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/const_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/const_buffers_type.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/const_buffers_type.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/consume.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/consume.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/consume.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/consume.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/data.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/data.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/data.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/data.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/is_dynamic_buffer_adapter.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/is_dynamic_buffer_adapter.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/is_dynamic_buffer_adapter.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/is_dynamic_buffer_adapter.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/max_size.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/max_size.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/max_size.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/max_size.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/mutable_buffers_type.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/mutable_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/mutable_buffers_type.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/mutable_buffers_type.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/operator_assign.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/operator_assign.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/operator_assign.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/prepare.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/prepare.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/prepare.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/prepare.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/size.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/size.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/size.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/size.html diff --git a/preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/vector_type.html b/preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/vector_type.html similarity index 100% rename from preview/reference/boost/capy/basic_vector_dynamic_buffer-0df/vector_type.html rename to preview/capy/reference/boost/capy/basic_vector_dynamic_buffer-0df/vector_type.html diff --git a/preview/reference/boost/capy/begin.html b/preview/capy/reference/boost/capy/begin.html similarity index 100% rename from preview/reference/boost/capy/begin.html rename to preview/capy/reference/boost/capy/begin.html diff --git a/preview/reference/boost/capy/begin_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/begin_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/begin_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/begin_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-02.html b/preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-02.html similarity index 100% rename from preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-02.html rename to preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-02.html diff --git a/preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-04.html b/preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-04.html similarity index 100% rename from preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-04.html rename to preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-04.html diff --git a/preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-07.html b/preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-07.html similarity index 100% rename from preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-07.html rename to preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-07.html diff --git a/preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-09.html b/preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-09.html similarity index 100% rename from preview/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-09.html rename to preview/capy/reference/boost/capy/begin_mrdocs_workaround_t/operator_call-09.html diff --git a/preview/reference/boost/capy/buffer_array.html b/preview/capy/reference/boost/capy/buffer_array.html similarity index 100% rename from preview/reference/boost/capy/buffer_array.html rename to preview/capy/reference/boost/capy/buffer_array.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-02.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-02.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-02.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-02.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-03.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-03.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-03.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-05.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-05.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-05.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-06.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-06.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-06.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-08.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-08.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-08.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-08.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-0a.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-0a.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-0a.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-0a.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-0f5.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-0f5.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-0f5.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-0f5.html diff --git a/preview/reference/boost/capy/buffer_array/2constructor-0f9.html b/preview/capy/reference/boost/capy/buffer_array/2constructor-0f9.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2constructor-0f9.html rename to preview/capy/reference/boost/capy/buffer_array/2constructor-0f9.html diff --git a/preview/reference/boost/capy/buffer_array/2conversion-00.html b/preview/capy/reference/boost/capy/buffer_array/2conversion-00.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2conversion-00.html rename to preview/capy/reference/boost/capy/buffer_array/2conversion-00.html diff --git a/preview/reference/boost/capy/buffer_array/2conversion-08.html b/preview/capy/reference/boost/capy/buffer_array/2conversion-08.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2conversion-08.html rename to preview/capy/reference/boost/capy/buffer_array/2conversion-08.html diff --git a/preview/reference/boost/capy/buffer_array/2destructor.html b/preview/capy/reference/boost/capy/buffer_array/2destructor.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/2destructor.html rename to preview/capy/reference/boost/capy/buffer_array/2destructor.html diff --git a/preview/reference/boost/capy/buffer_array/arr_.html b/preview/capy/reference/boost/capy/buffer_array/arr_.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/arr_.html rename to preview/capy/reference/boost/capy/buffer_array/arr_.html diff --git a/preview/reference/boost/capy/buffer_array/begin-02.html b/preview/capy/reference/boost/capy/buffer_array/begin-02.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/begin-02.html rename to preview/capy/reference/boost/capy/buffer_array/begin-02.html diff --git a/preview/reference/boost/capy/buffer_array/begin-0a4.html b/preview/capy/reference/boost/capy/buffer_array/begin-0a4.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/begin-0a4.html rename to preview/capy/reference/boost/capy/buffer_array/begin-0a4.html diff --git a/preview/reference/boost/capy/buffer_array/begin-0a7.html b/preview/capy/reference/boost/capy/buffer_array/begin-0a7.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/begin-0a7.html rename to preview/capy/reference/boost/capy/buffer_array/begin-0a7.html diff --git a/preview/reference/boost/capy/buffer_array/dummy_.html b/preview/capy/reference/boost/capy/buffer_array/dummy_.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/dummy_.html rename to preview/capy/reference/boost/capy/buffer_array/dummy_.html diff --git a/preview/reference/boost/capy/buffer_array/end-08.html b/preview/capy/reference/boost/capy/buffer_array/end-08.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/end-08.html rename to preview/capy/reference/boost/capy/buffer_array/end-08.html diff --git a/preview/reference/boost/capy/buffer_array/end-0b2.html b/preview/capy/reference/boost/capy/buffer_array/end-0b2.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/end-0b2.html rename to preview/capy/reference/boost/capy/buffer_array/end-0b2.html diff --git a/preview/reference/boost/capy/buffer_array/end-0bc.html b/preview/capy/reference/boost/capy/buffer_array/end-0bc.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/end-0bc.html rename to preview/capy/reference/boost/capy/buffer_array/end-0bc.html diff --git a/preview/reference/boost/capy/buffer_array/operator_assign.html b/preview/capy/reference/boost/capy/buffer_array/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/operator_assign.html rename to preview/capy/reference/boost/capy/buffer_array/operator_assign.html diff --git a/preview/reference/boost/capy/buffer_array/to_span-01.html b/preview/capy/reference/boost/capy/buffer_array/to_span-01.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/to_span-01.html rename to preview/capy/reference/boost/capy/buffer_array/to_span-01.html diff --git a/preview/reference/boost/capy/buffer_array/to_span-06.html b/preview/capy/reference/boost/capy/buffer_array/to_span-06.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/to_span-06.html rename to preview/capy/reference/boost/capy/buffer_array/to_span-06.html diff --git a/preview/reference/boost/capy/buffer_array/to_span-0a.html b/preview/capy/reference/boost/capy/buffer_array/to_span-0a.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/to_span-0a.html rename to preview/capy/reference/boost/capy/buffer_array/to_span-0a.html diff --git a/preview/reference/boost/capy/buffer_array/value_type.html b/preview/capy/reference/boost/capy/buffer_array/value_type.html similarity index 100% rename from preview/reference/boost/capy/buffer_array/value_type.html rename to preview/capy/reference/boost/capy/buffer_array/value_type.html diff --git a/preview/reference/boost/capy/buffer_copy.html b/preview/capy/reference/boost/capy/buffer_copy.html similarity index 100% rename from preview/reference/boost/capy/buffer_copy.html rename to preview/capy/reference/boost/capy/buffer_copy.html diff --git a/preview/reference/boost/capy/buffer_copy_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/buffer_copy_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/buffer_copy_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/buffer_copy_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/buffer_copy_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/buffer_copy_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/buffer_copy_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/buffer_copy_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/buffer_empty.html b/preview/capy/reference/boost/capy/buffer_empty.html similarity index 100% rename from preview/reference/boost/capy/buffer_empty.html rename to preview/capy/reference/boost/capy/buffer_empty.html diff --git a/preview/reference/boost/capy/buffer_empty_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/buffer_empty_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/buffer_empty_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/buffer_empty_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/buffer_empty_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/buffer_empty_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/buffer_empty_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/buffer_empty_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/buffer_length.html b/preview/capy/reference/boost/capy/buffer_length.html similarity index 100% rename from preview/reference/boost/capy/buffer_length.html rename to preview/capy/reference/boost/capy/buffer_length.html diff --git a/preview/reference/boost/capy/buffer_param-0a.html b/preview/capy/reference/boost/capy/buffer_param-0a.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a.html rename to preview/capy/reference/boost/capy/buffer_param-0a.html diff --git a/preview/reference/boost/capy/buffer_param-0a/2constructor.html b/preview/capy/reference/boost/capy/buffer_param-0a/2constructor.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/2constructor.html rename to preview/capy/reference/boost/capy/buffer_param-0a/2constructor.html diff --git a/preview/reference/boost/capy/buffer_param-0a/arr_.html b/preview/capy/reference/boost/capy/buffer_param-0a/arr_.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/arr_.html rename to preview/capy/reference/boost/capy/buffer_param-0a/arr_.html diff --git a/preview/reference/boost/capy/buffer_param-0a/buffer_type.html b/preview/capy/reference/boost/capy/buffer_param-0a/buffer_type.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/buffer_type.html rename to preview/capy/reference/boost/capy/buffer_param-0a/buffer_type.html diff --git a/preview/reference/boost/capy/buffer_param-0a/consume.html b/preview/capy/reference/boost/capy/buffer_param-0a/consume.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/consume.html rename to preview/capy/reference/boost/capy/buffer_param-0a/consume.html diff --git a/preview/reference/boost/capy/buffer_param-0a/data.html b/preview/capy/reference/boost/capy/buffer_param-0a/data.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/data.html rename to preview/capy/reference/boost/capy/buffer_param-0a/data.html diff --git a/preview/reference/boost/capy/buffer_param-0a/dummy_.html b/preview/capy/reference/boost/capy/buffer_param-0a/dummy_.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/dummy_.html rename to preview/capy/reference/boost/capy/buffer_param-0a/dummy_.html diff --git a/preview/reference/boost/capy/buffer_param-0a/more.html b/preview/capy/reference/boost/capy/buffer_param-0a/more.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0a/more.html rename to preview/capy/reference/boost/capy/buffer_param-0a/more.html diff --git a/preview/reference/boost/capy/buffer_param-0b.html b/preview/capy/reference/boost/capy/buffer_param-0b.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0b.html rename to preview/capy/reference/boost/capy/buffer_param-0b.html diff --git a/preview/reference/boost/capy/buffer_param-0d.html b/preview/capy/reference/boost/capy/buffer_param-0d.html similarity index 100% rename from preview/reference/boost/capy/buffer_param-0d.html rename to preview/capy/reference/boost/capy/buffer_param-0d.html diff --git a/preview/reference/boost/capy/buffer_size.html b/preview/capy/reference/boost/capy/buffer_size.html similarity index 100% rename from preview/reference/boost/capy/buffer_size.html rename to preview/capy/reference/boost/capy/buffer_size.html diff --git a/preview/reference/boost/capy/buffer_size_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/buffer_size_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/buffer_size_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/buffer_size_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/buffer_size_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/buffer_size_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/buffer_size_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/buffer_size_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/buffer_type.html b/preview/capy/reference/boost/capy/buffer_type.html similarity index 100% rename from preview/reference/boost/capy/buffer_type.html rename to preview/capy/reference/boost/capy/buffer_type.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/2constructor-01.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/2constructor-01.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-01.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0b.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0b.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0b.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0c.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0c.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0c.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0e.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0e.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0e.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0e.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0f.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/2constructor-0f.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/2constructor-0f.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/capacity.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/capacity.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/capacity.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/capacity.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/commit.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/commit.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/commit.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/commit.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/const_buffers_type.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/const_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/const_buffers_type.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/const_buffers_type.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/consume.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/consume.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/consume.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/consume.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/data.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/data.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/data.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/data.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/is_dynamic_buffer_adapter.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/is_dynamic_buffer_adapter.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/is_dynamic_buffer_adapter.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/is_dynamic_buffer_adapter.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/max_size.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/max_size.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/max_size.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/max_size.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/mutable_buffers_type.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/mutable_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/mutable_buffers_type.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/mutable_buffers_type.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/operator_assign.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/operator_assign.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/operator_assign.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/prepare.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/prepare.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/prepare.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/prepare.html diff --git a/preview/reference/boost/capy/circular_dynamic_buffer/size.html b/preview/capy/reference/boost/capy/circular_dynamic_buffer/size.html similarity index 100% rename from preview/reference/boost/capy/circular_dynamic_buffer/size.html rename to preview/capy/reference/boost/capy/circular_dynamic_buffer/size.html diff --git a/preview/reference/boost/capy/cond.html b/preview/capy/reference/boost/capy/cond.html similarity index 100% rename from preview/reference/boost/capy/cond.html rename to preview/capy/reference/boost/capy/cond.html diff --git a/preview/reference/boost/capy/const_buffer.html b/preview/capy/reference/boost/capy/const_buffer.html similarity index 96% rename from preview/reference/boost/capy/const_buffer.html rename to preview/capy/reference/boost/capy/const_buffer.html index 125dd07..7d0d6fd 100644 --- a/preview/reference/boost/capy/const_buffer.html +++ b/preview/capy/reference/boost/capy/const_buffer.html @@ -362,8 +362,7 @@
    -
    class const_buffer
    -    : public /* implementation-defined */
    +
    class const_buffer;
    @@ -377,29 +376,6 @@
    -

    Base Classes

    -
    - ---- - - - - - - - - - - - - -
    NameDescription

    /* implementation-defined */

    -
    -
    -

    Member Functions

    @@ -413,7 +389,7 @@ - + diff --git a/preview/reference/boost/capy/const_buffer/2constructor-03.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-03.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-03.html diff --git a/preview/capy/reference/boost/capy/const_buffer/2constructor-04.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-04.html new file mode 100644 index 0000000..7f2c967 --- /dev/null +++ b/preview/capy/reference/boost/capy/const_buffer/2constructor-04.html @@ -0,0 +1,429 @@ + + + + + + + + + + + + + +boost::capy::const_buffer::const_buffer :: Boost Libraries Documentation + + + + + + + + + + + + + + + + +
    +
    +
    + +

    boost::capy::const_buffer::const_buffer

    +
    +
    +
    +

    Constructors

    +
    +
    +
    +
    +

    Synopses

    +
    +
    +

    Declared in <boost/capy/buffers.hpp>

    +
    +
    +

    Construct an empty buffer.

    +
    +
    +
    +
    constexpr
    +const_buffer() = default;
    +
    +
    + +
    +

    Copy constructor.

    +
    +
    +
    +
    constexpr
    +const_buffer(const_buffer const& other) = default;
    +
    +
    + +
    +

    Construct from mutable_buffer.

    +
    +
    +
    +
    constexpr
    +const_buffer(mutable_buffer const& b) noexcept;
    +
    +
    + +
    +

    Construct from pointer and size.

    +
    +
    +
    +
    constexpr
    +const_buffer(
    +    void const* data,
    +    std::size_t size) noexcept;
    +
    +
    + +
    +

    Created with MrDocs

    +
    +
    +
    +
    +
    +
    +
    + +
    + + diff --git a/preview/reference/boost/capy/const_buffer/2constructor-0460.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-0460.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-0460.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-0460.html diff --git a/preview/reference/boost/capy/const_buffer/2constructor-0465.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-0465.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-0465.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-0465.html diff --git a/preview/reference/boost/capy/const_buffer/2constructor-07.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-07.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-07.html diff --git a/preview/reference/boost/capy/const_buffer/2constructor-0e.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-0e.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-0e.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-0e.html diff --git a/preview/reference/boost/capy/const_buffer/2constructor-0f.html b/preview/capy/reference/boost/capy/const_buffer/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/2constructor-0f.html rename to preview/capy/reference/boost/capy/const_buffer/2constructor-0f.html diff --git a/preview/reference/boost/capy/const_buffer/data.html b/preview/capy/reference/boost/capy/const_buffer/data.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/data.html rename to preview/capy/reference/boost/capy/const_buffer/data.html diff --git a/preview/reference/boost/capy/const_buffer/operator_assign.html b/preview/capy/reference/boost/capy/const_buffer/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/operator_assign.html rename to preview/capy/reference/boost/capy/const_buffer/operator_assign.html diff --git a/preview/reference/boost/capy/const_buffer/operator_plus_eq.html b/preview/capy/reference/boost/capy/const_buffer/operator_plus_eq.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/operator_plus_eq.html rename to preview/capy/reference/boost/capy/const_buffer/operator_plus_eq.html diff --git a/preview/reference/boost/capy/const_buffer/size.html b/preview/capy/reference/boost/capy/const_buffer/size.html similarity index 100% rename from preview/reference/boost/capy/const_buffer/size.html rename to preview/capy/reference/boost/capy/const_buffer/size.html diff --git a/preview/reference/boost/capy/const_buffer_archetype.html b/preview/capy/reference/boost/capy/const_buffer_archetype.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype.html rename to preview/capy/reference/boost/capy/const_buffer_archetype.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_.html b/preview/capy/reference/boost/capy/const_buffer_archetype_.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/2constructor-03.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/2constructor-03.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-03.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/2constructor-05.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/2constructor-05.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-05.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/2constructor-07.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/2constructor-07.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-07.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/2constructor-0d.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-0d.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/2constructor-0d.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/2constructor-0d.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/2conversion.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/2conversion.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/2conversion.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/2conversion.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/operator_assign-00.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-00.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/operator_assign-00.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-00.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/operator_assign-02.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/operator_assign-02.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-02.html diff --git a/preview/reference/boost/capy/const_buffer_archetype_/operator_assign-07.html b/preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-07.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_archetype_/operator_assign-07.html rename to preview/capy/reference/boost/capy/const_buffer_archetype_/operator_assign-07.html diff --git a/preview/reference/boost/capy/const_buffer_array.html b/preview/capy/reference/boost/capy/const_buffer_array.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_array.html rename to preview/capy/reference/boost/capy/const_buffer_array.html diff --git a/preview/reference/boost/capy/const_buffer_pair.html b/preview/capy/reference/boost/capy/const_buffer_pair.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_pair.html rename to preview/capy/reference/boost/capy/const_buffer_pair.html diff --git a/preview/reference/boost/capy/const_buffer_param.html b/preview/capy/reference/boost/capy/const_buffer_param.html similarity index 100% rename from preview/reference/boost/capy/const_buffer_param.html rename to preview/capy/reference/boost/capy/const_buffer_param.html diff --git a/preview/reference/boost/capy/consuming_buffers-06.html b/preview/capy/reference/boost/capy/consuming_buffers-06.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-06.html rename to preview/capy/reference/boost/capy/consuming_buffers-06.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c.html b/preview/capy/reference/boost/capy/consuming_buffers-0c.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/2constructor.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/2constructor.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/2constructor.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/2constructor.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/begin.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/begin.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/begin.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/begin.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-04.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-04.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-04.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-08.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-08.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-08.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-08.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-0f.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-0f.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/2constructor-0f.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/difference_type.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/difference_type.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/difference_type.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/difference_type.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/iterator_category.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/iterator_category.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/iterator_category.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/iterator_category.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-06.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-06.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-06.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-06.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-08.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-08.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-08.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-08.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-0c.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-0c.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-0c.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_dec-0c.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_eq.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_eq.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_eq.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-036.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-036.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-036.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-036.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-03f.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-03f.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-03f.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-03f.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-0b.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-0b.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-0b.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_inc-0b.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_not_eq.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_not_eq.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_not_eq.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_not_eq.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_star.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_star.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_star.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/operator_star.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/pointer.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/pointer.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/pointer.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/pointer.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/reference.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/reference.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/reference.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/reference.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/const_iterator/value_type.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/value_type.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/const_iterator/value_type.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/const_iterator/value_type.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/consume.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/consume.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/consume.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/consume.html diff --git a/preview/reference/boost/capy/consuming_buffers-0c/end.html b/preview/capy/reference/boost/capy/consuming_buffers-0c/end.html similarity index 100% rename from preview/reference/boost/capy/consuming_buffers-0c/end.html rename to preview/capy/reference/boost/capy/consuming_buffers-0c/end.html diff --git a/preview/reference/boost/capy/decomposes_to.html b/preview/capy/reference/boost/capy/decomposes_to.html similarity index 100% rename from preview/reference/boost/capy/decomposes_to.html rename to preview/capy/reference/boost/capy/decomposes_to.html diff --git a/preview/reference/boost/capy/dynamic_buffer-07.html b/preview/capy/reference/boost/capy/dynamic_buffer-07.html similarity index 100% rename from preview/reference/boost/capy/dynamic_buffer-07.html rename to preview/capy/reference/boost/capy/dynamic_buffer-07.html diff --git a/preview/reference/boost/capy/dynamic_buffer-0d.html b/preview/capy/reference/boost/capy/dynamic_buffer-0d.html similarity index 100% rename from preview/reference/boost/capy/dynamic_buffer-0d.html rename to preview/capy/reference/boost/capy/dynamic_buffer-0d.html diff --git a/preview/reference/boost/capy/dynamic_buffer-0f.html b/preview/capy/reference/boost/capy/dynamic_buffer-0f.html similarity index 100% rename from preview/reference/boost/capy/dynamic_buffer-0f.html rename to preview/capy/reference/boost/capy/dynamic_buffer-0f.html diff --git a/preview/reference/boost/capy/end.html b/preview/capy/reference/boost/capy/end.html similarity index 100% rename from preview/reference/boost/capy/end.html rename to preview/capy/reference/boost/capy/end.html diff --git a/preview/reference/boost/capy/end_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/end_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/end_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/end_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-09.html b/preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-09.html similarity index 100% rename from preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-09.html rename to preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-09.html diff --git a/preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0c.html b/preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0c.html similarity index 100% rename from preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0c.html rename to preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0c.html diff --git a/preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0f6.html b/preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0f6.html similarity index 100% rename from preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0f6.html rename to preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0f6.html diff --git a/preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0fa.html b/preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0fa.html similarity index 100% rename from preview/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0fa.html rename to preview/capy/reference/boost/capy/end_mrdocs_workaround_t/operator_call-0fa.html diff --git a/preview/reference/boost/capy/error.html b/preview/capy/reference/boost/capy/error.html similarity index 100% rename from preview/reference/boost/capy/error.html rename to preview/capy/reference/boost/capy/error.html diff --git a/preview/reference/boost/capy/execution_context.html b/preview/capy/reference/boost/capy/execution_context.html similarity index 100% rename from preview/reference/boost/capy/execution_context.html rename to preview/capy/reference/boost/capy/execution_context.html diff --git a/preview/reference/boost/capy/execution_context/2constructor-04.html b/preview/capy/reference/boost/capy/execution_context/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/execution_context/2constructor-04.html rename to preview/capy/reference/boost/capy/execution_context/2constructor-04.html diff --git a/preview/reference/boost/capy/execution_context/2constructor-05.html b/preview/capy/reference/boost/capy/execution_context/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/execution_context/2constructor-05.html rename to preview/capy/reference/boost/capy/execution_context/2constructor-05.html diff --git a/preview/reference/boost/capy/execution_context/2constructor-0d1.html b/preview/capy/reference/boost/capy/execution_context/2constructor-0d1.html similarity index 100% rename from preview/reference/boost/capy/execution_context/2constructor-0d1.html rename to preview/capy/reference/boost/capy/execution_context/2constructor-0d1.html diff --git a/preview/reference/boost/capy/execution_context/2constructor-0d8.html b/preview/capy/reference/boost/capy/execution_context/2constructor-0d8.html similarity index 100% rename from preview/reference/boost/capy/execution_context/2constructor-0d8.html rename to preview/capy/reference/boost/capy/execution_context/2constructor-0d8.html diff --git a/preview/reference/boost/capy/execution_context/2destructor.html b/preview/capy/reference/boost/capy/execution_context/2destructor.html similarity index 100% rename from preview/reference/boost/capy/execution_context/2destructor.html rename to preview/capy/reference/boost/capy/execution_context/2destructor.html diff --git a/preview/reference/boost/capy/execution_context/destroy.html b/preview/capy/reference/boost/capy/execution_context/destroy.html similarity index 100% rename from preview/reference/boost/capy/execution_context/destroy.html rename to preview/capy/reference/boost/capy/execution_context/destroy.html diff --git a/preview/reference/boost/capy/execution_context/find_service.html b/preview/capy/reference/boost/capy/execution_context/find_service.html similarity index 100% rename from preview/reference/boost/capy/execution_context/find_service.html rename to preview/capy/reference/boost/capy/execution_context/find_service.html diff --git a/preview/reference/boost/capy/execution_context/get_frame_allocator.html b/preview/capy/reference/boost/capy/execution_context/get_frame_allocator.html similarity index 100% rename from preview/reference/boost/capy/execution_context/get_frame_allocator.html rename to preview/capy/reference/boost/capy/execution_context/get_frame_allocator.html diff --git a/preview/reference/boost/capy/execution_context/has_service.html b/preview/capy/reference/boost/capy/execution_context/has_service.html similarity index 100% rename from preview/reference/boost/capy/execution_context/has_service.html rename to preview/capy/reference/boost/capy/execution_context/has_service.html diff --git a/preview/reference/boost/capy/execution_context/make_service.html b/preview/capy/reference/boost/capy/execution_context/make_service.html similarity index 100% rename from preview/reference/boost/capy/execution_context/make_service.html rename to preview/capy/reference/boost/capy/execution_context/make_service.html diff --git a/preview/reference/boost/capy/execution_context/operator_assign.html b/preview/capy/reference/boost/capy/execution_context/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/execution_context/operator_assign.html rename to preview/capy/reference/boost/capy/execution_context/operator_assign.html diff --git a/preview/reference/boost/capy/execution_context/service.html b/preview/capy/reference/boost/capy/execution_context/service.html similarity index 100% rename from preview/reference/boost/capy/execution_context/service.html rename to preview/capy/reference/boost/capy/execution_context/service.html diff --git a/preview/reference/boost/capy/execution_context/service/2constructor.html b/preview/capy/reference/boost/capy/execution_context/service/2constructor.html similarity index 100% rename from preview/reference/boost/capy/execution_context/service/2constructor.html rename to preview/capy/reference/boost/capy/execution_context/service/2constructor.html diff --git a/preview/reference/boost/capy/execution_context/service/2destructor.html b/preview/capy/reference/boost/capy/execution_context/service/2destructor.html similarity index 100% rename from preview/reference/boost/capy/execution_context/service/2destructor.html rename to preview/capy/reference/boost/capy/execution_context/service/2destructor.html diff --git a/preview/reference/boost/capy/execution_context/service/shutdown.html b/preview/capy/reference/boost/capy/execution_context/service/shutdown.html similarity index 100% rename from preview/reference/boost/capy/execution_context/service/shutdown.html rename to preview/capy/reference/boost/capy/execution_context/service/shutdown.html diff --git a/preview/reference/boost/capy/execution_context/set_frame_allocator-00.html b/preview/capy/reference/boost/capy/execution_context/set_frame_allocator-00.html similarity index 100% rename from preview/reference/boost/capy/execution_context/set_frame_allocator-00.html rename to preview/capy/reference/boost/capy/execution_context/set_frame_allocator-00.html diff --git a/preview/reference/boost/capy/execution_context/set_frame_allocator-07.html b/preview/capy/reference/boost/capy/execution_context/set_frame_allocator-07.html similarity index 100% rename from preview/reference/boost/capy/execution_context/set_frame_allocator-07.html rename to preview/capy/reference/boost/capy/execution_context/set_frame_allocator-07.html diff --git a/preview/reference/boost/capy/execution_context/set_frame_allocator-09.html b/preview/capy/reference/boost/capy/execution_context/set_frame_allocator-09.html similarity index 100% rename from preview/reference/boost/capy/execution_context/set_frame_allocator-09.html rename to preview/capy/reference/boost/capy/execution_context/set_frame_allocator-09.html diff --git a/preview/reference/boost/capy/execution_context/shutdown.html b/preview/capy/reference/boost/capy/execution_context/shutdown.html similarity index 100% rename from preview/reference/boost/capy/execution_context/shutdown.html rename to preview/capy/reference/boost/capy/execution_context/shutdown.html diff --git a/preview/reference/boost/capy/execution_context/target-07.html b/preview/capy/reference/boost/capy/execution_context/target-07.html similarity index 100% rename from preview/reference/boost/capy/execution_context/target-07.html rename to preview/capy/reference/boost/capy/execution_context/target-07.html diff --git a/preview/reference/boost/capy/execution_context/target-0b.html b/preview/capy/reference/boost/capy/execution_context/target-0b.html similarity index 100% rename from preview/reference/boost/capy/execution_context/target-0b.html rename to preview/capy/reference/boost/capy/execution_context/target-0b.html diff --git a/preview/reference/boost/capy/execution_context/target-0e.html b/preview/capy/reference/boost/capy/execution_context/target-0e.html similarity index 100% rename from preview/reference/boost/capy/execution_context/target-0e.html rename to preview/capy/reference/boost/capy/execution_context/target-0e.html diff --git a/preview/reference/boost/capy/execution_context/use_service.html b/preview/capy/reference/boost/capy/execution_context/use_service.html similarity index 100% rename from preview/reference/boost/capy/execution_context/use_service.html rename to preview/capy/reference/boost/capy/execution_context/use_service.html diff --git a/preview/reference/boost/capy/executor_ref.html b/preview/capy/reference/boost/capy/executor_ref.html similarity index 100% rename from preview/reference/boost/capy/executor_ref.html rename to preview/capy/reference/boost/capy/executor_ref.html diff --git a/preview/reference/boost/capy/executor_ref/2constructor-01.html b/preview/capy/reference/boost/capy/executor_ref/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/2constructor-01.html rename to preview/capy/reference/boost/capy/executor_ref/2constructor-01.html diff --git a/preview/reference/boost/capy/executor_ref/2constructor-04.html b/preview/capy/reference/boost/capy/executor_ref/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/2constructor-04.html rename to preview/capy/reference/boost/capy/executor_ref/2constructor-04.html diff --git a/preview/reference/boost/capy/executor_ref/2constructor-0b.html b/preview/capy/reference/boost/capy/executor_ref/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/2constructor-0b.html rename to preview/capy/reference/boost/capy/executor_ref/2constructor-0b.html diff --git a/preview/reference/boost/capy/executor_ref/2constructor-0c.html b/preview/capy/reference/boost/capy/executor_ref/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/2constructor-0c.html rename to preview/capy/reference/boost/capy/executor_ref/2constructor-0c.html diff --git a/preview/reference/boost/capy/executor_ref/2conversion.html b/preview/capy/reference/boost/capy/executor_ref/2conversion.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/2conversion.html rename to preview/capy/reference/boost/capy/executor_ref/2conversion.html diff --git a/preview/reference/boost/capy/executor_ref/context.html b/preview/capy/reference/boost/capy/executor_ref/context.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/context.html rename to preview/capy/reference/boost/capy/executor_ref/context.html diff --git a/preview/reference/boost/capy/executor_ref/dispatch.html b/preview/capy/reference/boost/capy/executor_ref/dispatch.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/dispatch.html rename to preview/capy/reference/boost/capy/executor_ref/dispatch.html diff --git a/preview/reference/boost/capy/executor_ref/on_work_finished.html b/preview/capy/reference/boost/capy/executor_ref/on_work_finished.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/on_work_finished.html rename to preview/capy/reference/boost/capy/executor_ref/on_work_finished.html diff --git a/preview/reference/boost/capy/executor_ref/on_work_started.html b/preview/capy/reference/boost/capy/executor_ref/on_work_started.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/on_work_started.html rename to preview/capy/reference/boost/capy/executor_ref/on_work_started.html diff --git a/preview/reference/boost/capy/executor_ref/operator_assign.html b/preview/capy/reference/boost/capy/executor_ref/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/operator_assign.html rename to preview/capy/reference/boost/capy/executor_ref/operator_assign.html diff --git a/preview/reference/boost/capy/executor_ref/operator_eq.html b/preview/capy/reference/boost/capy/executor_ref/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/operator_eq.html rename to preview/capy/reference/boost/capy/executor_ref/operator_eq.html diff --git a/preview/reference/boost/capy/executor_ref/post.html b/preview/capy/reference/boost/capy/executor_ref/post.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/post.html rename to preview/capy/reference/boost/capy/executor_ref/post.html diff --git a/preview/reference/boost/capy/executor_ref/target-00.html b/preview/capy/reference/boost/capy/executor_ref/target-00.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/target-00.html rename to preview/capy/reference/boost/capy/executor_ref/target-00.html diff --git a/preview/reference/boost/capy/executor_ref/target-04.html b/preview/capy/reference/boost/capy/executor_ref/target-04.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/target-04.html rename to preview/capy/reference/boost/capy/executor_ref/target-04.html diff --git a/preview/reference/boost/capy/executor_ref/target-0c.html b/preview/capy/reference/boost/capy/executor_ref/target-0c.html similarity index 100% rename from preview/reference/boost/capy/executor_ref/target-0c.html rename to preview/capy/reference/boost/capy/executor_ref/target-0c.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/2constructor-00.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-00.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/2constructor-00.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-00.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/2constructor-05.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-05.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/2constructor-05.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-05.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/2constructor-07.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-07.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/2constructor-07.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-07.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/2constructor-0c.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/2constructor-0c.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/2constructor-0c.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/capacity.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/capacity.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/capacity.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/capacity.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/commit.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/commit.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/commit.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/commit.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/const_buffers_type.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/const_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/const_buffers_type.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/const_buffers_type.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/consume.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/consume.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/consume.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/consume.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/data.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/data.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/data.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/data.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/is_dynamic_buffer_adapter.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/is_dynamic_buffer_adapter.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/is_dynamic_buffer_adapter.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/is_dynamic_buffer_adapter.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/max_size.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/max_size.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/max_size.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/max_size.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/mutable_buffers_type.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/mutable_buffers_type.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/mutable_buffers_type.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/mutable_buffers_type.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/operator_assign.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/operator_assign.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/operator_assign.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/prepare.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/prepare.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/prepare.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/prepare.html diff --git a/preview/reference/boost/capy/flat_dynamic_buffer/size.html b/preview/capy/reference/boost/capy/flat_dynamic_buffer/size.html similarity index 100% rename from preview/reference/boost/capy/flat_dynamic_buffer/size.html rename to preview/capy/reference/boost/capy/flat_dynamic_buffer/size.html diff --git a/preview/reference/boost/capy/front.html b/preview/capy/reference/boost/capy/front.html similarity index 100% rename from preview/reference/boost/capy/front.html rename to preview/capy/reference/boost/capy/front.html diff --git a/preview/reference/boost/capy/front_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/front_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/front_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/front_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-022.html b/preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-022.html similarity index 100% rename from preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-022.html rename to preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-022.html diff --git a/preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-02a.html b/preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-02a.html similarity index 100% rename from preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-02a.html rename to preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-02a.html diff --git a/preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-0c.html b/preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-0c.html similarity index 100% rename from preview/reference/boost/capy/front_mrdocs_workaround_t/operator_call-0c.html rename to preview/capy/reference/boost/capy/front_mrdocs_workaround_t/operator_call-0c.html diff --git a/preview/reference/boost/capy/get_current_frame_allocator.html b/preview/capy/reference/boost/capy/get_current_frame_allocator.html similarity index 100% rename from preview/reference/boost/capy/get_current_frame_allocator.html rename to preview/capy/reference/boost/capy/get_current_frame_allocator.html diff --git a/preview/reference/boost/capy/get_recycling_memory_resource.html b/preview/capy/reference/boost/capy/get_recycling_memory_resource.html similarity index 100% rename from preview/reference/boost/capy/get_recycling_memory_resource.html rename to preview/capy/reference/boost/capy/get_recycling_memory_resource.html diff --git a/preview/reference/boost/capy/get_system_context.html b/preview/capy/reference/boost/capy/get_system_context.html similarity index 100% rename from preview/reference/boost/capy/get_system_context.html rename to preview/capy/reference/boost/capy/get_system_context.html diff --git a/preview/reference/boost/capy/immediate.html b/preview/capy/reference/boost/capy/immediate.html similarity index 100% rename from preview/reference/boost/capy/immediate.html rename to preview/capy/reference/boost/capy/immediate.html diff --git a/preview/reference/boost/capy/immediate/await_ready.html b/preview/capy/reference/boost/capy/immediate/await_ready.html similarity index 100% rename from preview/reference/boost/capy/immediate/await_ready.html rename to preview/capy/reference/boost/capy/immediate/await_ready.html diff --git a/preview/reference/boost/capy/immediate/await_resume-00.html b/preview/capy/reference/boost/capy/immediate/await_resume-00.html similarity index 100% rename from preview/reference/boost/capy/immediate/await_resume-00.html rename to preview/capy/reference/boost/capy/immediate/await_resume-00.html diff --git a/preview/reference/boost/capy/immediate/await_resume-09.html b/preview/capy/reference/boost/capy/immediate/await_resume-09.html similarity index 100% rename from preview/reference/boost/capy/immediate/await_resume-09.html rename to preview/capy/reference/boost/capy/immediate/await_resume-09.html diff --git a/preview/reference/boost/capy/immediate/await_resume-0e.html b/preview/capy/reference/boost/capy/immediate/await_resume-0e.html similarity index 100% rename from preview/reference/boost/capy/immediate/await_resume-0e.html rename to preview/capy/reference/boost/capy/immediate/await_resume-0e.html diff --git a/preview/reference/boost/capy/immediate/await_suspend.html b/preview/capy/reference/boost/capy/immediate/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/immediate/await_suspend.html rename to preview/capy/reference/boost/capy/immediate/await_suspend.html diff --git a/preview/reference/boost/capy/immediate/value_.html b/preview/capy/reference/boost/capy/immediate/value_.html similarity index 100% rename from preview/reference/boost/capy/immediate/value_.html rename to preview/capy/reference/boost/capy/immediate/value_.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base.html similarity index 99% rename from preview/reference/boost/capy/io_awaitable_promise_base.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base.html index 88b7bb1..97c8172 100644 --- a/preview/reference/boost/capy/io_awaitable_promise_base.html +++ b/preview/capy/reference/boost/capy/io_awaitable_promise_base.html @@ -441,7 +441,7 @@ my_task example()
    -

    The mixin's await_transform intercepts this_coro::environment_tag and the fine‐grained tag types (this_coro::executor_tag, this_coro::stop_token_tag, this_coro::allocator_tag), then delegates all other awaitables to your transform_awaitable.

    +

    The mixin's await_transform intercepts this_coro::environment_tag and the fine‐grained tag types (this_coro::executor_tag, this_coro::stop_token_tag, this_coro::frame_allocator_tag), then delegates all other awaitables to your transform_awaitable.

    diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/2destructor.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/2destructor.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/2destructor.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/2destructor.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/await_transform.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/await_transform.html similarity index 98% rename from preview/reference/boost/capy/io_awaitable_promise_base/await_transform.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/await_transform.html index 38c1fdb..7109166 100644 --- a/preview/reference/boost/capy/io_awaitable_promise_base/await_transform.html +++ b/preview/capy/reference/boost/capy/io_awaitable_promise_base/await_transform.html @@ -373,7 +373,7 @@ await_transform(T&& t);

    Description

    -

    This function handles this_coro::environment_tag and the fine‐grained tags (this_coro::executor_tag, this_coro::stop_token_tag, this_coro::allocator_tag) specially, returning an awaiter that yields the stored value. All other awaitables are delegated to transform_awaitable.

    +

    This function handles this_coro::environment_tag and the fine‐grained tags (this_coro::executor_tag, this_coro::stop_token_tag, this_coro::frame_allocator_tag) specially, returning an awaiter that yields the stored value. All other awaitables are delegated to transform_awaitable.

    diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/continuation.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/continuation.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/continuation.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/continuation.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/environment.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/environment.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/environment.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/environment.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/operator_del.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/operator_del.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/operator_del.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/operator_del.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/operator_new.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/operator_new.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/operator_new.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/operator_new.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/set_continuation.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/set_continuation.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/set_continuation.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/set_continuation.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/set_environment.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/set_environment.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/set_environment.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/set_environment.html diff --git a/preview/reference/boost/capy/io_awaitable_promise_base/transform_awaitable.html b/preview/capy/reference/boost/capy/io_awaitable_promise_base/transform_awaitable.html similarity index 100% rename from preview/reference/boost/capy/io_awaitable_promise_base/transform_awaitable.html rename to preview/capy/reference/boost/capy/io_awaitable_promise_base/transform_awaitable.html diff --git a/preview/reference/boost/capy/io_env.html b/preview/capy/reference/boost/capy/io_env.html similarity index 98% rename from preview/reference/boost/capy/io_env.html rename to preview/capy/reference/boost/capy/io_env.html index b2b8c9f..362a463 100644 --- a/preview/reference/boost/capy/io_env.html +++ b/preview/capy/reference/boost/capy/io_env.html @@ -371,7 +371,7 @@

    Description

    -

    This struct bundles the execution context passed through coroutine chains via the IoAwaitable protocol. It contains the executor for resumption, a stop token for cancellation, and an optional allocator for coroutine frame allocation.

    +

    This struct bundles the execution context passed through coroutine chains via the IoAwaitable protocol. It contains the executor for resumption, a stop token for cancellation, and an optional frame allocator for coroutine frame allocation.

    @@ -405,14 +405,14 @@ - - - - + + + + diff --git a/preview/reference/boost/capy/io_env/allocator.html b/preview/capy/reference/boost/capy/io_env/allocator.html similarity index 100% rename from preview/reference/boost/capy/io_env/allocator.html rename to preview/capy/reference/boost/capy/io_env/allocator.html diff --git a/preview/reference/boost/capy/io_env/executor.html b/preview/capy/reference/boost/capy/io_env/executor.html similarity index 100% rename from preview/reference/boost/capy/io_env/executor.html rename to preview/capy/reference/boost/capy/io_env/executor.html diff --git a/preview/capy/reference/boost/capy/io_env/frame_allocator.html b/preview/capy/reference/boost/capy/io_env/frame_allocator.html new file mode 100644 index 0000000..2e35620 --- /dev/null +++ b/preview/capy/reference/boost/capy/io_env/frame_allocator.html @@ -0,0 +1,392 @@ + + + + + + + + + + + + + +boost::capy::io_env::frame_allocator :: Boost Libraries Documentation + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + + diff --git a/preview/reference/boost/capy/io_env/stop_token.html b/preview/capy/reference/boost/capy/io_env/stop_token.html similarity index 100% rename from preview/reference/boost/capy/io_env/stop_token.html rename to preview/capy/reference/boost/capy/io_env/stop_token.html diff --git a/preview/reference/boost/capy/io_result-02.html b/preview/capy/reference/boost/capy/io_result-02.html similarity index 100% rename from preview/reference/boost/capy/io_result-02.html rename to preview/capy/reference/boost/capy/io_result-02.html diff --git a/preview/reference/boost/capy/io_result-02/ec.html b/preview/capy/reference/boost/capy/io_result-02/ec.html similarity index 100% rename from preview/reference/boost/capy/io_result-02/ec.html rename to preview/capy/reference/boost/capy/io_result-02/ec.html diff --git a/preview/reference/boost/capy/io_result-02/t1.html b/preview/capy/reference/boost/capy/io_result-02/t1.html similarity index 100% rename from preview/reference/boost/capy/io_result-02/t1.html rename to preview/capy/reference/boost/capy/io_result-02/t1.html diff --git a/preview/reference/boost/capy/io_result-02/t2.html b/preview/capy/reference/boost/capy/io_result-02/t2.html similarity index 100% rename from preview/reference/boost/capy/io_result-02/t2.html rename to preview/capy/reference/boost/capy/io_result-02/t2.html diff --git a/preview/reference/boost/capy/io_result-02/t3.html b/preview/capy/reference/boost/capy/io_result-02/t3.html similarity index 100% rename from preview/reference/boost/capy/io_result-02/t3.html rename to preview/capy/reference/boost/capy/io_result-02/t3.html diff --git a/preview/reference/boost/capy/io_result-07.html b/preview/capy/reference/boost/capy/io_result-07.html similarity index 100% rename from preview/reference/boost/capy/io_result-07.html rename to preview/capy/reference/boost/capy/io_result-07.html diff --git a/preview/reference/boost/capy/io_result-0c.html b/preview/capy/reference/boost/capy/io_result-0c.html similarity index 100% rename from preview/reference/boost/capy/io_result-0c.html rename to preview/capy/reference/boost/capy/io_result-0c.html diff --git a/preview/reference/boost/capy/io_result-0c/ec.html b/preview/capy/reference/boost/capy/io_result-0c/ec.html similarity index 100% rename from preview/reference/boost/capy/io_result-0c/ec.html rename to preview/capy/reference/boost/capy/io_result-0c/ec.html diff --git a/preview/reference/boost/capy/io_result-0e1.html b/preview/capy/reference/boost/capy/io_result-0e1.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e1.html rename to preview/capy/reference/boost/capy/io_result-0e1.html diff --git a/preview/reference/boost/capy/io_result-0e1/ec.html b/preview/capy/reference/boost/capy/io_result-0e1/ec.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e1/ec.html rename to preview/capy/reference/boost/capy/io_result-0e1/ec.html diff --git a/preview/reference/boost/capy/io_result-0e1/t1.html b/preview/capy/reference/boost/capy/io_result-0e1/t1.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e1/t1.html rename to preview/capy/reference/boost/capy/io_result-0e1/t1.html diff --git a/preview/reference/boost/capy/io_result-0e7.html b/preview/capy/reference/boost/capy/io_result-0e7.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e7.html rename to preview/capy/reference/boost/capy/io_result-0e7.html diff --git a/preview/reference/boost/capy/io_result-0e7/ec.html b/preview/capy/reference/boost/capy/io_result-0e7/ec.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e7/ec.html rename to preview/capy/reference/boost/capy/io_result-0e7/ec.html diff --git a/preview/reference/boost/capy/io_result-0e7/t1.html b/preview/capy/reference/boost/capy/io_result-0e7/t1.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e7/t1.html rename to preview/capy/reference/boost/capy/io_result-0e7/t1.html diff --git a/preview/reference/boost/capy/io_result-0e7/t2.html b/preview/capy/reference/boost/capy/io_result-0e7/t2.html similarity index 100% rename from preview/reference/boost/capy/io_result-0e7/t2.html rename to preview/capy/reference/boost/capy/io_result-0e7/t2.html diff --git a/preview/reference/boost/capy/io_task.html b/preview/capy/reference/boost/capy/io_task.html similarity index 100% rename from preview/reference/boost/capy/io_task.html rename to preview/capy/reference/boost/capy/io_task.html diff --git a/preview/reference/boost/capy/keep_prefix.html b/preview/capy/reference/boost/capy/keep_prefix.html similarity index 100% rename from preview/reference/boost/capy/keep_prefix.html rename to preview/capy/reference/boost/capy/keep_prefix.html diff --git a/preview/reference/boost/capy/keep_prefix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/keep_prefix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/keep_prefix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/keep_prefix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/keep_prefix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/keep_prefix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/keep_prefix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/keep_prefix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/keep_suffix.html b/preview/capy/reference/boost/capy/keep_suffix.html similarity index 100% rename from preview/reference/boost/capy/keep_suffix.html rename to preview/capy/reference/boost/capy/keep_suffix.html diff --git a/preview/reference/boost/capy/keep_suffix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/keep_suffix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/keep_suffix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/keep_suffix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/keep_suffix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/keep_suffix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/keep_suffix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/keep_suffix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/make_buffer-002.html b/preview/capy/reference/boost/capy/make_buffer-002.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-002.html rename to preview/capy/reference/boost/capy/make_buffer-002.html diff --git a/preview/reference/boost/capy/make_buffer-00a.html b/preview/capy/reference/boost/capy/make_buffer-00a.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-00a.html rename to preview/capy/reference/boost/capy/make_buffer-00a.html diff --git a/preview/reference/boost/capy/make_buffer-00b4.html b/preview/capy/reference/boost/capy/make_buffer-00b4.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-00b4.html rename to preview/capy/reference/boost/capy/make_buffer-00b4.html diff --git a/preview/reference/boost/capy/make_buffer-00bc.html b/preview/capy/reference/boost/capy/make_buffer-00bc.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-00bc.html rename to preview/capy/reference/boost/capy/make_buffer-00bc.html diff --git a/preview/reference/boost/capy/make_buffer-010.html b/preview/capy/reference/boost/capy/make_buffer-010.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-010.html rename to preview/capy/reference/boost/capy/make_buffer-010.html diff --git a/preview/reference/boost/capy/make_buffer-011.html b/preview/capy/reference/boost/capy/make_buffer-011.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-011.html rename to preview/capy/reference/boost/capy/make_buffer-011.html diff --git a/preview/reference/boost/capy/make_buffer-0138.html b/preview/capy/reference/boost/capy/make_buffer-0138.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0138.html rename to preview/capy/reference/boost/capy/make_buffer-0138.html diff --git a/preview/reference/boost/capy/make_buffer-0139.html b/preview/capy/reference/boost/capy/make_buffer-0139.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0139.html rename to preview/capy/reference/boost/capy/make_buffer-0139.html diff --git a/preview/reference/boost/capy/make_buffer-02.html b/preview/capy/reference/boost/capy/make_buffer-02.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-02.html rename to preview/capy/reference/boost/capy/make_buffer-02.html diff --git a/preview/reference/boost/capy/make_buffer-030.html b/preview/capy/reference/boost/capy/make_buffer-030.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-030.html rename to preview/capy/reference/boost/capy/make_buffer-030.html diff --git a/preview/reference/boost/capy/make_buffer-037.html b/preview/capy/reference/boost/capy/make_buffer-037.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-037.html rename to preview/capy/reference/boost/capy/make_buffer-037.html diff --git a/preview/reference/boost/capy/make_buffer-039.html b/preview/capy/reference/boost/capy/make_buffer-039.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-039.html rename to preview/capy/reference/boost/capy/make_buffer-039.html diff --git a/preview/reference/boost/capy/make_buffer-03c.html b/preview/capy/reference/boost/capy/make_buffer-03c.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-03c.html rename to preview/capy/reference/boost/capy/make_buffer-03c.html diff --git a/preview/reference/boost/capy/make_buffer-03d.html b/preview/capy/reference/boost/capy/make_buffer-03d.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-03d.html rename to preview/capy/reference/boost/capy/make_buffer-03d.html diff --git a/preview/reference/boost/capy/make_buffer-041.html b/preview/capy/reference/boost/capy/make_buffer-041.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-041.html rename to preview/capy/reference/boost/capy/make_buffer-041.html diff --git a/preview/reference/boost/capy/make_buffer-042.html b/preview/capy/reference/boost/capy/make_buffer-042.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-042.html rename to preview/capy/reference/boost/capy/make_buffer-042.html diff --git a/preview/reference/boost/capy/make_buffer-043.html b/preview/capy/reference/boost/capy/make_buffer-043.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-043.html rename to preview/capy/reference/boost/capy/make_buffer-043.html diff --git a/preview/reference/boost/capy/make_buffer-045.html b/preview/capy/reference/boost/capy/make_buffer-045.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-045.html rename to preview/capy/reference/boost/capy/make_buffer-045.html diff --git a/preview/reference/boost/capy/make_buffer-048.html b/preview/capy/reference/boost/capy/make_buffer-048.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-048.html rename to preview/capy/reference/boost/capy/make_buffer-048.html diff --git a/preview/reference/boost/capy/make_buffer-060.html b/preview/capy/reference/boost/capy/make_buffer-060.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-060.html rename to preview/capy/reference/boost/capy/make_buffer-060.html diff --git a/preview/reference/boost/capy/make_buffer-0612.html b/preview/capy/reference/boost/capy/make_buffer-0612.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0612.html rename to preview/capy/reference/boost/capy/make_buffer-0612.html diff --git a/preview/reference/boost/capy/make_buffer-061e.html b/preview/capy/reference/boost/capy/make_buffer-061e.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-061e.html rename to preview/capy/reference/boost/capy/make_buffer-061e.html diff --git a/preview/reference/boost/capy/make_buffer-06a.html b/preview/capy/reference/boost/capy/make_buffer-06a.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-06a.html rename to preview/capy/reference/boost/capy/make_buffer-06a.html diff --git a/preview/reference/boost/capy/make_buffer-06b.html b/preview/capy/reference/boost/capy/make_buffer-06b.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-06b.html rename to preview/capy/reference/boost/capy/make_buffer-06b.html diff --git a/preview/reference/boost/capy/make_buffer-06e.html b/preview/capy/reference/boost/capy/make_buffer-06e.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-06e.html rename to preview/capy/reference/boost/capy/make_buffer-06e.html diff --git a/preview/reference/boost/capy/make_buffer-081.html b/preview/capy/reference/boost/capy/make_buffer-081.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-081.html rename to preview/capy/reference/boost/capy/make_buffer-081.html diff --git a/preview/reference/boost/capy/make_buffer-085.html b/preview/capy/reference/boost/capy/make_buffer-085.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-085.html rename to preview/capy/reference/boost/capy/make_buffer-085.html diff --git a/preview/reference/boost/capy/make_buffer-08f.html b/preview/capy/reference/boost/capy/make_buffer-08f.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-08f.html rename to preview/capy/reference/boost/capy/make_buffer-08f.html diff --git a/preview/reference/boost/capy/make_buffer-09e.html b/preview/capy/reference/boost/capy/make_buffer-09e.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-09e.html rename to preview/capy/reference/boost/capy/make_buffer-09e.html diff --git a/preview/reference/boost/capy/make_buffer-09f.html b/preview/capy/reference/boost/capy/make_buffer-09f.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-09f.html rename to preview/capy/reference/boost/capy/make_buffer-09f.html diff --git a/preview/reference/boost/capy/make_buffer-0a.html b/preview/capy/reference/boost/capy/make_buffer-0a.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0a.html rename to preview/capy/reference/boost/capy/make_buffer-0a.html diff --git a/preview/reference/boost/capy/make_buffer-0b.html b/preview/capy/reference/boost/capy/make_buffer-0b.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0b.html rename to preview/capy/reference/boost/capy/make_buffer-0b.html diff --git a/preview/reference/boost/capy/make_buffer-0e.html b/preview/capy/reference/boost/capy/make_buffer-0e.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0e.html rename to preview/capy/reference/boost/capy/make_buffer-0e.html diff --git a/preview/reference/boost/capy/make_buffer-0f1.html b/preview/capy/reference/boost/capy/make_buffer-0f1.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0f1.html rename to preview/capy/reference/boost/capy/make_buffer-0f1.html diff --git a/preview/reference/boost/capy/make_buffer-0f6.html b/preview/capy/reference/boost/capy/make_buffer-0f6.html similarity index 100% rename from preview/reference/boost/capy/make_buffer-0f6.html rename to preview/capy/reference/boost/capy/make_buffer-0f6.html diff --git a/preview/reference/boost/capy/make_error_code.html b/preview/capy/reference/boost/capy/make_error_code.html similarity index 100% rename from preview/reference/boost/capy/make_error_code.html rename to preview/capy/reference/boost/capy/make_error_code.html diff --git a/preview/reference/boost/capy/make_error_condition.html b/preview/capy/reference/boost/capy/make_error_condition.html similarity index 100% rename from preview/reference/boost/capy/make_error_condition.html rename to preview/capy/reference/boost/capy/make_error_condition.html diff --git a/preview/reference/boost/capy/make_work_guard.html b/preview/capy/reference/boost/capy/make_work_guard.html similarity index 100% rename from preview/reference/boost/capy/make_work_guard.html rename to preview/capy/reference/boost/capy/make_work_guard.html diff --git a/preview/reference/boost/capy/match_delim.html b/preview/capy/reference/boost/capy/match_delim.html similarity index 100% rename from preview/reference/boost/capy/match_delim.html rename to preview/capy/reference/boost/capy/match_delim.html diff --git a/preview/reference/boost/capy/match_delim/delim.html b/preview/capy/reference/boost/capy/match_delim/delim.html similarity index 100% rename from preview/reference/boost/capy/match_delim/delim.html rename to preview/capy/reference/boost/capy/match_delim/delim.html diff --git a/preview/reference/boost/capy/match_delim/operator_call.html b/preview/capy/reference/boost/capy/match_delim/operator_call.html similarity index 100% rename from preview/reference/boost/capy/match_delim/operator_call.html rename to preview/capy/reference/boost/capy/match_delim/operator_call.html diff --git a/preview/reference/boost/capy/mutable_buffer.html b/preview/capy/reference/boost/capy/mutable_buffer.html similarity index 97% rename from preview/reference/boost/capy/mutable_buffer.html rename to preview/capy/reference/boost/capy/mutable_buffer.html index 6f69d9b..422c228 100644 --- a/preview/reference/boost/capy/mutable_buffer.html +++ b/preview/capy/reference/boost/capy/mutable_buffer.html @@ -362,8 +362,7 @@
    -
    class mutable_buffer
    -    : public /* implementation-defined */
    +
    class mutable_buffer;
    @@ -377,29 +376,6 @@
    -

    Base Classes

    -
    -

    Description

    const_buffer [constructor]

    const_buffer [constructor]

    Constructors

    Description

    allocator

    The allocator for coroutine frame allocation.

    executor

    The executor for coroutine resumption.

    frame_allocator

    The frame allocator for coroutine frame allocation.

    stop_token

    The stop token for cancellation propagation.

    ---- - - - - - - - - - - - - -
    NameDescription

    /* implementation-defined */

    -
    -
    -

    Member Functions

    diff --git a/preview/reference/boost/capy/mutable_buffer/2constructor-00.html b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-00.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/2constructor-00.html rename to preview/capy/reference/boost/capy/mutable_buffer/2constructor-00.html diff --git a/preview/reference/boost/capy/mutable_buffer/2constructor-03.html b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/2constructor-03.html rename to preview/capy/reference/boost/capy/mutable_buffer/2constructor-03.html diff --git a/preview/reference/boost/capy/mutable_buffer/2constructor-09.html b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-09.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/2constructor-09.html rename to preview/capy/reference/boost/capy/mutable_buffer/2constructor-09.html diff --git a/preview/reference/boost/capy/mutable_buffer/2constructor-0a.html b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-0a.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/2constructor-0a.html rename to preview/capy/reference/boost/capy/mutable_buffer/2constructor-0a.html diff --git a/preview/reference/boost/capy/mutable_buffer/2constructor-0b.html b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-0b.html similarity index 96% rename from preview/reference/boost/capy/mutable_buffer/2constructor-0b.html rename to preview/capy/reference/boost/capy/mutable_buffer/2constructor-0b.html index 09668c5..036a093 100644 --- a/preview/reference/boost/capy/mutable_buffer/2constructor-0b.html +++ b/preview/capy/reference/boost/capy/mutable_buffer/2constructor-0b.html @@ -385,20 +385,6 @@

    » more...

    -

    Construct from Asio mutable_buffer.

    -
    -
    -
    -
    template<class MutableBuffer>
    -requires std::same_as<MutableBuffer, asio::mutable_buffer>
    -constexpr
    -mutable_buffer(MutableBuffer const& b) noexcept;
    -
    -
    - -

    Construct from pointer and size.

    diff --git a/preview/reference/boost/capy/mutable_buffer/data.html b/preview/capy/reference/boost/capy/mutable_buffer/data.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/data.html rename to preview/capy/reference/boost/capy/mutable_buffer/data.html diff --git a/preview/reference/boost/capy/mutable_buffer/operator_assign.html b/preview/capy/reference/boost/capy/mutable_buffer/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/operator_assign.html rename to preview/capy/reference/boost/capy/mutable_buffer/operator_assign.html diff --git a/preview/reference/boost/capy/mutable_buffer/operator_plus_eq.html b/preview/capy/reference/boost/capy/mutable_buffer/operator_plus_eq.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/operator_plus_eq.html rename to preview/capy/reference/boost/capy/mutable_buffer/operator_plus_eq.html diff --git a/preview/reference/boost/capy/mutable_buffer/size.html b/preview/capy/reference/boost/capy/mutable_buffer/size.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer/size.html rename to preview/capy/reference/boost/capy/mutable_buffer/size.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-06.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-06.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-06.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-06.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-09.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-09.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-09.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-09.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-0b.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-0b.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-0b.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-0c.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2constructor-0c.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2constructor-0c.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2conversion-0a.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2conversion-0a.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2conversion-0a.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2conversion-0a.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/2conversion-0e.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/2conversion-0e.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/2conversion-0e.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/2conversion-0e.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a2.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a2.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a2.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a2.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a3.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a3.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a3.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0a3.html diff --git a/preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0c.html b/preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0c.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0c.html rename to preview/capy/reference/boost/capy/mutable_buffer_archetype_/operator_assign-0c.html diff --git a/preview/reference/boost/capy/mutable_buffer_array.html b/preview/capy/reference/boost/capy/mutable_buffer_array.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_array.html rename to preview/capy/reference/boost/capy/mutable_buffer_array.html diff --git a/preview/reference/boost/capy/mutable_buffer_pair.html b/preview/capy/reference/boost/capy/mutable_buffer_pair.html similarity index 100% rename from preview/reference/boost/capy/mutable_buffer_pair.html rename to preview/capy/reference/boost/capy/mutable_buffer_pair.html diff --git a/preview/reference/boost/capy/prefix.html b/preview/capy/reference/boost/capy/prefix.html similarity index 100% rename from preview/reference/boost/capy/prefix.html rename to preview/capy/reference/boost/capy/prefix.html diff --git a/preview/reference/boost/capy/prefix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/prefix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/prefix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/prefix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/prefix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/prefix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/prefix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/prefix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/pull_from-04.html b/preview/capy/reference/boost/capy/pull_from-04.html similarity index 100% rename from preview/reference/boost/capy/pull_from-04.html rename to preview/capy/reference/boost/capy/pull_from-04.html diff --git a/preview/reference/boost/capy/pull_from-07.html b/preview/capy/reference/boost/capy/pull_from-07.html similarity index 100% rename from preview/reference/boost/capy/pull_from-07.html rename to preview/capy/reference/boost/capy/pull_from-07.html diff --git a/preview/reference/boost/capy/pull_from-09.html b/preview/capy/reference/boost/capy/pull_from-09.html similarity index 100% rename from preview/reference/boost/capy/pull_from-09.html rename to preview/capy/reference/boost/capy/pull_from-09.html diff --git a/preview/reference/boost/capy/push_to-01.html b/preview/capy/reference/boost/capy/push_to-01.html similarity index 100% rename from preview/reference/boost/capy/push_to-01.html rename to preview/capy/reference/boost/capy/push_to-01.html diff --git a/preview/reference/boost/capy/push_to-03.html b/preview/capy/reference/boost/capy/push_to-03.html similarity index 100% rename from preview/reference/boost/capy/push_to-03.html rename to preview/capy/reference/boost/capy/push_to-03.html diff --git a/preview/reference/boost/capy/push_to-0d.html b/preview/capy/reference/boost/capy/push_to-0d.html similarity index 100% rename from preview/reference/boost/capy/push_to-0d.html rename to preview/capy/reference/boost/capy/push_to-0d.html diff --git a/preview/reference/boost/capy/read-0a.html b/preview/capy/reference/boost/capy/read-0a.html similarity index 100% rename from preview/reference/boost/capy/read-0a.html rename to preview/capy/reference/boost/capy/read-0a.html diff --git a/preview/reference/boost/capy/read-0c.html b/preview/capy/reference/boost/capy/read-0c.html similarity index 100% rename from preview/reference/boost/capy/read-0c.html rename to preview/capy/reference/boost/capy/read-0c.html diff --git a/preview/reference/boost/capy/read-0e.html b/preview/capy/reference/boost/capy/read-0e.html similarity index 100% rename from preview/reference/boost/capy/read-0e.html rename to preview/capy/reference/boost/capy/read-0e.html diff --git a/preview/reference/boost/capy/read_until-0c.html b/preview/capy/reference/boost/capy/read_until-0c.html similarity index 100% rename from preview/reference/boost/capy/read_until-0c.html rename to preview/capy/reference/boost/capy/read_until-0c.html diff --git a/preview/reference/boost/capy/read_until-0d.html b/preview/capy/reference/boost/capy/read_until-0d.html similarity index 100% rename from preview/reference/boost/capy/read_until-0d.html rename to preview/capy/reference/boost/capy/read_until-0d.html diff --git a/preview/reference/boost/capy/read_until-0f.html b/preview/capy/reference/boost/capy/read_until-0f.html similarity index 100% rename from preview/reference/boost/capy/read_until-0f.html rename to preview/capy/reference/boost/capy/read_until-0f.html diff --git a/preview/reference/boost/capy/ready-00.html b/preview/capy/reference/boost/capy/ready-00.html similarity index 100% rename from preview/reference/boost/capy/ready-00.html rename to preview/capy/reference/boost/capy/ready-00.html diff --git a/preview/reference/boost/capy/ready-01.html b/preview/capy/reference/boost/capy/ready-01.html similarity index 100% rename from preview/reference/boost/capy/ready-01.html rename to preview/capy/reference/boost/capy/ready-01.html diff --git a/preview/reference/boost/capy/ready-05.html b/preview/capy/reference/boost/capy/ready-05.html similarity index 100% rename from preview/reference/boost/capy/ready-05.html rename to preview/capy/reference/boost/capy/ready-05.html diff --git a/preview/reference/boost/capy/ready-06.html b/preview/capy/reference/boost/capy/ready-06.html similarity index 100% rename from preview/reference/boost/capy/ready-06.html rename to preview/capy/reference/boost/capy/ready-06.html diff --git a/preview/reference/boost/capy/ready-0b.html b/preview/capy/reference/boost/capy/ready-0b.html similarity index 100% rename from preview/reference/boost/capy/ready-0b.html rename to preview/capy/reference/boost/capy/ready-0b.html diff --git a/preview/reference/boost/capy/ready-0c.html b/preview/capy/reference/boost/capy/ready-0c.html similarity index 100% rename from preview/reference/boost/capy/ready-0c.html rename to preview/capy/reference/boost/capy/ready-0c.html diff --git a/preview/reference/boost/capy/ready-0d0.html b/preview/capy/reference/boost/capy/ready-0d0.html similarity index 100% rename from preview/reference/boost/capy/ready-0d0.html rename to preview/capy/reference/boost/capy/ready-0d0.html diff --git a/preview/reference/boost/capy/ready-0df.html b/preview/capy/reference/boost/capy/ready-0df.html similarity index 100% rename from preview/reference/boost/capy/ready-0df.html rename to preview/capy/reference/boost/capy/ready-0df.html diff --git a/preview/reference/boost/capy/ready-0e.html b/preview/capy/reference/boost/capy/ready-0e.html similarity index 100% rename from preview/reference/boost/capy/ready-0e.html rename to preview/capy/reference/boost/capy/ready-0e.html diff --git a/preview/reference/boost/capy/recycling_memory_resource.html b/preview/capy/reference/boost/capy/recycling_memory_resource.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource.html rename to preview/capy/reference/boost/capy/recycling_memory_resource.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/2destructor.html b/preview/capy/reference/boost/capy/recycling_memory_resource/2destructor.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/2destructor.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/2destructor.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/allocate.html b/preview/capy/reference/boost/capy/recycling_memory_resource/allocate.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/allocate.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/allocate.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/allocate_fast.html b/preview/capy/reference/boost/capy/recycling_memory_resource/allocate_fast.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/allocate_fast.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/allocate_fast.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/deallocate.html b/preview/capy/reference/boost/capy/recycling_memory_resource/deallocate.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/deallocate.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/deallocate.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/deallocate_fast.html b/preview/capy/reference/boost/capy/recycling_memory_resource/deallocate_fast.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/deallocate_fast.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/deallocate_fast.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/do_allocate.html b/preview/capy/reference/boost/capy/recycling_memory_resource/do_allocate.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/do_allocate.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/do_allocate.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/do_deallocate.html b/preview/capy/reference/boost/capy/recycling_memory_resource/do_deallocate.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/do_deallocate.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/do_deallocate.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/do_is_equal.html b/preview/capy/reference/boost/capy/recycling_memory_resource/do_is_equal.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/do_is_equal.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/do_is_equal.html diff --git a/preview/reference/boost/capy/recycling_memory_resource/is_equal.html b/preview/capy/reference/boost/capy/recycling_memory_resource/is_equal.html similarity index 100% rename from preview/reference/boost/capy/recycling_memory_resource/is_equal.html rename to preview/capy/reference/boost/capy/recycling_memory_resource/is_equal.html diff --git a/preview/reference/boost/capy/remove_prefix.html b/preview/capy/reference/boost/capy/remove_prefix.html similarity index 100% rename from preview/reference/boost/capy/remove_prefix.html rename to preview/capy/reference/boost/capy/remove_prefix.html diff --git a/preview/reference/boost/capy/remove_prefix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/remove_prefix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/remove_prefix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/remove_prefix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/remove_prefix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/remove_prefix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/remove_prefix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/remove_prefix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/remove_suffix.html b/preview/capy/reference/boost/capy/remove_suffix.html similarity index 100% rename from preview/reference/boost/capy/remove_suffix.html rename to preview/capy/reference/boost/capy/remove_suffix.html diff --git a/preview/reference/boost/capy/remove_suffix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/remove_suffix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/remove_suffix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/remove_suffix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/remove_suffix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/remove_suffix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/remove_suffix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/remove_suffix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/run-025.html b/preview/capy/reference/boost/capy/run-025.html similarity index 100% rename from preview/reference/boost/capy/run-025.html rename to preview/capy/reference/boost/capy/run-025.html diff --git a/preview/reference/boost/capy/run-02e.html b/preview/capy/reference/boost/capy/run-02e.html similarity index 100% rename from preview/reference/boost/capy/run-02e.html rename to preview/capy/reference/boost/capy/run-02e.html diff --git a/preview/reference/boost/capy/run-03.html b/preview/capy/reference/boost/capy/run-03.html similarity index 100% rename from preview/reference/boost/capy/run-03.html rename to preview/capy/reference/boost/capy/run-03.html diff --git a/preview/reference/boost/capy/run-04.html b/preview/capy/reference/boost/capy/run-04.html similarity index 100% rename from preview/reference/boost/capy/run-04.html rename to preview/capy/reference/boost/capy/run-04.html diff --git a/preview/reference/boost/capy/run-055.html b/preview/capy/reference/boost/capy/run-055.html similarity index 100% rename from preview/reference/boost/capy/run-055.html rename to preview/capy/reference/boost/capy/run-055.html diff --git a/preview/reference/boost/capy/run-056.html b/preview/capy/reference/boost/capy/run-056.html similarity index 100% rename from preview/reference/boost/capy/run-056.html rename to preview/capy/reference/boost/capy/run-056.html diff --git a/preview/reference/boost/capy/run-058.html b/preview/capy/reference/boost/capy/run-058.html similarity index 100% rename from preview/reference/boost/capy/run-058.html rename to preview/capy/reference/boost/capy/run-058.html diff --git a/preview/reference/boost/capy/run-07.html b/preview/capy/reference/boost/capy/run-07.html similarity index 100% rename from preview/reference/boost/capy/run-07.html rename to preview/capy/reference/boost/capy/run-07.html diff --git a/preview/reference/boost/capy/run-09.html b/preview/capy/reference/boost/capy/run-09.html similarity index 100% rename from preview/reference/boost/capy/run-09.html rename to preview/capy/reference/boost/capy/run-09.html diff --git a/preview/reference/boost/capy/run-0e6.html b/preview/capy/reference/boost/capy/run-0e6.html similarity index 100% rename from preview/reference/boost/capy/run-0e6.html rename to preview/capy/reference/boost/capy/run-0e6.html diff --git a/preview/reference/boost/capy/run-0e8.html b/preview/capy/reference/boost/capy/run-0e8.html similarity index 100% rename from preview/reference/boost/capy/run-0e8.html rename to preview/capy/reference/boost/capy/run-0e8.html diff --git a/preview/reference/boost/capy/run_async-00.html b/preview/capy/reference/boost/capy/run_async-00.html similarity index 100% rename from preview/reference/boost/capy/run_async-00.html rename to preview/capy/reference/boost/capy/run_async-00.html diff --git a/preview/reference/boost/capy/run_async-01.html b/preview/capy/reference/boost/capy/run_async-01.html similarity index 100% rename from preview/reference/boost/capy/run_async-01.html rename to preview/capy/reference/boost/capy/run_async-01.html diff --git a/preview/reference/boost/capy/run_async-034.html b/preview/capy/reference/boost/capy/run_async-034.html similarity index 100% rename from preview/reference/boost/capy/run_async-034.html rename to preview/capy/reference/boost/capy/run_async-034.html diff --git a/preview/reference/boost/capy/run_async-039.html b/preview/capy/reference/boost/capy/run_async-039.html similarity index 100% rename from preview/reference/boost/capy/run_async-039.html rename to preview/capy/reference/boost/capy/run_async-039.html diff --git a/preview/reference/boost/capy/run_async-03d.html b/preview/capy/reference/boost/capy/run_async-03d.html similarity index 100% rename from preview/reference/boost/capy/run_async-03d.html rename to preview/capy/reference/boost/capy/run_async-03d.html diff --git a/preview/reference/boost/capy/run_async-05.html b/preview/capy/reference/boost/capy/run_async-05.html similarity index 100% rename from preview/reference/boost/capy/run_async-05.html rename to preview/capy/reference/boost/capy/run_async-05.html diff --git a/preview/reference/boost/capy/run_async-06.html b/preview/capy/reference/boost/capy/run_async-06.html similarity index 100% rename from preview/reference/boost/capy/run_async-06.html rename to preview/capy/reference/boost/capy/run_async-06.html diff --git a/preview/reference/boost/capy/run_async-07.html b/preview/capy/reference/boost/capy/run_async-07.html similarity index 100% rename from preview/reference/boost/capy/run_async-07.html rename to preview/capy/reference/boost/capy/run_async-07.html diff --git a/preview/reference/boost/capy/run_async-086.html b/preview/capy/reference/boost/capy/run_async-086.html similarity index 100% rename from preview/reference/boost/capy/run_async-086.html rename to preview/capy/reference/boost/capy/run_async-086.html diff --git a/preview/reference/boost/capy/run_async-08e.html b/preview/capy/reference/boost/capy/run_async-08e.html similarity index 100% rename from preview/reference/boost/capy/run_async-08e.html rename to preview/capy/reference/boost/capy/run_async-08e.html diff --git a/preview/reference/boost/capy/run_async-0c.html b/preview/capy/reference/boost/capy/run_async-0c.html similarity index 100% rename from preview/reference/boost/capy/run_async-0c.html rename to preview/capy/reference/boost/capy/run_async-0c.html diff --git a/preview/reference/boost/capy/run_async-0ef8.html b/preview/capy/reference/boost/capy/run_async-0ef8.html similarity index 100% rename from preview/reference/boost/capy/run_async-0ef8.html rename to preview/capy/reference/boost/capy/run_async-0ef8.html diff --git a/preview/reference/boost/capy/run_async-0ef9.html b/preview/capy/reference/boost/capy/run_async-0ef9.html similarity index 100% rename from preview/reference/boost/capy/run_async-0ef9.html rename to preview/capy/reference/boost/capy/run_async-0ef9.html diff --git a/preview/reference/boost/capy/run_async-0f1.html b/preview/capy/reference/boost/capy/run_async-0f1.html similarity index 100% rename from preview/reference/boost/capy/run_async-0f1.html rename to preview/capy/reference/boost/capy/run_async-0f1.html diff --git a/preview/reference/boost/capy/run_async-0f7.html b/preview/capy/reference/boost/capy/run_async-0f7.html similarity index 100% rename from preview/reference/boost/capy/run_async-0f7.html rename to preview/capy/reference/boost/capy/run_async-0f7.html diff --git a/preview/reference/boost/capy/run_async_wrapper.html b/preview/capy/reference/boost/capy/run_async_wrapper.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper.html rename to preview/capy/reference/boost/capy/run_async_wrapper.html diff --git a/preview/reference/boost/capy/run_async_wrapper/2constructor-01.html b/preview/capy/reference/boost/capy/run_async_wrapper/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/2constructor-01.html rename to preview/capy/reference/boost/capy/run_async_wrapper/2constructor-01.html diff --git a/preview/reference/boost/capy/run_async_wrapper/2constructor-0d.html b/preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0d.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/2constructor-0d.html rename to preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0d.html diff --git a/preview/reference/boost/capy/run_async_wrapper/2constructor-0e6.html b/preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0e6.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/2constructor-0e6.html rename to preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0e6.html diff --git a/preview/reference/boost/capy/run_async_wrapper/2constructor-0ed.html b/preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0ed.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/2constructor-0ed.html rename to preview/capy/reference/boost/capy/run_async_wrapper/2constructor-0ed.html diff --git a/preview/reference/boost/capy/run_async_wrapper/2destructor.html b/preview/capy/reference/boost/capy/run_async_wrapper/2destructor.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/2destructor.html rename to preview/capy/reference/boost/capy/run_async_wrapper/2destructor.html diff --git a/preview/reference/boost/capy/run_async_wrapper/operator_assign-0a.html b/preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0a.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/operator_assign-0a.html rename to preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0a.html diff --git a/preview/reference/boost/capy/run_async_wrapper/operator_assign-0b.html b/preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0b.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/operator_assign-0b.html rename to preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0b.html diff --git a/preview/reference/boost/capy/run_async_wrapper/operator_assign-0e.html b/preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0e.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/operator_assign-0e.html rename to preview/capy/reference/boost/capy/run_async_wrapper/operator_assign-0e.html diff --git a/preview/reference/boost/capy/run_async_wrapper/operator_call.html b/preview/capy/reference/boost/capy/run_async_wrapper/operator_call.html similarity index 100% rename from preview/reference/boost/capy/run_async_wrapper/operator_call.html rename to preview/capy/reference/boost/capy/run_async_wrapper/operator_call.html diff --git a/preview/reference/boost/capy/sans_prefix.html b/preview/capy/reference/boost/capy/sans_prefix.html similarity index 100% rename from preview/reference/boost/capy/sans_prefix.html rename to preview/capy/reference/boost/capy/sans_prefix.html diff --git a/preview/reference/boost/capy/sans_prefix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/sans_prefix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/sans_prefix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/sans_prefix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/sans_prefix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/sans_prefix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/sans_prefix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/sans_prefix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/sans_suffix.html b/preview/capy/reference/boost/capy/sans_suffix.html similarity index 100% rename from preview/reference/boost/capy/sans_suffix.html rename to preview/capy/reference/boost/capy/sans_suffix.html diff --git a/preview/reference/boost/capy/sans_suffix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/sans_suffix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/sans_suffix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/sans_suffix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/sans_suffix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/sans_suffix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/sans_suffix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/sans_suffix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/set_current_frame_allocator.html b/preview/capy/reference/boost/capy/set_current_frame_allocator.html similarity index 100% rename from preview/reference/boost/capy/set_current_frame_allocator.html rename to preview/capy/reference/boost/capy/set_current_frame_allocator.html diff --git a/preview/reference/boost/capy/size_tag.html b/preview/capy/reference/boost/capy/size_tag.html similarity index 100% rename from preview/reference/boost/capy/size_tag.html rename to preview/capy/reference/boost/capy/size_tag.html diff --git a/preview/reference/boost/capy/slice_how.html b/preview/capy/reference/boost/capy/slice_how.html similarity index 100% rename from preview/reference/boost/capy/slice_how.html rename to preview/capy/reference/boost/capy/slice_how.html diff --git a/preview/reference/boost/capy/slice_of-07.html b/preview/capy/reference/boost/capy/slice_of-07.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07.html rename to preview/capy/reference/boost/capy/slice_of-07.html diff --git a/preview/reference/boost/capy/slice_of-07/2constructor-01.html b/preview/capy/reference/boost/capy/slice_of-07/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/2constructor-01.html rename to preview/capy/reference/boost/capy/slice_of-07/2constructor-01.html diff --git a/preview/reference/boost/capy/slice_of-07/2constructor-04.html b/preview/capy/reference/boost/capy/slice_of-07/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/2constructor-04.html rename to preview/capy/reference/boost/capy/slice_of-07/2constructor-04.html diff --git a/preview/reference/boost/capy/slice_of-07/2constructor-0d.html b/preview/capy/reference/boost/capy/slice_of-07/2constructor-0d.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/2constructor-0d.html rename to preview/capy/reference/boost/capy/slice_of-07/2constructor-0d.html diff --git a/preview/reference/boost/capy/slice_of-07/begin.html b/preview/capy/reference/boost/capy/slice_of-07/begin.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/begin.html rename to preview/capy/reference/boost/capy/slice_of-07/begin.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/2constructor.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/2constructor.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/2constructor.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/2constructor.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/difference_type.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/difference_type.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/difference_type.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/difference_type.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/iterator_category.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/iterator_category.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/iterator_category.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/iterator_category.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/iterator_concept.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/iterator_concept.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/iterator_concept.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/iterator_concept.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05c.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05c.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05c.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05c.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05f.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05f.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05f.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-05f.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-0a.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-0a.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_dec-0a.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_dec-0a.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_eq.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_eq.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_eq.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-00.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-00.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-00.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-00.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-02.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-02.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-02.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-02.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-03.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-03.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_inc-03.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_inc-03.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_not_eq.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_not_eq.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_not_eq.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_not_eq.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/operator_star.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_star.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/operator_star.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/operator_star.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/pointer.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/pointer.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/pointer.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/pointer.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/reference.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/reference.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/reference.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/reference.html diff --git a/preview/reference/boost/capy/slice_of-07/const_iterator/value_type.html b/preview/capy/reference/boost/capy/slice_of-07/const_iterator/value_type.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/const_iterator/value_type.html rename to preview/capy/reference/boost/capy/slice_of-07/const_iterator/value_type.html diff --git a/preview/reference/boost/capy/slice_of-07/end.html b/preview/capy/reference/boost/capy/slice_of-07/end.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/end.html rename to preview/capy/reference/boost/capy/slice_of-07/end.html diff --git a/preview/reference/boost/capy/slice_of-07/value_type.html b/preview/capy/reference/boost/capy/slice_of-07/value_type.html similarity index 100% rename from preview/reference/boost/capy/slice_of-07/value_type.html rename to preview/capy/reference/boost/capy/slice_of-07/value_type.html diff --git a/preview/reference/boost/capy/slice_of-0a.html b/preview/capy/reference/boost/capy/slice_of-0a.html similarity index 100% rename from preview/reference/boost/capy/slice_of-0a.html rename to preview/capy/reference/boost/capy/slice_of-0a.html diff --git a/preview/reference/boost/capy/slice_tag.html b/preview/capy/reference/boost/capy/slice_tag.html similarity index 100% rename from preview/reference/boost/capy/slice_tag.html rename to preview/capy/reference/boost/capy/slice_tag.html diff --git a/preview/reference/boost/capy/slice_type.html b/preview/capy/reference/boost/capy/slice_type.html similarity index 100% rename from preview/reference/boost/capy/slice_type.html rename to preview/capy/reference/boost/capy/slice_type.html diff --git a/preview/reference/boost/capy/strand-02.html b/preview/capy/reference/boost/capy/strand-02.html similarity index 100% rename from preview/reference/boost/capy/strand-02.html rename to preview/capy/reference/boost/capy/strand-02.html diff --git a/preview/reference/boost/capy/strand-02/2constructor-01.html b/preview/capy/reference/boost/capy/strand-02/2constructor-01.html similarity index 100% rename from preview/reference/boost/capy/strand-02/2constructor-01.html rename to preview/capy/reference/boost/capy/strand-02/2constructor-01.html diff --git a/preview/reference/boost/capy/strand-02/2constructor-04.html b/preview/capy/reference/boost/capy/strand-02/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/strand-02/2constructor-04.html rename to preview/capy/reference/boost/capy/strand-02/2constructor-04.html diff --git a/preview/reference/boost/capy/strand-02/2constructor-0c.html b/preview/capy/reference/boost/capy/strand-02/2constructor-0c.html similarity index 100% rename from preview/reference/boost/capy/strand-02/2constructor-0c.html rename to preview/capy/reference/boost/capy/strand-02/2constructor-0c.html diff --git a/preview/reference/boost/capy/strand-02/2constructor-0f.html b/preview/capy/reference/boost/capy/strand-02/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/strand-02/2constructor-0f.html rename to preview/capy/reference/boost/capy/strand-02/2constructor-0f.html diff --git a/preview/reference/boost/capy/strand-02/context.html b/preview/capy/reference/boost/capy/strand-02/context.html similarity index 100% rename from preview/reference/boost/capy/strand-02/context.html rename to preview/capy/reference/boost/capy/strand-02/context.html diff --git a/preview/reference/boost/capy/strand-02/dispatch.html b/preview/capy/reference/boost/capy/strand-02/dispatch.html similarity index 100% rename from preview/reference/boost/capy/strand-02/dispatch.html rename to preview/capy/reference/boost/capy/strand-02/dispatch.html diff --git a/preview/reference/boost/capy/strand-02/get_inner_executor.html b/preview/capy/reference/boost/capy/strand-02/get_inner_executor.html similarity index 100% rename from preview/reference/boost/capy/strand-02/get_inner_executor.html rename to preview/capy/reference/boost/capy/strand-02/get_inner_executor.html diff --git a/preview/reference/boost/capy/strand-02/inner_executor_type.html b/preview/capy/reference/boost/capy/strand-02/inner_executor_type.html similarity index 100% rename from preview/reference/boost/capy/strand-02/inner_executor_type.html rename to preview/capy/reference/boost/capy/strand-02/inner_executor_type.html diff --git a/preview/reference/boost/capy/strand-02/on_work_finished.html b/preview/capy/reference/boost/capy/strand-02/on_work_finished.html similarity index 100% rename from preview/reference/boost/capy/strand-02/on_work_finished.html rename to preview/capy/reference/boost/capy/strand-02/on_work_finished.html diff --git a/preview/reference/boost/capy/strand-02/on_work_started.html b/preview/capy/reference/boost/capy/strand-02/on_work_started.html similarity index 100% rename from preview/reference/boost/capy/strand-02/on_work_started.html rename to preview/capy/reference/boost/capy/strand-02/on_work_started.html diff --git a/preview/reference/boost/capy/strand-02/operator_assign-04.html b/preview/capy/reference/boost/capy/strand-02/operator_assign-04.html similarity index 100% rename from preview/reference/boost/capy/strand-02/operator_assign-04.html rename to preview/capy/reference/boost/capy/strand-02/operator_assign-04.html diff --git a/preview/reference/boost/capy/strand-02/operator_assign-0d.html b/preview/capy/reference/boost/capy/strand-02/operator_assign-0d.html similarity index 100% rename from preview/reference/boost/capy/strand-02/operator_assign-0d.html rename to preview/capy/reference/boost/capy/strand-02/operator_assign-0d.html diff --git a/preview/reference/boost/capy/strand-02/operator_assign-0f.html b/preview/capy/reference/boost/capy/strand-02/operator_assign-0f.html similarity index 100% rename from preview/reference/boost/capy/strand-02/operator_assign-0f.html rename to preview/capy/reference/boost/capy/strand-02/operator_assign-0f.html diff --git a/preview/reference/boost/capy/strand-02/operator_eq.html b/preview/capy/reference/boost/capy/strand-02/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/strand-02/operator_eq.html rename to preview/capy/reference/boost/capy/strand-02/operator_eq.html diff --git a/preview/reference/boost/capy/strand-02/post.html b/preview/capy/reference/boost/capy/strand-02/post.html similarity index 100% rename from preview/reference/boost/capy/strand-02/post.html rename to preview/capy/reference/boost/capy/strand-02/post.html diff --git a/preview/reference/boost/capy/strand-02/running_in_this_thread.html b/preview/capy/reference/boost/capy/strand-02/running_in_this_thread.html similarity index 100% rename from preview/reference/boost/capy/strand-02/running_in_this_thread.html rename to preview/capy/reference/boost/capy/strand-02/running_in_this_thread.html diff --git a/preview/reference/boost/capy/strand-05.html b/preview/capy/reference/boost/capy/strand-05.html similarity index 100% rename from preview/reference/boost/capy/strand-05.html rename to preview/capy/reference/boost/capy/strand-05.html diff --git a/preview/reference/boost/capy/string_dynamic_buffer.html b/preview/capy/reference/boost/capy/string_dynamic_buffer.html similarity index 100% rename from preview/reference/boost/capy/string_dynamic_buffer.html rename to preview/capy/reference/boost/capy/string_dynamic_buffer.html diff --git a/preview/reference/boost/capy/suffix.html b/preview/capy/reference/boost/capy/suffix.html similarity index 100% rename from preview/reference/boost/capy/suffix.html rename to preview/capy/reference/boost/capy/suffix.html diff --git a/preview/reference/boost/capy/suffix_mrdocs_workaround_t.html b/preview/capy/reference/boost/capy/suffix_mrdocs_workaround_t.html similarity index 100% rename from preview/reference/boost/capy/suffix_mrdocs_workaround_t.html rename to preview/capy/reference/boost/capy/suffix_mrdocs_workaround_t.html diff --git a/preview/reference/boost/capy/suffix_mrdocs_workaround_t/operator_call.html b/preview/capy/reference/boost/capy/suffix_mrdocs_workaround_t/operator_call.html similarity index 100% rename from preview/reference/boost/capy/suffix_mrdocs_workaround_t/operator_call.html rename to preview/capy/reference/boost/capy/suffix_mrdocs_workaround_t/operator_call.html diff --git a/preview/reference/boost/capy/tag_invoke-00.html b/preview/capy/reference/boost/capy/tag_invoke-00.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-00.html rename to preview/capy/reference/boost/capy/tag_invoke-00.html diff --git a/preview/reference/boost/capy/tag_invoke-02.html b/preview/capy/reference/boost/capy/tag_invoke-02.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-02.html rename to preview/capy/reference/boost/capy/tag_invoke-02.html diff --git a/preview/reference/boost/capy/tag_invoke-07.html b/preview/capy/reference/boost/capy/tag_invoke-07.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-07.html rename to preview/capy/reference/boost/capy/tag_invoke-07.html diff --git a/preview/reference/boost/capy/tag_invoke-088.html b/preview/capy/reference/boost/capy/tag_invoke-088.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-088.html rename to preview/capy/reference/boost/capy/tag_invoke-088.html diff --git a/preview/reference/boost/capy/tag_invoke-08b.html b/preview/capy/reference/boost/capy/tag_invoke-08b.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-08b.html rename to preview/capy/reference/boost/capy/tag_invoke-08b.html diff --git a/preview/reference/boost/capy/tag_invoke-0a.html b/preview/capy/reference/boost/capy/tag_invoke-0a.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-0a.html rename to preview/capy/reference/boost/capy/tag_invoke-0a.html diff --git a/preview/reference/boost/capy/tag_invoke-0b.html b/preview/capy/reference/boost/capy/tag_invoke-0b.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-0b.html rename to preview/capy/reference/boost/capy/tag_invoke-0b.html diff --git a/preview/reference/boost/capy/tag_invoke-0c.html b/preview/capy/reference/boost/capy/tag_invoke-0c.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-0c.html rename to preview/capy/reference/boost/capy/tag_invoke-0c.html diff --git a/preview/reference/boost/capy/tag_invoke-0e.html b/preview/capy/reference/boost/capy/tag_invoke-0e.html similarity index 100% rename from preview/reference/boost/capy/tag_invoke-0e.html rename to preview/capy/reference/boost/capy/tag_invoke-0e.html diff --git a/preview/reference/boost/capy/task.html b/preview/capy/reference/boost/capy/task.html similarity index 100% rename from preview/reference/boost/capy/task.html rename to preview/capy/reference/boost/capy/task.html diff --git a/preview/reference/boost/capy/task/2constructor-00.html b/preview/capy/reference/boost/capy/task/2constructor-00.html similarity index 100% rename from preview/reference/boost/capy/task/2constructor-00.html rename to preview/capy/reference/boost/capy/task/2constructor-00.html diff --git a/preview/reference/boost/capy/task/2constructor-03.html b/preview/capy/reference/boost/capy/task/2constructor-03.html similarity index 100% rename from preview/reference/boost/capy/task/2constructor-03.html rename to preview/capy/reference/boost/capy/task/2constructor-03.html diff --git a/preview/reference/boost/capy/task/2constructor-0b.html b/preview/capy/reference/boost/capy/task/2constructor-0b.html similarity index 100% rename from preview/reference/boost/capy/task/2constructor-0b.html rename to preview/capy/reference/boost/capy/task/2constructor-0b.html diff --git a/preview/reference/boost/capy/task/2destructor.html b/preview/capy/reference/boost/capy/task/2destructor.html similarity index 100% rename from preview/reference/boost/capy/task/2destructor.html rename to preview/capy/reference/boost/capy/task/2destructor.html diff --git a/preview/reference/boost/capy/task/await_ready.html b/preview/capy/reference/boost/capy/task/await_ready.html similarity index 100% rename from preview/reference/boost/capy/task/await_ready.html rename to preview/capy/reference/boost/capy/task/await_ready.html diff --git a/preview/reference/boost/capy/task/await_resume.html b/preview/capy/reference/boost/capy/task/await_resume.html similarity index 100% rename from preview/reference/boost/capy/task/await_resume.html rename to preview/capy/reference/boost/capy/task/await_resume.html diff --git a/preview/reference/boost/capy/task/await_suspend.html b/preview/capy/reference/boost/capy/task/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/task/await_suspend.html rename to preview/capy/reference/boost/capy/task/await_suspend.html diff --git a/preview/reference/boost/capy/task/h_.html b/preview/capy/reference/boost/capy/task/h_.html similarity index 100% rename from preview/reference/boost/capy/task/h_.html rename to preview/capy/reference/boost/capy/task/h_.html diff --git a/preview/reference/boost/capy/task/handle.html b/preview/capy/reference/boost/capy/task/handle.html similarity index 100% rename from preview/reference/boost/capy/task/handle.html rename to preview/capy/reference/boost/capy/task/handle.html diff --git a/preview/reference/boost/capy/task/operator_assign-02.html b/preview/capy/reference/boost/capy/task/operator_assign-02.html similarity index 100% rename from preview/reference/boost/capy/task/operator_assign-02.html rename to preview/capy/reference/boost/capy/task/operator_assign-02.html diff --git a/preview/reference/boost/capy/task/operator_assign-06.html b/preview/capy/reference/boost/capy/task/operator_assign-06.html similarity index 100% rename from preview/reference/boost/capy/task/operator_assign-06.html rename to preview/capy/reference/boost/capy/task/operator_assign-06.html diff --git a/preview/reference/boost/capy/task/operator_assign-08.html b/preview/capy/reference/boost/capy/task/operator_assign-08.html similarity index 100% rename from preview/reference/boost/capy/task/operator_assign-08.html rename to preview/capy/reference/boost/capy/task/operator_assign-08.html diff --git a/preview/reference/boost/capy/task/promise_type.html b/preview/capy/reference/boost/capy/task/promise_type.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type.html rename to preview/capy/reference/boost/capy/task/promise_type.html diff --git a/preview/reference/boost/capy/task/promise_type/2constructor.html b/preview/capy/reference/boost/capy/task/promise_type/2constructor.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/2constructor.html rename to preview/capy/reference/boost/capy/task/promise_type/2constructor.html diff --git a/preview/reference/boost/capy/task/promise_type/2destructor.html b/preview/capy/reference/boost/capy/task/promise_type/2destructor.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/2destructor.html rename to preview/capy/reference/boost/capy/task/promise_type/2destructor.html diff --git a/preview/reference/boost/capy/task/promise_type/ep_.html b/preview/capy/reference/boost/capy/task/promise_type/ep_.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/ep_.html rename to preview/capy/reference/boost/capy/task/promise_type/ep_.html diff --git a/preview/reference/boost/capy/task/promise_type/exception.html b/preview/capy/reference/boost/capy/task/promise_type/exception.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/exception.html rename to preview/capy/reference/boost/capy/task/promise_type/exception.html diff --git a/preview/reference/boost/capy/task/promise_type/final_suspend.html b/preview/capy/reference/boost/capy/task/promise_type/final_suspend.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/final_suspend.html rename to preview/capy/reference/boost/capy/task/promise_type/final_suspend.html diff --git a/preview/reference/boost/capy/task/promise_type/get_return_object.html b/preview/capy/reference/boost/capy/task/promise_type/get_return_object.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/get_return_object.html rename to preview/capy/reference/boost/capy/task/promise_type/get_return_object.html diff --git a/preview/reference/boost/capy/task/promise_type/initial_suspend.html b/preview/capy/reference/boost/capy/task/promise_type/initial_suspend.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/initial_suspend.html rename to preview/capy/reference/boost/capy/task/promise_type/initial_suspend.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaitable.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaitable.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaitable.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaitable.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter/a_.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/a_.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter/a_.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/a_.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter/await_ready.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_ready.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter/await_ready.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_ready.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter/await_resume.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_resume.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter/await_resume.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_resume.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter/await_suspend.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_suspend.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter/await_suspend.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/await_suspend.html diff --git a/preview/reference/boost/capy/task/promise_type/transform_awaiter/p_.html b/preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/p_.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/transform_awaiter/p_.html rename to preview/capy/reference/boost/capy/task/promise_type/transform_awaiter/p_.html diff --git a/preview/reference/boost/capy/task/promise_type/unhandled_exception.html b/preview/capy/reference/boost/capy/task/promise_type/unhandled_exception.html similarity index 100% rename from preview/reference/boost/capy/task/promise_type/unhandled_exception.html rename to preview/capy/reference/boost/capy/task/promise_type/unhandled_exception.html diff --git a/preview/reference/boost/capy/task/release.html b/preview/capy/reference/boost/capy/task/release.html similarity index 100% rename from preview/reference/boost/capy/task/release.html rename to preview/capy/reference/boost/capy/task/release.html diff --git a/preview/reference/boost/capy/this_coro.html b/preview/capy/reference/boost/capy/this_coro.html similarity index 98% rename from preview/reference/boost/capy/this_coro.html rename to preview/capy/reference/boost/capy/this_coro.html index 63b4d59..01ec219 100644 --- a/preview/reference/boost/capy/this_coro.html +++ b/preview/capy/reference/boost/capy/this_coro.html @@ -372,7 +372,7 @@ auto const& env = co_await this_coro::environment; auto ex = co_await this_coro::executor; auto token = co_await this_coro::stop_token; - auto* alloc = co_await this_coro::allocator; + auto* alloc = co_await this_coro::frame_allocator; }
    @@ -392,10 +392,6 @@ - - - - @@ -404,6 +400,10 @@ + + + + @@ -425,10 +425,6 @@ - - - - @@ -437,6 +433,10 @@ + + + + diff --git a/preview/reference/boost/capy/this_coro/allocator.html b/preview/capy/reference/boost/capy/this_coro/allocator.html similarity index 100% rename from preview/reference/boost/capy/this_coro/allocator.html rename to preview/capy/reference/boost/capy/this_coro/allocator.html diff --git a/preview/reference/boost/capy/this_coro/allocator_tag.html b/preview/capy/reference/boost/capy/this_coro/allocator_tag.html similarity index 100% rename from preview/reference/boost/capy/this_coro/allocator_tag.html rename to preview/capy/reference/boost/capy/this_coro/allocator_tag.html diff --git a/preview/reference/boost/capy/this_coro/environment.html b/preview/capy/reference/boost/capy/this_coro/environment.html similarity index 99% rename from preview/reference/boost/capy/this_coro/environment.html rename to preview/capy/reference/boost/capy/this_coro/environment.html index 092699f..7216aad 100644 --- a/preview/reference/boost/capy/this_coro/environment.html +++ b/preview/capy/reference/boost/capy/this_coro/environment.html @@ -385,7 +385,7 @@ auto const& env = co_await this_coro::environment; // env.executor - the executor this coroutine is bound to // env.stop_token - the stop token for cancellation - // env.allocator - the allocator for frame allocation + // env.frame_allocator - the frame allocator } diff --git a/preview/reference/boost/capy/this_coro/environment_tag.html b/preview/capy/reference/boost/capy/this_coro/environment_tag.html similarity index 100% rename from preview/reference/boost/capy/this_coro/environment_tag.html rename to preview/capy/reference/boost/capy/this_coro/environment_tag.html diff --git a/preview/reference/boost/capy/this_coro/executor.html b/preview/capy/reference/boost/capy/this_coro/executor.html similarity index 100% rename from preview/reference/boost/capy/this_coro/executor.html rename to preview/capy/reference/boost/capy/this_coro/executor.html diff --git a/preview/reference/boost/capy/this_coro/executor_tag.html b/preview/capy/reference/boost/capy/this_coro/executor_tag.html similarity index 100% rename from preview/reference/boost/capy/this_coro/executor_tag.html rename to preview/capy/reference/boost/capy/this_coro/executor_tag.html diff --git a/preview/capy/reference/boost/capy/this_coro/frame_allocator.html b/preview/capy/reference/boost/capy/this_coro/frame_allocator.html new file mode 100644 index 0000000..960df1b --- /dev/null +++ b/preview/capy/reference/boost/capy/this_coro/frame_allocator.html @@ -0,0 +1,432 @@ + + + + + + + + + + + + + +boost::capy::this_coro::frame_allocator :: Boost Libraries Documentation + + + + + + + + + + + + + + + + +
    +
    +
    + +

    boost::capy::this_coro::frame_allocator

    +
    +
    +
    +

    Tag object that yields the current frame allocator when awaited.

    +
    +
    +
    +
    +

    Synopsis

    +
    +
    +

    Declared in <boost/capy/ex/this_coro.hpp>

    +
    +
    +
    +
    inline constexpr frame_allocator_tag frame_allocator = {};
    +
    +
    +
    +
    +
    +

    Description

    +
    +
    +

    Use co_await this_coro::frame_allocator inside a coroutine whose promise type supports frame allocator access (e.g., inherits from io_awaitable_promise_base). The returned pointer is the memory resource used for coroutine frame allocation.

    +
    +
    +
    +
    +

    Example

    +
    +
    +
    +
    task<void> example()
    +{
    +    auto* alloc = co_await this_coro::frame_allocator;
    +    // alloc is nullptr when using the default allocator
    +}
    +
    +
    +
    +
    +
    +

    Behavior

    +
    +
    +
      +
    • +

      Returns `nullptr` when the default allocator is in use.

      +
    • +
    • +

      This operation never suspends; `await_ready()` always returns `true`.

      +
    • +
    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    frame_allocator_tag

    +
    +
    +

    io_awaitable_promise_base

    +
    +
    +

    Created with MrDocs

    +
    +
    +
    +
    +
    +
    +
    + +
    + + diff --git a/preview/capy/reference/boost/capy/this_coro/frame_allocator_tag.html b/preview/capy/reference/boost/capy/this_coro/frame_allocator_tag.html new file mode 100644 index 0000000..66ab3f4 --- /dev/null +++ b/preview/capy/reference/boost/capy/this_coro/frame_allocator_tag.html @@ -0,0 +1,403 @@ + + + + + + + + + + + + + +boost::capy::this_coro::frame_allocator_tag :: Boost Libraries Documentation + + + + + + + + + + + + + + + + +
    +
    +
    + +

    boost::capy::this_coro::frame_allocator_tag

    +
    +
    +
    +

    Tag type for coroutine frame allocator retrieval.

    +
    +
    +
    +
    +

    Synopsis

    +
    +
    +

    Declared in <boost/capy/ex/this_coro.hpp>

    +
    +
    +
    +
    struct frame_allocator_tag;
    +
    +
    +
    +
    +
    +

    Description

    +
    +
    +

    This tag is intercepted by a promise type's await_transform to yield the coroutine's current frame allocator. The tag itself carries no data; it serves only as a sentinel for compile‐time dispatch.

    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    frame_allocator

    +
    +
    +

    io_awaitable_promise_base

    +
    +
    +

    Created with MrDocs

    +
    +
    +
    +
    +
    +
    +
    + +
    + + diff --git a/preview/reference/boost/capy/this_coro/stop_token.html b/preview/capy/reference/boost/capy/this_coro/stop_token.html similarity index 100% rename from preview/reference/boost/capy/this_coro/stop_token.html rename to preview/capy/reference/boost/capy/this_coro/stop_token.html diff --git a/preview/reference/boost/capy/this_coro/stop_token_tag.html b/preview/capy/reference/boost/capy/this_coro/stop_token_tag.html similarity index 100% rename from preview/reference/boost/capy/this_coro/stop_token_tag.html rename to preview/capy/reference/boost/capy/this_coro/stop_token_tag.html diff --git a/preview/reference/boost/capy/thread_pool.html b/preview/capy/reference/boost/capy/thread_pool.html similarity index 100% rename from preview/reference/boost/capy/thread_pool.html rename to preview/capy/reference/boost/capy/thread_pool.html diff --git a/preview/reference/boost/capy/thread_pool/2constructor-04.html b/preview/capy/reference/boost/capy/thread_pool/2constructor-04.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/2constructor-04.html rename to preview/capy/reference/boost/capy/thread_pool/2constructor-04.html diff --git a/preview/reference/boost/capy/thread_pool/2constructor-09.html b/preview/capy/reference/boost/capy/thread_pool/2constructor-09.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/2constructor-09.html rename to preview/capy/reference/boost/capy/thread_pool/2constructor-09.html diff --git a/preview/reference/boost/capy/thread_pool/2constructor-0f.html b/preview/capy/reference/boost/capy/thread_pool/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/2constructor-0f.html rename to preview/capy/reference/boost/capy/thread_pool/2constructor-0f.html diff --git a/preview/reference/boost/capy/thread_pool/2destructor.html b/preview/capy/reference/boost/capy/thread_pool/2destructor.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/2destructor.html rename to preview/capy/reference/boost/capy/thread_pool/2destructor.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type.html b/preview/capy/reference/boost/capy/thread_pool/executor_type.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/2constructor.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/2constructor.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/2constructor.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/2constructor.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/context.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/context.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/context.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/context.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/dispatch.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/dispatch.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/dispatch.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/dispatch.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/on_work_finished.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/on_work_finished.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/on_work_finished.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/on_work_finished.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/on_work_started.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/on_work_started.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/on_work_started.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/on_work_started.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/operator_eq.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/operator_eq.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/operator_eq.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/operator_eq.html diff --git a/preview/reference/boost/capy/thread_pool/executor_type/post.html b/preview/capy/reference/boost/capy/thread_pool/executor_type/post.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/executor_type/post.html rename to preview/capy/reference/boost/capy/thread_pool/executor_type/post.html diff --git a/preview/reference/boost/capy/thread_pool/get_executor.html b/preview/capy/reference/boost/capy/thread_pool/get_executor.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/get_executor.html rename to preview/capy/reference/boost/capy/thread_pool/get_executor.html diff --git a/preview/reference/boost/capy/thread_pool/operator_assign-0d.html b/preview/capy/reference/boost/capy/thread_pool/operator_assign-0d.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/operator_assign-0d.html rename to preview/capy/reference/boost/capy/thread_pool/operator_assign-0d.html diff --git a/preview/reference/boost/capy/thread_pool/operator_assign-0f.html b/preview/capy/reference/boost/capy/thread_pool/operator_assign-0f.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/operator_assign-0f.html rename to preview/capy/reference/boost/capy/thread_pool/operator_assign-0f.html diff --git a/preview/reference/boost/capy/thread_pool/stop.html b/preview/capy/reference/boost/capy/thread_pool/stop.html similarity index 100% rename from preview/reference/boost/capy/thread_pool/stop.html rename to preview/capy/reference/boost/capy/thread_pool/stop.html diff --git a/preview/reference/boost/capy/vector_dynamic_buffer.html b/preview/capy/reference/boost/capy/vector_dynamic_buffer.html similarity index 100% rename from preview/reference/boost/capy/vector_dynamic_buffer.html rename to preview/capy/reference/boost/capy/vector_dynamic_buffer.html diff --git a/preview/reference/boost/capy/when_all.html b/preview/capy/reference/boost/capy/when_all.html similarity index 100% rename from preview/reference/boost/capy/when_all.html rename to preview/capy/reference/boost/capy/when_all.html diff --git a/preview/reference/boost/capy/when_all_result_type.html b/preview/capy/reference/boost/capy/when_all_result_type.html similarity index 100% rename from preview/reference/boost/capy/when_all_result_type.html rename to preview/capy/reference/boost/capy/when_all_result_type.html diff --git a/preview/reference/boost/capy/when_any-09.html b/preview/capy/reference/boost/capy/when_any-09.html similarity index 100% rename from preview/reference/boost/capy/when_any-09.html rename to preview/capy/reference/boost/capy/when_any-09.html diff --git a/preview/reference/boost/capy/when_any-0d8.html b/preview/capy/reference/boost/capy/when_any-0d8.html similarity index 100% rename from preview/reference/boost/capy/when_any-0d8.html rename to preview/capy/reference/boost/capy/when_any-0d8.html diff --git a/preview/reference/boost/capy/when_any-0da.html b/preview/capy/reference/boost/capy/when_any-0da.html similarity index 100% rename from preview/reference/boost/capy/when_any-0da.html rename to preview/capy/reference/boost/capy/when_any-0da.html diff --git a/preview/reference/boost/capy/when_any-0f.html b/preview/capy/reference/boost/capy/when_any-0f.html similarity index 100% rename from preview/reference/boost/capy/when_any-0f.html rename to preview/capy/reference/boost/capy/when_any-0f.html diff --git a/preview/reference/boost/capy/work_guard.html b/preview/capy/reference/boost/capy/work_guard.html similarity index 100% rename from preview/reference/boost/capy/work_guard.html rename to preview/capy/reference/boost/capy/work_guard.html diff --git a/preview/reference/boost/capy/work_guard/2constructor-074.html b/preview/capy/reference/boost/capy/work_guard/2constructor-074.html similarity index 100% rename from preview/reference/boost/capy/work_guard/2constructor-074.html rename to preview/capy/reference/boost/capy/work_guard/2constructor-074.html diff --git a/preview/reference/boost/capy/work_guard/2constructor-075.html b/preview/capy/reference/boost/capy/work_guard/2constructor-075.html similarity index 100% rename from preview/reference/boost/capy/work_guard/2constructor-075.html rename to preview/capy/reference/boost/capy/work_guard/2constructor-075.html diff --git a/preview/reference/boost/capy/work_guard/2constructor-07d.html b/preview/capy/reference/boost/capy/work_guard/2constructor-07d.html similarity index 100% rename from preview/reference/boost/capy/work_guard/2constructor-07d.html rename to preview/capy/reference/boost/capy/work_guard/2constructor-07d.html diff --git a/preview/reference/boost/capy/work_guard/2constructor-0f.html b/preview/capy/reference/boost/capy/work_guard/2constructor-0f.html similarity index 100% rename from preview/reference/boost/capy/work_guard/2constructor-0f.html rename to preview/capy/reference/boost/capy/work_guard/2constructor-0f.html diff --git a/preview/reference/boost/capy/work_guard/2destructor.html b/preview/capy/reference/boost/capy/work_guard/2destructor.html similarity index 100% rename from preview/reference/boost/capy/work_guard/2destructor.html rename to preview/capy/reference/boost/capy/work_guard/2destructor.html diff --git a/preview/reference/boost/capy/work_guard/executor.html b/preview/capy/reference/boost/capy/work_guard/executor.html similarity index 100% rename from preview/reference/boost/capy/work_guard/executor.html rename to preview/capy/reference/boost/capy/work_guard/executor.html diff --git a/preview/reference/boost/capy/work_guard/executor_type.html b/preview/capy/reference/boost/capy/work_guard/executor_type.html similarity index 100% rename from preview/reference/boost/capy/work_guard/executor_type.html rename to preview/capy/reference/boost/capy/work_guard/executor_type.html diff --git a/preview/reference/boost/capy/work_guard/operator_assign.html b/preview/capy/reference/boost/capy/work_guard/operator_assign.html similarity index 100% rename from preview/reference/boost/capy/work_guard/operator_assign.html rename to preview/capy/reference/boost/capy/work_guard/operator_assign.html diff --git a/preview/reference/boost/capy/work_guard/owns_work.html b/preview/capy/reference/boost/capy/work_guard/owns_work.html similarity index 100% rename from preview/reference/boost/capy/work_guard/owns_work.html rename to preview/capy/reference/boost/capy/work_guard/owns_work.html diff --git a/preview/reference/boost/capy/work_guard/reset.html b/preview/capy/reference/boost/capy/work_guard/reset.html similarity index 100% rename from preview/reference/boost/capy/work_guard/reset.html rename to preview/capy/reference/boost/capy/work_guard/reset.html diff --git a/preview/reference/boost/capy/write.html b/preview/capy/reference/boost/capy/write.html similarity index 100% rename from preview/reference/boost/capy/write.html rename to preview/capy/reference/boost/capy/write.html diff --git a/preview/reference/index.html b/preview/capy/reference/index.html similarity index 99% rename from preview/reference/index.html rename to preview/capy/reference/index.html index 7d49b9b..85ab7bb 100644 --- a/preview/reference/index.html +++ b/preview/capy/reference/index.html @@ -1023,10 +1023,6 @@ - - - - @@ -1035,6 +1031,10 @@ + + + + @@ -1054,10 +1054,6 @@ - - - - @@ -1066,6 +1062,10 @@ + + + + diff --git a/preview/why-capy.html b/preview/capy/why-capy.html similarity index 100% rename from preview/why-capy.html rename to preview/capy/why-capy.html diff --git a/preview/charconv/index.html b/preview/charconv/index.html new file mode 100644 index 0000000..11c9701 --- /dev/null +++ b/preview/charconv/index.html @@ -0,0 +1,6933 @@ + + + + + + + + +CharConv: An Implementation of <charconv> in C++11 + + + +
    + +
    +
    +

    Overview

    +
    +
    +

    Description

    +
    +

    Boost.Charconv converts character buffers to numbers, and numbers to character buffers. +It is a small library of two overloaded functions to do the heavy lifting, plus several supporting enums, structures, templates, and constants, with a particular focus on performance and consistency +across the supported development environments.

    +
    +
    +

    Why should I be interested in this Library? Charconv is locale-independent, non-allocating1, non-throwing and only requires a minimum of C++ 11. +It provides functionality similar to that found in std::printf or std::strtod with substantial performance increases. +This library can also be used in place of the standard library <charconv> if unavailable with your toolchain. +Currently only GCC 11+ and MSVC 19.24+ support both integer and floating-point conversions in their implementation of <charconv>.
    +If you are using either of those compilers, Boost.Charconv is at least as performant as <charconv>, and can be up to several times faster. +See: Benchmarks

    +
    +
    +

    1 The one edge case where allocation may occur is you are parsing a string to an 80 or 128-bit long double or __float128, and the string is over 1024 bytes long.

    +
    +
    +
    +

    Supported Compilers / OS

    +
    +

    Boost.Charconv is tested on Ubuntu, macOS, and Windows with the following compilers:

    +
    +
    +
      +
    • +

      GCC 5 or later

      +
    • +
    • +

      Clang 3.8 or later

      +
    • +
    • +

      Visual Studio 2015 (14.0) or later

      +
    • +
    +
    +
    +

    Tested on GitHub Actions and Drone.

    +
    +
    +
    +
    +
    +

    Getting Started

    +
    +
    +

    B2

    +
    +

    Run the following commands to clone the latest versions of Boost and Charconv, prepare the Boost.Build system for use, and build the libraries with C++11 as the default standard:

    +
    +
    +
    +
    git clone https://github.com/boostorg/boost
    +cd boost
    +git submodule update --init
    +cd ..
    +./bootstrap
    +./b2 cxxstd=11
    +
    +
    +
    +

    To install the development environment, run:

    +
    +
    +
    +
    sudo ./b2 install cxxstd=11
    +
    +
    +
    +

    The value of cxxstd must be at least 11. See the b2 documentation under cxxstd for all valid values.

    +
    +
    +
    +

    __float128 and std::float128_t Support

    +
    +

    If using B2 or CMake the build system will automatically define BOOST_CHARCONV_HAS_QUADMATH and link against it if the build system can successfully run a small test case. +If you are using another build system and you want support for these types you will have to define BOOST_CHARCONV_HAS_QUADMATH, and link against libquadmath.

    +
    +
    +

    Description

    allocator_tag

    Tag type for coroutine allocator retrieval.

    environment_tag

    Tag type for coroutine environment retrieval.

    Tag type for coroutine executor retrieval.

    frame_allocator_tag

    Tag type for coroutine frame allocator retrieval.

    stop_token_tag

    Tag type for coroutine stop token retrieval.

    Description

    allocator

    Tag object that yields the current frame allocator when awaited.

    environment

    Tag object that yields the current environment when awaited.

    Tag object that yields the current executor when awaited.

    frame_allocator

    Tag object that yields the current frame allocator when awaited.

    stop_token

    Tag object that yields the current stop token when awaited.

    Description

    allocator_tag

    Tag type for coroutine allocator retrieval.

    environment_tag

    Tag type for coroutine environment retrieval.

    Tag type for coroutine executor retrieval.

    frame_allocator_tag

    Tag type for coroutine frame allocator retrieval.

    stop_token_tag

    Tag type for coroutine stop token retrieval.

    Description

    allocator

    Tag object that yields the current frame allocator when awaited.

    environment

    Tag object that yields the current environment when awaited.

    Tag object that yields the current executor when awaited.

    frame_allocator

    Tag object that yields the current frame allocator when awaited.

    stop_token

    Tag object that yields the current stop token when awaited.

    + + + + +
    +
    Important
    +
    +libquadmath is only available on supported platforms (e.g. Linux with x86, x86_64, PPC64, and IA64). +
    +
    +
    +
    +

    Dependencies

    +
    +

    This library depends on: Boost.Assert, Boost.Config, Boost.Core, and optionally libquadmath (see above).

    +
    +
    + + +
    +

    Basic Usage Examples

    +
    +
    +

    Usage Examples

    +
    +
    +
    #include <boost/charconv.hpp>
    +
    +const char* buffer = "42";
    +int v = 0;
    +boost::charconv::from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
    +assert(r.ec == std::errc());
    +assert(v == 42);
    +
    +char buffer[64];
    +int v = 123456;
    +boost::charconv::to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), v);
    +assert(r.ec == std::errc());
    +assert(!strncmp(buffer, "123456", 6)); // Strncmp returns 0 on match
    +
    +
    +
    +
    +
    +
    +

    API Reference

    +
    + + +
    +

    Enums

    + +
    + + +
    +
    +
    +

    from_chars

    +
    +
    +

    from_chars overview

    +
    +

    from_chars is a set of functions that parse a string from [first, last) in an attempt to convert the string into value according to the chars_format specified (if applicable). +The parsing of number is locale-independent (e.g. equivalent to the "C" locale). +The result of from_chars is from_chars_result which on success returns ptr == last and ec == std::errc(), and on failure returns ptr equal to the last valid character parsed or last on underflow/overflow, and ec == std::errc::invalid_argument or std::errc::result_out_of_range respectively. from_chars does not require the character sequence to be null terminated.

    +
    +
    +
    +

    Definitions

    +
    +
    +
    namespace boost { namespace charconv {
    +
    +struct from_chars_result
    +{
    +    const char* ptr;
    +    std::errc ec;
    +
    +    friend constexpr bool operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default;
    +    constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
    +}
    +
    +template <typename Integral>
    +BOOST_CXX14_CONSTEXPR from_chars_result from_chars(const char* first, const char* last, Integral& value, int base = 10) noexcept;
    +
    +template <typename Integral>
    +BOOST_CXX14_CONSTEXPR from_chars_result from_chars(boost::core::string_view sv, Integral& value, int base = 10) noexcept;
    +
    +BOOST_CXX14_CONSTEXPR from_chars_result from_chars<bool>(const char* first, const char* last, bool& value, int base) = delete;
    +
    +template <typename Real>
    +from_chars_result from_chars(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
    +
    +template <typename Real>
    +from_chars_result from_chars(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
    +
    +// See note below Usage notes for from_chars for floating point types
    +
    +template <typename Real>
    +from_chars_result from_chars_erange(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
    +
    +template <typename Real>
    +from_chars_result from_chars_erange(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
    +
    +}} // Namespace boost::charconv
    +
    +
    +
    +
    +

    from_chars parameters

    +
    +
      +
    • +

      first, last - pointers to a valid range to parse

      +
    • +
    • +

      sv - string view of a valid range to parse. +Compatible with boost::core::string_view, std::string, and std::string_view

      +
    • +
    • +

      value - where the output is stored upon successful parsing

      +
    • +
    • +

      base (integer only) - the integer base to use. Must be between 2 and 36 inclusive

      +
    • +
    • +

      fmt (floating point only) - The format of the buffer. See chars_format overview for description.

      +
    • +
    +
    +
    +
    +

    from_chars_result

    +
    +
      +
    • +

      ptr - On return from from_chars it is a pointer to the first character not matching the pattern, or pointer to last if all characters are successfully parsed.

      +
    • +
    • +

      ec - the error code. Values returned by from_chars are:

      +
    • +
    +
    + ++++ + + + + + + + + + + + + + + + + + + +

    Return Value

    Description

    std::errc()

    Successful Parsing

    std::errc::invalid_argument

    1) Parsing a negative into an unsigned type

    +

    2) Leading + sign

    +

    3) Leading space

    +

    4) Incompatible formatting (e.g. exponent on chars_format::fixed, or p as exponent on value that is not chars_format::hex) See chars_format overview

    std::errc::result_out_of_range

    1) Overflow

    +

    2) Underflow

    +
    +
      +
    • +

      operator== - compares the values of ptr and ec for equality

      +
    • +
    +
    +
    +
    +

    Usage Notes

    +
    +

    Usage notes for from_chars for integral types

    +
    +
      +
    • +

      All built-in integral types are allowed except bool which is deleted

      +
    • +
    • +

      These functions have been tested to support __int128 and unsigned __int128

      +
    • +
    • +

      from_chars for integral types is constexpr when compiled using -std=c++14 or newer

      +
      +
        +
      • +

        One known exception is GCC 5 which does not support constexpr comparison of const char*.

        +
      • +
      +
      +
    • +
    • +

      A valid string must only contain the characters for numbers. Leading spaces are not ignored, and will return std::errc::invalid_argument.

      +
    • +
    +
    +
    +
    +

    Usage notes for from_chars for floating point types

    +
    +
      +
    • +

      On std::errc::result_out_of_range we return ±0 for small values (e.g. 1.0e-99999) or ±HUGE_VAL for large values (e.g. 1.0e+99999) to match the handling of std::strtod. +This is a divergence from the standard which states we should return the value argument unmodified.

      +
      +
        +
      • +

        from_chars has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. +The standard for <charconv> does not distinguish between underflow and overflow like strtod does. +Let’s say you are writing a JSON library, and you replace std::strtod with boost::charconv::from_chars for performance reasons. +Charconv returns std::errc::result_out_of_range on some conversion. +You would then have to parse the string again yourself to figure out which of the four possible reasons you got std::errc::result_out_of_range. +Charconv can give you that information by using boost::charconv::from_chars_erange instead of boost::charconv::from_chars throughout the code base. +By implementing the resolution to the LWG issue that matches the established strtod behavior I think we are providing the correct behavior without waiting on the committee’s decision.

        +
      • +
      +
      +
    • +
    • +

      These functions have been tested to support all built-in floating-point types and those from C++23’s <stdfloat>

      +
      +
        +
      • +

        Long doubles can be 64, 80, or 128-bit, but must be IEEE 754 compliant. An example of a non-compliant, and therefore unsupported, format is __ibm128.

        +
      • +
      • +

        Use of __float128 or std::float128_t requires compiling with -std=gnu++xx and linking GCC’s libquadmath. +This is done automatically when building with CMake.

        +
      • +
      +
      +
    • +
    +
    +
    +
    +
    +

    Examples

    +
    +

    Basic usage

    +
    +
    Integral
    +
    +
    +
    const char* buffer = "42";
    +int v = 0;
    +from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(v == 42);
    +
    +std::string str_buffer (buffer);
    +boost::core::string_view sv(str_buffer);
    +int v2;
    +auto r2 = boost::charconv::from_chars(sv, v2);
    +assert(r);
    +assert(v2 == v);
    +
    +
    +
    +
    +
    Floating Point
    +
    +
    +
    const char* buffer = "1.2345"
    +double v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(v == 1.2345);
    +
    +std::string str_buffer(buffer);
    +double v2;
    +auto r2 = boost::charconv::from_chars(buffer, v2);
    +assert(r2);
    +assert(v == v2);
    +
    +
    +
    +
    +
    +

    Hexadecimal

    +
    +
    Integral
    +
    +
    +
    const char* buffer = "2a";
    +unsigned v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, 16);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(v == 42);
    +
    +
    +
    +
    +
    Floating Point
    +
    +
    +
    const char* buffer = "1.3a2bp-10";
    +double v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::hex);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(v == 8.0427e-18);
    +
    +
    +
    +
    +
    +

    std::errc::invalid_argument

    +
    +

    The below is invalid because a negative value is being parsed into an unsigned integer.

    +
    +
    +
    +
    const char* buffer = "-123";
    +unsigned v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
    +assert(r.ec == std::errc::invalid_argument);
    +assert(!r); // Same as above but less verbose. Added in C++26.
    +
    +
    +
    +

    The below is invalid because a fixed format floating-point value can not have an exponent.

    +
    +
    +
    +
    const char* buffer = "-1.573e-3";
    +double v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::fixed);
    +assert(r.ec == std::errc::invalid_argument);
    +assert(!r); // Same as above but less verbose. Added in C++26.
    +
    +
    +
    +

    Note: In the event of std::errc::invalid_argument, v is not modified by from_chars

    +
    +
    +
    +

    std::errc::result_out_of_range

    +
    +
    +
    const char* buffer = "1234";
    +unsigned char v = 0;
    +auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
    +assert(r.ec == std::errc::result_out_of_range);
    +assert(!r); // Same as above but less verbose. Added in C++26.
    +assert(v == 0)
    +
    +
    +
    +

    Note: In the event of std::errc::result_out_of_range, v is not modified by from_chars

    +
    +
    +
    +
    +
    +
    +

    to_chars

    +
    +
    +

    to_chars overview

    +
    +

    to_chars is a set of functions that attempts to convert value into a character buffer specified by [first, last). +The result of to_chars is to_chars_result which on success returns ptr equal to one-past-the-end of the characters written and ec == std::errc() and on failure returns std::errc::value_too_large and ptr == last. +to_chars does not null-terminate the returned characters.

    +
    +
    +
    +

    Definitions

    +
    +
    +
    namespace boost { namespace charconv {
    +
    +struct to_chars_result
    +{
    +    char* ptr;
    +    std::errc ec;
    +
    +    friend constexpr bool operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept; = default;
    +    constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
    +};
    +
    +template <typename Integral>
    +BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars(char* first, char* last, Integral value, int base = 10) noexcept;
    +
    +template <typename Integral>
    +BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars<bool>(char* first, char* last, Integral value, int base) noexcept = delete;
    +
    +template <typename Real>
    +to_chars_result to_chars(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision) noexcept;
    +
    +}} // Namespace boost::charconv
    +
    +
    +
    +
    +

    to_chars parameters

    +
    +
      +
    • +

      first, last - pointers to the beginning and end of the character buffer

      +
    • +
    • +

      value - the value to be parsed into the buffer

      +
    • +
    • +

      base (integer only) - the integer base to use. Must be between 2 and 36 inclusive

      +
    • +
    • +

      fmt (float only) - the floating point format to use. +See chars_format overview for description.

      +
    • +
    • +

      precision (float only) - the number of decimal places required

      +
    • +
    +
    +
    +
    +

    to_chars_result

    +
    +
      +
    • +

      ptr - On return from to_chars points to one-past-the-end of the characters written on success or last on failure

      +
    • +
    • +

      ec - the error code. Values returned by to_chars are:

      +
    • +
    +
    + ++++ + + + + + + + + + + + + + + +

    Return Value

    Description

    std::errc()

    Successful Parsing

    std::errc::value_too_large

    1) Overflow

    +

    2) Underflow

    +
    +
      +
    • +

      operator== - compares the value of ptr and ec for equality

      +
    • +
    +
    +
    +
    +

    Usage Notes

    +
    +

    Usage notes for to_chars for integral types

    +
    +
      +
    • +

      All built-in integral types are allowed except bool which is deleted

      +
    • +
    • +

      from_chars for integral type is constexpr (BOOST_CHARCONV_CONSTEXPR is defined) when:

      +
      +
        +
      • +

        compiled using -std=c++14 or newer

        +
      • +
      • +

        using a compiler with __builtin_ is_constant_evaluated

        +
      • +
      +
      +
    • +
    • +

      These functions have been tested to support __int128 and unsigned __int128

      +
    • +
    +
    +
    +
    +

    Usage notes for to_chars for floating point types

    +
    +
      +
    • +

      The following will be returned when handling different values of NaN

      +
      +
        +
      • +

        qNaN returns "nan"

        +
      • +
      • +

        -qNaN returns "-nan(ind)"

        +
      • +
      • +

        sNaN returns "nan(snan)"

        +
      • +
      • +

        -sNaN returns "-nan(snan)"

        +
      • +
      +
      +
    • +
    • +

      These functions have been tested to support all built-in floating-point types and those from C++23’s <stdfloat>

      +
      +
        +
      • +

        Long doubles can be 64, 80, or 128-bit, but must be IEEE 754 compliant. An example of a non-compliant, and therefore unsupported, format is ibm128.

        +
      • +
      • +

        Use of __float128 or std::float128_t requires compiling with -std=gnu++xx and linking GCC’s libquadmath. +This is done automatically when building with CMake.

        +
      • +
      +
      +
    • +
    +
    +
    +
    +
    +

    Examples

    +
    +

    Basic Usage

    +
    +
    Integral
    +
    +
    +
    char buffer[64] {};
    +int v = 42;
    +to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
    +assert(r.ec == std::errc());
    +assert(!strcmp(buffer, "42")); // strcmp returns 0 on match
    +
    +
    +
    +
    +
    Floating Point
    +
    +
    +
    char buffer[64] {};
    +double v = 1e300;
    +to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(!strcmp(buffer, "1e+300"));
    +
    +
    +
    +
    +
    +

    Hexadecimal

    +
    +
    Integral
    +
    +
    +
    char buffer[64] {};
    +int v = 42;
    +to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(!strcmp(buffer, "2a")); // strcmp returns 0 on match
    +
    +
    +
    +
    +
    Floating Point
    +
    +
    +
    char buffer_u[64] {};
    +double u = -1.08260383390082950e+20;
    +
    +char buffer_v[64] {};
    +double v = -1.08260383390082946e+20;
    +
    +to_chars(buffer_u, buffer_u + sizeof(buffer_u) - 1, u, chars_format::hex);
    +to_chars(buffer_v, buffer_v + sizeof(buffer_v) - 1, v, chars_format::hex);
    +
    +std::cout << "U: " << buffer_u << "\nV: " << buffer_v << std::endl;
    +
    +// U: -1.779a8946bb5fap+66
    +// V: -1.779a8946bb5f9p+66
    +//
    +// With hexfloats we can see the ULP distance between U and V is a - 9 == 1.
    +
    +
    +
    +
    +
    +

    std::errc::value_too_large

    +
    +
    Integral
    +
    +
    +
    char buffer[3] {};
    +int v = -1234;
    +to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
    +assert(r.ec == std::errc::value_too_large);
    +assert(!r); // Same as above but less verbose. Added in C++26.
    +
    +
    +
    +
    +
    Floating Point
    +
    +
    +
    char buffer[3] {};
    +double v = 1.2345;
    +auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
    +assert(r.ec == std::errc::value_too_large);
    +assert(!r); // Same as above but less verbose. Added in C++26.
    +
    +
    +
    +

    In the event of std::errc::value_too_large, to_chars_result.ptr is equal to last

    +
    +
    +
    +
    +
    +
    +
    +

    chars_format

    +
    +
    +

    chars_format overview

    +
    +

    boost::charconv::chars_format is an enum class used to define the format of floating point types with from_chars and to_chars.

    +
    +
    +
    +

    Definition

    +
    +
    +
    namespace boost { namespace charconv {
    +
    +enum class chars_format : unsigned
    +{
    +    scientific = 1 << 0,
    +    fixed = 1 << 1,
    +    hex = 1 << 2,
    +    general = fixed | scientific
    +};
    +
    +}} // Namespace boost::charconv
    +
    +
    +
    +
    +

    Formats

    +
    +

    Scientific Format

    +
    +

    Scientific format will be of the form 1.3e+03. +The integer part will be between 0 and 9 inclusive. The fraction and exponent will always appear. +The exponent will always have a minimum of 2 digits.

    +
    +
    +
    +

    Fixed Format

    +
    +

    Fixed format will be of the form 2.30 or 3090. An exponent will not appear with this format. +If the precision of to_chars exceeds that of the type (e.g. std::numeric_limits<double>::chars10), 0s will be appended to the end of the significant digits.

    +
    +
    +
    +

    Hex Format

    +
    +

    Hex format will be of the form 1.0cp+05. The integer part will always be 0 or 1. +The exponent will be with a p instead of an e as used with base 10 formats, because e is a valid hex value. +Note: Every binary floating-point number has a unique representation as a hexfloat, but not every hexfloat has a unique representation as a binary floating-point number. +This is due to the fact that the number of bits in the significand of an IEEE754 binary32 and binary64 are not divisible by 4.

    +
    +
    +
    Hexfloat Use Cases
    +
    +

    For those unfamiliar with hexfloats, they are valuable in specific instances:

    +
    +
    +
      +
    • +

      Precision control: Hexfloats can offer finer control over the precision of floating-point values. +In hexadecimal notation, each digit represents four bits (one hexit), allowing you to directly manipulate the precision of the number by specifying a certain number of hexadecimal digits. +This can be useful when you need to precisely control the level of accuracy required for your calculations.

      +
    • +
    • +

      Bit-level representation: Hexfloats provide a direct representation of the underlying bits of a floating-point number. +Each hexadecimal digit corresponds to a specific group of bits, making it easier to visualize and understand the internal structure of the floating-point value. +This can be helpful for debugging or analyzing floating-point arithmetic operations (e.g. Computing ULP distances).

      +
    • +
    +
    +
    +
    +
    +

    General

    +
    +

    General format will be the shortest representation of a number in either fixed or general format (e.g. 1234 instead of 1.234e+03.

    +
    +
    +
    +
    +
    +
    +

    Limits

    +
    +
    +

    Limits overview

    +
    +

    The contents of <boost/charconv/limits.hpp> are designed to help the user optimize the size of the buffer required for to_chars.

    +
    +
    +
    +

    Definitions

    +
    +
    +
    namespace boost { namespace charconv {
    +
    +template <typename T>
    +constexpr int limits<T>::max_chars10;
    +
    +template <typename T>
    +constexpr int limits<T>::max_chars;
    +
    +}} // Namespace boost::charconv
    +
    +
    +
    +

    max_chars10

    +
    +

    The minimum size of the buffer that needs to be +passed to to_chars to guarantee successful conversion for all values of type T, when either no base is passed, or base 10 is passed.

    +
    +
    +
    +

    max_chars

    +
    +

    The minimum size of the buffer that needs to be passed to to_chars to guarantee successful conversion for all values of type T, for any value of base.

    +
    +
    +
    +
    +

    Examples

    +
    +

    The following two examples are for max_chars10 to optimize the buffer size with to_chars for an integral type and a floating-point type respectively.

    +
    +
    +
    +
    char buffer [boost::charconv::limits<std::int32_t>::max_chars10;
    +auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::int32_t>::max());
    +
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(!strcmp(buffer, "2147483647")); // strcmp returns 0 on match
    +
    +
    +
    +
    +
    char buffer [boost::charconv::limits<float>::max_chars10;
    +auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<float>::max());
    +
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(!strcmp(buffer, "3.40282347e+38")); // strcmp returns 0 on match
    +
    +
    +
    +

    The following example is a usage of max_chars when used to serialize an integer in binary (base = 2).

    +
    +
    +
    +
    char buffer [boost::charconv::limits<std::uint16_t>::max_chars;
    +auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::uint16_t>::max(), 2);
    +
    +assert(r.ec == std::errc());
    +assert(r); // Same as above but less verbose. Added in C++26.
    +assert(!strcmp(buffer, "1111111111111111")); // strcmp returns 0 on match
    +
    +
    +
    +
    +
    +
    +

    Benchmarks

    +
    +
    +

    This section describes a range of performance benchmarks that have been run comparing this library with the standard library, and how to run your own benchmarks if required.

    +
    +
    +

    The values are relative to the performance of std::printf and std::strtoX. +Larger numbers are more performant (e.g. 2.00 means twice as fast, and 0.50 means it takes twice as long). +std::printf and std::strtoX are always listed first as they will be the reference value.

    +
    +
    +

    How to run the Benchmarks

    +
    +

    To run the benchmarks yourself, navigate to the test folder and define BOOST_CHARCONV_RUN_BENCHMARKS when running the tests. +An example on Linux with b2: ../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark linkflags="-lfmt" -a release .

    +
    +
    +

    Additionally, you will need the following:

    +
    +
    +
      +
    • +

      A compiler with full <charconv> support:

      +
      +
        +
      • +

        GCC 11 or newer

        +
      • +
      • +

        MSVC 19.24 or newer

        +
      • +
      +
      +
    • +
    • +

      libdouble-conversion

      +
    • +
    • +

      {fmt}

      +
    • +
    +
    +
    +
    +

    Results

    +
    +

    x86_64 Linux

    +
    +

    Data in tables 1 - 4 were run on Ubuntu 23.04 with x86_64 architecture using GCC 13.1.0 with libstdc++.

    +
    +
    +
    Floating Point
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 1. to_chars floating point with the shortest representation
    FunctionRelative Performance (float / double)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    0.56 / 0.49

    Boost.spirit.karma

    1.70 / 2.62

    std::to_chars

    4.01 / 6.03

    Boost.Charconv.to_chars

    4.46 / 6.20

    Google double-conversion

    1.26 / 1.91

    {fmt}

    2.52 / 3.63

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 2. from_chars floating point with scientific formatting
    FunctionRelative Performance (float / double)

    std::strto(f/d)

    1.00 / 1.00

    Boost.lexical_cast

    0.33 / 0.42

    Boost.spirit.qi

    3.17 / 4.65

    std::from_chars

    3.23 / 5.77

    Boost.Charconv.from_chars

    3.28 / 5.75

    Google double-conversion

    1.16 / 1.30

    +
    +
    +
    Integral
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 3. to_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    1.80 / 1.38

    Boost.spirit.karma

    2.81 / 1.62

    std::to_chars

    4.06 / 2.45

    Boost.Charconv.to_chars

    4.13 / 2.48

    {fmt}

    2.88 / 2.21

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 4. from_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::strto(ul,ull)

    1.00 / 1.00

    Boost.lexical_cast

    0.53 / 0.52

    Boost.spirit.qi

    2.24 / 1.49

    std::from_chars

    1.97 / 1.68

    Boost.Charconv.from_chars

    2.54 / 1.78

    +
    +
    +
    +

    x86_64 Windows

    +
    +

    Data in tables 5 - 8 were run on Windows 11 with x86_64 architecture using MSVC 14.3 (V17.7.0).

    +
    +
    +
    Floating Point
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 5. to_chars floating point with the shortest representation
    FunctionRelative Performance (float / double)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    0.50 / 0.70

    Boost.spirit.karma

    2.23 / 7.58

    std::to_chars

    5.58 / 15.77

    Boost.Charconv.to_chars

    5.62 / 15.26

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 6. from_chars floating point with scientific formatting
    FunctionRelative Performance (float / double)

    std::strto(f/d)

    1.00 / 1.00

    Boost.lexical_cast

    0.14 / 0.20

    Boost.spirit.qi

    2.03 / 4.58

    std::from_chars

    1.01 / 1.23

    Boost.Charconv.from_chars

    2.06 / 5.21

    +
    +
    +
    Integral
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 7. to_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    0.68 / 0.68

    Boost.spirit.karma

    2.75 / 1.67

    std::to_chars

    2.75 / 2.10

    Boost.Charconv.to_chars

    2.75 / 2.06

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 8. from_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::strto(ul,ull)

    1.00 / 1.00

    Boost.lexical_cast

    0.46 / 0.39

    Boost.spirit.qi

    1.94 / 1.63

    std::from_chars

    2.43 / 2.18

    Boost.Charconv.from_chars

    2.68 / 2.27

    +
    +
    +
    +

    ARM MacOS

    +
    +

    Data in tables 9-12 were run on MacOS Ventura 13.5.2 with M1 Pro architecture using Homebrew GCC 13.2.0 with libstdc++.

    +
    +
    +
    Floating Point
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 9. to_chars floating point with the shortest representation
    FunctionRelative Performance (float / double)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    0.58 / 0.16

    Boost.spirit.karma

    1.39 / 1.22

    std::to_chars

    6.78 / 6.47

    Boost.Charconv.to_chars

    7.25 / 6.86

    Google double-conversion

    2.26 / 2.16

    {fmt}

    3.78 / 3.38

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 10. from_chars floating point with scientific formatting
    FunctionRelative Performance (float / double)

    std::strto(f/d)

    1.00 / 1.00

    Boost.lexical_cast

    0.06 / 0.06

    Boost.spirit.qi

    1.12 / 1.06

    std::from_chars

    1.32 / 1.65

    Boost.Charconv.from_chars

    1.28 / 1.63

    Google double-conversion

    0.45 / 0.32

    +
    +
    +
    Integral
    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 11. to_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::printf

    1.00 / 1.00

    Boost.lexical_cast

    2.08 / 1.75

    Boost.spirit.karma

    4.17 / 2.06

    std::to_chars

    6.25 / 4.12

    Boost.Charconv.to_chars

    6.25 / 4.12

    {fmt}

    5.29 / 3.47

    + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 12. from_chars base 10 integers
    FunctionRelative Performance (uint32_t / uint64_t)

    std::strto(ul,ull)

    1.00 / 1.00

    Boost.lexical_cast

    0.56 / 0.54

    Boost.spirit.qi

    1.39 / 1.33

    std::from_chars

    1.92 / 1.65

    Boost.Charconv.from_chars

    2.27 / 1.65

    +
    +
    +
    +
    +
    +
    +

    Sources

    +
    +
    +

    The following papers and blog posts serve as the basis for the algorithms used in the library:

    +
    +
    + +
    +
    +
    +
    +

    Acknowledgments

    +
    +
    +

    Special thanks to the following people (non-inclusive list):

    +
    +
    +
      +
    • +

      Peter Dimov for providing technical guidance and contributing to the library throughout development.

      +
    • +
    • +

      Junekey Jeon for developing and answering my questions about his integer-formatting, Dragonbox, and Floff.

      +
    • +
    • +

      Chris Kormanyos for serving as the library review manager.

      +
    • +
    • +

      Stephan T. Lavavej for providing the basis for the benchmarks.

      +
    • +
    • +

      All that reviewed the library and provided feedback to make it better.

      +
    • +
    +
    +
    +
    +
    + +
    +
    +

    This documentation is copyright 2022-2023 Peter Dimov and Matt Borland and is distributed under +the Boost Software License, Version 1.0.

    +
    +
    +
    + + + + + + \ No newline at end of file diff --git a/preview/contributor-guide/_images/boost-logo-carbon.png b/preview/contributor-guide/_images/boost-logo-carbon.png new file mode 100644 index 0000000..7c58b6d Binary files /dev/null and b/preview/contributor-guide/_images/boost-logo-carbon.png differ diff --git a/preview/contributor-guide/_images/boost-logo.png b/preview/contributor-guide/_images/boost-logo.png new file mode 100644 index 0000000..2bfe70e Binary files /dev/null and b/preview/contributor-guide/_images/boost-logo.png differ diff --git a/preview/contributor-guide/_images/test-matrix-asio-completion-handler.png b/preview/contributor-guide/_images/test-matrix-asio-completion-handler.png new file mode 100644 index 0000000..a01322f Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-asio-completion-handler.png differ diff --git a/preview/contributor-guide/_images/test-matrix-asio.png b/preview/contributor-guide/_images/test-matrix-asio.png new file mode 100644 index 0000000..a1eb1c9 Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-asio.png differ diff --git a/preview/contributor-guide/_images/test-matrix-developer-report.png b/preview/contributor-guide/_images/test-matrix-developer-report.png new file mode 100644 index 0000000..f487efa Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-developer-report.png differ diff --git a/preview/contributor-guide/_images/test-matrix-legend.png b/preview/contributor-guide/_images/test-matrix-legend.png new file mode 100644 index 0000000..0f79186 Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-legend.png differ diff --git a/preview/contributor-guide/_images/test-matrix-sample-2.png b/preview/contributor-guide/_images/test-matrix-sample-2.png new file mode 100644 index 0000000..5147602 Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-sample-2.png differ diff --git a/preview/contributor-guide/_images/test-matrix-sample.png b/preview/contributor-guide/_images/test-matrix-sample.png new file mode 100644 index 0000000..47b10ac Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-sample.png differ diff --git a/preview/contributor-guide/_images/test-matrix-summary.png b/preview/contributor-guide/_images/test-matrix-summary.png new file mode 100644 index 0000000..048f64c Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-summary.png differ diff --git a/preview/contributor-guide/_images/test-matrix-teeks.png b/preview/contributor-guide/_images/test-matrix-teeks.png new file mode 100644 index 0000000..3ca21f7 Binary files /dev/null and b/preview/contributor-guide/_images/test-matrix-teeks.png differ diff --git a/preview/contributor-guide/_images/tweet_structure.jpg b/preview/contributor-guide/_images/tweet_structure.jpg new file mode 100644 index 0000000..bc6a0e0 Binary files /dev/null and b/preview/contributor-guide/_images/tweet_structure.jpg differ diff --git a/preview/contributor-guide/_images/url-style-guide-image.png b/preview/contributor-guide/_images/url-style-guide-image.png new file mode 100644 index 0000000..9947659 Binary files /dev/null and b/preview/contributor-guide/_images/url-style-guide-image.png differ diff --git a/preview/contributor-guide/best-practices.html b/preview/contributor-guide/best-practices.html new file mode 100644 index 0000000..5280b07 --- /dev/null +++ b/preview/contributor-guide/best-practices.html @@ -0,0 +1,1054 @@ + + + + + + + + + + + + + + Development Best Practices :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Development Best Practices

    +
    +
    +
    +

    This section contains guidance on how to reduce development time from concept through to publishing of a new library, whilst ensuring a quality and maintainability to the open source project that will be the result.

    +
    + +
    +
    +
    +

    Engage Beneficial Dependencies

    +
    +
    +

    Some libraries are published with the intended primary audience, or in some cases the sole audience, being developers of other libraries. These libraries are published to make some of the time consuming and awkward processes of Boost-compliance easier. It is good practice for a new library developer to read the introductions to each of these libraries, and ascertain if they might be of value to the library they are developing.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LibraryDescription

    Boost.Config

    Helps Boost library developers adapt to compiler idiosyncrasies. The range of macros can be extended, if required, with Boost.Predef.

    Boost.Core

    A collection of simple core utilities with minimal dependencies. The range of utilities can be extended, if required, with Boost.Utility

    Boost.Assert

    Customizable assert macros.

    Boost.ThrowException

    A common infrastructure for throwing exceptions from Boost libraries.

    Boost.Mp11

    Provides a template metaprogramming framework, useful if metaprogramming is a feature of your new library.

    +
    +
    +
    +

    Use Robust GitHub Strategies

    +
    +
    +

    Always submit changes to a Boost repo using a Pull Request (PR), never use the GitHub website to change the contents of a repository directly.

    +
    +
    +

    It is good practice to bring your local repo up to date before submitting a PR, perhaps on a weekly or even daily basis - depending on the activity in the repo.

    +
    +
    +

    Merge commits are to be avoided. These commits happens when a local origin branch and remote branch are out of sync.

    +
    +
    +

    The focus is on strategies that emphasize linear history, rebasing, and collaborative discipline. What follows are the best practices that can help.

    +
    +
    +

    Use Rebase Instead of Merge

    +
    +

    When integrating changes from one branch into another, use git rebase instead of git merge. This rewrites the commit history, applying your changes on top of the target branch and maintains a linear history. Keep branches short-lived and focused on specific features or bug fixes. This reduces the likelihood of conflicts and simplifies rebasing onto the main branch. Regularly rebase your feature branch onto main or the target branch to keep up with upstream changes and avoid a large, complex integration at the end. For example:

    +
    +
    +
    +
    git checkout feature-branch
    +git rebase main
    +
    +
    +
    +

    Then push changes after resolving any conflicts:

    +
    +
    +
    +
    git push --force
    +
    +
    +
    +
    +

    Always Pull Using Rebase

    +
    +

    Configure your Git client to rebase when pulling changes, rather than creating merge commits:

    +
    +
    +
    +
    git config --global pull.rebase true
    +
    +
    +
    +

    When working collaboratively on a branch, use git pull --rebase to fetch and reapply your local changes on top of the latest commits from the remote branch.

    +
    +
    +
    +
    git pull --rebase origin main
    +
    +
    +
    +
    +

    Squash Commits Before Merging

    +
    +

    Use interactive rebasing (git rebase -i) to clean up your branch history and squash multiple commits into one meaningful commit. This keeps the repository history tidy and avoids unnecessary merge commits.

    +
    +
    +
    +
    git rebase -i HEAD~n  # Replace 'n' with the number of commits to squash
    +
    +
    +
    +

    After squashing, you can fast-forward the branch without creating a merge commit:

    +
    +
    +
    +
    git checkout main
    +git rebase feature-branch
    +
    +
    +
    +
    +

    Use Fast-Forward Merges

    +
    +

    Enable fast-forward-only merges to ensure the branch history is linear. This avoids creating a merge commit.

    +
    +
    +
    +
    git merge --ff-only feature-branch
    +
    +
    +
    +

    Configure the repository to enforce fast-forward merges:

    +
    +
    +
    +
    git config --global merge.ff only
    +
    +
    +
    +
    +

    Enforce Commit Discipline

    +
    +

    Avoid unnecessary commits and ensure that every commit is meaningful. Use git add -p or git commit --amend to refine commits before pushing.

    +
    +
    +
    +
    git commit --amend
    +
    +
    +
    +

    This ensures that when changes are rebased or fast-forwarded, the history remains clean and easy to understand.

    +
    +
    +

    By following these practices, you’ll avoid merge commits and maintain a clean, linear history in your Git repository while keeping the dev community happy!

    +
    +
    +
    +
    +
    +

    Take Time to Comment Your Code

    +
    +
    +

    Boost has informal coding standards that encourage clear, concise, and useful comments. The following are the main policy recommendations:

    +
    +
    +
      +
    1. +

      Doxygen-style comments for documenting APIs.

      +
    2. +
    3. +

      Explanatory comments preceding a function for complex logic and important decisions.

      +
    4. +
    5. +

      Minimal but meaningful inline comments.

      +
    6. +
    +
    +
    +

    Doxygen API Comments

    +
    +

    Boost libraries can use Doxygen to generate API reference documentation from specifically formatted comments. Many libraries follow this structure, for example:

    +
    +
    +
    +
    /// \brief Brief description of the function
    +/// \details More detailed explanation if necessary.
    +/// \param x Description of parameter x
    +/// \return Description of return value
    +int my_function(int x);
    +
    +
    +
    +

    This makes it easier to generate consistent and readable documentation for users, as the build process picks up the triple-slash comments and creates API documentation automatically from them. Here is a more complete example using all the most useful annotations:

    +
    +
    +
    +
    #include <cmath>
    +#include <stdexcept>
    +
    +/**
    + * @brief Computes the area of a triangle using Heron's formula.
    + *
    + * This function calculates the area of a triangle given the lengths of its three sides.
    + * It uses Heron's formula, which states that for a triangle with sides a, b, and c:
    + *
    + * \f[
    + * A = \sqrt{s \cdot (s - a) \cdot (s - b) \cdot (s - c)}
    + * \f]
    + *
    + * where \f$s\f$ is the semi-perimeter:
    + *
    + * \f[
    + * s = \frac{a + b + c}{2}
    + * \f]
    + *
    + * @param a The length of the first side (must be positive).
    + * @param b The length of the second side (must be positive).
    + * @param c The length of the third side (must be positive).
    + * @return The computed area of the triangle.
    + * @throws std::invalid_argument if the sides do not form a valid triangle.
    + * @throws std::domain_error if the computed area is invalid due to floating-point errors.
    + */
    +double computeTriangleArea(double a, double b, double c) {
    +    if (a <= 0 || b <= 0 || c <= 0) {
    +        throw std::invalid_argument("All side lengths must be positive.");
    +    }
    +
    +    // Check for the triangle inequality
    +    if (a + b <= c || a + c <= b || b + c <= a) {
    +        throw std::invalid_argument("The given sides do not form a valid triangle.");
    +    }
    +
    +    // Calculate semi-perimeter
    +    double s = (a + b + c) / 2.0;
    +
    +    // Compute area using Heron's formula
    +    double area = std::sqrt(s * (s - a) * (s - b) * (s - c));
    +
    +    if (std::isnan(area) || area <= 0) {
    +        throw std::domain_error("Computed area is invalid due to floating-point errors.");
    +    }
    +
    +    return area;
    +}
    +
    +
    +
    +

    The most useful Doxygen annotations are:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    AnnotationDescription

    @brief

    A short summary of the function’s purpose.

    @param

    Describes the function parameters and their constraints.

    @return

    Explains the function’s return value.

    @throws

    Lists the possible exceptions that the function may throw.

    +
    +
    +
    Notes
    +
    +
    +
      +
    • +

      For mathematical formulas the \f[ …​ \f] tags render inline LaTeX-style math formulas in the generated documentation.

      +
    • +
    • +

      @brief is used inside block comments (/** …​ */), while \brief works with both block and single-line (///) comments. Good practice is simply being consistent with your preference.

      +
    • +
    +
    +
    +
    +
    +
    +
    +

    Explanatory Comments

    +
    +

    Since many Boost libraries aim to be compatible with (or eventually integrated into) the Standard Library, you might adopt commenting styles similar to standard library headers, keeping explanations brief, precise, and technical. Sometimes though, the comments are more numerous and helpful in specific implementations, such as Clang libc++, GNU libstc++ or MSVC STL. The following code comes from std::vector::resize in libc++.

    +
    +
    +
    +
    /**
    + * @brief Resizes the container to contain @p __sz elements.
    + *
    + * If @p __sz is smaller than the current size, the container is reduced to its first @p __sz elements.
    + * If @p __sz is greater than the current size, additional default-constructed elements are appended.
    + *
    + * @param __sz The new size of the container.
    + *
    + * If an expansion is needed and sufficient capacity exists, no reallocation occurs.
    + * Otherwise, new storage is allocated and existing elements are moved.
    + *
    + * @exception If an exception is thrown during element construction or move, the container remains unchanged.
    + *
    + * Complexity: Linear in the difference between old and new size.
    + */
    +template <class _Tp, class _Allocator>
    +void vector<_Tp, _Allocator>::resize(size_type __sz) {
    +    if (__sz < size()) {
    +
    +        // Shrink: Destroy extra elements
    +        erase(begin() + __sz, end());
    +    } else if (__sz > size()) {
    +
    +        // Grow: Append default-constructed elements
    +        insert(end(), __sz - size(), _Tp());
    +    }
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Both exception safety and performance considerations are covered in the comments above, which are good practices!

    +
    +
    +
    +
    +

    Boost encourages documenting exception safety guarantees (noexcept, strong guarantee, basic guarantee), and thread-safety considerations if applicable. For example:

    +
    +
    +
    +
    /// \pre `ptr` must not be null.
    +/// \post Returns a valid shared_ptr managing `ptr`.
    +/// \throws std::bad_alloc if allocation fails.
    +std::shared_ptr<T> safe_wrap(T* ptr);
    +
    +
    +
    +

    Some Boost libraries include comments explaining design choices, performance considerations, or trade-offs. These are typically found in complex implementations like Boost.Hana, Boost.Asio or Boost.Spirit. Here’s an example from the Boost.Hana library, which demonstrates the use of comments to explain the code’s purpose and functionality:

    +
    +
    +
    +
    /*!
    +@file
    +Defines `boost::hana::transform`.
    +*/
    +
    +namespace boost { namespace hana {
    +
    +    //! Transform each element of a sequence with a given function.
    +    //! @ingroup group-Sequence
    +    //!
    +    //! Example:
    +    //! @code
    +    //! auto doubled = hana::transform(hana::make_tuple(1, 2, 3), [](auto x) { return x * 2; });
    +    //! @endcode
    +    //! doubled == hana::make_tuple(2, 4, 6)
    +    //!
    +    template <typename Xs, typename F>
    +    constexpr auto transform(Xs&& xs, F&& f) {
    +
    +        // See below for the commented version of this function.
    +    }
    +}}
    +
    +
    +
    +
    +
    Note
    +
    +

    The @file entry provides an overview of the file contents. The //! syntax precedes a function-level Doxygen comment, providing an example usage of the function hana::transform in the code snippet above.

    +
    +
    +
    +
    +
    +

    Inline Comments

    +
    +

    Inline comments, throughout the source code, are used to explain the purpose of specific statements. This example is taken from hana::transform, mentioned previously.

    +
    +
    +
    +
        constexpr auto transform(Xs&& xs, F&& f) {
    +        return hana::adjust_if(
    +
    +            static_cast<Xs&&>(xs), // Forward the sequence `xs`
    +
    +            [](auto const&) { return true; }, // Always apply the transformation
    +
    +            static_cast<F&&>(f) // Forward the transformation function
    +        );
    +    }
    +
    +
    +
    +

    Here is another example of inline commenting, from the Boost.Asio library, notice how the comments make understanding the flow easy.

    +
    +
    +
    +
    void start_read() {
    +
    +    // Prepare a buffer to store incoming data.
    +    socket_.async_read_some(boost::asio::buffer(data_, max_length),
    +        [this](boost::system::error_code ec, std::size_t length) {
    +            if (!ec) {
    +
    +                // Successfully read some data, process it.
    +                handle_data(data_, length);
    +
    +                // Initiate another asynchronous read to continue receiving data.
    +                start_read();
    +            } else {
    +
    +                // An error occurred, log and handle it.
    +                handle_error(ec);
    +            }
    +        });
    +}
    +
    +
    +
    +

    Here is a more in-depth example, showing how to comment non-trivial code behavior (for example, shared pointers, async operations). The comments also describe purpose rather than restating code (for example, "Keep session alive" rather than "Creates a shared pointer"). And finally the comments guide the reader through the flow (such as explaining what happens after a read or write).

    +
    +
    +
    +
    #include <boost/asio.hpp>
    +#include <iostream>
    +#include <memory>
    +#include <utility>
    +
    +using boost::asio::ip::tcp;
    +
    +class Session : public std::enable_shared_from_this<Session> {
    +public:
    +    explicit Session(tcp::socket socket)
    +
    +        : socket_(std::move(socket)) {}  // Move socket into this session
    +
    +    void start() {
    +
    +        read();  // Begin reading data from the client
    +    }
    +
    +private:
    +    void read() {
    +
    +        auto self = shared_from_this();  // Ensure session remains alive during async operation
    +
    +        // Asynchronous read operation
    +        socket_.async_read_some(boost::asio::buffer(data_, max_length),
    +            [self](boost::system::error_code ec, std::size_t length) {
    +                if (!ec) {
    +
    +                    // Successfully received data, now send a response
    +                    self->write(length);
    +                } else {
    +
    +                    // Handle connection errors (for example, client disconnected)
    +                    std::cerr << "Read error: " << ec.message() << std::endl;
    +                }
    +            });
    +    }
    +
    +    void write(std::size_t length) {
    +
    +        auto self = shared_from_this();  // Keep session alive for async write
    +
    +        // Asynchronous write operation
    +        boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
    +            [self](boost::system::error_code ec, std::size_t /*bytes_transferred*/) {
    +                if (!ec) {
    +
    +                    // Successfully wrote data, continue reading for more client input
    +                    self->read();
    +                } else {
    +
    +                    // Handle write error (for example, broken pipe)
    +                    std::cerr << "Write error: " << ec.message() << std::endl;
    +                }
    +            });
    +    }
    +
    +    tcp::socket socket_;
    +    enum { max_length = 1024 };
    +
    +    char data_[max_length];  // Buffer to store incoming data
    +};
    +
    +// Server class that listens for incoming connections
    +class Server {
    +public:
    +    Server(boost::asio::io_context& io_context, short port)
    +        : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
    +
    +        accept();  // Start listening for connections
    +    }
    +
    +private:
    +    void accept() {
    +        acceptor_.async_accept(
    +            [this](boost::system::error_code ec, tcp::socket socket) {
    +                if (!ec) {
    +
    +                    // Successfully accepted a connection, create a session
    +                    std::make_shared<Session>(std::move(socket))->start();
    +                } else {
    +
    +                    // Log accept error
    +                    std::cerr << "Accept error: " << ec.message() << std::endl;
    +                }
    +
    +                // Continue accepting new connections
    +                accept();
    +            });
    +    }
    +
    +    tcp::acceptor acceptor_;
    +};
    +
    +// Main function to run the server
    +int main() {
    +    try {
    +        boost::asio::io_context io_context;
    +
    +        Server server(io_context, 12345);  // Start server on port 12345
    +
    +        io_context.run();  // Run the IO context to handle async operations
    +    } catch (std::exception& e) {
    +        std::cerr << "Exception: " << e.what() << std::endl;
    +    }
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Inline comments are clearer if they are preceded by a blank line. Many libraries do not strictly stick to this practice, but it should be clear from the above example that the preceding-blank-line is a best practice for readability.

    +
    +
    +
    +
    +
    +
    +
    +

    Craft Helpful Error Messages

    +
    +
    +

    Ideally, when writing error message text, use the following rules of thumb:

    +
    +
    +
      +
    1. +

      Name the library (so user knows the source)

      +
    2. +
    3. +

      Show the input and expected type/value

      +
    4. +
    5. +

      Give context (function name, file, line, operation)

      +
    6. +
    7. +

      Provide standard error codes (for example: POSIX, errno)

      +
    8. +
    9. +

      Avoid low-level noise (memory addresses)

      +
    10. +
    11. +

      Be actionable (help the user fix the error)

      +
    12. +
    +
    +
    +

    Here are some example error messages that have issues:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MessageIssue

    error C2679: binary '=': no operator found which takes a right-hand operand of type 'boost::gregorian::date' (or there is no acceptable conversion)

    Too verbose, compiler jargon, doesn’t say what the user did wrong.

    boost::system::system_error

    Just the type name, no context, no error code, no description.

    Error in lexical_cast

    What input? What target type? Which file/line?

    terminate called after throwing an instance of boost::archive::archive_exception what(): input stream error

    Too vague - “input stream error” — which input, which archive format?

    Unhandled exception at 0x00007FF9B7114ED9 in test.exe: Microsoft C++ exception: boost::bad_any_cast at memory location 0x0000009F4A2FD9A0.

    Very low-level, memory address is useless to most users.

    assertion failed

    No filename, no condition, no hint at what caused it.

    +
    +

    Here are some useful error messages:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MessageNotes

    boost::date_time::invalid_date: "2025-02-30" is not a valid Gregorian date

    Names the library, the invalid input, and the problem.

    boost::system::system_error: connect() failed: Connection refused [ECONNREFUSED]

    Explains what call failed and gives a standard POSIX error code.

    boost::lexical_cast: cannot convert string "abc" to int

    Shows the input ("abc") and the target type (int).

    boost::serialization::archive_exception: failed to open file "savegame.dat" for reading

    Explains the archive issue and gives the file name.

    boost::any_cast failed: stored type is 'std::string', requested type was 'int'

    Shows both the stored and requested types — no guesswork.

    boost::assertion failed: vec.size() == 3, function normalize_vector, file vector_utils.hpp, line 42

    Includes condition, function, file, and line number.

    +
    +

    Well written error messages can be one of the hidden superpowers of your library. A well-crafted message can save hours of debugging, while a cryptic one can scare away even experienced devs - part of the approachable vs hostile experience!

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/build-systems/b2.html b/preview/contributor-guide/build-systems/b2.html new file mode 100644 index 0000000..2b04db7 --- /dev/null +++ b/preview/contributor-guide/build-systems/b2.html @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + B2 :: Boost Site Docs + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + + diff --git a/preview/contributor-guide/build-systems/cmake.html b/preview/contributor-guide/build-systems/cmake.html new file mode 100644 index 0000000..765befc --- /dev/null +++ b/preview/contributor-guide/build-systems/cmake.html @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + CMake :: Boost Site Docs + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + + diff --git a/preview/contributor-guide/contributor-community-introduction.html b/preview/contributor-guide/contributor-community-introduction.html new file mode 100644 index 0000000..5bbefab --- /dev/null +++ b/preview/contributor-guide/contributor-community-introduction.html @@ -0,0 +1,415 @@ + + + + + + + + + + + + + + Introduction to the Contributor Community :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Introduction to the Contributor Community

    +
    +
    +
    +

    The Boost Contributors Community is a dedicated group of developers and enthusiasts committed to advancing the Boost libraries. +There are many different ways of Getting Involved with this community.

    +
    + +
    +
    +
    +

    Communications

    +
    +
    +

    The Boost Developers Mailing List is focused on the development and maintenance of the libraries. +It is a platform for proposing new libraries, discussing design and implementation details, and coordinating efforts among contributors. +Participation in these mailing lists is open to all. +In addition to mailing lists, the Boost community also leverages Slack for real-time communication. +The Slack Workspace hosts various channels dedicated to specific libraries, general discussions, and coordination among contributors.

    +
    +
    +

    When discussing Boost-related topics on social media, contributors are encouraged to follow our Tweeting guidelines. +These guidelines help ensure that the community maintains a positive and informative presence on social media.

    +
    +
    +

    New library developers usually have a lot of questions on their mind, before asking for help or information refer to the Contributors Frequently Asked Questions for answers to many common questions and dilemmas.

    +
    +
    +
    +
    +

    Documentation Style

    +
    +
    +

    A consistent documentation style, that emphasizes readability and accessibility, is encouraged. +This includes all the library Documentation Guidelines and contributions to this website (refer to Site-docs Style Guide).

    +
    +
    +
    +
    +

    Governance

    +
    +
    +

    Refer to The Fiscal Sponsorship Committee for an overview of the role of this committee, the assets it maintains, and contact information if needed.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/contributors-faq.html b/preview/contributor-guide/contributors-faq.html new file mode 100644 index 0000000..603d352 --- /dev/null +++ b/preview/contributor-guide/contributors-faq.html @@ -0,0 +1,1776 @@ + + + + + + + + + + + + + + Contributors Frequently Asked Questions :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Contributors Frequently Asked Questions

    +
    +
    +
    +

    This section contains answers to the common questions that new contributors to Boost often have.

    +
    +
    +
    + +
    +

    Adding New Libraries

    +
    +
    +
      +
    1. +

      Do Boost libraries typically come from gauging outside interest, or perhaps more from developers following their own interests?

      +
      +

      Most Boost Libraries originate from individual developers, or small teams, following their own interests, rather than from organized external demand. Typically, self-motivated developers identify a gap in the C++ ecosystem or have a strong interest in a particular domain. To be clear, Boost is not driven by corporate feature requests, community polling or public wishlists, nor top-down direction (though The C++ Alliance might sponsor, or partially sponsor, work it deems of specific value, such as it did with Boost.Json). The community acts as a gatekeeper to ensure quality, generality, and long-term usefulness, rather than as a source for library concepts.

      +
      +
    2. +
    3. +

      When considering developing a library for Boost, what is the right balance between ambitious functionality and limited functionality?

      +
      +

      The keys to a successful development of a new library are to identify core functionality and start simple. Prioritize functionality that provides significant value to developers and aligns with Boost’s goals of promoting high-quality, reusable libraries. Avoid adding unnecessary features that may increase complexity without adding much value. It’s often beneficial to start with a simpler implementation that addresses a specific problem or use case effectively. A library with a narrow focus and a clear, intuitive API is more likely to be accepted by the Boost community than one that attempts to solve too many problems at once or introduces unnecessary complexity.

      +
      +
      +

      In addition to this, consider future extensibility, performance, portability, current trends, and always remember you can seek community advice and feedback through the Boost mailing lists.

      +
      +
    4. +
    5. +

      Am I right in thinking that Boost libraries are typically low-level and very specific, rather than higher-level and for tackling large scale issues such as generative AI, a modern game engine, or quantum computing, to name a few examples?

      +
      +

      Yes, Boost libraries have traditionally excelled in areas such as high-performance computing, cross-platform, embedded systems, and networking. Taking your example of generative AI, many Boost libraries could be used as components of a new AI model - such as parsing, networking, serialization, errors and exception handling, math and statistics, randomness, and so on. A new quality generative AI model is a considerable undertaking, and Boost libraries could do a lot of the grunt work and leave a development team with the most creative aspects. Simulating quantum computing, or creating a modern game engine, gets a similar answer, a development team could focus on the interactive UI, with Boost libraries handling a myriad of administrative and operational tasks.

      +
      +
      +

      A key aspect of a successful Boost library is focus: what is the problem that the library in question is the solution for?

      +
      +
    6. +
    7. +

      If there is social media discussion on new libraries, typically what does the discussion entail?

      +
      +

      The new libraries most requested tend to be more like updates to existing libraries. There’s a common desire for more comprehensive asynchronous programming support, often for higher-level abstractions or more extensive async features. Another example is more programming options, say for an enhanced version of Boost.ProgramOptions, or for libraries supporting earlier or later C++ standards, such as requests to support pre-C++17 standards.

      +
      +
    8. +
    +
    +
    +
    +
    +

    Boost Software License

    +
    +
    +
      +
    1. +

      Where can I read the current version of the Boost Software License?

      + +
    2. +
    3. +

      How should Boost programmers apply the license to source and header files?

      +
      +

      Add a multi-line comment based on the following template, substituting appropriate text for the name and date on the top line:

      +
      +
      +
      +
      //          Copyright Joe Coder 2004 - 2006.
      +// Distributed under the Boost Software License, Version 1.0.
      +//    (See accompanying file LICENSE_1_0.txt or copy at
      +//          https://www.boost.org/LICENSE_1_0.txt)
      +
      +
      +
      +
      +
      Notes
      +
      +
      +
        +
      1. +

        Leave an empty line before and after the above comment block.

        +
      2. +
      3. +

        It is fine if the copyright and license messages are not on different lines; in no case should there be other intervening text.

        +
      4. +
      5. +

        Do not include "All rights reserved" anywhere.

        +
      6. +
      7. +

        Other ways of licensing source files have been considered, but some of them turned out to unintentionally nullify legal elements of the license. Having fixed language for referring to the license helps corporate legal departments evaluate the Boost distribution.

        +
      8. +
      9. +

        Creativity in license reference language is strongly discouraged, but judicious changes in the use of whitespace are fine.

        +
      10. +
      +
      +
      +
      +
      +
    4. +
    5. +

      How should the license be applied to documentation files rather than source files?

      +
      +

      Similarly to the way it is applied to source files: the user should see the very same text indicated in the template above, with the only difference that your local copy of LICENSE_1_0.txt should also be linked to.

      +
      +
    6. +
    7. +

      How should Boost programmers maintain the copyright messages?

      +
      +

      Copyright is only claimed for changes meeting a certain threshold of originality. Therefore, the copyright message only covers expressions of creativity. It is up to authors of changes to add themselves to the copyright message if they so decide. Typically, a new claimant is added when someone takes over maintenance of a library or a new version of an existing library is developed. In principle, do not remove previous copyright claims - just add new claims and/or claimants.

      +
      +
    8. +
    9. +

      How is the Boost Software License (BSL) different from the GNU General Public License (GPL)?

      +
      +

      The GNU General Public License is longer, and may be harder to understand. The Boost license permits the creation of derivative works for any use with no legal requirement to release your source code. Other differences include BSL not requiring reproduction of copyright messages for object code redistribution, and the fact that BSL is not "viral": if you distribute your own code along with some Boost code, the BSL applies only to the Boost code (and modified versions thereof); you are free to license your own code under any terms you like.

      +
      +
    10. +
    11. +

      Why the phrase "machine-executable object code generated by a source language processor"?

      +
      +

      To distinguish cases where we do not require reproduction of the copyrights and license (such as object libraries, shared libraries, and final program executables), from cases where reproduction is still required (such as distribution of self-extracting archives of source code or precompiled header files). More detailed wording was rejected as not being legally necessary, and reducing readability.

      +
      +
    12. +
    13. +

      Why is the "disclaimer" paragraph of the license entirely in uppercase?

      +
      +

      Capitalization of these particular provisions is a US legal mandate for consumer protection.

      +
      +
    14. +
    15. +

      Does the copyright and license cover interfaces too?

      +
      +

      The conceptual interface to a library is not covered. The particular representation expressed in the header is covered, as is the documentation, examples, test programs, and all the other material that goes with the library. A different implementation is free to use the same logical interface, however. Interface issues have been fought out in court several times; refer to a lawyer if this is likely to be an issue.

      +
      +
    16. +
    17. +

      Why doesn’t the license prohibit the copyright holder from patenting the covered software?

      +
      +

      No one who distributes their code under the terms of this license could turn around and sue a user for patent infringement. Boost’s lawyers were well aware of patent provisions in licenses like the GPL and CPL, and would have included such provisions in the Boost license if they were believed to be legally useful.

      +
      +
    18. +
    19. +

      Why doesn’t the copyright message say "All rights reserved"?

      +
      +

      This provision does not belong in the copyright notice for anything (software, electronic documentation, etc.) that is being licensed. It belongs in books that are sold where, in fact, all rights (for example, to reproduce the book, etc.) are being reserved by the publisher or author.

      +
      +
    20. +
    21. +

      Do I have to copyright/license trivial files?

      +
      +

      Yes, even a test file that just contains an empty main() should have a copyright notice. Files without copyright notices make corporate lawyers nervous, and that’s a barrier to adoption. The more Boost is uniformly copyrighted and licensed, the better.

      +
      +
    22. +
    23. +

      Can I use the Boost Software License for my own projects outside of Boost?

      +
      +

      Yes, there are no restrictions on the use of the license itself.

      +
      +
    24. +
    25. +

      Is the Boost license Open Source?

      + +
    26. +
    +
    +
    +
    +
    +

    Development Environments

    +
    +
    +
      +
    1. +

      Many developers opt for lightweight integrated developer environments (IDEs), rather than the full-fledged IDE. What lightweight IDEs are popular for C++ development?

      +
      +

      There are several popular options for both Windows and Linux. CLion, developed by JetBrains, is a cross-platform IDE that offers advanced code analysis, refactoring tools, and integration with the CMake build system, which is commonly used in C++ projects.

      +
      +
      +

      GNU Emacs and Vim are highly configurable and popular among developers who prefer a more minimalistic environment. They offer powerful features for editing code, and many plugins are available to enhance development workflows.

      +
      +
      +

      Qt Creator provides features like code completion, syntax highlighting, and debugging support for C++ and Qt (projects that use the Qt framework).

      +
      +
      +

      Sublime Text is a lightweight yet powerful text editor known for its speed and simplicity. It offers features like syntax highlighting, multiple selections, and a wide range of plugins for enhancing functionality, including support for C++ development.

      +
      +
      +

      Atom is an open-source text editor developed by GitHub. It’s highly customizable and extensible through packages, and provides features like syntax highlighting, auto-completion, and project navigation.

      +
      +
      +

      There are many other tools, Microsoft’s Visual Studio provides a full IDE and is well respected as a professional development environment, and Visual Studio Code is a lighter weight but versatile code editor that can be extended and customized with various extensions.

      +
      +
    2. +
    +
    +
    +
    +
    +

    Existing Boost Libraries

    +
    +
    +
      +
    1. +

      What are the biggest pain points that developers are running into, that are not addressed by current Boost libraries?

      +
      +

      Some Boost libraries have a steep learning curve, especially for newcomers to C++. Simplifying the API design, providing extensive documentation, and offering beginner-friendly tutorials helps lower the barrier to entry and make your library more accessible to a wider audience. Other pain points include support for modern language features, working with concurrency and parallelism, providing a seamless experience across different platforms, and providing optimal performance.

      +
      +
    2. +
    3. +

      For reference, what libraries are good examples of ones that are easy to learn?

      +
      +

      One library known for its relatively straightforward API and ease of learning compared to some others is Boost.Filesystem. +This library provides portable facilities to work with files and directories, offering an intuitive interface for common file system operations such as file creation, deletion, copying, moving, and directory traversal. Its design is user-friendly and follows familiar patterns. Boost.Filesystem documentation is comprehensive and well-structured. Overall, Boost.Filesystem is often recommended as a starting point for those looking to dip their toes into Boost libraries due to its simplicity, practicality, and broad applicability across various projects.

      +
      +
      +

      Other libraries that are known for their shallow learning curve include Boost.Optional which is particularly useful for handling functions that may return an optional value or dealing with nullable data types in a safe and clear manner. Boost.Any allows developers to store objects of different types in a single container and retrieve them without typecasting. Boost.TypeIndex provides facilities for obtaining type information at runtime, making it easy to work with types dynamically.

      +
      +
    4. +
    5. +

      What libraries have the steepest learning curve?

      +
      +

      While all Boost libraries have their complexities, some are known to have steeper learning curves due to their advanced nature or the intricacies of the domain they address. Boost.Spirit is a parsing and generation library that uses a domain-specific embedded language (DSEL) implemented as C++ template metaprograms. It allows developers to define parsers and generators directly within code using EBNF-like syntax. However, the template-based approach and the metaprogramming techniques used can make it challenging for newcomers to grasp, especially those unfamiliar with advanced template programming or parsing theory.

      +
      +
      +

      Boost.Mp11 (Meta-Programming Library) is a powerful library for metaprogramming, providing tools for compile-time computation, type manipulation, and template metaprogramming. It allows developers to perform complex compile-time computations and transformations using a functional programming style. However, the functional programming paradigm and the intricacies of template metaprogramming can be daunting for beginners and require a solid understanding of C++ templates and meta-programming concepts.

      +
      +
    6. +
    7. +

      What libraries were the most ambitious in what they attempted to achieve?

      +
      +

      The many notable examples include:

      +
      +
      +
        +
      • +

        Boost.Graph provides a generic and efficient framework for working with graphs, making it suitable for a variety of applications in areas such as network analysis, optimization, and data visualization.

        +
      • +
      • +

        Boost.Compute provides abstractions for memory management, kernel execution, and data parallelism, enabling developers to harness the computational power of modern hardware for tasks such as numerical simulations, image processing, and machine learning.

        +
      • +
      • +

        Boost.Spirit is ambitious in its goal of providing a high-level and composable framework for parsing complex data formats and domain-specific languages entirely within C++ code, without the need for external tools or preprocessors.

        +
      • +
      • +

        Boost.Hana aims to simplify and modernize metaprogramming in C++, making it more accessible and powerful for developing generic libraries and applications.

        +
      • +
      +
      +
    8. +
    9. +

      What libraries were the least ambitious technically?

      +
      +

      The useful utilities such as Boost.Any, Boost.Variant, and Boost.Optional offer relatively simple functionality. Another simpler library is Boost.Bimap which provides a container for maintaining one-to-one mappings between keys and values. While bidirectional maps are a useful data structure, the functionality provided is relatively straightforward and focused on this specific use case.

      +
      +
    10. +
    +
    +
    +
    +
    +

    Generative Artificial Intelligence

    +
    +
    +
      +
    1. +

      I have always been interested in Artificial Intelligence (AI), and would like to contribute an AI component library to Boost. Within the field of Generative AI, what components would work well as a C++ library?

      +
      +

      In simple terms, generative AI works by first breaking down known constructs (for example, text or images) into small reusable components. This might be tokens, subwords, or characters for textual input, or pixels, patches, or semantic elements (sky, tree, car, etc.) for an image. Then, using statistical models, patterns, or learned rules, generative AI assembles these atomic components into something new, ideally in novel and interesting ways.

      +
      +
      +

      Of course, text and images are not the only complex constructs you might want to work with. There are too many others to list, but high-value constructs include audio and speech (breaking them down into phonemes, spectral features, or waveforms), video (decomposing into frames, objects, motion vectors, or scene segments), and time series data such as sensor data or stock prices (breaking down into patterns, cycles, and perhaps anomalies). More esoteric examples would include molecular structures and chemical compounds, social graph data, handwriting and gesture data, 3D models, and so on.

      +
      +
      +

      A new Boost library could address one or more of the tasks involved in decomposing existing structures into atomic components, then the processes involved in rebuilding these components into something new that adheres to a significant set of rules/patterns/behavior. Handling user-input to guide the process is another challenging component.

      +
      +
      +

      Perhaps take inspiration from the following table:

      +
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ConstructSubcomponents / Atomic UnitsNotes

      Text

      Subwords, Characters, Tokens, Words

      BPE (Byte Pair Encoding), WordPiece, SentencePiece, or character-based tokenization

      Images

      Pixels, Patches, Segments, Regions, Object Masks

      Vision Transformers often use image patches; segmentation maps are used for context

      Audio

      Frames, Spectrogram Windows, Mel-Frequency Cepstral Coefficients (MFCCs), Waveform Samples

      Typically converted into spectrograms or embeddings for processing. MFCCs determine how humans perceive sound.

      Speech

      Phonemes, Syllables, Graphemes, Acoustic Frames

      Combines audio processing and linguistic modeling

      Video

      Frames, Clips, Objects per Frame, Motion Vectors, Scene Changes

      Often handled as sequences of images with temporal dependencies

      Time Series

      Time Steps, Sliding Windows, Seasonal Components, Trends

      Used in forecasting models like Long-Short Term Memory (LSTMs), Transformers, etc.

      3D Models

      Mesh Vertices, Faces, Point Clouds, Voxels, Primitives

      Decomposed for neural rendering or reconstruction

      Code

      Tokens, AST Nodes, Lines, Statements, Functions

      Abstract Syntax Trees (ASTs) used by code Large Language Models (LLMs)

      Music

      Notes, Chords, Bars, Timing Events, MIDI Tokens

      Representation varies: symbolic (MIDI), waveform, or spectrogram

      Sensor Data

      Events, Packets, Timestamps, Multimodal Vectors

      Used in robotics and IoT, often real-time

      +
    2. +
    3. +

      Many current AI libraries are built using Python or Rust, is there a need for C++ versions of these libraries?

      +
      +

      Perhaps not in all cases, but many applications will need performance, cross-platform portability, or integration with existing or embedded systems, all of which C++ excels at. Imagine adding real-time generative AI into a game or visual simulation, the performance requirement is the deciding factor.

      +
      +
    4. +
    5. +

      Can you give me some ideas for libraries that could be created and added to Boost?

      +
      +

      Here are some good candidates for AI libraries, with their respective use-cases:

      +
      +
      +
        +
      • +

        Boost.TokenStream - efficiently tokenizes words into subwords and characters so that a command such as "Turn on the lights" is understood. A C++ version could support inference on an edge device such as a microcontroller to run offline voice assistance.

        +
      • +
      • +

        Boost.AIGen - rapidly prototypes models that generate descriptions of simulation states, and returns generated descriptions or structured images. This could be a lightweight generative model abstraction layer that enables experimentation with text, image, audio, or multi-modal generation.

        +
      • +
      • +

        Boost.Autograd - provides a lightweight automatic differentiation engine to +simulate and optimize fluid flow using neural networks that respect physical laws. This requires differentiation of physical equations.

        +
      • +
      • +

        Boost.MLGraph - defines and executes computation graphs with typed nodes and edges, enabling graph-based machine language research using custom model formats.

        +
      • +
      • +

        Boost.Prompting - a C++ toolkit to structure, serialize, and test prompts for Large Lanugage Model (LLM)-based applications. Prompts could be built dynamically and used by assistants, chatbots, games, and perhaps robotics.

        +
      • +
      +
      +
    6. +
    7. +

      Would the project structure of a generative AI library be any different for any other Boost library?

      +
      +

      Not at all, if you were to take our Boost.TokenStream idea and develop it, the project structure could look like this:

      +
      +
      +
      +
      boost-token-stream/
      +├── include/
      +│   └── boost/
      +│       └── token-stream/
      +│           ├── bpe.hpp             # Public API
      +│           ├── vocab.hpp           # Vocab structure
      +│           ├── merge_rules.hpp     # Merge rules structure
      +│           └── error.hpp           # Error handling and outcome types
      +├── src/
      +│   └── bpe.cpp                     # Implementation (if not header-only)
      +├── test/
      +│   ├── test_bpe.cpp                # Unit tests
      +│   └── test_vocab.cpp              # Vocab loading/lookup tests
      +├── CMakeLists.txt
      +└── README.md
      +
      +
      +
    8. +
    9. +

      I want to experiment with creating a library for scene based generative AI, but I find all the necessary components somewhat daunting. Are there Boost libraries that can lighten the load?

      +
      +

      For an experimental project, consider structuring it around the following, assuming the input is a raw still image, and the output is a generated image:

      +
      +
      + +
      +
    10. +
    11. +

      What is considered to be best practices when testing a generative AI model, given we can never be sure when it has got it all right?

      +
      +

      Testing a generative AI model, or library component, is fundamentally different from traditional software testing because there’s no single correct output — outputs are often subjective, diverse, and probabilistic. However, there are best practices that help ensure quality, safety, and usefulness. Start by engaging the following methods:

      +
      + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      MethodDescriptionProsCons

      Automated Metrics

      BLEU, ROUGE, METEOR, Perplexity, FID (for images), etc.

      Fast, repeatable

      Poor at capturing nuance

      Human Evaluation

      Judges rate quality, relevance, etc.

      High-quality insights

      Time-consuming, subjective

      Adversarial Testing

      Try to break the model with edge cases or trick inputs

      Uncovers weaknesses

      Requires creativity and care

      Behavioral Unit Tests

      Small, targeted tests for expected responses

      Precise

      Limited coverage

      +
      +

      Perfect doesn’t apply in generative AI. Instead, strive for consistent quality, clear boundaries, and safe behavior:

      +
      +
      +
        +
      • +

        Define clear evaluation goals and test across diverse datasets

        +
      • +
      • +

        Simulate misuse - prompt injection, toxic output, sensitive topics

        +
      • +
      • +

        Track hallucinations - the AI term for clearly incorrect statements or images

        +
      • +
      • +

        Track consistency - does the model contradict itself

        +
      • +
      • +

        Conduct temperature sweeps - AI term for measuring the balance between boring/repetitive and overly chaotic output

        +
      • +
      • +

        Be transparent and document limitations

        +
      • +
      • +

        Consider continuous monitoring in production - collect and analyze feedback

        +
        +

        A prospective generative AI Boost library would only need testing within its own domain of functionality, but the design should be cognizant of the testing a finished application is going to require.

        +
        +
      • +
      +
      +
    12. +
    +
    +
    +
    +
    +

    Modular Boost

    +
    +
    +
      +
    1. +

      What is meant by "Modular Boost"?

      +
      +

      Technically, Modular Boost consists of the Boost super-project and separate projects for each individual library in Boost. In terms of Git, the Boost super-project treats the individual libraries as submodules. Currently (early 2024) when the Boost libraries are downloaded and installed, the build organization does not match the modular arrangement of the Git super-project. This is largely a legacy issue, and there are advantages to the build layout matching the super-project layout. This concept, and the effort behind it, is now known as "Modular Boost".

      +
      +
      +

      In the past, the term has been used more broadly to refer simply to libraries in different repositories. This definition has now been tightened to mean a flat layout where each library is in its own sub-module, and there are no sub-libraries as there have been in the past (for example, the numeric libraries).

      +
      +
      +

      Refer to Super-Project Layout for a full description of the super-project.

      +
      +
    2. +
    3. +

      What exactly is a "modular arrangement"?

      +
      +

      It’s when the libraries can be used, and hence built, without creating the monolithic headers, without needing the root build files, and without needing the libraries to be arranged in the usual root/libs/<name> format.

      +
      +
    4. +
    5. +

      Will the move to Modular Boost change testing?

      +
      +

      No, unless you want to. You will still be able to test with the current non-modular way. But you could also test the modular way.

      +
      +
    6. +
    7. +

      How will modular Boost work if there is no root/libs/<name> structure? Or is the structure still required?

      +
      +

      The structure is still required for things like testing and documentation building.

      +
      +
    8. +
    9. +

      What happens to the numeric libraries that are currently sub-libraries, when sub-libraries are no longer supported?

      +
      +

      The numeric libraries have been divided into four packages: libboost-numeric-conversion/, libboost-numeric-interval/, libboost-numeric-odeint/, libboost-numeric-ublas/.

      +
      +
    10. +
    +
    +
    +
    +
    +

    Post-Release Engagement

    +
    +
    +
      +
    1. +

      Through what channels do Boost library authors typically receive the most feedback?

      +
      +

      Primarily the Boost Users Mailing List and the Boost Developers Mailing List. In addition, checkout GitHub Issues and Pull Requests. Also, the Boost forums on Slack can be active.

      +
      +
      +

      Example of communication flow:

      +
      +
      +
        +
      1. +

        A new library release is announced on the Boost mailing lists.

        +
      2. +
      3. +

        Users start discussing the new release on the mailing lists, reporting initial impressions and any issues encountered.

        +
      4. +
      5. +

        Users report bugs and request features on the relevant GitHub repository, leading to active discussions in the issues and pull requests sections.

        +
      6. +
      7. +

        Boost library authors and contributors discuss technical details and implementation strategies on the Boost Developers Mailing List.

        +
      8. +
      9. +

        Users seeking immediate help might turn to Slack or sometimes Discord for quick responses, or directly communicate with the authors if email or forum addresses are made public.

        +
      10. +
      +
      +
    2. +
    3. +

      What kind of communication from the C++ developer community have library authors received after public release of their library into the Boost collection?

      +
      +

      Authors often receive a variety of feedback, which should be welcomed to help authors gauge the acceptance and usability of their library. Feedback can be categorized into several types:

      +
      +
      +
        +
      1. +

        General feedback includes both positive and negative comments about the overall design, usability, and documentation of the library. The most common comments include praise for a well-designed API, criticism of complex or confusing documentation, and suggestions for improving user experience.

        +
      2. +
      3. +

        Developers may ask for help or clarification on how to use certain features of the library, especially clarifications on API usage. Another common request is for example code to demonstrate specific use cases, or help with integrating the library into their own projects.

        +
      4. +
      5. +

        Bug reports or issues developers encounter while using the library. These can range from minor issues, such as documentation typos, to major bugs that affect the functionality of the library. The more serious examples include: inconsistent behavior across different platforms, crashes or memory leaks in certain use cases, or incorrect results from specific functions.

        +
      6. +
      7. +

        Feature requests are not uncommon, such as support for additional platforms or compilers, new algorithms or data structures, or performance improvements and optimizations.

        +
      8. +
      9. +

        Performance feedback related to the performance of the library, including benchmarking results and suggestions for optimizations. Typically this centers around reports of slow performance in certain scenarios, comparisons with similar libraries, or suggestions for algorithmic improvements.

        +
      10. +
      11. +

        Portability issues are also to be expected, related to building or running the library on different platforms, operating systems, or compilers. Obvious issues include compilation errors on specific platforms, incompatibilities with certain compiler versions, or issues with platform-specific dependencies.

        +
      12. +
      13. +

        There can be integration feedback on how well the library integrates with other libraries, frameworks, or tools in the C++ ecosystem. This can include integrating even with other Boost libraries as well as other third-party libraries.

        +
      14. +
      15. +

        Finally, it is important to remember that members of the community can contribute to a library by submitting patches, improvements, or additional features. These updates tend to focus on code optimizations, and bug fixes. Less often they are enhancements to the library’s functionality.

        +
      16. +
      +
      +
    4. +
    5. +

      Can you give me some examples of user requests for library improvements and describe the response from the authors or maintainers?

      +
      +
        +
      • +

        Boost.Asio received numerous bug reports and feature requests related to its asynchronous I/O capabilities. Users asked for better documentation and examples for common use cases, such as implementing network protocols. The author, Christopher M. Kohlhoff, responded by improving documentation and providing more examples and tutorials. The library also received several community-contributed enhancements and bug fixes.

        +
      • +
      • +

        Boost.Python users reported issues related to compatibility with different versions of Python and C++ compilers. There were also many requests for new features to better support modern C++ standards and Python 3.x. The maintainers addressed these issues by updating the library to support newer Python versions and C++ standards. The community also contributed patches to fix compatibility issues and add new features.

        +
      • +
      • +

        Boost.Spirit, a library for creating parsers and generators, received feedback about its steep learning curve and complex documentation. Users requested more tutorials and simpler examples. The authors and the community worked on improving the documentation and providing more examples. The library also saw several enhancements to make it more user-friendly and easier to learn.

        +
      • +
      • +

        Boost.Thread ran into issues with changes in the C++11 standard library, which introduced its own threading support. +The authors had to adapt Boost.Thread to coexist with and complement the standard library’s threading facilities, leading to significant refactoring.

        +
      • +
      • +

        Boost.Graph initially included some incorrect assumptions about graph properties and algorithms, this led to bugs that required reworking the design to support a wider range of graph types and use cases.

        +
      • +
      • +

        Boost.Math initially had issues in mathematical algorithms that produced incorrect results in some cases, and required redesigning the affected components to ensure greater robustness.

        +
      • +
      • +

        Boost.Interprocess had some bugs related to shared memory management that led to memory corruption, requiring a redesign of the allocation and synchronization mechanisms.

        +
      • +
      • +

        Boost.Filesystem early versions had an API that was inconsistent and difficult to extend. The introduction of the v3 API addressed these issues, providing a more robust and user-friendly interface.

        +
      • +
      • +

        Boost.MultiIndex had performance issues with certain types of queries and modifications which required rethinking the internal data structures and algorithms to improve efficiency.

        +
      • +
      • +

        Boost.Geometry had performance bottlenecks in spatial indexing and query algorithms. This required redesigning parts of the library to handle large datasets more efficiently.

        +
      • +
      • +

        Boost.Regex had issues with regular expression processing that could be exploited for denial-of-service attacks. This required redesigning parts of the matching engine to improve security and robustness. Refer to Security for more details.

        +
      • +
      • +

        Boost.Serialization also had Security issues - vulnerabilities in handling serialized data could lead to arbitrary code execution or data corruption. This was addressed with changes to the serialization mechanisms.

        +
      • +
      +
      +
    6. +
    7. +

      What have been the most unpleasant surprises that Boost library authors have to deal with?

      +
      +

      Here are some of the most notable ones:

      +
      +
      +
        +
      1. +

        Changes in the C++ standard or the introduction of new features can sometimes break backward compatibility, leading to user complaints and requiring significant effort to fix.

        +
      2. +
      3. +

        Authors have encountered unexpected behavior or compilation errors on less common platforms, requiring extensive debugging and platform-specific fixes.

        +
      4. +
      5. +

        Boost has its own B2 system (though CMake can also be used), which can be complex and difficult for new users to understand. Authors have received feedback about difficulties in building the library, leading to extensive support and documentation efforts to help users get started.

        +
      6. +
      7. +

        Authors have had to deal with unexpected slowdowns (performance regressions) reported by users, requiring detailed performance analysis and sometimes reworking or reverting changes.

        +
      8. +
      9. +

        Users often have high expectations, and meeting these expectations can be challenging, especially for volunteer-driven projects. Authors sometimes face criticism for perceived shortcomings in these areas.

        +
      10. +
      11. +

        Dependency hell : there can be a complex web of dependencies, and managing these dependencies can be challenging, especially when changes in one library affect others. Authors sometimes find it difficult to keep everything in sync.

        +
      12. +
      13. +

        Like all software, Boost libraries can have security vulnerabilities that need to be addressed promptly. Carefully read the Security section.

        +
      14. +
      15. +

        Managing contributions from the community, ensuring code quality, and handling disagreements can be challenging.

        +
      16. +
      17. +

        Writing and maintaining comprehensive documentation is crucial but often neglected due to the focus on coding.

        +
      18. +
      +
      +
    8. +
    9. +

      What mitigation strategies have Boost library authors employed to mitigate these unpleasant surprises?

      +
      +

      Primarily implementing a comprehensive Test Matrix to catch issues early. Continuous Integration (CI) systems ensure consistent builds and tests across multiple platforms and configurations. Also actively engaging with the community through forums, mailing lists, and GitHub to gather feedback and address issues promptly. Last but not least, investing time in writing clear, detailed Documentation and tutorials to help users get started and understand complex features.

      +
      +
      +

      After the initial release, consider releasing regular updates to address bugs, improve performance, and add features as necessary, based on user feedback. Refer to Version Control.

      +
      +
      +
      +
      Note
      +
      +

      Whereas promptly addressing issues is important, haste is not always the right approach. When critical bugs are identified, detailed bug reports are needed, and the library authors and contributors analyze the bugs, discuss possible solutions, and plan the necessary changes. Significant redesign or refactoring of the affected parts of the library may be needed to address the issues. This will involve extensive testing and should not be rushed.

      +
      +
      +
      +
    10. +
    11. +

      About how long following release of a library does it take before communication dies down, say to just an occasional email or forum question?

      +
      +

      The duration and intensity of communication following the release of a Boost library obviously varies widely depending on several factors, the complexity and popularity of the library, the initial quality of the release, and the responsiveness of the authors to early feedback. However, a general pattern has been observed:

      +
      +
      +
        +
      • +

        During the initial surge (0-3 months) the communication intensity is high. Authors are typically engaged and active during this period, addressing issues promptly, releasing patches or updates, and improving documentation based on feedback.

        +
      • +
      • +

        A stabilization period (3-12 months) follows, with moderate feedback. Authors continue to be engaged but may start shifting focus to other projects or new features for the library, so response times can slow.

        +
      • +
      • +

        The maturity phase (12+ months) involves sporadic communication, often related to edge cases or specific environments. Authors may check in periodically but are generally less active unless major issues arise or a significant update is planned.

        +
        +

        More complex libraries (for example, Boost.Spirit or Boost.Asio) tend to have longer periods of active communication due to their advanced features and higher potential for integration challenges. Libraries that quickly gain a large user base will have prolonged and more intense periods of communication. Popular libraries like Boost.Python tend to have more sustained engagement. Libraries with thorough initial documentation and fewer bugs tend to stabilize faster. Poor documentation or frequent bugs can extend the period of high communication.

        +
        +
      • +
      +
      +
    12. +
    13. +

      Say developers greatly appreciate a new library, what kind of praise have they given, or have they remained fairly silent?

      +
      +

      Silence is common but praise does come in various ways, both publicly and privately. The feedback can be quite enthusiastic and detailed, highlighting the library’s impact on their work and its overall quality. Developers often post messages of appreciation on the Boost mailing lists or Slack forums. These posts can range from simple thank-yous to detailed accounts of how the library has helped solve specific problems: "Boost.Python has significantly reduced the complexity of integrating C++ with Python in our project. The documentation is clear, and the API is intuitive. Kudos to the developers!"

      +
      +
      +

      Praise is also shared on social media platforms like X, LinkedIn, and personal or company blogs. Developers might write blog posts detailing their experiences and the benefits they’ve gained from using the library: "Just integrated Boost.Asio into our server application. The performance improvements are phenomenal! Big thanks to the Boost community!"

      +
      +
      +

      Developers might mention and praise Boost libraries in their talks at conferences or meetups. They often showcase how they used the library to solve challenging problems: for example, a presentation at CppCon highlighted the use of Boost.Hana for metaprogramming and how it simplified complex template code.

      +
      +
      +

      Private emails to the library authors expressing their gratitude and sharing success stories are also not uncommon. +For example "I wanted to thank you for your work on Boost.Graph. It has been instrumental in our network analysis tool. Your dedication and support are greatly appreciated."

      +
      +
      +

      "The documentation for Boost.Spirit is outstanding. The examples made it easy to get started and understand the complex concepts."

      +
      +
      +

      "Boost.MultiIndex has drastically improved our query performance. The library’s efficiency and flexibility are top-notch."

      +
      +
      +

      "Integrating Boost.Beast for our HTTP server was seamless. The design and ease of use are commendable."

      +
      +
      +

      "Boost.Filesystem has been rock-solid in our cross-platform application. It handles all edge cases gracefully."

      +
      +
      +

      Positive feedback and praise from developers not only encourages the library authors but also helps promote the library within the wider community. This can lead to increased adoption, further contributions, and continuous improvement of the library by the community. It can of course lead to additional communication.

      +
      +
      +

      Financial contributions or sponsorships as a token of appreciation are rare!

      +
      +
    14. +
    +
    +
    +
    +
    +

    Safe C++

    +
    +
    +
      +
    1. +

      As a contributor of a library to Boost, what do I need to know about Safe C++?

      +
      +

      The current lack of memory-safety makes it too easy for malicious software to exploit C++ language vulnerabilities and perform a variety of attacks. However, retrofitting the C++ language with memory-safe constructs has proven to be daunting. The Safe C++ proposal for a memory-safe set of operations is currently in a state of indefinite hiatus.

      +
      +
      +

      Clearly there could be significant interest in safe versions of Boost libraries, though the level of work involved extends well beyond rewriting a library using safe extensions, as all dependencies would also have to be safe versions too.

      +
      +
      +

      Currently, an astute developer should use known safe practices (some of which are shown below), avoid unsafe libraries if there is a choice, and be aware of the discussions on safe coding practices going on in social media.

      +
      +
    2. +
    3. +

      What kind of feedback did the proposal for Safe C++ receive?

      +
      +

      Positive feedback centered on appreciation of the initiative to address longstanding safety concerns in C++. More challenging feedback has included concerns about the complexity of integrating new safety features into the existing C++ framework, balancing enhanced safety with the language’s core design features of performance and flexibility, and competition from the RUST and Swift programming languages.

      +
      +
    4. +
    5. +

      Are there references I can read that will help me understand safe concepts and so understand the online discussions?

      +
      +

      Yes, in addition to the, now stalled, Safe C++ proposal, the C++ safety, in context blog post, by Herb Sutter, has been written for a broad audience. Also by Herb Sutter, there is a paper entitled Core safety Profiles: Specification, adoptability, and impact.

      +
      +
      +

      If you refer to the References section of any of these papers, you will find a range of books, papers, presentations and the like that delve to various depths into safety issues. For example, the Safety Profiles: Type-and-resource Safe programming in ISO Standard C++, by Bjarne Stroustrup and Gabriel Dos Reis, outlines a talk on the broad spectrum of safety issues in a chattier style than the more formal programming papers - and might be a good place to start!

      +
      +
    6. +
    7. +

      Can you recommend some Boost libraries that demonstrate current best safe-coding practices?

      +
      +

      By examining the source code and documentation for any of these libraries, you should be able to educate yourself on a robust approach to safe programming, using current development tools.

      +
      +
      +

      For memory-safety, Boost.SmartPtr provides smart pointer types like boost::shared_ptr, boost::weak_ptr, and boost::scoped_ptr to manage dynamic memory safely and avoid common pitfalls like memory leaks and dangling pointers. Boost.Pool offers memory pooling utilities that efficient managing of memory allocations while minimizing fragmentation. It can help show how to avoid unsafe manual memory management.

      +
      +
      +

      For type-safety, Boost.StaticAssert facilitates compile-time checks with BOOST_STATIC_ASSERT, ensuring that certain conditions are met during compilation, thus improving type-safety. Also, Boost.TypeTraits supplies a set of tools for type introspection, enabling safer template programming by providing ways to query and manipulate types.

      +
      +
      +

      For resource-safety Boost.Filesystem is designed to work with file paths and directories safely, minimizing errors in handling filesystem resources and ensuring proper cleanup. Boost.ScopeExit provides a mechanism for ensuring cleanup of resources (e.g., releasing locks or closing file handles) when a scope is exited, both normally or due to an exception. And Boost.Interprocess facilitates safe and efficient interprocess communication (IPC), managing shared memory and other resources in a resource-safe way.

      +
      +
      +

      For thread-safety Boost.Thread offers portable thread management and synchronization primitives (such as boost::mutex, boost::lock_guard) to help developers write thread-safe code. Boost.Asio enables asynchronous I/O operations with an emphasis on thread-safety, making it easier to build safe and scalable networked applications. At a lower level, Boost.Atomic provides atomic operations for thread-safe programming, avoiding data races in concurrent applications.

      +
      +
      +

      For a more general approach to safety, Boost.Optional introduces a way to handle optional values safely, avoiding issues like null pointer dereferencing. +Boost.Variant2 provides a type-safe union type, ensuring that only one active type is stored at any time, preventing type misuse errors. Boost.Coroutine2 implements stackful coroutines with resource management in mind, preventing unsafe usage patterns.

      +
      +
    8. +
    9. +

      Using current development tools what are the design principles of safe programming?

      +
      +

      Current best practices start with the use of static and compile-time checks to enforce constraints early. For resource-safety the idiom is Resource Acquisition Is Initialization (RAII). This idiom ties the lifetime of a resource to a programming object, so that when the object is created the resource is initialized, and when the object is destroyed the resource is released. However, the central theme of current safety is Encapsulation - the encapsulation of known unsafe operations in well-tested, robust, reusable abstractions, for example:

      +
      +
      +
        +
      • +

        Instead of exposing raw pointers, use smart pointers or custom encapsulation to ensure safe memory management:

        +
        +
        +
        //
        +// Unsafe code
        +//
        +
        +int* allocateArray(size_t size) {
        +    return new int[size];
        +}
        +
        +void useArray() {
        +    int* arr = allocateArray(10);
        +
        +    // No bounds checking.
        +    arr[10] = 42;
        +
        +    // Forgetting to delete could cause memory leaks.
        +    delete[] arr;
        +}
        +
        +//
        +// Safe encapsulation
        +//
        +
        +#include <vector>
        +#include <memory>
        +
        +class SafeArray {
        +private:
        +    std::unique_ptr<int[]> data;
        +    size_t size;
        +
        +public:
        +    SafeArray(size_t size) : data(std::make_unique<int[]>(size)), size(size) {}
        +
        +    int& operator[](size_t index) {
        +        if (index >= size) {
        +            throw std::out_of_range("Index out of range");
        +        }
        +        return data[index];
        +    }
        +
        +    size_t getSize() const { return size; }
        +};
        +
        +void useSafeArray() {
        +    SafeArray arr(10);
        +
        +    // Safe access
        +    arr[0] = 42;
        +    try {
        +
        +        // Throws an exception
        +        arr[10] = 13;
        +    } catch (const std::out_of_range& e) {
        +        std::cerr << e.what() << std::endl;
        +    }
        +}
        +
        +
        +
      • +
      • +

        Handle file operations safely by ensuring that the file is properly closed after use.

        +
        +
        +
        //
        +// Unsafe code
        +//
        +
        +void writeFile(const std::string& filename) {
        +    FILE* file = fopen(filename.c_str(), "w");
        +    if (file) {
        +        fputs("Hello, World!", file);
        +
        +        // Forgetting fclose could cause resource leaks.
        +    }
        +}
        +
        +//
        +// Safe encapsulation
        +//
        +
        +#include <fstream>
        +#include <string>
        +
        +class FileHandler {
        +private:
        +    std::ofstream file;
        +
        +public:
        +    explicit FileHandler(const std::string& filename) {
        +        file.open(filename, std::ios::out);
        +        if (!file) {
        +            throw std::ios_base::failure("Failed to open file");
        +        }
        +    }
        +
        +    ~FileHandler() {
        +        if (file.is_open()) {
        +            file.close();
        +        }
        +    }
        +
        +    void write(const std::string& content) {
        +        if (!file) {
        +            throw std::ios_base::failure("File not open");
        +        }
        +        file << content;
        +    }
        +};
        +
        +void safeWriteFile(const std::string& filename) {
        +    try {
        +        FileHandler fh(filename);
        +        fh.write("Hello, World!");
        +    } catch (const std::exception& e) {
        +        std::cerr << "Error: " << e.what() << std::endl;
        +    }
        +}
        +
        +
        +
      • +
      • +

        Prevent race conditions by wrapping shared resources in a thread-safe interface.

        +
        +
        +
        //
        +// Unsafe code
        +//
        +
        +#include <iostream>
        +#include <thread>
        +#include <vector>
        +
        +int counter = 0;
        +
        +void incrementCounter() {
        +    for (int i = 0; i < 1000; ++i) {
        +
        +        // Race condition
        +        ++counter;
        +    }
        +}
        +
        +void unsafeThreads() {
        +    std::thread t1(incrementCounter);
        +    std::thread t2(incrementCounter);
        +    t1.join();
        +    t2.join();
        +
        +    // Undefined behavior
        +    std::cout << "Counter: " << counter << std::endl;
        +}
        +
        +//
        +// Safe encapsulation
        +//
        +
        +#include <iostream>
        +#include <thread>
        +#include <vector>
        +#include <mutex>
        +
        +class ThreadSafeCounter {
        +private:
        +    int counter = 0;
        +    std::mutex mtx;
        +
        +public:
        +    void increment() {
        +        std::lock_guard<std::mutex> lock(mtx);
        +        ++counter;
        +    }
        +
        +    int get() const {
        +        return counter;
        +    }
        +};
        +
        +void safeThreads() {
        +    ThreadSafeCounter counter;
        +
        +    auto worker = [&counter]() {
        +        for (int i = 0; i < 1000; ++i) {
        +            counter.increment();
        +        }
        +    };
        +
        +    std::thread t1(worker);
        +    std::thread t2(worker);
        +    t1.join();
        +    t2.join();
        +
        +    // Guaranteed correct result
        +    std::cout << "Counter: " << counter.get() << std::endl;
        +}
        +
        +
        +
      • +
      • +

        Instead of using raw sockets, encapsulate them in a class that ensures proper resource cleanup.

        +
        +
        +
        //
        +// Unsafe code
        +//
        +
        +#include <sys/socket.h>
        +#include <unistd.h>
        +
        +int createSocket() {
        +    int sock = socket(AF_INET, SOCK_STREAM, 0);
        +    if (sock == -1) {
        +        perror("Socket creation failed");
        +        return -1;
        +    }
        +
        +    // Forgetting close(sock) could cause resource leaks.
        +    return sock;
        +}
        +
        +//
        +// Safe encapsulation
        +//
        +
        +#include <sys/socket.h>
        +#include <unistd.h>
        +#include <stdexcept>
        +
        +class SafeSocket {
        +private:
        +    int sock;
        +
        +public:
        +    SafeSocket() {
        +        sock = socket(AF_INET, SOCK_STREAM, 0);
        +        if (sock == -1) {
        +            throw std::runtime_error("Socket creation failed");
        +        }
        +    }
        +
        +    ~SafeSocket() {
        +        if (sock != -1) {
        +            close(sock);
        +        }
        +    }
        +
        +    int getSocket() const {
        +        return sock;
        +    }
        +};
        +
        +
        +
        +

        By wrapping low-level operations in safe abstractions, you make the code easier to use and much harder to misuse!

        +
        +
      • +
      +
      +
    10. +
    +
    +
    +
    +
    +

    Security

    +
    +
    +
      +
    1. +

      What are the known security vulnerabilities of the language C++ that I should be aware of when developing my Boost library?

      +
      +

      There are several known security vulnerabilities and pitfalls associated with the C++ language that developers should be aware of when developing libraries. Leveraging security tools, static analysis, and code reviews can help identify and address security issues early in the development lifecycle. In particular, be aware of:

      +
      +
      +
        +
      • +

        Buffer overflows occur when data is written beyond the boundaries of a fixed-size buffer, leading to memory corruption and potential exploitation. This vulnerability can be exploited by attackers to execute arbitrary code, crash the application, or manipulate program behavior.

        +
      • +
      • +

        Null Pointer Dereferences (accessing memory at address 0) can lead to undefined behavior, crashes, or security vulnerabilities. Null pointer dereferences are a common source of application instability and can be exploited by attackers to cause denial-of-service conditions or execute arbitrary code.

        +
      • +
      • +

        Memory leaks occur when memory allocated dynamically is not properly deallocated, leading to the exhaustion of available memory over time. While memory leaks may not directly result in security vulnerabilities, they can indirectly impact system stability and performance, potentially facilitating denial-of-service attacks or other security incidents.

        +
      • +
      • +

        Deprecated functions and APIs may be insecure or outdated, exposing applications to known vulnerabilities or security risks. Developers should avoid using deprecated functions and select modern, secure alternatives provided by the latest Boost or Standard libraries.

        +
      • +
      • +

        Integer overflows and underflows occur when arithmetic operations result in values that exceed the range of representable integer types. These vulnerabilities can lead to unexpected behavior, data corruption, or security vulnerabilities, especially in security-critical code paths such as input validation or memory allocation.

        +
      • +
      • +

        Insecure input handling, such as failure to validate input data or sanitize user input, can lead to injection attacks or buffer overflows. Developers should validate and sanitize input data to ensure that it meets expected criteria and is safe to process further.

        +
      • +
      • +

        Unsafe type conversions, such as casting pointers between incompatible types or using implicit type conversions without validation, can lead to memory corruption or data integrity issues. Developers should use explicit type conversions and perform appropriate validation to prevent unintended behavior.

        +
      • +
      • +

        Concurrency and synchronization issues, such as data races, deadlocks, and race conditions, can lead to unpredictable behavior and security vulnerabilities in multithreaded applications. Developers should use thread-safe synchronization primitives and adopt best practices for concurrent programming.

        +
      • +
      +
      +
    2. +
    3. +

      Are there certain kinds of tests or certain testing styles that work well when trying to identify and remove security liabilities in C++ code?

      +
      +

      There are several types of tests and testing techniques that can be particularly effective for identifying and mitigating security vulnerabilities in C++ code, consider:

      +
      +
      +
        +
      • +

        Unit testing involves testing individual components or units of code in isolation to ensure they behave as expected. Writing comprehensive unit tests for critical functions, classes, and modules helps verify their correctness and robustness, including edge cases, boundary conditions, and error handling paths. Refer to Writing Tests.

        +
      • +
      • +

        Fuzz testing, also known as fuzzing, involves providing invalid, unexpected, or random input data to the program to identify potential vulnerabilities such as buffer overflows, null pointer dereferences, and other memory-related issues. Fuzz testing tools generate large volumes of test cases automatically and monitor the program’s behavior for crashes, hangs, or unexpected outputs. Refer to Fuzz Testing.

        +
      • +
      • +

        Static analysis tools analyze source code without executing it and identify potential security vulnerabilities, code smells, and best practice violations. Static analysis tools for C++ can detect issues such as buffer overflows, null pointer dereferences, integer overflows, uninitialized variables, and unsafe type conversions.

        +
      • +
      • +

        Dynamic analysis involves analyzing the behavior of the program during execution to identify security vulnerabilities, memory leaks, and runtime errors. Dynamic analysis tools for C++ can detect issues such as memory corruption, resource leaks, concurrency issues, and other runtime anomalies. Dynamic analysis techniques include memory sanitizers, address sanitizers, thread sanitizers, and runtime instrumentation. Refer to Sanitize Your Code.

        +
      • +
      • +

        Penetration testing, also known as pen testing or sometimes ethical hacking, involves simulating real-world attacks against the software to identify security vulnerabilities and assess the effectiveness of existing security measures.

        +
      • +
      • +

        Finally, code reviews conducted by peers, security experts, or automated tools, and focus on identifying potential security vulnerabilities, design flaws, and implementation errors.

        +
      • +
      +
      +
    4. +
    5. +

      Are there Boost libraries that would help me guard against null pointer dereferencing?

      +
      +

      While there is not a specific library dedicated solely to null pointer dereference prevention, you can leverage several libraries:

      +
      +
      +
        +
      • +

        Boost.SmartPtr provides smart pointer classes such as shared_ptr, unique_ptr, and weak_ptr, which help manage dynamic memory allocation and deallocation automatically. Smart pointers implement RAII (Resource Acquisition Is Initialization) semantics, ensuring that memory is properly released when it goes out of scope or is no longer needed. By using smart pointers instead of raw pointers, you can reduce the risk of null pointer dereferencing errors, as smart pointers automatically handle null checks and memory deallocation.

        +
      • +
      • +

        Boost.Optional provides a type-safe wrapper for optional values, allowing you to represent nullable objects without resorting to raw pointers or null references.

        +
      • +
      • +

        Boost.Assert provides macros and utilities for defining runtime assertions and preconditions in your code. You can use assertions to validate assumptions and guard against null pointer dereferences by checking for null pointers before dereferencing them.

        +
      • +
      • +

        Boost.Contract provides a framework for specifying and enforcing function contracts, including preconditions, postconditions, and invariants. You can use contracts to define and enforce conditions that must be satisfied by function parameters, return values, and object states, including null pointer checks.

        +
      • +
      +
      +
    6. +
    7. +

      Are there Boost libraries that I could include in my library project that help with secure input validation?

      +
      +

      There are several libraries that provide functionalities for input validation, sanitization, and handling, helping to mitigate security vulnerabilities related to invalid or malicious input data:

      +
      +
      +
        +
      • +

        Boost.String_Algo provides a collection of algorithms for string manipulation, including functions for removing leading or trailing whitespace, case conversion, tokenization, and search.

        +
      • +
      • +

        Boost.Tokenizer provides a tokenizer class for splitting input strings into tokens based on delimiter characters or regular expressions. This can be useful for parsing and validating input data that is structured or delimited, such as CSV files, configuration files, or network protocols. The tokenizer class allows you to define custom tokenization rules and handle edge cases effectively, improving the reliability and security of input data processing.

        +
      • +
      • +

        Boost.PropertyTree provides a hierarchical data structure for representing and manipulating structured data, such as XML, JSON, INI, or property list formats. You can use it to parse, validate, and sanitize input data in various formats, ensuring that it conforms to expected schema or constraints before further processing.

        +
      • +
      • +

        Boost.Regex provides a comprehensive regular expression library for pattern matching and text processing. Regular expressions can be powerful tools for validating and sanitizing input data, such as validating email addresses, URLs, or other structured formats.

        +
      • +
      • +

        Boost.Spirit is a parsing and generation library that allows you to define parsers and generators directly within C++ code using a domain-specific embedded language (DSEL).

        +
      • +
      +
      +
    8. +
    9. +

      Are there Boost libraries that help with secure memory management?

      +
      +

      You can leverage various libraries to help ensure memory-safety, prevent memory-related vulnerabilities, and manage resources efficiently:

      +
      +
      +
        +
      • +

        Boost.SmartPtr provides smart pointer classes such as shared_ptr, unique_ptr, and weak_ptr, which help manage dynamic memory allocation and deallocation automatically. By using smart pointers, you can prevent common memory-related vulnerabilities such as memory leaks, dangling pointers, and double frees.

        +
      • +
      • +

        Boost.Pool provides memory pool classes that allow you to efficiently allocate and deallocate fixed-size memory blocks from preallocated memory pools. Memory pools can help reduce memory fragmentation, improve memory locality, and minimize overhead associated with dynamic memory allocation.

        +
      • +
      • +

        Boost.Interprocess povides classes and utilities for interprocess communication and shared memory management. This library allows multiple processes to share memory regions securely and efficiently, facilitating communication and data exchange between them, and offers features such as named shared memory, mutexes, condition variables, and allocators for managing shared memory resources robustly.

        +
      • +
      • +

        Boost.PtrContainer provides container classes that manage ownership and lifetime of dynamically allocated objects stored within them. These containers, such as ptr_vector, ptr_list, and ptr_map, automatically delete contained objects when the container is destroyed or when objects are removed from it. By using pointer containers, you can simplify memory management and ensure proper cleanup of dynamically allocated objects, reducing the risk of memory leaks and resource exhaustion.

        +
      • +
      • +

        Boost.CircularBuffer provides a circular buffer data structure that manages a fixed-size buffer with automatic wrapping behavior. Circular buffers can be used to manage memory efficiently in scenarios where a fixed-size buffer is sufficient, and memory allocation and deallocation overhead, and fragmentation, need to be minimized.

        +
      • +
      +
      +
    10. +
    11. +

      What penetration testing frameworks might work well with a new Boost library?

      +
      +

      While penetration testing frameworks typically focus on testing web applications, network services, and software systems, they are still useful for identifying security vulnerabilities and weaknesses in a new library, typically by developing a test application that fully engages the features of the library:

      +
      +
      +
        +
      • +

        Metasploit is one of the most popular penetration testing frameworks, offering a wide range of tools and modules for exploiting vulnerabilities, conducting network reconnaissance, and assessing security posture. Metasploit modules can be customized to target specific vulnerabilities or attack vectors, such as buffer overflows, injection attacks, or memory corruption issues.

        +
      • +
      • +

        OWASP ZAP is an open-source web application security testing tool designed for finding security vulnerabilities in web applications and APIs. Boost libraries used in web applications or services may benefit from integration with ZAP to identify vulnerabilities related to input validation, injection attacks, and other web security issues.

        +
      • +
      • +

        Nmap (Network Mapper) is a powerful network scanning and reconnaissance tool used for discovering hosts and services on a network, identifying open ports, and detecting potential security vulnerabilities. Boost libraries used in networked applications or services may benefit from integration with Nmap to identify potential attack vectors, misconfigurations, or exposed services.

        +
      • +
      • +

        NESSUS is a widely-used vulnerability scanning tool designed for identifying security vulnerabilities, misconfigurations, and compliance violations in networked environments.

        +
      • +
      • +

        Burp Suite is a comprehensive web application security testing tool designed for finding security vulnerabilities in web applications and APIs, including input validation and injection attacks.

        +
      • +
      +
      +
    12. +
    13. +

      In the past, can you give me some examples of where Boost libraries have fallen short and not prevented a malicious attack?

      +
      +

      Security vulnerabilities in Boost libraries are rare compared to many other software projects, thanks to the rigorous testing, code reviews, and scrutiny they undergo. Nevertheless, there have been a few instances where security issues have been identified in Boost libraries. Here are a couple of examples:

      +
      +
      +
        +
      • +

        A vulnerability affected multiple versions of Boost (versions 1.61 through 1.63) and was related to the Boost.Filesystem library. The vulnerability allowed an attacker to bypass security restrictions and potentially execute arbitrary code by exploiting a symbolic link issue in the remove_all function. This issue was addressed in later versions of Boost, and users were advised to update their installations to mitigate the risk.

        +
      • +
      • +

        Another vulnerability affected a later version of Boost (version 1.70). This vulnerability was related to the Boost.Asio library and could allow an attacker to cause a denial-of-service condition by triggering a stack overflow via a recursive function call. The issue was addressed in subsequent versions of Boost.Asio, and users were encouraged to upgrade to the latest version to prevent potential exploitation.

        +
      • +
      +
      +
    14. +
    15. +

      If I write a library for Boost, what are the legal ramifications if there are security breaches using features of my library?

      +
      +

      As a developer contributing a library to the Boost C++ libraries, you generally retain ownership of the copyright to your code, but you also grant a license to the Boost Software License (BSL) for distribution as part of the Boost libraries. The Boost Software License is a permissive open-source license that allows users to freely use, modify, and distribute the library, subject to certain conditions.

      +
      +
      +

      The Boost Software License includes a disclaimer of liability clause, which limits the liability of the library author and contributors for damages arising from the use or distribution of the library. This means that as the library author, you are generally not held legally responsible for any damages or losses resulting from security breaches or vulnerabilities in your library.

      +
      +
      +

      Users of your library are responsible for their own use and deployment of the library, including ensuring the security of their applications and systems. While you have a duty to exercise reasonable care in the development and maintenance of your library, users are ultimately responsible for assessing and mitigating any security risks associated with its usage.

      +
      +
      +

      In the event of a security breach or vulnerability in your library, it is important to respond promptly and responsibly by disclosing the issue, providing mitigations or workarounds, and releasing updates or patches to address the vulnerability. Prompt and transparent communication with the community helps minimize the impact of security incidents and demonstrates your commitment to security and accountability.

      +
      +
      +

      Depending on the circumstances and applicable laws, there may be legal obligations to report security breaches or vulnerabilities, especially if they involve personal data or sensitive information. It’s important to familiarize yourself with relevant legal requirements and best practices for handling security incidents, including data breach notification laws and industry-specific regulations. Engaging with the Boost community and collaborating with security researchers can help identify and address security vulnerabilities proactively. Encouraging responsible disclosure of security issues, providing clear channels for reporting vulnerabilities, and acknowledging contributions from security researchers fosters a culture of security awareness and helps improve the overall security posture of your library.

      +
      +
    16. +
    17. +

      Can you recommend a book that would give me best practices for threat modelling for my Boost library?

      +
      +

      There are several books that cover threat modeling principles, techniques, and applicable best practices:

      +
      +
      +
        +
      • +

        Threat Modeling: Designing for Security by Adam Shostack. This book includes a comprehensive introduction to threat modeling, covering fundamental concepts, methodologies, and practical techniques for identifying and mitigating security threats in software systems.

        +
      • +
      • +

        Threat Modeling: Uncover Security Design Flaws Using the STRIDE Approach by Frank Swiderski and Window Snyder. This book introduces the STRIDE threat modeling framework, which helps identify and analyze security threats based on six categories: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privilege.

        +
      • +
      • +

        Threat Modeling: A Practical Guide for Development Teams by Mark E. Donaldson, James B. Ransome, and Andrew N. Nelson. This book offers practical guidance, real-world examples, and insights for integrating threat modeling into the software development process. It covers a range of threat modeling techniques, tools, and best practices, including data flow diagrams, attack trees, and risk analysis.

        +
      • +
      • +

        Software Security Engineering: A Guide for Project Managers by Julia H. Allen, Sean Barnum, and Robert J. Ellison. This book provides a comprehensive overview of software security engineering principles, practices, and processes. It covers a wide range of topics related to software security, including threat modeling, security requirements analysis, security architecture, secure coding practices, and security testing.

        +
      • +
      +
      +
    18. +
    +
    +
    +
    +
    +

    Testing

    +
    +
    +
      +
    1. +

      What Boost libraries are useful examples of how to add Continuous Integration (CI) into the library testing process?

      +
      +

      The following libraries are solid examples of how Continuous Integration (CI) is integrated into the testing process:

      +
      +
      +
        +
      • +

        Boost.Asio is a cross-platform library for network and low-level I/O programming that relies heavily on CI systems for testing and validation.

        +
      • +
      • +

        Boost.Test supports unit testing in C++ and provides a framework for writing and running test cases, as well as utilities for organizing and reporting test results. Boost.Test leverages CI to ensure the correctness and reliability of its functionality across different platforms, compilers, and network configurations.

        +
      • +
      • +

        Boost.Thread, a set of classes and functions for multithreading, is tested rigorously using CI systems to verify its correctness, performance, and portability across various platforms and environments. CI helps identify threading-related issues, including feared and difficult-to-debug race conditions.

        +
      • +
      • +

        Boost.PropertyTree reads, manipulates and writes structured data. CI is used to validate the correctness and robustness of the parsing, serialization and manipulation features across diverse use cases and data sources.

        +
      • +
      • +

        Boost.Filesystem relies on CI systems to validate its functionality across different operating systems, file systems, and compiler environments, from basic file I/O operations to more complex file management tasks.

        +
        +

        By studying how these libraries implement CI into their testing processes, newcomers can gain valuable insights into best practices for ensuring the quality and reliability of their own library contributions.

        +
        +
        +

        Refer also to Continuous Integration.

        +
        +
      • +
      +
      +
    2. +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/debug-visualisers.html b/preview/contributor-guide/debug-visualisers.html new file mode 100644 index 0000000..ebfc03d --- /dev/null +++ b/preview/contributor-guide/debug-visualisers.html @@ -0,0 +1,1020 @@ + + + + + + + + + + + + + + Mastering Debug Visualizers in MSVC and GDB :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Mastering Debug Visualizers in MSVC and GDB

    +
    +
    +
    +

    Debug Visualizers offer a powerful way to simplify the debugging process by allowing developers to see complex data structures in a more understandable format. In this section, we explore how to use and write Debug Visualizers for both Microsoft Visual Studio (MSVC) and the GNU Debugger (GDB), two of the most popular debugging tools available today.

    +
    +
    +

    Debug Visualizers are tools that allow developers to customize how complex data structures are displayed during a debugging session. Instead of manually parsing through raw data, Visualizers can present information in a human-readable format, making it easier to understand the state of a program and identify issues.

    +
    +
    +

    For example, if you’re working with a linked list, a Debug Visualizer can display the elements of the list in a clear, ordered format rather than as a series of memory addresses. This can significantly reduce the time and effort required to diagnose and fix bugs.

    +
    +
    +

    This section covers:

    +
    + +
    +
    +
    +

    Debug Visualizers in MSVC

    +
    +
    +

    Microsoft Visual Studio comes with built-in support for Debug Visualizers. MSVC includes several built-in Visualizers for common data types like std::vector, std::map, and std::string. However, one of the most powerful features of Visual Studio is the ability to create custom Visualizers to suit your specific needs. These Visualizers are often referred to as Natvis files, - short for Native Visualizer - a script-style display language for creating custom views of C++ objects.

    +
    +
    +

    Using Built-in Visualizers

    +
    +

    Using built-in Visualizers in Visual Studio is straightforward. When you hit a breakpoint or pause the execution of your program, the debugger will automatically use the appropriate Visualizer to display the contents of variables.

    +
    +
    +

    For example, if you’re debugging a std::vector, Visual Studio will show the number of elements, their values, and the current capacity of the vector in a neatly organized format. You can also hover over variables to see a quick summary, or expand them in the Watch window to see more details.

    +
    +
    +
    +

    Writing Custom Visualizers in MSVC

    +
    +

    To create a custom Visualizer, you need to write a Natvis file. Natvis files are XML files that allow you to present data in a way that makes sense for your application, whether that means showing a simplified view or expanding complex structures, and annotating the output appropriately.

    +
    +
    +

    Natvis Syntax

    +
    +

    The syntax of a Natvis file is both straightforward and flexible. Here’s a basic structure of a Natvis file:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="MyNamespace::MyClass">
    +    <DisplayString>{{m_member1}}, {{m_member2}}</DisplayString>
    +    <Expand>
    +      <Item Name="Member 1">m_member1</Item>
    +      <Item Name="Member 2">m_member2</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    In this example, the DisplayString element defines a simple summary of the data that will be shown when you hover over a variable of type MyClass. The Expand element defines what will be shown when you expand the variable in the debugger.

    +
    +
    +
    +

    Example Visualizer

    +
    +

    Let’s consider an example where you have a custom linked list class:

    +
    +
    +
    +
    namespace MyNamespace {
    +    struct Node {
    +        int value;
    +        Node* next;
    +    };
    +
    +    class LinkedList {
    +    public:
    +        Node* head;
    +    };
    +}
    +
    +
    +
    +

    Now, write a Natvis file to visualize this linked list in a user-friendly manner:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="MyNamespace::LinkedList">
    +    <DisplayString>LinkedList with head at {head}</DisplayString>
    +    <Expand>
    +      <Item Name="Head">head</Item>
    +      <LinkedListItems>
    +        <Size>size</Size>
    +        <ValuePointer>head</ValuePointer>
    +        <NextPointer>next</NextPointer>
    +      </LinkedListItems>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Natvis file will show the head of the linked list and allow you to expand it to see all the elements in a list format.

    +
    +
    +
    +

    Deploy and Test

    +
    +

    Once you have written your Natvis file, you can deploy it in Visual Studio by placing it in the My Documents\Visual Studio <Version>\Visualizers directory or by including it directly in your project. After loading your project and hitting a breakpoint, Visual Studio will use your custom Visualizer automatically.

    +
    +
    +
    +

    Tips and Best Practices

    +
    +

    When writing Natvis files, keep the following best practices in mind:

    +
    +
    +
      +
    1. +

      Visualizers should simplify the debugging process, so avoid overly complex representations.

      +
    2. +
    3. +

      Visualizers run during debugging, so inefficient Natvis files can slow down the debugger.

      +
    4. +
    5. +

      Ensure that your Visualizer works correctly with all possible states of the data structure, including having a single entry, or a NULL empty state, or being highly populated.

      +
    6. +
    7. +

      Document and comment your Natvis file so that others (or your future self) can understand and maintain them.

      +
    8. +
    +
    +
    +
    +
    +
    +
    +

    Debug Visualizers in GDB

    +
    +
    +

    GNU Debugger (GDB) is a powerful and flexible debugger that is widely used in the open-source Unix community. While GDB does not have a direct equivalent to MSVC’s Natvis files, it supports a feature called pretty-printers, which serve a similar purpose. Pretty-printers are written in Python and allow developers to customize the output of data structures during debugging.

    +
    +
    +

    GDB comes with several built-in pretty-printers, particularly for standard library containers like std::vector and std::map. These pretty-printers can be enabled by loading the appropriate scripts during your debugging session.

    +
    +
    +

    For example, to enable STL pretty-printers, you might add the following to your .gdbinit file:

    +
    +
    +
    +
    python
    +import sys
    +sys.path.insert(0, '/usr/share/gcc-<version>/python')
    +from libstdcxx.v6.printers import register_libstdcxx_printers
    +register_libstdcxx_printers(gdb.current_objfile())
    +end
    +
    +
    +
    +

    Once enabled, GDB will automatically use these pretty-printers to display STL containers in a more readable format.

    +
    +
    +

    Writing Custom Pretty-Printers in GDB

    +
    +

    Here’s a simple Python template for a GDB pretty-printer:

    +
    +
    +
    +
    class MyClassPrinter:
    +    "Print a MyNamespace::MyClass"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        return "MyClass: member1 = {}, member2 = {}".format(
    +            self.val['member1'], self.val['member2'])
    +
    +def lookup_function(val):
    +    if str(val.type) == "MyNamespace::MyClass":
    +        return MyClassPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    Example Pretty-Printer

    +
    +

    Let’s write a pretty-printer for the same linked list example used in the MSVC section:

    +
    +
    +
    +
    class LinkedListPrinter:
    +    "Print a MyNamespace::LinkedList"
    +
    +    class Iterator:
    +        def __init__(self, head):
    +            self.node = head
    +
    +        def __iter__(self):
    +            return self
    +
    +        def __next__(self):
    +            if self.node == 0:
    +                raise StopIteration
    +            value = self.node['value']
    +            self.node = self.node['next']
    +            return value
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        return "LinkedList"
    +
    +    def children(self):
    +        return enumerate(self.Iterator(self.val['head']))
    +
    +def lookup_function(val):
    +    if str(val.type) == "MyNamespace::LinkedList":
    +        return LinkedListPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This script will allow GDB to display the elements of the linked list in a way that is easy to understand.

    +
    +
    +
    +

    Deploy and Test

    +
    +

    To deploy the pretty-printer, you can add it to your .gdbinit file or load it manually during a debugging session. Once loaded, GDB will use the pretty-printer to display the linked list whenever it encounters the LinkedList type.

    +
    +
    +
    +
    +

    Tips and Best Practices

    +
    +
      +
    1. +

      Write modular pretty-printers that can be easily extended or reused.

      +
    2. +
    3. +

      Keep performance in mind, as pretty-printers run in real-time during debugging.

      +
    4. +
    5. +

      Ensure that your pretty-printer works correctly with all possible states of the data structure, including having a single entry, or a NULL empty state, or being highly populated.

      +
    6. +
    7. +

      Document and comment your pretty-printers so that others (or your future self) can understand and maintain them.

      +
    8. +
    +
    +
    +
    +
    +
    +

    Comparing MSVC and GDB Debug Visualizers

    +
    +
    +

    While both MSVC and GDB support custom visualization of data structures during debugging, they differ significantly in their approach:

    +
    +
    +
      +
    1. +

      Natvis files are XML-based and tightly integrated with the Visual Studio IDE, offering a more graphical and user-friendly experience.

      +
    2. +
    3. +

      GDB’s pretty-printers are written in Python, providing greater flexibility but requiring more manual setup and scripting.

      +
    4. +
    +
    +
    +
    +
    +

    Real-World Use Cases

    +
    +
    +

    Debug Visualizers are particularly useful in scenarios where data structures are complex and difficult to interpret from raw memory views. This includes debugging custom containers, graphical objects, or any data structure with a non-trivial internal representation.

    +
    +
    +

    Consider a case where a developer is working on a 3D game engine. The engine uses complex data structures to represent scenes, including trees of graphical objects and spatial partitions. Without Debug Visualizers, diagnosing issues with these structures would involve manually traversing pointers and interpreting binary data. With custom Visualizers, the developer can see these structures as they are meant to be seen, such as a tree view of the scene graph or a grid of spatial partitions, making it much easier to identify and fix problems.

    +
    +
    +
    +
    +

    Using Debug Visualizers with Synchronous Boost Libraries

    +
    +
    +

    The following examples refer to Boost.Optional, Boost.Variant, and Boost.Container.

    +
    +
    +

    Visualizing boost::optional

    +
    +

    The boost::optional type represents an object that may or may not contain a value. When debugging code that uses boost::optional, it’s helpful to quickly see whether a value is present and, if so, what that value is.

    +
    +
    +

    Here’s an example of a Natvis file that visualizes boost::optional in MSVC:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::optional<*>" Priority="High">
    +    <DisplayString Condition="!is_initialized">empty</DisplayString>
    +    <DisplayString Condition="is_initialized">Value = {*(this->storage_.data_)}</DisplayString>
    +    <Expand>
    +      <Item Name="Value" Condition="is_initialized">*(this->storage_.data_)</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer checks if the boost::optional contains a value using the is_initialized method. If a value is present, it displays the content; otherwise, it shows "empty".

    +
    +
    +

    For GDB, you can create a pretty-printer in Python:

    +
    +
    +
    +
    class OptionalPrinter:
    +    "Print a boost::optional"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        is_initialized = self.val['m_initialized']
    +        if is_initialized:
    +            return "Value = {}".format(self.val['m_storage']['m_storage']['data'])
    +        else:
    +            return "empty"
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::optional'):
    +        return OptionalPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer works similarly to the Natvis example, displaying either the value stored in the boost::optional or indicating that it is empty.

    +
    +
    +
    +

    Visualizing boost::variant

    +
    +

    boost::variant is a type-safe union that can hold one of several types. Visualizing it during debugging can be tricky, as you need to see which type is currently stored and what its value is.

    +
    +
    +

    The following Natvis file visualizes boost::variant:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::variant<*>">
    +    <DisplayString>{ which = {which}, value = {*(void*)&storage_ + 16} }</DisplayString>
    +    <Expand>
    +      <Item Name="Which">which</Item>
    +      <Item Name="Value">{*(void*)&storage_ + 16}</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer displays the active type stored in the boost::variant and its value. The which member determines which of the possible types is currently in use, and the corresponding value is extracted and displayed.

    +
    +
    +

    Here’s how you might implement a pretty-printer for boost::variant in GDB:

    +
    +
    +
    +
    class VariantPrinter:
    +    "Print a boost::variant"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        which = self.val['which_']
    +        value = gdb.parse_and_eval('((void*)&{})->boost::detail::variant::which_types::types[{}]'.format(self.val.address, which))
    +        return "which = {}, value = {}".format(which, value)
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::variant'):
    +        return VariantPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer identifies the active type using which_ and displays its value.

    +
    +
    +
    +

    Visualizing boost::container::vector

    +
    +

    boost::container::vector is a drop-in replacement for std::vector with improved performance in certain scenarios. Like std::vector, it benefits greatly from a Visualizer that can show the contents of the container in a user-friendly way.

    +
    +
    +

    Here’s a Natvis file for visualizing boost::container::vector:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::container::vector<*>">
    +    <DisplayString>Size = {size()}</DisplayString>
    +    <Expand>
    +      <Item Name="[size() elements]">[ptr_, ptr_ + size()]</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer displays the size of the vector, and allows you to expand the vector to see all its elements.

    +
    +
    +

    For GDB, you can use the following pretty-printer:

    +
    +
    +
    +
    class BoostVectorPrinter:
    +    "Print a boost::container::vector"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        size = self.val['m_holder']['m_size']
    +        return "Size = {}".format(size)
    +
    +    def children(self):
    +        size = int(self.val['m_holder']['m_size'])
    +        start = self.val['m_holder']['m_start']
    +        return (('[{}]'.format(i), start[i]) for i in range(size))
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::container::vector'):
    +        return BoostVectorPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer shows the size of the boost::container::vector, and lists its elements.

    +
    +
    +

    Now, let’s look at debugging a more complex library.

    +
    +
    +
    +
    +
    +

    Visualizing Boost Asio

    +
    +
    +

    Boost.Asio is a powerful and widely used library, with the challenge of debugging asynchronous code. Debug Visualizers can make this process significantly easier by providing insights into the state of your Asio objects during debugging.

    +
    +
    +

    The boost::asio::io_context (formerly io_service) is a core component of the library, used to initiate and manage asynchronous operations. When debugging, it can be helpful to see the state of the io_context, including the number of pending tasks and whether it is currently running.

    +
    +
    +

    Here’s an example of a Natvis file that visualizes boost::asio::io_context in MSVC:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::asio::io_context">
    +    <DisplayString>Work = {this->impl_.work_count_}, Threads = {this->impl_.thread_count_}</DisplayString>
    +    <Expand>
    +      <Item Name="Work Count">this->impl_.work_count_</Item>
    +      <Item Name="Thread Count">this->impl_.thread_count_</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer displays the number of pending tasks (work_count_) and the number of threads currently running in the io_context. This information is crucial for understanding the load and activity level of the io_context.

    +
    +
    +

    For GDB, you can create a pretty-printer in Python:

    +
    +
    +
    +
    class IoContextPrinter:
    +    "Print a boost::asio::io_context"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        work_count = self.val['impl_']['work_count_']
    +        thread_count = self.val['impl_']['thread_count_']
    +        return "Work = {}, Threads = {}".format(work_count, thread_count)
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::asio::io_context'):
    +        return IoContextPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer provides similar information as the Natvis file, showing the number of pending tasks and threads in the io_context.

    +
    +
    +

    Visualizing boost::asio::steady_timer

    +
    +

    The boost::asio::steady_timer is used for scheduling asynchronous operations to occur after a specified time period. Visualizing its state can help you understand when the next operation is scheduled to run.

    +
    +
    +

    The following Natvis file visualizes boost::asio::steady_timer:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::asio::steady_timer">
    +    <DisplayString>Expires At = {this->impl_.expiry_}</DisplayString>
    +    <Expand>
    +      <Item Name="Expiry Time">this->impl_.expiry_</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer displays the time at which the timer is set to expire, helping you to easily track the timing of scheduled operations.

    +
    +
    +

    Here’s a pretty-printer for boost::asio::steady_timer in GDB:

    +
    +
    +
    +
    class SteadyTimerPrinter:
    +    "Print a boost::asio::steady_timer"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        expiry_time = self.val['impl_']['expiry_']
    +        return "Expires At = {}".format(expiry_time)
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::asio::steady_timer'):
    +        return SteadyTimerPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer shows when the timer is set to expire, similar to the Natvis Visualizer.

    +
    +
    +
    +

    Visualizing boost::asio::socket

    +
    +

    Sockets are one of the most commonly used components in Boost.Asio, allowing for network communication. Visualizing socket states and addresses during debugging can provide clarity on the connections being managed.

    +
    +
    +

    Here’s a Natvis file that visualizes a TCP socket:

    +
    +
    +
    +
    <?xml version="1.0" encoding="utf-8"?>
    +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    +  <Type Name="boost::asio::ip::tcp::socket">
    +    <DisplayString>Local = {this->impl_.socket_.local_address_}:{this->impl_.socket_.local_port_}, Remote = {this->impl_.socket_.remote_address_}:{this->impl_.socket_.remote_port_}</DisplayString>
    +    <Expand>
    +      <Item Name="Local Address">{this->impl_.socket_.local_address_}:{this->impl_.socket_.local_port_}</Item>
    +      <Item Name="Remote Address">{this->impl_.socket_.remote_address_}:{this->impl_.socket_.remote_port_}</Item>
    +    </Expand>
    +  </Type>
    +</AutoVisualizer>
    +
    +
    +
    +

    This Visualizer shows the local and remote addresses and ports for a TCP socket, giving you immediate insight into the connection being managed.

    +
    +
    +

    A pretty-printer for a TCP socket in GDB might look like this:

    +
    +
    +
    +
    class TcpSocketPrinter:
    +    "Print a boost::asio::ip::tcp::socket"
    +
    +    def __init__(self, val):
    +        self.val = val
    +
    +    def to_string(self):
    +        local_address = self.val['impl_']['socket_']['local_address_']
    +        local_port = self.val['impl_']['socket_']['local_port_']
    +        remote_address = self.val['impl_']['socket_']['remote_address_']
    +        remote_port = self.val['impl_']['socket_']['remote_port_']
    +        return "Local = {}:{}, Remote = {}:{}".format(local_address, local_port, remote_address, remote_port)
    +
    +def lookup_function(val):
    +    if str(val.type).startswith('boost::asio::ip::tcp::socket'):
    +        return TcpSocketPrinter(val)
    +    return None
    +
    +gdb.pretty_printers.append(lookup_function)
    +
    +
    +
    +

    This pretty-printer displays the local and remote addresses and ports, providing clear information about the socket’s connections.

    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    By understanding how to use and write Debug Visualizers, you can gain deeper insights into your code, catch bugs more quickly, and ultimately produce higher-quality software. Whether you’re new to debugging or an experienced developer, taking the time to master these tools will pay off in the long run.

    +
    +
    +

    Consider downloading sample Natvis and Python pretty-printer files from the Boost library’s GitHub repository.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/backwards-compatibility.html b/preview/contributor-guide/design-guide/backwards-compatibility.html new file mode 100644 index 0000000..08d25ea --- /dev/null +++ b/preview/contributor-guide/design-guide/backwards-compatibility.html @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + Backwards Compatibility :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Backwards Compatibility

    +
    +

    Boost libraries generally have a large and diverse user base. To ensure successful transitions from old APIs to newer APIs under those circumstances, library authors are encouraged to follow a few guidelines when introducing breaking changes in their library:

    +
    +
    +
      +
    1. +

      Non-breaking changes can be done without restriction.

      +
    2. +
    3. +

      Small breaking changes can be made, but users should be given notice a few releases before the change is published. Most breaking changes fall into this category.

      +
    4. +
    5. +

      For large breaking changes with a migration path from the old API to the new API (for example Boost.Filesystem v2 to v3), the new API should be introduced in a separate directory/namespace, and users should be noticed and given a few releases to move over. The old API can be removed after some time.

      +
    6. +
    7. +

      For large breaking changes without a migration path (for example Boost.Spirit v2 to v3), the new API should be provided in a separate directory/namespace, and the old API should be preserved (because there’s no migration path). Removing the API should be considered the same as removing a Boost library, which can be done but needs a more extensive deprecation period.

      +
    8. +
    9. +

      Large breaking changes that are equivalent to a redesign or rewrite of the library should be treated as a new library and a formal review (or at least a mini review) is encouraged.

      +
    10. +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/borland.html b/preview/contributor-guide/design-guide/borland.html new file mode 100644 index 0000000..f570bd6 --- /dev/null +++ b/preview/contributor-guide/design-guide/borland.html @@ -0,0 +1,735 @@ + + + + + + + + + + + + + + Portability Hints using Borland C++ Compilers :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Portability Hints using Borland C++ Compilers

    +
    +
    +
    +

    It is a general aim for boost libraries to be Portable. The primary means for achieving this goal is to adhere to ISO Standard C++. However, ISO C++ is a broad and complex standard and most compilers are not fully conformant to ISO C++ yet. In order to achieve portability in the light of this restriction, it seems advisable to get acquainted with those language features that some compilers do not fully implement yet.

    +
    +
    +

    This topic gives portability hints on some language features of the Borland C++ version 5.5.1 compiler. Furthermore, the appendix presents additional problems with Borland C++ version 5.5. Borland C++ 5.5.1 is a freely available command-line compiler for Win32: Download and Install Borland C++ Compiler on Windows 10 & 11.

    +
    +
    +

    Each section below describes a particular issue, complete with sample source code to demonstrate the effect. Most sample code herein has been verified to compile with gcc 2.95.2 and Comeau C++ 4.2.44.

    +
    +
    +
    +
    +

    Preprocessor Symbol

    +
    +
    +

    The preprocessor symbol BORLANDC is defined for all Borland C++ compilers. Its value is the version number of the compiler interpreted as a hexadecimal number. The following table lists some known values.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CompilerBORLANDC value

    Borland C++ Builder 4

    0x0540

    Borland C++ Builder 5

    0x0550

    Borland C++ 5.5

    0x0550

    Borland C++ 5.5.1

    0x0551

    Borland C++ Builder 6

    0x0560

    +
    +
    +
    +

    Core Language

    +
    +
    +

    Mixing using-declarations and using-directives

    +
    +

    Mixing using-directives (which refer to whole namespaces) and namespace-level using-declarations (which refer to individual identifiers within foreign namespaces) causes ambiguities where there are none. The following code fragment illustrates this:

    +
    +
    +
    +
    namespace N {
    +  int x();
    +}
    +
    +using N::x;
    +using namespace N;
    +
    +int main()
    +{
    +  &x;     // Ambiguous overload
    +}
    +
    +
    +
    +
    +

    using-declarations for Class Templates

    +
    +

    Identifiers for class templates can be used as arguments to using-declarations as any other identifier. However, the following code fails to compile with Borland C++:

    +
    +
    +
    +
    template<class T>
    +class X { };
    +
    +namespace N
    +{
    +// "cannot use template 'X<T>' without specifying specialization parameters"
    +  using ::X;
    +};
    +
    +
    +
    +
    +

    Deduction of Constant Arguments to Function Templates

    +
    +

    Template function type deduction should omit top-level constness. However, this code fragment instantiates f<const int>(int):

    +
    +
    +
    +
    template<class T>
    +void f(T x)
    +{
    +  x = 1;  // works
    +  (void) &x;
    +  T y = 17;
    +  y = 20;  // "Cannot modify a const object in function f<const int>(int)"
    +  (void) &y;
    +}
    +
    +int main()
    +{
    +  const int i = 17;
    +  f(i);
    +}
    +
    +
    +
    +
    +

    Resolving Addresses of Overloaded Functions

    +
    +

    Addresses of overloaded functions are not in all contexts properly resolved (std:13.4 [over.over]); here is a small example:

    +
    +
    +
    +
    template<class Arg>
    +void f( void(\*g)(Arg) );
    +
    +void h(int);
    +void h(double);
    +
    +template<class T>
    +void h2(T);
    +
    +int main()
    +{
    +  void (\*p)(int) = h;                // this works (std:13.4-1.1)
    +  void (\*p2)(unsigned char) = h2;    // this works as well (std:13.4-1.1)
    +  f<int>(h2);                         // this also works (std:13.4-1.3)
    +
    +  // "Cannot generate template specialization from h(int)",
    +  // "Could not find a match for f<Arg>(void (\*)(int))"
    +  f<double>(h);                       // should work (std:13.4-1.3)
    +
    +  f( (void(\*)(double))h);            // C-style cast works (std:13.4-1.6 with 5.4)
    +
    +  // "Overloaded 'h' ambiguous in this context"
    +  f(static_cast<void(\*)(double)>(h)); // should work (std:13.4-1.6 with 5.2.9)
    +}
    +
    +
    +
    +
    +
    Workaround
    +
    +

    Always use C-style casts when determining addresses of (potentially) overloaded functions.

    +
    +
    +
    +
    +
    +

    Converting const char * to std::string

    +
    +

    Implicitly converting const char * parameters to std::string arguments fails if template functions are explicitly instantiated (it works in the usual cases, though):

    +
    +
    +
    +
    #include <string>
    +
    +template<class T>
    +void f(const std::string & s)
    +{}
    +
    +int main()
    +{
    +  f<double>("hello");  // "Could not find a match for f<T>(char \*)"
    +}
    +
    +
    +
    +
    +
    Workaround
    +
    +

    Avoid explicit template function instantiations (they have significant problems with Microsoft Visual C++) and pass default-constructed unused dummy arguments with the appropriate type. Alternatively, if you wish to keep to the explicit instantiation, you could use an explicit conversion to std::string or declare the template function as taking a const char * parameter.

    +
    +
    +
    +
    +
    +

    Dependent Default Arguments for Template Value Parameters

    +
    +

    Template value parameters which default to an expression dependent on previous template parameters don’t work:

    +
    +
    +
    +
    template<class T>
    +struct A
    +{
    +  static const bool value = true;
    +};
    +
    +// "Templates must be classes or functions", "Declaration syntax error"
    +template<class T, bool v = A<T>::value>
    +struct B {};
    +
    +int main()
    +{
    +  B<int> x;
    +}
    +
    +
    +
    +
    +
    Workaround
    +
    +

    If the relevant non-type template parameter is an implementation detail, use inheritance and a fully qualified identifier (for example, ::N::A<T>::value).

    +
    +
    +
    +
    +
    +

    Partial Ordering of Function Templates

    +
    +

    Partial ordering of function templates, as described in std:14.5.5.2 [temp.func.order], does not work:

    +
    +
    +
    +
    #include <iostream>
    +
    +template<class T> struct A {};
    +
    +template<class T1>
    +void f(const A<T1> &)
    +{
    +  std::cout << "f(const A<T1>&)\n";
    +}
    +
    +template<class T>
    +void f(T)
    +{
    +  std::cout << "f(T)\n";
    +}
    +
    +int main()
    +{
    +  A<double> a;
    +  f(a);   // output: f(T)  (wrong)
    +  f(1);   // output: f(T)  (correct)
    +}
    +
    +
    +
    +
    +
    Workaround
    +
    +

    Declare all such functions uniformly as either taking a value or a reference parameter.

    +
    +
    +
    +
    +
    +

    Instantiation with Member Function Pointer

    +
    +

    When directly instantiating a template with some member function pointer, which is itself dependent on some template parameter, the compiler cannot cope:

    +
    +
    +
    +
    template<class U> class C { };
    +template<class T>
    +class A
    +{
    +  static const int v = C<void (T::\*)()>::value;
    +};
    +
    +
    +
    +
    +
    Workaround
    +
    +

    Use an intermediate typedef:

    +
    +
    +
    +
    +
    +
    template<class U> class C { };
    +template<class T>
    +class A
    +{
    +  typedef void (T::\*my_type)();
    +  static const int v = C<my_type>::value;
    +};
    +
    +
    +
    +
    +
    Note
    +
    +

    Extracted from an e-mail exchange between David Abrahams, Fernando Cacciola, and Peter Dimov; not actually tested.

    +
    +
    +
    +
    +
    +
    +
    +

    Math Library

    +
    +
    +

    Function double std::abs(double) Missing

    +
    +

    The function double std::abs(double) should be defined (std:26.5-5 [lib.c.math]), but it is not:

    +
    +
    +
    +
    #include <cmath>
    +
    +int main()
    +{
    +  double (\*p)(double) = std::abs;  // error
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    int std::abs(int) will be used without warning if you write std::abs(5.1).

    +
    +
    +
    +
    +

    Similar remarks apply to seemingly all of the other standard math functions, where Borland C++ fails to provide float and long double overloads.

    +
    +
    +
    +
    Workaround
    +
    +

    Use std::fabs instead if type genericity is not required.

    +
    +
    +
    +
    +
    +
    +
    +

    Appendix: Additional Issues with Borland C++ Version 5.5

    +
    +
    +

    These issues are documented mainly for historic reasons. If you are still using Borland C++ version 5.5, you are strongly encouraged to obtain an upgrade to version 5.5.1, which fixes the issues described in the following section.

    +
    +
    +

    Inline Friend Functions in Template Classes

    +
    +

    If a friend function of some class has not been declared before the friend function declaration, the function is declared at the namespace scope surrounding the class definition. Together with class templates and inline definitions of friend functions, the code in the following fragment should declare (and define) a non-template function bool N::f(int,int), which is a friend of class N::A<int>. However, Borland C++ v5.5 expects the function f to be declared beforehand:

    +
    +
    +
    +
    namespace N {
    +  template<class T>
    +  class A
    +  {
    +    // "f is not a member of 'N' in function main()"
    +    friend bool f(T x, T y) { return x < y; }
    +  };
    +}
    +
    +int main()
    +{
    +    N::A<int> a;
    +}
    +
    +
    +
    +

    This technique is extensively used in boost/operators.hpp. Giving in to the wish of the compiler doesn’t work in this case, because then the instantiate one template, get lots of helper functions at namespace scope approach doesn’t work anymore. Defining BOOST_NO_OPERATORS_IN_NAMESPACE (a define BOOST_NO_INLINE_FRIENDS_IN_CLASS_TEMPLATES would match this case better) works around this problem and leads to another one, see the template discussion in Core Language.

    +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/dependencies.html b/preview/contributor-guide/design-guide/dependencies.html new file mode 100644 index 0000000..1d5fa2b --- /dev/null +++ b/preview/contributor-guide/design-guide/dependencies.html @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + Dependencies :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Dependencies

    +
    +
    +
    +

    A Boost library does not generally depend on other libraries, except for Boost or the C++ Standard Library. There are some exceptions. For example, Boost.Iostreams, and Boost.Beast, have an optional dependency on zlib, to provide support for gzip and zlib compression and decompression. If zlib is not available, Boost.Iostreams will still work, but without the ability to handle gzip and zlib formats. Another example is Boost.Asio, which has an optional dependency on OpenSSL, to provide support for SSL and TLS protocols. These protocols are widely used for secure network communications. Again, if OpenSSL is not available, Boost.Asio will still work, but without support for SSL or TLS.

    +
    +
    +

    Other examples include Boost.Python interfaces with the Python C API, so obviously depends on a Python installation. Boost.Locale depends on the International Components for Unicode (ICU) to provide Unicode and localization support. On Unix systems, Boost.Thread relies on the pthread library. Boost.Compute has a dependency on OpenCL.

    +
    +
    +

    For other libraries that you might want to take a dependency on, get a discussion going first with the Boost developers' mailing list. The general rule is avoid unreasonable dependencies.

    +
    +
    +
    +
    +

    Benefits and Effects of Coupling

    +
    +
    +

    A Boost library should use other Boost Libraries, or the C++ Standard Library, when the benefits outweigh the costs. In general, Boost libraries are designed to be as independent as possible, so that users can pick and choose the libraries they need without being forced to include unnecessary code. Many Boost libraries are indeed standalone and can be used separately without any dependencies on other libraries.

    +
    +
    +

    The benefits of using components from other libraries may include clearer, more understandable code, reduced development and maintenance costs, and the assurance which comes from reusing well-known and trusted building blocks. The costs may include undesirable coupling between components, and added compilation and runtime costs. If the interface to the additional component is complex, using it may make code less readable, and thus actually increase development and maintenance costs.

    +
    +
    +

    Negative effects of coupling become obvious when one library uses a second library which uses a third, and so on. The worst form of coupling requires the user understand each of the coupled libraries. Coupling may also reduce the portability of a library - even in cases when all used libraries are self-sufficient (see Examples of Questionable Dependencies).

    +
    +
    +
    +
    +

    Examples of Acceptable Dependencies

    +
    +
    +

    The Boost.Graph library depends on Boost.Iterator and Boost.PropertyMap. Similarly, Boost.Asio, mentioned above, depends on several other Boost libraries including Boost.System, Boost.DateTime, and Boost.Bind, and others. Boost.Asio itself is recommended if your library needs networking.

    +
    +
    +

    A good example where another boost component should certainly be used is Boost.Core, as it has considerable benefits; it simplifies code, improves readability, and signals intent. Boost.Core contains small utilities, usually polyfills for standard components, which you use when targeting C++ standards where they are not available. Costs are low as coupling is limited; the Boost.Core header includes only lightweight headers. There are no runtime costs at all. With costs so low and benefits so high, other boost libraries should use Boost.Core when the need arises.

    +
    +
    +

    Other Boost libraries you might consider as good foundational components include:

    +
    +
    +
      +
    • +

      Boost.Compatibility has been updated recently and has a similar role to Boost.Core. Its' classes provide polyfills from std classes, and have no extensions.

      +
    • +
    • +

      Boost.Config is used by almost all libraries. It provides macro definitions to make your code portable. It enables you to detect standard levels prior to C++17, to check which platform/compiler you are building for, and to add the relevant platform-specific code to create compiled libraries.

      +
    • +
    • +

      Boost.Assert is in general recommended over plain <cassert>, as it provides a source_location polyfill. Boost.Assert is used by almost all Boost libraries, so using it makes your library more interoperable with the others.

      +
    • +
    • +

      Similarly, Boost.ThrowException is in general recommended over plainly throwing exceptions, as it adds more info to the thrown exceptions and makes behavior more configurable. As it too is widely used in exiting Boost libraries, good interoperability applies.

      +
    • +
    • +

      Boost.Utility includes several non-templated, non-data structure related classes and functions, such as base-from-member idiom, checked delete, next and prior functions, noncopyable, and result_of.

      +
    • +
    • +

      Boost.ConceptCheck provides tools for specifying and checking that types meet the requirements of generic algorithms. It’s used by many other libraries to ensure that template parameters meet the necessary requirements.

      +
    • +
    • +

      For handling data types and structures, one of Boost.FunctionTypes, Boost.Fusion, Boost.Any, Boost.Variant, or Boost.Variant2 might provide what you need.

      +
    • +
    • +

      As well as supporting data types, Boost.Variant2 is preferred over std::variant, as it enforces better invariants and is never valueless, unlike is standard counterpart.

      +
    • +
    • +

      For metaprogramming, Boost.Mp11 is the latest metaprogramming library and provides many of the building blocks for this style of programming. Boost.Mp11 should be used in preference over the older Boost.Mpl and Boost.Preprocessor.

      +
    • +
    • +

      Boost.Describe is valuable if you need reflection as part of your interface, which will occur when your library users are passing in user-defined types for your library to process.

      +
    • +
    +
    +
    +
    +
    +

    Examples of Questionable Dependencies

    +
    +
    +

    An example where another Boost component should not be used is simply where the use of the library is minimal, and does not justify the cost of having the dependency. Or perhaps when a C++ Standard Library has the same functionality for a lower cost.

    +
    +
    +

    Other examples of questionable dependencies, outside of Boost, include libraries with unstable interfaces (libraries that change frequently), libraries that are platform-specific, not widely supported, not public, or are internal in some way. Obviously libraries with heavy runtime requirements should largely be avoided altogether.

    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/design-best-practices.html b/preview/contributor-guide/design-guide/design-best-practices.html new file mode 100644 index 0000000..75634e0 --- /dev/null +++ b/preview/contributor-guide/design-guide/design-best-practices.html @@ -0,0 +1,1118 @@ + + + + + + + + + + + + + + Design Best Practices :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Design Best Practices

    +
    +
    +
    +

    Use these guidelines as recommendations based on past author’s experiences of preparing content for a library submission.

    +
    + +
    +
    +
    +

    Overview

    +
    +
    +

    When designing a new library:

    +
    +
    +
      +
    • +

      Aim first for clarity and correctness; optimization should be only a secondary concern in most Boost libraries.

      +
    • +
    • +

      Aim for ISO Standard C++. Than means making effective use of the standard features of the language, and avoiding non-standard compiler extensions. It also means using the Standard Library where applicable.

      +
    • +
    • +

      Headers should be good neighbors. See Headers and Naming Consistency.

      +
    • +
    • +

      Follow quality programming practices. Recommended texts include Effective C++ 2nd Edition and More Effective C++, both by Scott Meyers and published by Addison Wesley.

      +
    • +
    • +

      Use the C++ Standard Library or other Boost libraries, but only when the benefits outweigh the costs. Except in special cases, do not use libraries other than the C++ Standard Library or Boost.

      +
    • +
    • +

      Read Implementation Variation Techniques to see how to supply performance, platform, or other implementation variations.

      +
    • +
    • +

      Read the guidelines for Separate Compilation, to see how to ensure that compiled link libraries meet user expectations.

      +
    • +
    +
    +
    +
    +
    +

    Source Files

    +
    +
    +
      +
    • +

      Begin all source files (including programs, headers, scripts, etc.) with:

      +
      +
        +
      1. +

        A comment line describing the contents of the file.

        +
      2. +
      3. +

        Comments describing copyright and licensing: again, refer to License Requirements. Note that developers are allowed to provide a copy of the license text in LICENSE_1_0.txt, LICENSE.txt or LICENSE file within repositories of their libraries.

        +
      4. +
      5. +

        A comment line referencing your library on the Boost web site. For example:`// See https://www.boost.org/libs/foo` for library home page.

        +
        +

        Where foo is the directory name (see below) for the library. As well as aiding users who come across a Boost file detached from its documentation, some of Boost’s automatic tools depend on this comment to identify which library header files belong to.

        +
        +
      6. +
      +
      +
    • +
    • +

      Although some Boost members use proportional fonts, tabs, and unrestricted line lengths in their own code, Boost’s widely distributed source code should follow more conservative guidelines:

      +
      +
        +
      1. +

        Use fixed-width fonts. See Source Code Fonts Rationale.

        +
      2. +
      3. +

        Use spaces rather than tabs. See Tabs Rationale.

        +
      4. +
      5. +

        Limit line lengths to 80 characters.

        +
      6. +
      +
      +
    • +
    • +

      End all documentation files (HTML or otherwise) with a copyright message and a licensing message. Refer to published library documentation for examples.

      +
    • +
    +
    +
    +
    +
    +

    Naming

    +
    +
    +

    Use the naming conventions of the C++ Standard Library (See Naming Conventions Rationale):

    +
    +
    +
      +
    • +

      Names (except as noted below) should be all lowercase, with words separated by underscores.

      +
    • +
    • +

      Acronyms should be treated as ordinary names (e.g. xml_parser instead of XML_parser).

      +
    • +
    • +

      Template parameter names begin with an uppercase letter.

      +
    • +
    • +

      Macro names all uppercase and begin with BOOST_.

      +
    • +
    • +

      Choose meaningful names - explicit is better than implicit, and readability counts. There is a strong preference for clear and descriptive names, even if lengthy.

      +
    • +
    +
    +
    +

    Naming Consistency

    +
    +

    As library developers and users have gained experience with Boost, the following consistent naming approach has come to be viewed as helpful, particularly for larger libraries that need their own header subdirectories and namespaces.

    +
    +
    +
      +
    • +

      The library is given a name that describes the contents of the library. Cryptic abbreviations are strongly discouraged. Following the practice of the C++ Standard Library, names are usually singular rather than plural. For example, a library dealing with file systems might chose the name "filesystem", but not "filesystems", "fs" or "nicecode".

      +
    • +
    • +

      The library’s primary directory (in parent boost-root/libs) is given that same name. For example, boost-root/libs/filesystem.

      +
    • +
    • +

      The library’s primary header directory (in boost-root/libs/name/include) is given that same name. For example, boost-root/libs/filesystem/boost/filesystem.

      +
    • +
    • +

      The library’s primary namespace (in parent ::boost) is given that same name, except when there’s a component with that name (e.g., boost::tuple), in which case the namespace name is pluralized. For example, ::boost::filesystem.

      +
    • +
    • +

      The first letter of the library name is capitalized.

      +
    • +
    • +

      A period between "Boost" and the library name (e.g., Boost.Bind) is used if and only if the library name is not followed by the word "library".

      +
    • +
    • +

      The word "library" is not part of the library name and is therefore lowercased.

      +
    • +
    +
    +
    +

    Here are a few example sentences of how to apply these conventions:

    +
    +
    +
      +
    • +

      "Boost.Bind was written by Peter Dimov."

      +
    • +
    • +

      "The Boost Asio library was written by Christopher Kohlhoff."

      +
    • +
    • +

      "I regularly use Spirit, a Boost library written by Joel de Guzman and Hartmut Kaiser."

      +
    • +
    +
    +
    +
    +

    Filenames

    +
    +

    Naming requirements ensure that file and directory names are relatively portable, including to ISO 9660:1999 (with extensions) and other relatively limited file systems. Superscript links are provided to detailed rationale for each choice.

    +
    +
    +
      +
    • +

      Names must contain only lowercase ASCII letters ('a'-'z'), numbers ('0'-'9'), underscores ('_'), hyphens ('-'), and periods ('.'). Spaces are not allowed.

      +
      +
        +
      • +

        Some legacy file systems require single-case names. Single-case names eliminate casing mistakes when moving from case-insensitive to case-sensitive file systems.

        +
      • +
      • +

        To quote the POSIX standard, "Filenames should be constructed from the portable filename character set because the use of other characters can be confusing or ambiguous in certain contexts."

        +
      • +
      +
      +
    • +
    • +

      Directory names must not contain periods ('.').

      +
      +
        +
      • +

        Strict implementations of ISO 9660:1999 and some legacy operating systems prohibit dots in directory names. The need for this restriction is fading, and may be removed in time.

        +
      • +
      +
      +
    • +
    • +

      The first and last character of a file name must not be a period ('.').

      +
      +
        +
      • +

        POSIX has special rules for names beginning with a period. Windows prohibits names ending in a period.

        +
      • +
      +
      +
    • +
    • +

      The first character of names must not be a hyphen ('-'), as this would be too confusing or ambiguous in certain contexts.

      +
    • +
    • +

      The maximum length of directory and file names is 31 characters. We had to draw the line somewhere, and so the limit imposed by a now obsolete Apple file system was chosen years ago.

      +
    • +
    • +

      The total path length must not exceed 207 characters (ISO 9660:1999).

      +
    • +
    +
    +
    +

    Other conventions ease communication:

    +
    +
    +
      +
    • +

      Files intended to be processed by a C++ compiler as part of a translation unit should have a three-letter filename extension ending in "pp" (typically .cpp and .hpp). Other files should not use extensions ending in "pp". This convention makes it easy to identify all of the source in Boost.

      +
    • +
    • +

      All libraries have at their highest level a primary directory named for the particular library. See Naming Consistency. The primary directory may have sub-directories.

      +
    • +
    +
    +
    +
    +
    +
    +

    Testing and Error Handling

    +
    +
    +
      +
    • +

      Provide sample programs or confidence tests so potential users can see how to use your library.

      +
    • +
    • +

      Provide a regression test program or programs which follow the Test Policy.

      +
    • +
    • +

      Use exceptions to report errors where appropriate, and write code that is safe in the face of exceptions.

      +
    • +
    • +

      Avoid exception-specifications. See Exception Specification Rationale.

      +
    • +
    +
    +
    +

    Assertions

    +
    +

    It is recommended you add runtime assertions to your code (including library headers). Avoid C’s assert macro and use Boost’s BOOST_ASSERT macro (in boost/assert.hpp) instead as it is more configurable.

    +
    +
    +

    Make sure your code compiles in the presence of the min() and max() macros. Some platform headers define min() and `max() ` macros which cause some common C++ constructs to fail to compile. To protect your code from inappropriate macro substitution:

    +
    +
    +
      +
    • +

      If you want to call std::min() or std::max():

      +
      +
        +
      • +

        If you do not require argument-dependent look-up, use (std::min)(a,b).

        +
      • +
      • +

        If you do require argument-dependent look-up, you should:

        +
        +
          +
        1. +

          #include <boost/config.hpp>

          +
        2. +
        3. +

          Use BOOST_USING_STD_MIN(); to bring std::min() into the current scope.

          +
        4. +
        5. +

          Use min BOOST_PREVENT_MACRO_SUBSTITUTION (a,b); to make an argument-dependent call to min(a,b).

          +
        6. +
        +
        +
      • +
      +
      +
    • +
    • +

      If you want to call std::numeric_limits<int>::max(), use (std::numeric_limits<int>::max)() instead.

      +
    • +
    • +

      If you want to call a min() or max() member function, instead of doing obj.min(), use (obj.min)().

      +
    • +
    • +

      If you want to declare or define a function or a member function named min or max, then you must use the BOOST_PREVENT_MACRO_SUBSTITUTION macro. Instead of writing int min() { return 0; } you should write int min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; }. This is true regardless if the function is a free (namespace scope) function, a member function or a static member function, and it applies for the function declaration as well as for the function definition.

      +
    • +
    +
    +
    +
    +
    +
    +

    Redirection

    +
    +
    +

    The primary directory should always contain a file named index.html. Authors have requested this so that they can publish URL’s in the form https://www.boost.org/libs/lib-name with the assurance a documentation reorganization won’t invalidate the URL. Boost’s internal tools are also simplified if a library’s documentation is always reachable via the simplified URL.

    +
    +
    +

    The primary directory index.html file should do an automatic redirection to the doc/html subdirectory. For example, the json library contains the following index.html file:

    +
    +
    +
    +
    <html>
    +    <head>
    +        <title>Boost.JSON</title>
    +        <meta http-equiv="refresh" content="0; URL=./doc/html/index.html">
    +    </head>
    +    <body>
    +        Automatic redirection failed, please go to
    +        <a href="./doc/html/index.html">./doc/html/index.html</a>
    +        <hr>
    +        <tt>
    +        Boost.JSON<br>
    +        <br>
    +        Copyright&nbsp;(C)&nbsp;2019&nbsp;Vinnie&nbsp;Falco<br>
    +        Copyright&nbsp;(C)&nbsp;2020&nbsp;Krystian&nbsp;Stasiowski<br>
    +        <br>
    +        Distributed under the Boost Software License, Version 1.0.
    +        (See accompanying file LICENSE_1_0.txt or copy at
    +        <a href=http://www.boost.org/LICENSE_1_0.txt>http://www.boost.org/LICENSE_1_0.txt</a>) <br>
    +        <br>
    +        </tt>
    +    </body>
    +</html>
    +
    +
    +
    +
    +
    +

    Rationale

    +
    +
    +

    Rationale is defined as "The fundamental reasons for something; basis" by the American Heritage Dictionary.

    +
    +
    +

    Beman Dawes comments: "Failure to supply contemporaneous rationale for design decisions is a major defect in many software projects. Lack of accurate rationale causes issues to be revisited endlessly, causes maintenance bugs when a maintainer changes something without realizing it was done a certain way for some purpose, and shortens the useful lifetime of software."

    +
    +
    +

    Rationale is fairly easy to provide at the time decisions are made, but hard to accurately recover even a short time later. Rationale for some of the requirements and guidelines follows.

    +
    +
    +

    Exception Specification Rationale

    +
    +

    Exception specifications (ISO 15.4) are sometimes coded to indicate what exceptions may be thrown, or because the programmer hopes they will improve performance. But consider the following member from a smart pointer:

    +
    +
    +
    +
    T& operator*() const throw()  { return *ptr; }
    +
    +
    +
    +

    This function calls no other functions; it only manipulates fundamental data types like pointers Therefore, no runtime behavior of the exception-specification can ever be invoked. The function is completely exposed to the compiler; indeed it is declared inline. Therefore, a smart compiler can easily deduce that the functions are incapable of throwing exceptions, and make the same optimizations it would have made based on the empty exception-specification. A "dumb" compiler, however, may make all kinds of pessimizations.

    +
    +
    +

    For example, some compilers turn off inlining if there is an exception-specification. Some compilers add try/catch blocks. Such pessimizations can be a performance disaster which makes the code unusable in practical applications.

    +
    +
    +

    Although initially appealing, an exception-specification tends to have consequences that require very careful thought to understand. The biggest problem with exception-specifications is that programmers use them as though they have the effect the programmer would like, instead of the effect they actually have.

    +
    +
    +

    A non-inline function is the one place a "throws nothing" exception-specification may have some benefit with some compilers.

    +
    +
    +
    +

    Naming Conventions Rationale

    +
    +

    The C++ standard committee’s Library Working Group discussed this issue in detail, and over a long period of time. The discussion was repeated again in early Boost postings. A short summary:

    +
    +
    +
      +
    • +

      Naming conventions are contentious, and although several are widely used, no one style predominates.

      +
    • +
    • +

      Given the intent to propose portions of Boost for the next revision of the C++ Standard Library, Boost decided to follow the Standard Library’s conventions.

      +
    • +
    • +

      Once a library settles on a particular convention, a vast majority of stakeholders want that style to be consistently used.

      +
    • +
    +
    +
    +
    +

    Source Code Fonts Rationale

    +
    +

    Dave Abrahams comments: "An important purpose (I daresay the primary purpose) of source code is communication: the documentation of intent. This is a doubly important goal for Boost, I think. Using a fixed-width font allows us to communicate with more people, in more ways (diagrams are possible) right there in the source. Code written for fixed-width fonts using spaces will read reasonably well when viewed with a variable-width font, and as far as I can tell every editor supporting variable-width fonts also supports fixed width. I don’t think the converse is true".

    +
    +
    +
    +

    Tabs Rationale

    +
    +

    Tabs are banned because of the practical problems caused by tabs in multi-developer projects like Boost, rather than any dislike in principle. See mailing list archives. Problems include maintenance of a single source file by programmers using tabs and programmers using spaces, and the difficulty of enforcing a consistent tab policy other than just "no tabs". Discussions concluded that Boost files should either all use tabs, or all use spaces, and thus the decision to stick with spaces for indentation.

    +
    +
    +
    +

    ECMAScript/JavaScript Rationale

    +
    +

    ECMAScript/JavaScript use is allowed but discouraged. Before the 1.29.0 release, two Boost libraries added ECMAScript/JavaScript documentation. Controversy followed (see mailing list archives), and the developers were asked to remove the ECMAScript/JavaScript. Reasons given for banning included:

    +
    +
    +
      +
    • +

      Incompatible with some older browsers and some text based browsers.

      +
    • +
    • +

      Makes printing docs pages difficult.

      +
    • +
    • +

      Often results in really bad user interface design.

      +
    • +
    • +

      Would require Boost to test web pages for ECMAScript/JavaScript compliance.

      +
    • +
    • +

      Makes docs maintenance by other than the original developer more difficult.

      +
    • +
    +
    +
    +

    Consider those reasons if you decide that JavaScript is something you must use. In particular keep in mind that the Boost community is not responsible for testing your use of JavaScript. And hence it is up to you to ensure that the above issues are fully resolved in your use case.

    +
    +
    +
    +

    Acknowledgements Rationale

    +
    +

    As a library matures, it almost always accumulates improvements suggested to the authors by other Boost members. It is a part of the culture of boost.org to acknowledge such contributions, identifying the person making the suggestion. Major contributions are usually acknowledged in the documentation, while minor fixes are often mentioned in comments within the code itself.

    +
    +
    +
    +
    +
    +

    Good and Less-Good Examples of API Design

    +
    +
    +

    The following section provides examples of good and not-so-good API design, with examples.

    +
    +
    +

    Class Sizes

    +
    +

    A class should represent one concept (for example boost::filesystem::path, boost::asio::ip::address, boost::gregorian::date). Avoid “god objects” that know or do everything. If a class has too many unrelated members, split into smaller classes or helpers. If more than seven private members, ask: “should this be two classes?”, and if a class requires long docs to explain, maybe the abstraction is too fat.

    +
    +
    +

    Most Boost classes behave like values, not like heavy opaque handles: copyable, movable, comparable, assignable. This makes them easy to store in containers and pass by value.

    +
    +
    +

    Keep private data small and tightly scoped. Avoid storing things that can be recomputed cheaply.

    +
    +
    +

    If something doesn’t need state, make it a free function or template, not a class. Boost prefers non-member functions when possible (for example boost::algorithm::to_upper_copy vs. a string utility class).

    +
    +
    +

    Classes don’t usually embed “last error” members. Errors are surfaced via exceptions, or dual APIs with error_code&.

    +
    +
    +
    +

    Namespaces

    +
    +

    Namespaces in C++ are a balancing act - they prevent name collisions (especially in template-heavy libraries), they clarify context (boost::asio::ip::tcp::socket is very precise), but they can get verbose and intimidating for new users.

    +
    +
    +

    The rule of thumb for namespaces is to have a single obvious point of entry, with a namespace depth of no more than three. If you need more, consider grouping with traits or helper classes instead of new namespaces.

    +
    +
    +

    Consider using inline namespaces for versioning, as they are useful when evolving APIs without breaking existing code.

    +
    +
    +

    Repetition does not work well with namespaces, if a higher namespace already disambiguates the purpose, keep lower level namespace names short.

    +
    +
    +

    Implementation details can be encapsulated in a detail namespace, such as boost::asio::detail, and all entries in the detail namespace should be private.

    +
    +
    +

    Namespaces should reflect what the user thinks about, not how you implemented it.

    +
    + ++++ + + + + + + + + + + + + + + + + +
    Less-GoodGood

    boost::asio::detail::socket_ops

    boost::asio::ip

    boost::filesystem::filesystem_error

    boost::filesystem::error

    +
    +
    +

    Clear Overloads

    +
    +

    It is easier to understand multiple clear, simple overloads instead of one monster function.

    +
    + ++++ + + + + + + + + + + + + + + + + +
    Less-GoodGood

    remove(const path& p, bool recursive, bool force, bool follow_symlinks, …​);

    boost::filesystem::remove("file.txt"); // simple +boost::filesystem::remove_all("dir"); // recursive +boost::filesystem::remove(path("file.txt"), ec); // with error_code

    connect(host, port, use_ssl, timeout, retries, verbose, follow_redirects);

    connect(host, port); // minimal +connect(host, port, connection_options); // advanced

    +
    +
    +

    Option Objects

    +
    +

    Group each concern into option objects, which are practically self-documenting, extensible, and avoids parameter overload. Boolean parameters in particular quickly become unreadable (true, false, true). Wrap them in option types.

    +
    + ++++ + + + + + + + + + + + + +
    Less-GoodGood

    socket::set_options(…​parameters…​);

    boost::asio::ip::tcp::socket socket(io_context); +socket.set_option(boost::asio::ip::tcp::no_delay(true)); +socket.set_option(boost::asio::socket_base::reuse_address(true)); +socket.set_option(boost::asio::socket_base::linger(true, 30));

    +
    +
    +

    Flexible Constructors

    +
    +

    Clear constructors, each handling one case. Use factory functions for anything fancy.

    +
    + ++++ + + + + + + + + + + + + +
    Less-GoodGood

    date(int year, int month, int day, int calendar_type, int offset, bool validate, …​);

    boost::gregorian::date d1(2025, 9, 6); +boost::gregorian::date d2 = boost::gregorian::from_simple_string("2025-09-06");

    +
    +
    +

    Attribute-Based Configuration

    +
    +

    Named keyword parameters (via boost::parameter) give clarity without giant parameter lists.

    +
    + ++++ + + + + + + + + + + + + + + + + +
    Less-GoodGood

    log.add_file_log(…​parameters…​);

    boost::log::add_file_log( +boost::log::keywords::file_name = "sample_%N.log", +boost::log::keywords::rotation_size = 10 * 1024 * 1024, +boost::log::keywords::format = "[%TimeStamp%] <%Severity%>: %Message%");

    parse(argc, argv, true, true, true, "default.cfg");

    po::options_description desc("Options"); +desc.add_options() +("help", "Show help") +("config", po::value<std::string>(), "Config file"); +po::store(po::parse_command_line(argc, argv, desc), vm);

    +
    +
    +

    Handling Errors

    +
    +

    Allow both exception-throwing and error_code style.

    +
    + ++++ + + + + + + + + + + + + +
    Less-GoodGood

    file f("data.txt"); // throws only

    file f("data.txt", ec); // no-throw version

    +
    +
    +

    Return Values

    +
    +

    Return the result directly if there is only one natural result. Use output parameters (or error_code) only when performance matters (avoiding temporaries), or multiple results must be returned. Avoid returning int or bool for multi-state results. Use enums, optionals, variants to make meaning clear.

    +
    +
    +

    When algorithms partially consume input, returns iterators to mark progress, for example the following calls return iterators and not counts: boost::sregex_iterator it(text.begin(), text.end(), pattern); and auto new_end = boost::remove(vec, 42);. Another example of returning a more complex object is the use of lazy proxy objects that behave like containers but defer computation. This enables zero-cost abstraction and makes pipelines composable. An example is auto rng = boost::adaptors::filter(vec, pred);. It is a key to good return values though not to get too clever, consistency is the king.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Less-GoodGood

    void file_size(const path& p, uintmax_t& size); // output param for main result

    bool exists(const path& p); +uintmax_t file_size(const path& p, error_code& ec); // returns via value + error_code

    int parse_number(const std::string&); // -1 means failure

    boost::optional<int> parse_number(const std::string&);

    void file_size(const path& p, uintmax_t& out_size); // output param

    uintmax_t file_size(const path& p);uintmax_t file_size(const path& p, error_code& ec) noexcept; // alt API

    std::string find_user(int id); // returns empty string if not found

    boost::optional<std::string> find_user(int id);

    int divide(int a, int b); // returns 0 if divide-by-zero

    boost::system::result<int> divide(int a, int b); // success or error_code

    int remove(std::vector<int>& v, int x); // returns count removed

    auto new_end = boost::remove(v, x); // returns iterator (range style)

    std::vector<int> filter_positive(const std::vector<int>& v); // always allocates

    auto rng = boost::adaptors::filter(v, [](int n){ return n > 0; }); // lazy view

    Config& set_option(Config& c, int x); // modifies existing config

    Config c = Config().set_option(42).set_flag(true); // fluent style

    +
    +
    +

    Interfaces

    +
    +

    If a beginner can do something useful in one line of code, and an expert can still optimize/control everything with traits/policies, you’ve designed a good interface.

    +
    +
    +

    Keep interfaces minimal but composable. Boost often prefers non-member, non-friend functions to avoid bloating classes. Free functions are easier to extend later without breaking ABI.

    +
    +
    +

    Avoid int or std::string everywhere when domain types make intent clear.

    +
    + ++++ + + + + + + + + + + + + + + + + +
    Less-GoodGood

    my_vector.reverse_in_place_with_allocator_and_logging(…​);

    auto r = boost::adaptors::reverse(my_vector);

    bool schedule(const std::string& d);

    bool schedule(const boost::gregorian::date& d);

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/headers.html b/preview/contributor-guide/design-guide/headers.html new file mode 100644 index 0000000..f53d80f --- /dev/null +++ b/preview/contributor-guide/design-guide/headers.html @@ -0,0 +1,468 @@ + + + + + + + + + + + + + + Headers :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Headers

    +
    +
    +
    +

    Header files are the place where a library comes into contact with user code and other libraries. To co-exist peacefully and productively, headers must be "good neighbors".

    +
    +
    +
    +
    +

    Boost Standards

    +
    +
    +

    Here are the standards for boost headers. Many of these are also reasonable guidelines for general use.

    +
    +
    +
      +
    • +

      Header filenames should have a .hpp (lowercase) extension.

      +
    • +
    • +

      Unless multiple inclusion is intended, wrap the header in #ifndef guards. Use a naming convention that minimizes the chance of clashes with macro names from other’s code. The Sample uses the Boost convention of all uppercase letters, with the header name prefixed by the namespace name, followed by the relative path, and suffixed with HPP, separated by underscores. Refer also to the Example Guards.

      +
    • +
    • +

      Wrap the header contents in a namespace to prevent global namespace pollution. The namespace approach to pollution control is strongly preferred to older approaches such as adding funny prefixes to global names. Libraries which are designed to work well with other Boost libraries should be placed in namespace boost.

      +
    • +
    • +

      Make sure that a translation unit, consisting of just the contents of the header file, will compile successfully.

      +
    • +
    • +

      Place the header file in a sub-directory to prevent conflict with identically named header files in other libraries. The parent directory is added to the compiler’s include search path. Then both your code and user code specifies the sub-directory in #include directives. Thus the header Sample would be included by #include <boost/furball.hpp>. Including from the current file directory using #include "furball.hpp" syntax is discouraged.

      +
    • +
    • +

      The preferred ordering for class definitions is public members, protected members, and finally private members.

      +
    • +
    • +

      Include the boost/config.hpp if there is a need to deal with compiler or platform configuration issues.

      +
    • +
    +
    +
    +
    +
    +

    Sample

    +
    +
    +
    +
    //  Boost general library furball.hpp header file ---------------------------//
    +
    +//  (C) Copyright <Your Name> 2023. Permission to copy, use, modify, sell and
    +//  distribute this software is granted provided this copyright notice appears
    +//  in all copies. This software is provided "as is" without express or implied
    +//  warranty, and with no claim as to its suitability for any purpose.
    +
    +//  See https://www.boost.org/ for latest version.
    +
    +#ifndef BOOST_FURBALL_HPP
    +#define BOOST_FURBALL_HPP
    +
    +namespace boost {
    +
    +//  Furball class declaration  -----------------------------------------------//
    +
    +  class furball
    +  {
    +    public:
    +      void throw_up();
    +    protected:
    +      double duration();
    +    private:
    +      int whatever;
    +  };  // furball
    +
    +} // namespace
    +
    +#endif  // include guard
    +
    +
    +
    +
    +
    +

    Example Guards

    +
    +
    +

    Many libraries will include a large number of .hpp header files in a tree structure of folders. Taking Boost.Beast as an example. The header guard code is:

    +
    +
    +
    +
    #ifndef BOOST_BEAST_HPP
    +#define BOOST_BEAST_HPP
    +
    +
    +
    +

    The subfolder beast includes several more headers, including Core.hpp, which has the header guard:

    +
    +
    +
    +
    #ifndef BOOST_BEAST_CORE_HPP
    +#define BOOST_BEAST_CORE_HPP
    +
    +
    +
    +

    In the beast\core subfolder there is the async_base.hpp header file. Its' guard is:

    +
    +
    +
    +
    #ifndef BOOST_BEAST_CORE_ASYNC_BASE_HPP
    +#define BOOST_BEAST_CORE_ASYNC_BASE_HPP
    +
    +
    +
    +

    And in the beast\core\impl subfolder there is another header named async_base.hpp, this time with the guard:

    +
    +
    +
    +
    #ifndef BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
    +#define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
    +
    +
    +
    +

    Refer to beast/include/boost to view the full hierarchy of folders and headers for this library.

    +
    +
    +

    Coding Style

    +
    +

    The alert reader will have noticed that the Sample header employs a certain coding style for indentation, positioning braces, commenting ending braces, and similar formatting issues. These stylistic issues are viewed as personal preferences and are not part of the Boost Header Policy.

    +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/design-guide/separate-compilation.html b/preview/contributor-guide/design-guide/separate-compilation.html new file mode 100644 index 0000000..1674ecd --- /dev/null +++ b/preview/contributor-guide/design-guide/separate-compilation.html @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + Separate Compilation :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Separate Compilation

    +
    +
    +
    +

    These guidelines are designed for authors of Boost libraries which have separate sources that need compiling in order to use the library. Throughout, this guide refers to a fictitious "whatever" library, so replace all occurrences of "whatever" (or "WHATEVER") with your own library’s name when copying the examples.

    +
    +
    +
    +
    +

    Changes Affecting Source Code

    +
    +
    +

    Preventing Compiler ABI Clashes

    +
    +

    There are some compilers (mostly Microsoft Windows compilers), which feature a range of compiler switches that alter the (Application Binary Interface) ABI of C++ classes and functions. By way of example, consider Borland’s compiler which has the following options:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    OptionDescription

    -b

    on or off - effects enum sizes

    -Vx

    on or off - empty members

    -Ve

    on or off - empty base classes

    -aX

    alignment - 5 options

    -pX

    Calling convention - 4 options

    -VmX

    member pointer size and layout - 5 options

    -VC

    on or off, changes name mangling

    -Vl

    on or off, changes struct layout

    +
    +

    These options are provided in addition to those affecting which runtime library is used (more later); the total number of combinations of options can be obtained by multiplying together the individual options above, so that gives 2x2x2x5x4x5x2x2 = 3200 combinations!

    +
    +
    +

    The problem is that users often expect to be able to build the Boost libraries and then just link to them and have everything just plain work, no matter what their project settings are. Irrespective of whether this is a reasonable expectation or not, without some means of managing this issue, the user may well find that their program will experience strange and hard to track down crashes at runtime unless the library they link to was built with the same options as their project (changes to the default alignment setting are a prime culprit). One way to manage this is with "prefix and suffix" headers: these headers invoke compiler specific #pragma directives to instruct the compiler that whatever code follows was built (or is to be built) with a specific set of compiler ABI settings.

    +
    +
    +

    Boost.Config provides the macro BOOST_HAS_ABI_HEADERS which is set whenever there are prefix and suffix headers available for the compiler in use, typical usage in a header like this:

    +
    +
    +
    +
    #ifndef BOOST_WHATEVER_HPP
    +#define BOOST_WHATEVER_HPP
    +
    +#include <boost/config.hpp>
    +
    +// this must occur after all of the includes and before any code appears:
    +#ifdef BOOST_HAS_ABI_HEADERS
    +#  include BOOST_ABI_PREFIX
    +#endif
    +//
    +// this header declares one class, and one function by way of examples:
    +//
    +class whatever
    +{
    +   // details.
    +};
    +
    +whatever get_whatever();
    +
    +// the suffix header occurs after all of our code:
    +#ifdef BOOST_HAS_ABI_HEADERS
    +#  include BOOST_ABI_SUFFIX
    +#endif
    +
    +#endif
    +
    +
    +
    +

    You can include this code in your library source files as well if you want, although you probably shouldn’t need to:

    +
    +
    +
      +
    • +

      If you don’t use these in the library source files (but do in your library’s headers) and the user attempts to compile the library source with a non-default ABI setting, then they will get compiler errors if there are any conflicts.

      +
    • +
    • +

      If you do include them in both the library’s headers and the library source files, then the code should always compile no matter what the compiler settings used, although the result might not match what the user was expecting: since we’ve forced the ABI back into default mode.

      +
    • +
    +
    +
    +
    +

    Rationale

    +
    +

    Without some means of managing this issue, users often report bugs along the line of "Your silly library always crashes when I try and call it" and so on. These issues can be extremely difficult and time consuming to track down, only to discover in the end that it’s a compiler setting that’s changed the ABI of the class and/or function types of the program compared to those in the pre-compiled library. The use of prefix/suffix headers can minimize this problem, although probably not remove it completely.

    +
    +
    +

    Counter Argument #1

    +
    +

    Trust the user, if they want 13-byte alignment (!) let them have it.

    +
    +
    +
    +

    Counter Argument #2

    +
    +

    Prefix/suffix headers have a tendency to "spread" to other boost libraries - for example if boost::shared_ptr<> forms part of your class’s ABI, then including prefix/suffix headers in your code will be of no use unless shared_ptr.hpp also uses them. Authors of header-only boost libraries may not be so keen on this solution - with some justification - since they don’t face the same problem.

    +
    +
    +
    +
    +
    +
    +

    Static or Dynamic Libraries

    +
    +
    +

    When the users runtime is dynamically linked the Boost libraries can be built either as dynamic libraries (.so on Unix platforms, .dll on Windows, .dylib on macOS) or as static libraries (.a on Unix or macOS, .lib on Windows). So we have a choice as to which is supported by default:

    +
    +
    +
      +
    • +

      On Unix platforms it typically makes no difference to the code: the user just selects in their makesfile which library they prefer to link to.

      +
    • +
    • +

      On Windows platforms, the code has to be specially annotated to support DLL’s, so we need to pick one option as the default and one as an alternative.

      +
    • +
    • +

      On Windows platforms, we can inject special code to automatically select which library variant to link against: so again we need to decide which is to be the default (see the section on Auto-linking below).

      +
    • +
    +
    +
    +

    The recommendation is to pick static linking by default.

    +
    +
    +

    Rationale

    +
    +

    There is no one policy that fits all here.

    +
    +
    +

    The rationale for the current behaviour was inherited from Boost.Regex (and it’s ancestor regex++): this library originally used dynamic linking by default whenever the runtime was dynamic. It’s actually safer that way should you be using regex from a dll for example. However, this behavior brought a persistent stream of user complaints: mainly about deployment, all asking if static linking could be the default. After regex changed behavior the complaints stopped, and the author hasn’t had one complaint about static linking by default being the wrong decision.

    +
    +
    +

    Note that other libraries might need to make other choices: for example libraries that are intended to be used to implement dll pluggin’s would like need to use dynamic linking in almost all cases.

    +
    +
    +
    +
    +
    +

    Supporting Windows Dll’s

    +
    +
    +

    On most Unix-like platforms no special annotations of source code are required in order for that source to be compiled as a shared library because all external symbols are exposed. However the majority of Windows compilers require that symbols that are to be imported or exported from a dll, be prefixed with declspec(dllimport) or declspec(dllexport). Without this mangling of source code, it is not possible to correctly build shared libraries on Windows (historical note - originally these declaration modifiers were required on 16-bit Windows where the memory layout for exported classes was different from that of "local" classes - although this is no longer an issue, there is still no way to instruct the linker to "export everything", it also remains to be seen whether 64-bit Windows will resurrect the segmented architecture that led to this problem in the first place. Note also that the mangled names of exported symbols are different from non-exported ones, so __declspec(dllimport) is required in order to link to code within a dll).

    +
    +
    +

    In order to support the building of shared libraries on MS Windows your code will have to prefix all the symbols that your library exports with a macro (lets call it BOOST_WHATEVER_DECL) that your library will define to expand to either declspec(dllexport) or declspec(dllimport) or nothing, depending upon how your library is being built or used. Typical usage would look like this:

    +
    +
    +
    +
    #ifndef BOOST_WHATEVER_HPP
    +#define BOOST_WHATEVER_HPP
    +
    +#include <boost/config.hpp>
    +
    +#ifdef BOOST_HAS_DECLSPEC // defined in config system
    +// we need to import/export our code only if the user has specifically
    +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
    +// libraries to be dynamically linked, or BOOST_WHATEVER_DYN_LINK
    +// if they want just this one to be dynamically liked:
    +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
    +// export if this is our own source, otherwise import:
    +#ifdef BOOST_WHATEVER_SOURCE
    +# define BOOST_WHATEVER_DECL __declspec(dllexport)
    +#else
    +# define BOOST_WHATEVER_DECL __declspec(dllimport)
    +#endif  // BOOST_WHATEVER_SOURCE
    +#endif  // DYN_LINK
    +#endif  // BOOST_HAS_DECLSPEC
    +//
    +// if BOOST_WHATEVER_DECL isn't defined yet define it now:
    +#ifndef BOOST_WHATEVER_DECL
    +#define BOOST_WHATEVER_DECL
    +#endif
    +
    +//
    +// this header declares one class, and one function by way of examples:
    +//
    +class BOOST_WHATEVER_DECL whatever
    +{
    +   // details.
    +};
    +
    +BOOST_WHATEVER_DECL whatever get_whatever();
    +
    +#endif
    +
    +
    +
    +

    And then in the source code for this library one would use:

    +
    +
    +
    +
    //
    +// define BOOST_WHATEVER SOURCE so that our library's
    +// setup code knows that we are building the library (possibly exporting code),
    +// rather than using it (possibly importing code):
    +//
    +#define BOOST_WHATEVER_SOURCE
    +#include <boost/whatever.hpp>
    +
    +// class members don't need any further annotation:
    +whatever::whatever() { }
    +// but functions do:
    +BOOST_WHATEVER_DECL whatever get_whatever()
    +{
    +   return whatever();
    +}
    +
    +
    +
    +
    +
    +

    Importing/Exporting Dependencies

    +
    +
    +

    As well as exporting your main classes and functions (those that are actually documented), Microsoft Visual C++ will warn loudly and often if you try to import/export a class whose dependencies are not also exported. Dependencies include: any base classes, any user defined types used as data members, plus all of the dependencies of your dependencies and so on. This causes particular problems when a dependency is a template class, because although it is technically possible to export these, it is not at all easy, especially if the template itself has dependencies which are implementation-specific details. In most cases it’s probably better to simply suppress the warnings using:

    +
    +
    +
    +
    #ifdef BOOST_MSVC
    +#  pragma warning(push)
    +#  pragma warning(disable : 4251 4231 4660)
    +#endif
    +
    +// code here
    +
    +#ifdef BOOST_MSVC
    +#pragma warning(pop)
    +#endif
    +
    +
    +
    +

    This is safe provided that there are no dependencies that are (template) classes with non-constant static data members, these really do need exporting, otherwise there will be multiple copies of the static data members in the program, and that’s really really bad.

    +
    +
    +

    Historical note: on 16-bit Windows you really did have to export all dependencies or the code wouldn’t work, however since the latest Visual Studio .NET supports the import/export of individual member functions, it’s a reasonably safe bet that Windows compilers won’t do anything nasty - like changing the class’s ABI - when importing/exporting a class.

    +
    +
    +

    Rationale

    +
    +

    Why bother - doesn’t the import/export mechanism take up more code that the classes themselves?

    +
    +
    +

    A good point, and probably true, however there are some circumstances where library code must be placed in a shared library - for example when the application consists of multiple dll’s as well as the executable, and more than one those dll’s link to the same Boost library - in this case if the library isn’t dynamically linked and it contains any global data (even if that data is private to the internals of the library) then really bad things can happen - even without global data, we will still get a code bloating effect. Incidentally, for larger applications, splitting the application into multiple dll’s can be highly advantageous - by using Microsoft’s "delay load" feature the application will load only those parts it really needs at any one time, giving the impression of a much more responsive and faster-loading application.

    +
    +
    +

    Why static linking by default?

    +
    +
    +

    In the worked example above, the code assumes that the library will be statically linked unless the user asks otherwise. Most users seem to prefer this (there are no separate dll’s to distribute, and the overall distribution size is often significantly smaller this way as well: i.e. you pay for what you use and no more), but this is a subjective call, and some libraries may even only be available in dynamic versions (Boost.Thread for example).

    +
    +
    +
    +
    +
    +

    Automatic Library

    +
    +
    +

    This section describes selection and linking with auto_link.hpp (find this file in the boost/config folder after installation).

    +
    +
    +

    Many Windows compilers ship with multiple runtime libraries - for example Microsoft Visual Studio .NET comes with 6 versions of the C and C++ runtime. It is essential that the Boost library that the user links to is built against the same C runtime as the program is built against. If that is not the case, then the user will experience linker errors at best, and runtime crashes at worst. The Boost build system manages this by providing different build variants, each of which is build against a different runtime, and gets a slightly different mangled name depending upon which runtime it is built against. For example the regex libraries get named as follows when built with Visual Studio .NET 2003:

    +
    +
    +
    +
    boost_regex-vc71-mt-1_31.lib
    +boost_regex-vc71-mt-gd-1_31.lib
    +libboost_regex-vc71-mt-1_31.lib
    +libboost_regex-vc71-mt-gd-1_31.lib
    +libboost_regex-vc71-mt-s-1_31.lib
    +libboost_regex-vc71-mt-sgd-1_31.lib
    +libboost_regex-vc71-s-1_31.lib
    +libboost_regex-vc71-sgd-1_31.lib
    +
    +
    +
    +

    The difficulty now is selecting which of these the user should link his or her code to.

    +
    +
    +

    In contrast, most Unix compilers typically only have one runtime (or sometimes two if there is a separate thread safe option). For these systems the only choice in selecting the right library variant is whether they want debugging info, and possibly thread safety.

    +
    +
    +

    Historically Microsoft Windows compilers have managed this issue by providing a #pragma option that allows the header for a library to automatically select the library to link to. This makes everything automatic and extremely easy for the end user: as soon as they include a header file that has separate source code, the name of the right library build variant gets embedded in the object file, and as long as that library is in the linker search path, it will get pulled in by the linker without any user intervention.

    +
    +
    +

    Automatic library selection and linking can be enabled for a Boost library by including the header <boost/config/auto_link.hpp>, after first defining BOOST_LIB_NAME and, if applicable, BOOST_DYN_LINK.

    +
    +
    +
    +
    //
    +// Automatically link to the correct build variant where possible.
    +//
    +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_WHATEVER_NO_LIB) && !defined(BOOST_WHATEVER_SOURCE)
    +//
    +// Set the name of our library, this will get undef'ed by auto_link.hpp
    +// once it's done with it:
    +//
    +#define BOOST_LIB_NAME boost_whatever
    +//
    +// If we're importing code from a dll, then tell auto_link.hpp about it:
    +//
    +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
    +#  define BOOST_DYN_LINK
    +#endif
    +//
    +// And include the header that does the work:
    +//
    +#include <boost/config/auto_link.hpp>
    +#endif  // auto-linking disabled
    +
    +
    +
    +

    The library’s user documentation should note that the feature can be disabled by defining either BOOST_ALL_NO_LIB or BOOST_WHATEVER_NO_LIB:

    +
    +
    +

    If for any reason you need to debug this feature, the header <boost/config/auto_link.hpp> will output some helpful diagnostic messages if you first define BOOST_LIB_DIAGNOSTIC.

    +
    +
    +
    +
    +

    Changes Affecting the Build System

    +
    +
    +

    Creating the Library Jamfile

    +
    +

    The Jamfile for building library "whatever" typically lives in boost-root/libs/whatever/build, the only extra step required is to add a <define> requirement to the library target so that your code knows whether it’s building a dll or static library, a typical Jamfile would like like this:

    +
    +
    +
    +
    lib boost_regex : ../src/whatever.cpp :
    +  <link>shared:<define>BOOST_WHATEVER_DYN_LINK=1 ;
    +
    +
    +
    +
    +

    Auto-linking

    +
    +

    Testing the auto-link feature is somewhat convoluted, and requires access to a compiler that supports the feature: refer to the jamfile.v2 file for the type_traits library (in the libs\type_traits\test folder) for an example.

    +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/antora.html b/preview/contributor-guide/docs/antora.html new file mode 100644 index 0000000..07400a5 --- /dev/null +++ b/preview/contributor-guide/docs/antora.html @@ -0,0 +1,904 @@ + + + + + + + + + + + + + + Antora Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Antora Guide

    +
    +

    Antora

    +
    +
    +
    +
     https://antora.org/[Antora] is a static site generator designed for creating documentation sites from AsciiDoc content.
    +The tool renders the documentation for Boost modules whose documentation are defined as components in the Antora playbook.
    +
    +
    +
    +
    +
    +

    Installing Antora

    +
    +
    +

    Dependencies

    +
    +

    Antora requires Node.js:

    +
    +
    +
    +
    $ node -v
    +
    +
    +
    +

    This command should return the Node.js version number:

    +
    +
    +
    +
    v16.18.0
    +
    +
    +
    +

    Antora requires Node.js version 16 or later. +If you have Node.js installed but need to upgrade it:

    +
    +
    +
    +
    $ nvm install --lts
    +
    +
    +
    +

    The following instructions also require Git to clone the repository:

    +
    +
    +
    +
    $ git --version
    +
    +
    +
    +

    This command should return the Git version number:

    +
    +
    +
    +
    git version 2.25.1
    +
    +
    +
    +
    +

    Cloning the repository

    +
    +

    To clone the repository that defines the Antora playbook for the Boost documentation:

    +
    +
    +
    +
    $ git clone https://www.github.com/boostorg/website-v2-docs
    +
    +
    +
    +

    This command clones the repository into a directory named website-v2-docs. +This directory contains the Antora playbook files site.playbook.yml (website documentation) and libs.playbook.yml (library documentation).

    +
    +
    +
    +

    Running Antora

    +
    +

    After cloning the project, you need to install its dependencies using the Node.js package manager, npm:

    +
    +
    +
    +
    $ npm ci
    +
    +
    +
    +

    Then build the Antora UI bundle used for the documentation:

    +
    +
    +
    +
    $ cd antora-ui
    +$ npx gulp
    +$ cd ..
    +
    +
    +
    +

    The npx command, which comes with npm, can be used to build any of the playbooks in the repository.

    +
    +
    +
    +
    $ npx antora --fetch libs.playbook.yml
    +
    +
    +
    +

    Or to build the website documentation:

    +
    +
    +
    +
    $ npx antora --fetch site.playbook.yml
    +
    +
    +
    +

    This commands will build the documentation in the build/ directory.

    +
    +
    +

    npx will download the Antora CLI and the Antora site generator, and then run the antora command with the specified playbook. +These dependencies are cached locally, so the next time you run npx antora, it will be faster.

    +
    +
    +

    In the release process, Antora is called with extra attributes used by the documentation components. +For instance:

    +
    +
    +
    +
    $ npx antora --fetch --attribute page-boost-branch=master --attribute page-boost-ui-branch=master --attribute page-commit-id=151c2ac libs.playbook.yml
    +
    +
    +
    + + + + + +
    + + +
    +

    Instead of using the Antora versioning control system, we render the documentation for a single version by setting version: ~ in the antora.yml file. +The --attribute options let us render the playbook for a single documentation version with context about the current version.

    +
    +
    +
    +
    +

    The libdoc.sh script simplifies the process by building the UI bundle, identifying these attributes, and running the Antora command with the specified playbook.

    +
    +
    +
    +
    $ ./libdoc.sh master
    +
    +
    +
    +

    Or to build the website documentation:

    +
    +
    +
    +
    $ ./sitedoc.sh master
    +
    +
    +
    +
    +
    Site generation complete!
    +Open file:///home/user/path/to/antora/build/master/doc in a browser to view your site.
    +Site generation complete!
    +Open file:///home/user/path/to/antora/build/doc in a browser to view your site.
    +
    +
    +
    +

    The build.sh script identifies the branch of the current repository and runs the sitedoc.sh script with the branch name as an argument:

    +
    +
    +
    +
    $ ./build.sh
    +
    +
    +
    +

    Although not necessary, you also have the option of installing Antora globally so that the antora command is available on your PATH.

    +
    +
    +
    +
    $ npm i -g @antora/cli @antora/site-generator
    +
    +
    +
    +
    +
    $ antora -v
    +
    +
    +
    +

    Read more about antora on their Quickstart guide.

    +
    +
    +
    +
    +
    +

    Playbook Components

    +
    +
    +

    The website is composed of components defined in the content.sources field of its playbook file +site.playbook.yml. +All components of the website are relative to the website-v2-docs repository.

    +
    +
    +

    The process for generating the documentation for all libraries is similar. +However, the components are defined in the libs.playbook.yml file and their URLs are relative to the boostorg organization. +Each library documentation is defined as a component in the playbook file libs.playbook.yml:

    +
    +
    +
    +
    content:
    +  sources:
    +    - url: https://github.com/boostorg/url
    +      start_path: doc
    +  # ...
    +
    +
    +
    +

    The complete libdoc.sh command syntax is:

    +
    +
    +
    +
    Usage: ./libdoc.sh { branch | version | 'release' | 'all' }...
    +
    +    branch : 'develop' | 'master' | 'release'
    +    version: [0-9]+ '.' [0-9]+ '.' [0-9]+
    +    'release': builds master to build/doc/html
    +    'all': rebuilds develop, master, and every version
    +
    +Examples:
    +
    +    ./libdoc.sh develop master      # build develop and master
    +    ./libdoc.sh 1.83.0              # build tagged version boost-1.83.0
    +
    +
    +
    +

    The first positional argument is the only parameter, which identifies which version should be built.

    +
    +
    +
      +
    • +

      branch: valid arguments are master or develop. +Builds the master or develop versions of the documentation in build/master/libs or build/develop/libs. +It checks out all libraries in their master or develop branches.

      +
    • +
    • +

      version: a semver version, such as 1.82.0 describing a Boost version. +This allows us to generate the documentation content of an old Boost version with the current version of the Antora UI.

      +
    • +
    • +

      'release': generate the master version to build/doc/html with the release UI layout. +This layout omits the header, Google analytics, and Edit this Page. +This version of the documentation is meant to be distributed with sources files in the Boost release.

      +
    • +
    • +

      'all': retroactively iterate and generate the documentation for all versions of Boost +with the most recent Antora UI. This command iterates each playbook in the history directory.

      +
    • +
    +
    +
    +

    The master/develop branches of the library documentation are designed to co-exist alongside the per-release documentation and thus the branch name (or release version) does appear in its URLs.

    +
    +
    +
    +
    +

    Component Layout

    +
    +
    +

    Each Antora-enabled library includes the component version descriptor file doc/antora.yml. +Each library should contain an antora.yml describing the component. +For instance,

    +
    +
    +
    +
    name: mp11
    +title: Boost.Mp11
    +version: ~
    +nav:
    +  - modules/ROOT/nav.adoc
    +
    +
    +
    +

    After defining the doc/antora.yml file, the source files should be organized in the modules directory. +Typically, doc/modules/ROOT/nav.adoc is the main navigation file for the library documentation and doc/modules/ROOT/pages/index.adoc is the main page. +You can find more information about the Component Version Descriptor and Pages in the Antora documentation.

    +
    +
    +

    Once these files are in place, the library can be registered as a component in the libs.playbook.yml file with a Pull Request to the website-v2-docs repository:

    +
    +
    +
    +
    content:
    +  sources:
    +  # ...
    +    - <library-name>: https://github.com/boostorg/<library-name>
    +      start_path: doc
    +
    +
    +
    +
    +
    +

    Local playbooks

    +
    +
    +

    When working locally on an individual component, it’s usually desirable to create a local playbook for your project so that you can render the documentation locally for a single component. +The local playbook is a copy of the main playbook that removes all components except the one you are working on.

    +
    +
    +

    For instance, you can create a copy of libs.playbook.yml as doc/local-playbook.yml, remove all components except the one you are working on, and adjust the component URL to point to your local filesystem:

    +
    +
    +
    +
    # ...
    +content:
    +  sources:
    +    - url: ..
    +      start_path: doc
    +      edit_url: 'https://github.com/boostorg/<library-name>/edit/{refname}/{path}'
    +# ...
    +
    +
    +
    +

    This way, you can render the documentation locally for your component without having to render the entire Boost documentation:

    +
    +
    +
    +
    $ npx antora --fetch local-playbook.yml
    +
    +
    +
    +

    When writing a Boost library proposal, include your library in this local playbook.

    +
    +
    +
    +
    +

    Antora Extensions

    +
    +
    +

    Antora supports extensions that can be used to augment the functionality of the generator. +The playbooks in the website-v2-docs repository include a number of extensions that are available to all components.

    +
    +
    +

    C++ Tagfiles Extension

    +
    +

    The @cppalliance/antora-cpp-tagfiles-extension extension allows components to include links to C++ symbols defined in the library or external libraries.

    +
    +
    +

    For instance, std::string will generate a link to the std::string symbol in the documentation. +Note that after the cpp: prefix from custom inline macros, the syntax is similar to the one used to generate regular links in AsciiDoc, where the link is replaced by the symbol name.

    +
    +
    +

    The link for each symbol is generated from a tagfile provided by the main playbook or by the extension. +The playbook can define tagfiles for other libraries by including the cpp-tagfiles field in the extension configuration:

    +
    +
    +
    +
    antora:
    +  extensions:
    +    # ...
    +    - require: '@cppalliance/antora-cpp-tagfiles-extension'
    +      cpp-tagfiles:
    +        files:
    +          - file: ./doc/tagfiles/boost-url-doxygen.tag.xml
    +            base_url: 'xref:reference:'
    +          - file: ./doc/tagfiles/boost-system-doxygen.tag.xml
    +            base_url: https://www.boost.org/doc/libs/master/libs/system/doc/html/
    +        using-namespaces:
    +          - 'boost::'
    +    # ...
    +
    +
    +
    +

    Note that the files field is a list of tagfiles that are used to generate links to symbols in the documentation. +These tagfiles can be generated by other tools like Doxygen or MrDocs. +In some cases, users might want to write their own tagfiles to include symbols from other libraries. +As tagfiles only describe relative links to symbols, the base_url field is used to generate the full URL to the symbol.

    +
    +
    +

    Also note the using-namespaces field, which is a list of namespaces that are used to generate links to symbols in the documentation. +In the example above, small_vector will generate a link to the boost::small_vector symbol in the documentation unless there’s a tagfile that defines a symbol with the same name in the global namespace.

    +
    +
    +

    Each component can also define its own tagfiles by including the cpp-tagfiles field in the component descriptor file:

    +
    +
    +
    +
    ext:
    +  cpp-tagfiles:
    +      files:
    +        - file: ./doc/tagfiles/boost-url-doxygen.tag.xml
    +          base_url: 'xref:reference:'
    +        - file: ./doc/tagfiles/boost-system-doxygen.tag.xml
    +          base_url: https://www.boost.org/doc/libs/master/libs/system/doc/html/
    +        - file: ./doc/tagfiles/boost-core-doxygen.tag.xml
    +          base_url: https://www.boost.org/doc/libs/master/libs/core/doc/html/
    +        - file: ./doc/tagfiles/boost-filesystem-doxygen.tag.xml
    +          base_url: https://www.boost.org/doc/libs/master/libs/filesystem/doc/
    +      using-namespaces:
    +        - boost::urls
    +        - boost::urls::grammar
    +        - boost::system
    +        - boost::core
    +
    +
    +
    +

    Files and namespaces defined in components are only applied to that component.

    +
    +
    +

    More information about the extension can be found in its repository and issues should be reported in its issue tracker.

    +
    +
    +
    +

    C++ Reference Extension

    +
    +

    The @cppalliance/antora-cpp-reference-extension extension generates reference documentation for C++ symbols in your codebase and creates an Antora module with its pages. +The asciidoc documentation pages are generated with MrDocs and populated in the reference Antora module.

    +
    +
    +

    This means, the generated reference pages can be linked in your doc/modules/ROOT/nav.adoc file as:

    +
    +
    +
    +
    // ...
    +* Reference
    +** xref:reference:index.adoc[]
    +// ...
    +
    +
    +
    +

    To enable the extension for your component, include the extension configuration in the antora.yml file:

    +
    +
    +
    +
    # ...
    +ext:
    +  cpp-reference:
    +    config: doc/mrdocs.yml
    +# ...
    +
    +
    +
    +

    The mrdocs.yml file will typically include parameters to generate a compile_commands.json file used to generate the reference documentation. +For more information about MrDocs and configuration files, see https://www.mrdocs.com/docs.

    +
    +
    +

    The process to generate compile_commands.json typically depends on third-party libraries used to compile the project. +In the case of Boost libraries, other Boost libraries should be available to the command that generates the compile_commands.json file. +The dependencies available to components are defined in the libs.playbook.yml file.

    +
    +
    +
    +
    antora:
    +  extensions:
    +    - require: '@cppalliance/antora-cpp-reference-extension'
    +      dependencies:
    +        - name: 'boost'
    +          repo: 'https://github.com/boostorg/boost.git'
    +          tag: 'develop'
    +          variable: 'BOOST_SRC_DIR'
    +          system-env: 'BOOST_SRC_DIR'
    +
    +
    +
    +

    The extension will download each dependency defined in this list and expose it to the MrDocs environment via the environment variable defined in variable. +If the library is already available in the system, the system-env field can be used to expose it to Antora, so it uses this existing path instead of downloading the library.

    +
    +
    +

    More information about the extension can be found in its repository and issues should be reported in its issue tracker.

    +
    +
    +
    + +
    +

    The @cppalliance/asciidoctor-boost-links extension allows component pages to include links to Boost libraries and tools. +For instance:

    +
    +
    +
    +
    boost:core[]
    +
    +
    +
    +

    This will render as if the equivalent AsciiDoc code was used:

    +
    +
    +
    +
    https://www.boost.org/libs/core[Boost.Core]
    +
    +
    +
    +

    When processed by Asciidoc, this renders as "Boost.Core":

    +
    +
    +
    +
    <a href="https://www.boost.org/libs/core">Boost.Core</a>
    +
    +
    +
    +

    The extension supports Boost libraries and tools. +When no custom text is provided, the extension will use the library name in PascalCase as the link text. +When a Boost author has a preference for a different default link text, these are implemented directly in the extension.

    +
    +
    +

    More information about the extension can be found in its repository and issues should be reported in its issue tracker.

    +
    +
    +
    +

    Playbook Macros Extension

    +
    +

    The @cppalliance/antora-playbook-macros-extension extension allows playbooks to include macros that can be used to generate content in the playbook. +Each macro has a default value that can be overridden with environment variables, the Antora --attribute command line option, or directly in the playbook with the asciidoc.attributes field.

    +
    +
    +

    The macro is used to implement the branch functionality described in section Running Antora. +More information about the extension can be found in its repository and issues should be reported in its issue tracker.

    +
    +
    +
    +
    +
    +

    Antora UI Bundle

    +
    +
    +

    Each Antora playbook includes a UI bundle that defines the layout of the documentation.

    +
    +
    +
    +
    ui:
    +  bundle:
    +    url: ./antora-ui/build/ui-bundle.zip
    +    snapshot: true
    +
    +
    +
    +

    This provides a consistent layout across all components of the playbook.

    +
    +
    +

    The source code for the UI bundle is located in the antora-ui directory of the repository.

    +
    +
    +

    The bundle includes a few options to customize the Boost UI by setting the following options in the main playbook:

    +
    +
    +
    +
    asciidoc:
    +  attributes:
    +    # Enable pagination
    +    page-pagination: ''
    +    # Remove the sidenav and include TOC in index.adoc page
    +    remove-sidenav: ''
    +    # Include the contents panel with the TOC for the current page
    +    page-toc: ''
    +
    +
    +
    +

    By default, all options are disabled. +Setting the options to any string (including the empty string) enables it. +This is a convention used by Antora to enable/disable options in bundles.

    +
    +
    +

    The settings defined in the playbook apply to all documentation components.

    +
    +
    +

    The UI bundle documentation is available in the antora-ui/README.adoc file. This file describes the structure of the UI bundle and how to customize it.

    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/asciidoc.html b/preview/contributor-guide/docs/asciidoc.html new file mode 100644 index 0000000..6298e49 --- /dev/null +++ b/preview/contributor-guide/docs/asciidoc.html @@ -0,0 +1,853 @@ + + + + + + + + + + + + + + AsciiDoc Style Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    AsciiDoc Style Guide

    +
    +
    +
    +

    This section describes the style of writing and formatting to use when contributing to Boost documentation.

    +
    +
    +
    +
    +

    Priorities

    +
    +
    +

    Our documentation priorities are:

    +
    +
    +
      +
    1. +

      Clarity first - clear and accurate.

      +
    2. +
    3. +

      Brevity next.

      +
    4. +
    5. +

      Consistency is good.

      +
    6. +
    7. +

      All else.

      +
    8. +
    +
    +
    +
    +
    +

    Mark Up

    +
    +
    +

    The mark up tool we are using is AsciiDoc. Throughout this topic examples of AsciiDoc format follow for each topic.

    +
    +
    +
    +
    +

    Headings

    +
    +
    +

    Headings are crucial elements to guide readers to find the information they’re looking for.

    +
    +
    +
      +
    1. +

      Title Case: Capitalize all the important words (not: to, and, a, at, with, etc.). In title case, conjunctions, articles, and prepositions typically remain in lowercase unless they’re the first or last word in the title. For example: "To Install a Boost Library" is title cased.

      +
    2. +
    3. +

      Top Level: Use only one top-level heading per page, as the first entry.

      +
    4. +
    5. +

      Engagement: Use active headings for procedures. For example "Install Boost" is active, "Boost Installation" is inactive.

      +
    6. +
    7. +

      Acronyms and Jargon: Do not use acronyms in headings. For example, do not use "Working with CI", instead use "Working with Continuous Integration", and then in the text "Continuous Integration (CI) means …​.". Avoid jargon too, as it is notoriously confusing for a non-English-as-a-first-language reader.

      +
    8. +
    9. +

      Clarity: Avoid vague or generic headings.

      +
    10. +
    11. +

      Avoid Overuse: Too many levels of headings can confuse your readers. Try not to exceed four levels of headings.

      +
    12. +
    +
    +
    +

    AsciiDoc Headings

    +
    +

    The equals sign is used to determine the heading level.

    +
    +
    +
    +
    = Top Level
    +== Second Level
    +=== Third Level
    +==== Fourth Level
    +
    +
    +
    +
    +
    +
    +

    Text

    +
    +
    +

    The main priorities of brevity and clarity apply as top priority to all text. Avoid jargon altogether, and spell out acronyms on first use.

    +
    +
    +
      +
    1. +

      Active Voice: Use the active voice as much as possible. It’s generally more direct and easier to understand than the passive voice.

      +
    2. +
    3. +

      Logical Flow: Ensure there’s a logical flow from one paragraph to the next. Each paragraph should build on the previous one, adding new information or further detail.

      +
    4. +
    5. +

      Use Contractions: Contractions make for a chattier and easier to read style. For example, use "doesn’t" instead of "does not", or "would’ve" instead of "would have".

      +
    6. +
    7. +

      Avoid Walls of Text: Break up large text blocks with images, lists, diagrams where appropriate.

      +
    8. +
    9. +

      Avoid Duplication: Sometimes duplication is necessary, for example within a tutorial to keep the flow within the tutorial itself. Otherwise, avoid duplication whenever possible, and simply link to one source of truth.

      +
    10. +
    +
    +
    +
    +
    Text in AsciiDoc is entered as is. Be sure to leave a blank line between paragraphs.
    +
    +Next paragraph.
    +
    +
    +
    +

    Project References

    +
    +

    When writing about the Boost libraries for this website, library documentation or manuals, blog posts, social media, and any official communications - take the following guidelines as pertinent:

    +
    +
    +
      +
    1. +

      The name of the project as a whole is the "Boost C++ Libraries", noting that "the" is not part of the project name, and that "libraries" is plural.

      +
    2. +
    3. +

      After first use of the full project name, avoid over-use of the word "Boost" in following paragraphs. Subsequent references to the project can select from terms such as "project", "libraries", and "collection", as determined by context. It is acceptable to use the single word "Boost" if it is needed for clarity (such as when comparing library collections).

      +
    4. +
    5. +

      Avoid the use of the word "Boost" in section or topic headings, especially those that will appear in the table of contents.

      +
    6. +
    +
    +
    +
    +
    +
    +

    Pages

    +
    +
    +

    Generally avoid the off-putting user-experience of over-long pages.

    +
    +
    +
      +
    1. +

      Landing Page: A landing page is best kept fairly short, say around 500 words, though clarity is the top priority.

      +
    2. +
    3. +

      Information Pages: For Search Engine Optimization (SEO) a length of 1500 to 2000 words per page works well. Avoid over-long pages - split them logically with a clear heading for each section.

      +
    4. +
    +
    +
    +
    +
    +

    Operating Systems and Tools

    +
    +
    +

    We assume the users of Boost are using Windows, macOS, or Linux based systems. Examples of installation and running code examples should be provided for each of these three systems. There are many variants of Linux, and providing examples for the most popular variants is encouraged.

    +
    +
    +

    Popular Windows tools are Microsoft Visual C++, Visual Studio Code, and GCC (MinGW or Cygwin). On macOS, Clang is a popular compiler, and on Linux Cmake, GCC and Clang are popular.

    +
    +
    +

    The recommendation for Boost examples is to use a popular tool in the various steps and processes, but not to recommend one tool over any other. And to mention other tools that we know work well with Boost.

    +
    +
    +

    It is important that processes in our documentation work, so it will be necessary to state which tool you are using when creating working examples.

    +
    +
    +
    +
    +

    Code Snippets

    +
    +
    +

    Our code snippets include C++ examples on using libraries, but also Command Prompt entries on installing and building, and other text commands.

    +
    +
    +
      +
    1. +

      Accuracy: Remember that code snippets are going to be copied and pasted by users, who are going to (rightly or wrongly) assume that the code conforms to best practices.

      +
    2. +
    3. +

      Simplicity: The code snippet should be as simple as possible. Avoid complex or confusing code structures, as they can distract from the point you’re trying to make.

      +
    4. +
    5. +

      Commenting: Include comments in your code to explain what’s happening. This can help readers understand the code, especially if it’s complex or non-obvious.

      +
    6. +
    7. +

      Consistency: Be consistent in your coding style throughout your documentation. This includes things like indentation, naming conventions, comments, and the use of spaces or tabs.

      +
    8. +
    9. +

      Context: Provide enough context around the code snippet. Explain what the code does and how it relates to the text.

      +
    10. +
    11. +

      Complete: If a code snippet is intended to be run by the reader, make sure it includes all necessary parts to actually run.

      +
    12. +
    13. +

      Versioning: Indicate the version of the programming language, library or framework that the code snippet is intended for. This can help prevent confusion or issues with running the code.

      +
    14. +
    +
    +
    +

    Asciidoc Code Snippet

    +
    +

    To include a snippet of source code like the following, precede it with [source, cpp] on one line, followed by ----, then the code itself, and finish it with a second ----, again on its own line.

    +
    +
    +
    +
    #include <boost/lambda/lambda.hpp>
    +#include <iostream>
    +#include <iterator>
    +#include <algorithm>
    +
    +int main()
    +{
    +    using namespace boost::lambda;
    +    typedef std::istream_iterator<int> in;
    +
    +    std::for_each(
    +        in(std::cin), in(), std::cout << (_1 * 3) << " ");
    +}
    +
    +
    +
    +
    +
    +
    +

    Lists

    +
    +
    +

    Whether ordered (with numbers), or unordered (with bullets), these are the general best practices for all lists:

    +
    +
    +
      +
    1. +

      Parallelism: Start each point with the same part of speech (noun, verb, etc.) to keep the list parallel. This makes the list easier to read and understand.

      +
    2. +
    3. +

      Punctuation: If your points are not complete sentences, they typically do not need to be punctuated. If the points are complete sentences or if each point is a distinct idea that forms a multi-sentence paragraph, use proper punctuation.

      +
    4. +
    5. +

      Length: Keep your points concise. If a point is running longer than two lines, consider breaking it down further.

      +
    6. +
    7. +

      Introduction: Always introduce a list with a lead-in sentence or phrase.

      +
    8. +
    +
    +
    +

    Numbered Lists

    +
    +

    Numbered lists are best used when describing a process, a sequence of steps, or priorities.

    +
    +
    +

    If the sequence or order of points does not matter, use a Bulleted Lists instead. If the sequence matters, use a numbered list (sometimes called "ordered lists").

    +
    +
    +

    AsciiDoc Numbered Lists

    +
    +

    Numbered list entries start with a period (.). There is no need to enter any numbers, the renderer will work them out correctly. Be sure to leave a blank line before and after a list.

    +
    +
    +
    +
    Introductory sentence.
    +
    +. point A
    +. point B
    +.. Point B.1
    +.. Point B.2
    +. Point C
    +. Point D
    +
    +
    +
    +

    Introductory sentence.

    +
    +
    +
      +
    1. +

      point A

      +
    2. +
    3. +

      point B

      +
      +
        +
      1. +

        Point B.1

        +
      2. +
      3. +

        Point B.2

        +
      4. +
      +
      +
    4. +
    5. +

      Point C

      +
    6. +
    7. +

      Point D

      +
    8. +
    +
    +
    +
    +
    +

    Bulleted Lists

    +
    +

    If the sequence or order of points matters, use a Numbered Lists instead. If the sequence doesn’t matter, use a bulleted list (sometimes called "unordered" lists).

    +
    +
    +
      +
    1. +

      Order: Arrange your bullet points logically. This could be in order of importance, chronologically, or in some other meaningful way for the reader.

      +
    2. +
    3. +

      Avoid Overuse: Bulleted lists are most effective when used sparingly. Too many lists can make your document hard to read.

      +
    4. +
    +
    +
    +

    AsciiDoc Bulleted Lists

    +
    +

    Note the [disc] entry determining the symbol. Alternatives are [square] and [circle]. Be sure to leave a blank line before and after a list.

    +
    +
    +
    +
    Introductory sentence.
    +
    +[disc]
    +* point A
    +* point B
    +** Point B.1
    +** Point B.2
    +
    +[circle]
    +* Point C
    +* Point D
    +
    +
    +
    +

    Introductory sentence.

    +
    +
    +
      +
    • +

      point A

      +
    • +
    • +

      point B

      +
      +
        +
      • +

        Point B.1

        +
      • +
      • +

        Point B.2

        +
      • +
      +
      +
    • +
    +
    +
    +
      +
    • +

      Point C

      +
    • +
    • +

      Point D

      +
    • +
    +
    +
    +
    +
    +
    +
    +

    Tables

    +
    +
    +

    If content naturally falls into a row/column format, then encapsulate as a table.

    +
    +
    +
      +
    1. +

      Title: Every table should have a clear, concise title that describes its content and purpose.

      +
    2. +
    3. +

      Headers: Use headers for each column to indicate what information is contained in that column.

      +
    4. +
    5. +

      Consistency: Maintain consistent formatting and structure across all tables in a document to enhance readability and avoid confusion.

      +
    6. +
    7. +

      Simplicity: Keep the table as simple as possible. Avoid unnecessary columns or rows, and ensure that the data presented is relevant and necessary.

      +
    8. +
    9. +

      Size: The table should fit the page size. If the table is too large, consider breaking it down into several smaller tables.

      +
    10. +
    11. +

      Striping: If your table has many rows, consider using striping (alternating row colors) to make it easier to follow across large tables.

      +
    12. +
    13. +

      Units: If your table includes measures, ensure to specify the units.

      +
    14. +
    15. +

      Notes and References: If necessary, include footnotes or references right below the table for any clarifications.

      +
    16. +
    17. +

      Data Order: Consider the most logical order to present your data. This could be alphabetical, numerical, chronological, or in order of importance.

      +
    18. +
    +
    +
    +

    AsciiDoc Tables

    +
    +

    The following example asciidoc source would produce the table shown below. Note the relative column widths (1 and 2). This means the first column uses 1/3rd of the width available, and the second column 2/3rds of the width. Also, a header row is required, and zebra striping. Be sure to leave a blank line before and after a table.

    +
    +
    +
    +
    [cols="1,2",options="header",stripes=even,frame=none]
    +|===
    +| *Head1*  | *Head2*
    +| row1 | text
    +| row2 | text
    +|===
    +
    +
    + ++++ + + + + + + + + + + + + + + + + +
    Head1Head2

    row1

    text

    row2

    text

    +
    +
    +
    +
    +

    Images

    +
    +
    +

    Images work well in tutorials, and other process-style documentation, where the reader can find visual confirmation that they have followed the correct procedure.

    +
    +
    +
      +
    1. +

      Relevance: Ensure the images used are relevant and directly aid in understanding the content. Avoid using images as mere decorations or fillers. Don’t overload diagrams or images with too much information. They should aid understanding, not create confusion.

      +
    2. +
    3. +

      Quality: Images should be of high quality. They should be clear and easy to read/understand, even when printed.

      +
    4. +
    5. +

      Referencing: Always reference images in the text. This not only directs the reader’s attention to the image but also clarifies what the image is meant to illustrate.

      +
    6. +
    7. +

      Accessibility: Ensure images are accessible for people with visual impairments. This can include providing alt text for online documents, and detailed captions for printed documents. Be aware that color choices can have an impact on readability, especially for people with color blindness.

      +
    8. +
    9. +

      Consistency: Try to maintain a consistent style, quality, and appearance for all images throughout the document.

      +
    10. +
    11. +

      File Type and Compression: Use the correct file type for your images. JPEGs are best for photographs, while PNGs are better for screenshots, SVGs for logos and diagrams. Also, be aware of file size - compress images if they are large, but ensure this doesn’t compromise quality.

      +
    12. +
    13. +

      Copyright: Only use images that you have the right to use. Always attribute images correctly according to the terms of the license.

      +
    14. +
    +
    +
    +

    AsciiDoc Images

    +
    +

    Place the image in the images folder, then add the following link in the file. Add an appropriate caption, and alt-text to describe the image to the visually impaired.

    +
    +
    +
    +
    image::filename.png[caption="Figure 1: caption", alt="alternate text"]
    +
    +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/components.html b/preview/contributor-guide/docs/components.html new file mode 100644 index 0000000..6f85f9b --- /dev/null +++ b/preview/contributor-guide/docs/components.html @@ -0,0 +1,778 @@ + + + + + + + + + + + + + + Documentation Components :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Documentation Components

    +
    +

    Introduction

    +
    +
    +

    Boost does not require any specific documentation structure. However, +there are some important considerations that influence content and +structure. For example, many Boost libraries wind up being proposed for +inclusion in the C++ Standard, so writing them initially with text +suitable for inclusion in the Standard may be helpful.

    +
    +
    +

    Also, Boost library documentation is often accessed via the World Wide Web, including via search engines, so context is often important for every page.

    +
    +
    +

    Finally, Boost libraries should provide additional documentation, +such as introductory, tutorial, example, and rationale content. With +those things in mind, we suggest the following guidelines for Boost +library documentation.

    +
    +
    +
    +
    +

    Conforming to Standards

    +
    +
    +

    The documentation structure required for the C++ Standard is an +effective way to describe the technical specifications for a library. +Although terse, that format is familiar to many Boost users and is far +more precise than most ad hoc formats. The following description is +based upon §17.3 of the Standard. (Note that while final Standard +proposals must include full standard-ese wording, which the committee +will not do for you, that level of detail is not expected of Boost +library documentation.)

    +
    +
    +

    Document Elements

    +
    +

    Each document contains the following elements, as +applicable. (1):

    +
    + +
    +

    Summary

    +
    +

    The Summary provides a synopsis of the category, and introduces the +first-level subclauses. Each subclause also provides a summary, listing the headers specified in the subclause and the library entities provided in each header.

    +
    +
    +

    Paragraphs labeled "Note(s):" or "Example(s):" are informative, other +paragraphs are normative.

    +
    +
    +

    The summary and the detailed specifications are presented in the order:

    +
    +
    +
      +
    • +

      Macros

      +
    • +
    • +

      Values

      +
    • +
    • +

      Types

      +
    • +
    • +

      Classes

      +
    • +
    • +

      Functions

      +
    • +
    • +

      Objects

      +
    • +
    +
    +
    +
    +

    Requirements

    +
    +

    The library can be extended by a C++ program. Each clause, as +applicable, describes the requirements that such extensions must meet. +Such extensions are generally one of the following:

    +
    +
    +
      +
    • +

      Template arguments

      +
    • +
    • +

      Derived classes

      +
    • +
    • +

      Containers, iterators, and/or algorithms that meet an interface +convention

      +
    • +
    +
    +
    +

    Interface convention requirements are stated as generally as possible. +For example, instead of stating " class X has to define a member function operator++() ", say " the interface requires for any object x of class X, ++x is defined" (noting that whether the operator is a member or not is unspecified).

    +
    +
    +

    Requirements are stated in terms of well-defined expressions, which +define valid terms of the types that satisfy the requirements. For every set of requirements there is a table that specifies an initial set of +the valid expressions and their semantics. Any generic algorithm that +uses the requirements is described in terms of the valid expressions for its formal type parameters.

    +
    +
    +

    Template argument requirements are sometimes referenced by name.

    +
    +
    +

    In some cases the semantic requirements are presented as C++ code. Such +code is intended as a specification of equivalence of a construct to +another construct, not necessarily as the way the construct must be +implemented.(2)

    +
    +
    +
    +

    Detailed Specifications

    +
    +

    The detailed specifications each contain the following elements:

    +
    +
    +
      +
    • +

      Name and brief description

      +
    • +
    • +

      Synopsis (class definition or function prototype, as appropriate)

      +
    • +
    • +

      Restrictions on template arguments, if any

      +
    • +
    • +

      Description of class invariants

      +
    • +
    • +

      Description of function semantics

      +
    • +
    +
    +
    +

    Descriptions of class member functions follow the order (as +appropriate) (3):

    +
    +
    +
      +
    • +

      Constructor(s) and destructor

      +
    • +
    • +

      Copying and assignment functions

      +
    • +
    • +

      Comparison functions

      +
    • +
    • +

      Modifier functions

      +
    • +
    • +

      Observer functions

      +
    • +
    • +

      Operators and other non-member functions

      +
    • +
    +
    +
    +

    Descriptions of function semantics contain the following +elements (as appropriate) (4):

    +
    +
    +
      +
    • +

      Requires: the preconditions for calling the function

      +
    • +
    • +

      Effects: the actions performed by the function

      +
    • +
    • +

      Post-conditions": the observable results established by the function

      +
    • +
    • +

      Returns: a description of the value(s) returned by the function

      +
    • +
    • +

      Throws: any exceptions thrown by the function, and the conditions that would cause the exception

      +
    • +
    • +

      Complexity: the time and/or space complexity of the function

      +
    • +
    • +

      Rationale: the rationale for the function’s design or existence

      +
    • +
    +
    +
    +

    Complexity requirements specified in the library clauses are upper bounds, and implementations that provide better complexity guarantees satisfy the requirements.

    +
    +
    +
    +

    References to the C++ Standard Library

    + +
    +
    +

    References to the C Standard Library

    + +
    +
    +
    +

    Other Conventions

    +
    +

    These conventions are for describing implementation-defined types, and member functions.

    +
    +
    +

    Type Descriptions

    +
    +

    The Requirements subclauses may describe names that are used to specify constraints on template arguments.

    +
    +
    +
    +
    +
    +
    +

    More Information

    +
    +
    +

    Function Semantic Element Explanations

    +
    +

    The function semantic element description above is taken directly from the C++ standard, and is quite terse. Here is a +more detailed explanation of each of the elements.

    +
    +
    +

    Note the use of the <code> …​ </code> font tag to distinguish actual C++ usage from English prose.

    +
    +
    +

    Requires

    +
    +

    Preconditions for calling the function, typically expressed as predicates. The most common preconditions are requirements on the value of arguments, often in the form of C++ expressions. For example,

    +
    +
    +
    +
    void limit( int * p, int min, int max );
    +
    +
    +
    +

    Requires: p != 0 && min ⇐ max

    +
    +
    +

    Requirements already enforced by the C++ language rules (such as the +type of arguments) are not repeated in Requires paragraphs.

    +
    +
    +
    +

    Effects

    +
    +

    The actions performed by the function, described either in prose or in +C++. A description in prose is often less limiting on implementors, but +is often less precise than C++ code.

    +
    +
    +

    If an effect is specified in one of the other elements, particularly +post-conditions, returns, or throws, it is not also described in +the effects paragraph. Having only a single description ensures that +there is one and only one specification, and thus eliminates the risk of +divergence.

    +
    +
    +
    +

    Post-conditions

    +
    +

    The observable results of the function, such as the value of variables. +Post-conditions are often expressed as predicates that are true after the +function completes, in the form of C++ expressions. For example:

    +
    +
    +
    +
    void make_zero_if_negative( int & x );
    +
    +
    +
    +

    Post-condition: x >= 0

    +
    +
    +
    +

    Returns

    +
    +

    The value returned by the function, usually in the form of a C++ +expression. For example:

    +
    +
    +
    +
    int sum( int x, int y );
    +
    +
    +
    +

    Returns: x + y

    +
    +
    +

    Only specify the return value; the type is already dictated by C++ +language rules.

    +
    +
    +
    +

    Throws

    +
    +

    Specify both the type of exception thrown, and the condition that causes +the exception to be thrown. For example, the std::basic_string class +specifies:

    +
    +
    +
    +
    void resize(size_type n, charT c);
    +
    +
    +
    +

    Throws: length_error if n > max_size().

    +
    +
    +
    +

    Complexity

    +
    +

    Specifying the time and/or space complexity of a function is often not +desirable because it over-constrains implementors and is hard to specify +correctly. Complexity is thus often best left as a quality of +implementation issue.

    +
    +
    +

    A library component, however, can become effectively non-portable if +there is wide variation in performance between conforming +implementations. Containers are a prime example. In these cases it +becomes worthwhile to specify complexity.

    +
    +
    +

    Complexity is often specified in generalized +"Big-O" notation.

    +
    +
    +
    +

    Rationale

    +
    +

    Specifying the rationale for a function’s design or existence can often +give users a lot of insight into why a library is designed the way it +is. More importantly, it can help prevent "fixing" something that wasn’t +really broken as the library matures.

    +
    +
    +
    +
    +
    +
    +

    Web References

    +
    +
    +

    Boost library documentation is often accessed via the World Web. Using +search engines, a page deep in the reference content could be viewed +without any further context. Therefore, it is helpful to add extra +context, such as the following, to each page:

    +
    +
    +
      +
    • +

      Describe the enclosing namespace or use fully scoped identifiers.

      +
    • +
    • +

      Document required headers for each type or function.

      +
    • +
    • +

      Link to relevant tutorial information.

      +
    • +
    • +

      Link to related example code.

      +
    • +
    • +

      Include the library name.

      +
    • +
    • +

      Include navigation elements to the beginning of the documentation.

      +
    • +
    +
    +
    +

    It is also useful to consider the effectiveness of a description in +search engines. Terse or cryptic descriptions are less likely to help +the curious find a relevant function or type.

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) To save space, items that do not apply to +a clause are omitted. For example, if a clause does not specify any +requirements, there will be no "Requirements" subclause.

    +
    +
    +

    (2) Although in some cases the code is +unambiguously the optimum implementation.

    +
    +
    +

    (3) To save space, items that do not apply to +a class are omitted. For example, if a class does not specify any +comparison functions, there will be no "Comparison functions" subclause.

    +
    +
    +

    (4) To save space, items that do not apply to +a function are omitted. For example, if a function does not specify any +precondition, there will be no "Requires" paragraph.

    +
    +
    +
    +

    Revised April, 2023

    +
    +
    +

    Distributed under the Boost Software License, Version 1.0. Refer to http://www.boost.org/LICENSE_1_0.txt.

    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/content.html b/preview/contributor-guide/docs/content.html new file mode 100644 index 0000000..19c15ff --- /dev/null +++ b/preview/contributor-guide/docs/content.html @@ -0,0 +1,1060 @@ + + + + + + + + + + + + + + Documentation Content Structure :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Documentation Content Structure

    +
    +
    +
    +

    It is not a requirement for a Boost library for the documentation to adhere to the following structure. +However, it is listed here as a guide, if needed.

    +
    +
    +

    The following structure for Boost library documentation should work for most libraries. +Take each section in the order listed below, and fill in the details for your library. +Alternatively, if you want your documentation to be closer to the C++ Standard, refer to Documentation Components.

    +
    +
    +

    Although library documentation can use any format in +standalone documentation, the instructions on this page will use AsciiDoc as the format. +Visit AsciiDoc Syntax Quick Reference for more information on AsciiDoc syntax.

    +
    +
    +

    Where you see <LibraryName> in the templates below, replace with the name of your library.

    +
    +
    +
    +
    +

    Overview

    +
    +
    +

    Provide a brief overview of the focus and features of your library.

    +
    +
    +

    Mention the portability of the library, platforms and compilers. +List dependencies.

    +
    +
    +

    A developer should have a good idea if the library is right for their project, after reading your Overview.

    +
    +
    +

    Note that footnote references link to the footnotes section, and the entries in the footnote section link back to the references.

    +
    +
    +

    Overview Template

    +
    +
    +
    == Overview
    +
    +Add an introduction to your library here. Refer to previous libraries on the content of an Overview.
    +
    +== First Topic
    +
    +[#footnote1-location]
    +text
    +text that requires a footnote. link:#footnote1[(1)]
    +
    +== Second Topic
    +
    +[#footnote2-location]
    +text
    +text that requires a footnote. link:#footnote2[(2)]
    +
    +== Third Topic
    +
    +text
    +
    +== Footnotes
    +
    +[#footnote1]
    +link:#footnote1-location[(1)]: footnote 1 text
    +
    +[#footnote2]
    +link:#footnote2-location[(2)]: footnote 2 text
    +
    +
    +
    +
    +
    +
    +

    Design Rationale

    +
    +
    +

    A Rationale provides a description of the motivation behind the library. +Describe the current problems that exist, and the goals of the library in addressing those problems.

    +
    +
    +

    Rationale Template

    +
    +
    +
    == Introduction
    +
    +Add an introduction to the rationale for your library here. Refer to previous libraries on the content of a Rationale.
    +
    +== First Topic
    +
    +[#footnote1-location]
    +text
    +text that requires a footnote. link:#footnote1[(1)]
    +
    +== Second Topic
    +
    +[#footnote2-location]
    +text
    +text that requires a footnote. link:#footnote2[(2)]
    +
    +== Third Topic
    +
    +text
    +
    +
    +== Footnotes
    +
    +[#footnote1]
    +link:#footnote1-location[(1)]: footnote 1 text
    +
    +[#footnote2]
    +link:#footnote2-location[(2)]: footnote 2 text
    +
    +
    +
    +
    +
    +
    +

    Guide

    +
    +
    +

    The contents of the guide should be enough to get a new user up and running with your library.

    +
    +
    +

    Guide Template

    +
    +
    +
    == Guide to <LibraryName>
    +
    +Intro text
    +
    +=== Basic Tutorials and Examples
    +
    +Add simple tutorials and/or examples.
    +
    +=== How to Compile and Link
    +
    +text
    +
    +=== How to Test and Debug
    +
    +text
    +
    +
    +
    +
    +
    +
    +

    Reference

    +
    +
    +

    Provide a complete API reference to your library, without duplicating the contents of the Configuration or Definitions sections, which follow.

    +
    +
    +

    Reference Template

    +
    +
    +
    == Introduction
    +
    +Introductory text
    +
    +== Macros
    +
    +=== Macro1
    +
    +=== Macro2
    +
    +== Values
    +
    +=== Value1
    +
    +=== Value2
    +
    +== Types
    +
    +=== Type1
    +
    +=== Type2
    +
    +== Classes
    +
    +=== Class `class name`
    +
    +class overview text
    +
    +==== Class `class name` synopsis
    +
    +....
    +namespace boost
    +{
    +    class <class name>
    +        {
    +        };
    +};
    +....
    +
    +==== Class `class name` constructors and destructor
    +
    +....
    +constructor
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +....
    +destructor
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +==== Class `class name` comparison functions
    +
    +....
    +comparison-function
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +==== Class `class name` modifier functions
    +
    +....
    +modifier-function
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +==== Class `class name` observer functions
    +
    +....
    +observer-function
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +==== Class `class name` static functions
    +
    +....
    +static-function
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +== Functions
    +
    +....
    +function1
    +....
    +
    +*Requires:* text
    +
    +*Effects:* text
    +
    +*Post-conditions:* text
    +
    +*Returns:* text
    +
    +*Throws:* text
    +
    +*Complexity:* text
    +
    +*Note:* text
    +
    +*Danger:* text
    +
    +*Rationale:* text
    +
    +== Objects
    +
    +== Object specifications
    +
    +== Examples
    +
    +
    +
    +

    If your documentation is defined as an Antora component, the @cppalliance/antora-cpp-reference-extension extension can be used to generate the reference documentation from the source code. +Refer to Antora Guide for more details.

    +
    +
    +
    +
    +
    +

    Configuration

    +
    +
    +

    Describe the configuration macros that are used in your library.

    +
    +
    +

    Configuration Template

    +
    +
    +
    == `<LibraryName>`  Configuration
    +
    +== Introduction
    +
    +`<LibraryName>` uses several configuration macros in
    +http://www.boost.org/libs/config/config.htm[<boost/config.hpp>], as well as configuration macros meant to be supplied by the application. These macros are documented here.
    +
    +== Application Defined Macros
    +
    +These are the macros that may be defined by an application using `<LibraryName>`.
    +
    +[cols="1,2",options="header",stripes=even,frame=none]
    +|===
    +| *Macro*  | *Meaning*
    +|`macro` |meaning text
    +|`macro` |meaning text
    +|===
    +
    +== Public Library Defined Macros
    +
    +These macros are defined by `<LibraryName>`, but are also expected to be used by application code.
    +
    +[cols="1,2",options="header",stripes=even,frame=none]
    +|===
    +| *Macro*  | *Meaning*
    +|`macro` |meaning text
    +|`macro` |meaning text
    +|===
    +
    +== Library Defined Implementation Macros
    +
    +These macros are defined by `<LibraryName>` and are implementation details of interest only to implementers.
    +
    +[cols="1,2",options="header",stripes=even,frame=none]
    +|===
    +| *Macro*  | *Meaning*
    +|`macro` |meaning text
    +|`macro` |meaning text
    +|===
    +
    +
    +
    +
    +
    Example
    +
    +

    Application Defined Macros

    +
    +

    These are the macros that may be defined by an application using <LibraryName>, for example:

    +
    + ++++ + + + + + + + + + + + + + + + + +
    MacroMeaning

    add(x,y)

    The x and y values are added together.

    mult(x,y)

    The x and Y values are multiplied together.

    +
    +
    +
    +
    +
    +
    +
    +

    Definitions

    +
    +
    +

    If your library uses any terminology that might benefit from a description, consider adding a "Definitions" page to your documentation.

    +
    +
    +

    Each definition is typically preceded by an anchor, so can be linked to from any other section of your documentation. +This can help reduce duplication of explanations: link to your definitions rather than repeat explanations.

    +
    +
    +

    Definitions Template

    +
    +
    +
    ==  <LibraryName> Definitions
    +
    +Introductory text.
    +
    +== Definitions
    +
    +[#definition-term1]
    +*Term1*::
    +definition-text1
    +
    +[#definition-term2]
    +*Term2*::
    +definition-text2
    +
    +
    +
    +
    +
    Example
    +
    +

    Assume there is a String-Container library, and that String container algorithms work using some pre-defined concepts:

    +
    +
    Finder Concept
    +
    +

    A Finder is a function which searches for an arbitrary part of a container. +For example (add example logic here).

    +
    +
    Formatter Concept
    +
    +

    Formatters are used by string replace algorithms. +For example (add example logic here).

    +
    +
    +
    +
    +
    +
    +
    +

    Advanced Topics

    +
    +
    +

    Advanced topics include advanced tutorials or examples, and also cover porting, customization, synchronization, and performance tuning.

    +
    +
    +

    Advanced Topics Template

    +
    +
    +
    == Advanced Use of <LibraryName>
    +
    +Intro text
    +
    +=== Porting Guide
    +
    +text
    +
    +=== Customization
    +
    +text
    +
    +=== Synchronization
    +
    +text
    +
    +=== Performance Tuning
    +
    +text
    +
    +=== Complex Examples
    +
    +text
    +
    +=== Troubleshooting
    +
    +text
    +
    +
    +
    +
    +
    +
    +

    Frequently Asked Questions (FAQs)

    +
    +
    +

    A Frequently Asked Questions (FAQ) section might add value to your documentation, by aiding developers with answers to known issues or complexities.

    +
    +
    +

    If there are a large number of questions and answers, group them into sections with headings such as Errors and Exceptions, Performance, and so on.

    +
    +
    +

    Note that every question is in bold, and always ends with a question mark.

    +
    +
    +

    FAQ Template

    +
    +
    +
    === FAQ
    +
    +==== *question1?*
    +
    +answer1
    +
    +==== *question2?*
    +
    +answer2
    +
    +
    +
    +
    +
    Example
    +
    +
    +

    Does this library work with COM methods?

    +
    +
    +

    Yes, if you add #define BOOST_ENABLE_STDCALL to your code.

    +
    +
    +

    Does this library support Windows earlier than Windows 10?

    +
    +
    +

    No, the only supported versions of Windows supported are 10 and 11.

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Versioning and Release Notes

    +
    +
    +

    Make sure to version your library correctly, and provide release notes for each release. +Refer to Version Control and Release Notes for details.

    +
    +
    +
    +
    +

    Bibliography

    +
    +
    +

    If bibliographic references are required in your documentation for your library, add a bibliography to the documentation.

    +
    +
    +

    The book title can be text, or can be a link to a site too if the text of the book is available online. +The ISBN number can be replaced by another reference number if the reference is to an academic paper, or other reference that is not published in book form.

    +
    +
    +

    Ideally, list the bibliography in alphabetical order.

    +
    +
    +

    Bibliography Template

    +
    +
    +
    === Bibliography
    +[Surname/s] Authors full names. _Book title_. ISBN number, Publication date.
    +[Surname/s] Authors full names. _Book title_. ISBN number, Publication date.
    +
    +
    +
    +
    +
    Example
    +
    +

    [Turcan, Wasson] Peter Turcan, Mike Wasson. Fundamentals of Audio and Video Programming for Games. +ISBN: 073561945X, 2003.

    +
    +
    +
    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    If acknowledgements are required for your library, add an acknowledgements section to the documentation. +As a rule of thumb, the acknowledgements should be ordered with the most important contributions coming first. +Links can be included, if required.

    +
    +
    +

    Acknowledgements Template

    +
    +
    +
    === Acknowledgements
    +
    +The author appreciates the contributions to the library made by the following:
    +
    +* text1
    +* text2
    +
    +
    +
    +
    +
    Example
    +
    +

    The author appreciates the contributions to the library made by the following:

    +
    +
      +
    • +

      John Doe and Jane Doe for editing the original draft documentation.

      +
    • +
    • +

      John Doe for input on the architecture and design of the API interfaces.

      +
    • +
    • +

      Jane Doe for numerous improvements and suggestions on the text of the error messages.

      +
    • +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Other Appendices

    +
    +
    +

    If any other appendices are needed, add them here.

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +

    Revised April, 2023

    +
    +
    +

    Distributed under the Boost Software License, Version 1.0. Refer to http://www.boost.org/LICENSE_1_0.txt.

    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/layout.html b/preview/contributor-guide/docs/layout.html new file mode 100644 index 0000000..211d66b --- /dev/null +++ b/preview/contributor-guide/docs/layout.html @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + Documentation Guidelines :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Documentation Guidelines

    +
    +
    +
    +

    This section covers how to structure library documentation.

    +
    +
    +
    +
    +

    Documentation Entry Point

    +
    +
    +

    In the Boost release, the entry point for the documentation for a library should be in the libs/<LIBRARY NAME>/index.html directory. +This means all projects should contain an index.html file in the root of the library directory.

    +
    +
    +

    Since the Boost releases including all source files and artifacts are available from https://www.boost.org/doc/libs/<VERSION>/, the location for published library documentation will match the following:

    +
    +
    +
    +
    https://www.boost.org/doc/libs/<VERSION>/libs/<LIBRARY NAME>/index.html
    +
    +
    +
    +

    For example:

    +
    +
    +
    +
    https://www.boost.org/doc/libs/latest/libs/json/index.html
    +https://www.boost.org/doc/libs/latest/libs/serialization/index.html
    +https://www.boost.org/doc/libs/latest/libs/beast/index.html
    +
    +
    +
    +

    Although the content of the index.html file is up to the library author, libraries use this index.html entry point to redirect to the main documentation page located elsewhere. +For instance, assuming the final library documentation is located in doc/index.html, the index.html file might contain the following:

    +
    +
    +
    +
    <head>
    +    <meta http-equiv="refresh" content="0; URL=doc/index.html">
    +</head>
    +<body>
    +    Automatic redirection failed, please go to
    +    <a href="doc/index.html">doc/index.html</a>.
    +</body>
    +</html>
    +
    +
    +
    +

    In principle, the page to which index.html redirects can be another source file in the library directory. +In most cases, however, it redirects to another HTML file generated by the build system in the release process.

    +
    +
    +
    +
    +

    Required Organization

    +
    +
    +

    In order for a library’s documentation to be built correctly and the finished product written to the location described above, you must follow the Organization Requirements, in particular the Building Documentation section.

    +
    +
    +

    In particular, the source files for the documentation must be located in the doc directory of the library. +Two types of documentation layouts that are supported:

    +
    +
    +
      +
    • +

      Antora component documentation

      +
    • +
    • +

      Standalone documentation

      +
    • +
    +
    +
    +

    Antora Component Documentation

    +
    +

    Antora is a documentation site generator used to build the Boost website documentation and library documentation for libraries that opt to use it. +A library can choose to use Antora for its documentation by including an doc/antora.yml file to the repository, such as:

    +
    +
    +
    +
    name: mp11
    +title: Boost.Mp11
    +version: ~
    +nav:
    +  - modules/ROOT/nav.adoc
    +
    +
    +
    +

    The navigation structure is defined in doc/modules/ROOT/nav.adoc and the documentation pages are defined in doc/modules/ROOT/pages/. +All pages are written in AsciiDoc format.

    +
    +
    +

    Once the component is defined, it can be enabled in the Boost website repository by adding the component to the libs.playbook.yml file.

    +
    +
    +

    In the Boost release process, this Antora playbook is built with all the other documentation components, and the resulting HTML files are written to the doc/antora directory of the release. +At this point, the Documentation Entry Point for the library documentation should be updated, so it redirects to ../../doc/antora/<LIBRARY NAME>/index.html.

    +
    +
    +

    For detailed instructions on how to set up an Antora component for a library, please refer to Antora Guide.

    +
    +
    +
    +

    Standalone Documentation

    +
    +

    If a library chooses not to use Antora, the doc directory of the library should contain a doc/Jamfile file that specifies how the documentation should be built. +Although this build script can be used to invoke any documentation tool, common tools used for building documentation include: AsciiDoc, Doxygen, and Boost.Quickbook. +When deciding to include standalone documentation with your library, the doc/Jamfile build scripts from other Boost libraries are typically used as reference for new libraries.

    +
    +
    +

    In the Boost release process, these scripts defined in doc/Jamfile are built for each library. +The script typically builds the HTML documentation files in-place, often to doc/html/. +These in-place files are then copied as-is to the release directory. +For instance, if your library’s documentation is built to doc/html/index.html, the Documentation Entry Point should be updated to redirect to doc/html/index.html.

    +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +

    Revised April, 2023

    +
    +
    +

    Distributed under the Boost Software License, Version 1.0. Refer to http://www.boost.org/LICENSE_1_0.txt.

    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/docs/logo-policy-media-guide.html b/preview/contributor-guide/docs/logo-policy-media-guide.html new file mode 100644 index 0000000..f0ef51e --- /dev/null +++ b/preview/contributor-guide/docs/logo-policy-media-guide.html @@ -0,0 +1,510 @@ + + + + + + + + + + + + + + Logo Policy and Media Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Logo Policy and Media Guide

    +
    +

    The Boost trademark

    +
    +
    +

    The Boost C++ Library collection (or “Libraries”) is a community-driven, open source project published under the terms of The Boost Software License (the “BSL”). It is governed by a core team (the “Developers”), consisting of the members of the official Boost GitHub organization located at https://github.com/boostorg (the “Boost GitHub”) having the Owner role, plus any proxies they designate.

    +
    +
    +

    The Libraries are sponsored in part by The C++ Alliance, Inc. (or “Alliance”), a California 501(c)(3) non-profit which owns and protects the Boost logo trademark (the “Boost Logo”) shown below. This document provides information about the use of the Logo, as well as examples of common ways people might want to use this trademark, with explanations as to whether those uses are permitted or not or require additional written permission.

    +
    +
    +

    The Boost Logo:

    +
    +
    +
    +Boost logo +
    +
    +
    +
    +
    Note
    +
    +

    The background is transparent. The source for the image is available at boost-logo-transparent.svg.

    +
    +
    +
    +
    +

    A trademark is a name or design that tells the world the source of a good or service. Protecting trademarks for an open-source project is particularly important. Anyone can change the source code and produce a product from that code, so it’s important that only the original product, or variations that have been approved by the project, use the project’s trademarks. By limiting use of the Boost Logo, the Alliance and the Developers can help users and contributors know they are getting an official product and not someone else’s modified version, or something unrelated. The trademark assures users and developers of the quality and safety of the product they are using.

    +
    +
    +
    +
    +

    Trademark policy

    +
    +
    +

    The Boost Logo (bitmap and vectors) are owned by the Alliance and distributed under the terms of the license granted by this policy.

    +
    +
    +
    +
    Note
    +
    +

    The use of the Boost Logo is also governed by trademark, whose policy is described herein.

    +
    +
    +
    +
    +

    The Boost Logo makes it possible to determine whether or not a library is officially a part of Boost, and whether or not a communication is from the Developers. So we’re careful about where we allow it to appear. But at the same time, we want the community to have confidence using it in prescribed ways without written approval. The policy laid out here explains how we strike a balance. If you have any doubts about whether your intended use requires permission, please contact us (Boost developers mailing list).

    +
    +
    +

    The Boost Logo may not be used in ways that appear (to a casual observer) official, affiliated, or endorsed by the Developers or part of the Libraries, unless you have written permission from the Alliance.

    +
    +
    +
    +
    +

    Referring to Boost

    +
    +
    +

    As with any trademark, the Boost Logo can be used with minimal restriction to refer to the Libraries, or on official communication from the Developers such as when announcing the results of a formal review, or announcing the publishing of a new version of the Libraries. If you use the Boost Logo to distribute any product or content created by someone else, then you must give appropriate credit to the creator(s) of the content and you must indicate if you made changes to the content.

    +
    +
    +

    The Boost Logo may not be used:

    +
    +
    +
      +
    • +

      to refer to any other library or collection of libraries,

      +
    • +
    • +

      in a way that is misleading or may imply an association between the Libraries and unrelated modules, tools, documentation, or other resources, or

      +
    • +
    • +

      in a way that implies an endorsement or communication from the Developers, or

      +
    • +
    • +

      in ways that confuse the community as to whether the Libraries are open source and free to use.

      +
    • +
    +
    +
    +
    +
    +

    Uses that do not require explicit approval

    +
    +
    +
      +
    • +

      Indicating accurately that a work (components such as source code, documentation, and tests) is part of the Libraries. In this case you may reflect this by using the Boost Logo without prior approval, for both commercial and non-commercial uses.

      +
    • +
    • +

      Watermarking official communications from the Developers when referencing milestones or events related to the Libraries such as formal review results or releases is allowed.

      +
    • +
    • +

      Using the Boost Logo on websites, brochures, documentation, academic papers, and books to refer to the Libraries is allowed.

      +
    • +
    +
    +
    +
    +
    +

    Uses that require written approval

    +
    +
    +
      +
    • +

      Using the Boost Logo where the products are not part of the Libraries. In this case, written approval from the Alliance is required to ensure that the usage of the Boost Logo does not confuse users or indicate an official association.

      +
    • +
    • +

      Using the Boost Logo on any thing you wear such as T-shirts, hats, and other artwork or merchandise, requires written approval from the Alliance to ensure that the presentation of the mark reflects the high quality of the brand, and does not confuse users or indicate an official association.

      +
    • +
    • +

      Using the Boost Logo for social events like meetups, tutorials, and the like is allowed for events that are related to the Libraries and free to attend. For commercial events (including sponsored ones), prior written approval from the Alliance is required. The event cannot appear to be officially endorsed or run by the Developers without written permission.

      +
    • +
    +
    +
    +
    +
    +

    Logo reproduction requirements

    +
    +
    +

    Reproduction of the Boost Logo in compliance with the terms and conditions stated above must meet the following additional requirements:

    +
    +
    +
      +
    • +

      Color reproductions must use Boost Mustard (or the closest possible color match), defined as:

      +
      +
        +
      • +

        Freetone: P 17-8 C

        +
      • +
      • +

        CIE Lab: 69.52, 21.09, 66.9

        +
      • +
      +
      +
    • +
    • +

      Black and white reproductions of the Boost Logo must be either pure black or pure white.

      +
    • +
    • +

      The background color must maintain at least 50% contrast with the logo color.

      +
    • +
    • +

      The logo must not be rotated or have its aspect ratio changed.

      +
    • +
    • +

      The logo may only appear once on any individual page, artwork, or product packaging.

      +
    • +
    • +

      The logo cannot be combined with any other artwork without prior written approval from the Alliance.

      +
    • +
    +
    +
    +

    Permission to use the Boost Logo is granted for as long as the usage is consistent with the terms and conditions herein. Usage of the Boost Logo not in accordance with this document and without written approval from Alliance is expressly prohibited.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/getting-involved.html b/preview/contributor-guide/getting-involved.html new file mode 100644 index 0000000..9faab75 --- /dev/null +++ b/preview/contributor-guide/getting-involved.html @@ -0,0 +1,545 @@ + + + + + + + + + + + + + + Getting Involved :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Getting Involved

    +
    +
    +
    +

    There are many ways to get involved with Boost, up to and including submitting your own library. In roughly ascending order of time and work commitment, here are the ways you can contribute to Boost:

    +
    + +
    +
    +
    +

    Participate in the Boost Developers Mailing List

    +
    +
    +

    The Boost mailing list is a platform for discussions and communications related to the Boost Libraries. The mailing list serves several key purposes:

    +
    +
    +
      +
    • +

      Announcements: The mailing list is a channel for updates, announcements about new releases, bug fixes, events, or any other relevant news.

      +
    • +
    • +

      Collaboration: The mailing list also serves as a platform for collaboration, fostering connections between developers and encouraging team-based projects.

      +
    • +
    • +

      Discussion: Developers discuss ideas, techniques, issues, and potential improvements related to Boost libraries.

      +
    • +
    • +

      Support: Newcomers or users encountering difficulties can seek help from the community. Experienced members provide solutions, advice, and share their experiences.

      +
    • +
    +
    +
    +

    If you do join, follow the Boost Discussion Policy of the mailing list, as it helps in maintaining a respectful and productive environment.

    +
    +
    +

    To subscribe to the Developers Mailing List go Boost developers' mailing list.

    +
    +
    +

    There are other mailing lists you might want to join, such as the Boost Users mailing list, or project-specific lists. Visit Boost Mailing Lists for more details.

    +
    +
    +
    +
    +

    Report Issues and Suggest Improvements

    +
    +
    +

    There are different locations to report issues, depending on which content needs updated.

    +
    +
    +

    To Report an Issue with a Library

    +
    +

    To formally report an issue on an individual library, locate the repo for that library. Many of these repos exist in the Boost Super-project on GitHub. Search under the libs folder. For example, to file an issue on the Boost.Json library, click New Issue at https://github.com/boostorg/json/issues. If you have difficulty locating the correct repo, then ask the question of the Boost developers' mailing list.

    +
    +
    +

    Before filing an issue, it is good practice to identify the admins (authors or maintainers) of a library. This information can be found in the meta folder for the library. For example: https://github.com/boostorg/json/blob/develop/meta/libraries.json contains the authors for the Boost.Json library. Also, library documentation and commit history may well specify who is actively involved. Make a connection first to ensure the library admins are open to updates.

    +
    +
    +

    Whichever list you add your issue to, the issue will be triaged and addressed appropriately. Providing full details, examples and screenshots where appropriate, should give you a quicker response.

    +
    +
    +
    +

    To Report an Issue with an Outside Source

    +
    +

    There are sources of information on the Boost libraries outside of this website and the library documentation, including:

    +
    + +
    +

    If you notice content that needs updated in these sources, perhaps out-of-date information, incorrect or missing information, or perhaps just language that could be improved, then complete the same process as To Report an Issue with this Website. Feedback like this is welcome.

    +
    +
    +
    +

    To Report an Issue with this Website

    +
    +

    To report an issue with the website, including this documentation, click the New Issue button on GitHub page: website-v2-docs/issues.

    +
    +
    +

    After clicking New Issue, you will be able to add a Title and Description. Provide as much detail as possible, including links where helpful and suggestions for the updated content.

    +
    +
    +
    +
    +
    +

    Engage in the Review Process

    +
    +
    +

    All libraries are reviewed by the community before becoming part of Boost. There are several roles in the review process, from managing the steps of the review process, to testing and providing feedback. Read the Formal Review Guide for details.

    +
    +
    +
    +
    +

    Contribute to an Existing Library

    +
    +
    +

    Rather than report an issue, or suggested improvement, and wait for another developer to address it, you can make the code changes yourself (after verifying with the library admins that they are open to updates). To be successful you will need to be familiar with GitHub, and obviously a competent C++ developer. After finding the issue, you will need to go to the GitHub repository for that library, and create a fork and clone the library.

    +
    +
    +

    With your fork of the library in your own GitHub account, you can make any changes and updates you wish. It is certainly recommended to thoroughly test the changes, and be aware of the test matrix for the library. It is also recommended you thoroughly comment your code changes, potentially every line of code you add should be commented as to its purpose.

    +
    +
    +

    When you are satisfied you have met the bar for testing, you can commit the changes, push them to GitHub, and create a Pull Request. Most libraries have Continuous Integration (CI) set up, and will check your changes on several operating systems and compilers. If CI is not set up, there will be more onus on you and your testers to verify the test matrix.

    +
    +
    +

    After this, you can take a step back, and the owners or maintainers of the library will review your code. They might ask for some modifications or improvements. Incorporate the feedback provided by the reviewers and push your modifications.

    +
    +
    +

    If all goes well, your changes will be merged by the library admins, and you will have made a welcome contribution.

    +
    +
    +
    +
    +

    Maintain an Existing Library

    +
    +
    +

    There may be an existing library that you have a deep interest in, that for some reason no longer has an active owner or maintainer. Or, perhaps, is being less well maintained than might be ideal. Find what you can out by asking questions of the existing maintainers (listed in the Library Metadata json file) and, if no reply, on the Boost developers' mailing list. If the replies suggest you could take a role, consider requesting, again via the mailing list, to become a library maintainer. For larger libraries there can certainly be more than one maintainer.

    +
    +
    +

    Maintaining an existing library is similar in steps to Contribute to an Existing Library, in that you will have to create a fork and clone the library. However, more is expected. You will have to spend time educating yourself on the full functionality of the library, and be prepared to make changes to the code anywhere changes are needed.

    +
    +
    +

    For a larger library this education can turn out to be a significant, and perhaps onerous task. It can be quite difficult to reverse engineer in your mind the processes and purpose of code written by another developer, with all the expected personal style and idiosyncrasies that make their way into source code. However, that being said, it can be a valuable contribution to take an existing, but not fully maintained, library you are interested in and give it a new lease of life.

    +
    +
    + + + + + +
    + + +All libraries in Boost are tested when the super-project is tested, so even without a dedicated maintainer the libraries must pass a series of automated tests. +
    +
    +
    +
    +
    +

    Contribute a New Library

    +
    +
    +

    This is the big dog of contributions. There are developers who have contributed several libraries to Boost. Start by reading the Library Requirements section, and make sure to engage the Boost community before getting too deep into a massive coding project.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/index.html b/preview/contributor-guide/index.html new file mode 100644 index 0000000..bd8439c --- /dev/null +++ b/preview/contributor-guide/index.html @@ -0,0 +1,367 @@ + + + + + + + + + + + + + + Contributor Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Contributor Guide

    +
    +
    +
    +

    This Contributor Guide is for C++ developers who wish to submit a library to the Boost collection. Or to contribute in some other way, such as testing or evaluating library submissions.

    +
    +
    +
    +
    +

    Feedback

    +
    +
    +

    Feedback on any aspect of the documentation is encouraged, and is available by creating a New Issue. Also, if you have feedback on any particular library, create an issue in the repo for that library.

    +
    +
    +
    +
    +

    First Steps

    +
    +
    +

    Start by reading about how to get involved in Boost.

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/organization-guide.html b/preview/contributor-guide/organization-guide.html new file mode 100644 index 0000000..32bb094 --- /dev/null +++ b/preview/contributor-guide/organization-guide.html @@ -0,0 +1,506 @@ + + + + + + + + + + + + + + Appendix I - Organization Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Appendix I - Organization Guide

    +
    +
    +
    +

    The information in this appendix is only pertinent to those contributors who are involved with the server hosting, operations and infrastructure for the Website v2. The sections contains links to the eclectic set of documentation maintained on GitHub which provides the detailed implementation notes required by developers and system administrators for the website.

    +
    + +
    +
    +
    +

    Server Hosting

    +
    +
    +

    Provides details on the staging and production processes.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Document LinkDescription

    Deployments

    If you are involved in testing the Boost website-v2, you might not need a full cloud deployment. This document describes potentially more convenient options, including using a local Docker composition, the existing staging site, or the existing production site. If you are involved in the C++ Alliance’s development efforts, code may be checked in directly to the staging and production sites, so another site isn’t needed.

    GCP Notes

    The website is hosted on Google Cloud Platform in a project named "boostorg-project1" within a CPPAlliance account. This document describes the Kubernetes cluster running in the us-central1 region, the Memorystore instance for each environment, and Archive Registry of the Docker images for each website release.

    Amazon AWS Notes

    In the us-east-2 region AWS S3 buckets store the described content.

    Fastly Notes

    A Fastly CDN is configured as a front-end to the stage and production sites. This document describes the configuration steps.

    Mailman Notes

    Mailman-core servers have been installed to test a selection of REST API calls.

    Website Admin

    Contains some notes on staging synchronization.

    +
    +
    +
    +

    Website Operations

    +
    +
    +

    Provides operational details, specifically for each release.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Document LinkDescription

    Documentation and Website Previews for The C++ Alliance

    This section covers what contributors should know about the preview generation on cppalliance.github.io and other github repositories.

    Jenkins Summary

    Provides notes on the operation of Jenkins. A Jenkins build server is hosted on AWS at https://jenkins.cppalliance.org:8443. The server builds and publishes previews of the documentation for a number of GitHub repositories when pull requests are submitted.

    Jenkins System and Job Information

    This section goes into exhaustive detail on Jenkins output that can be used as a reference for any job.

    Job Inventory

    The current Jenkins job inventory.

    Drone Docs

    Provides operational details on the CPPAlliance Drone CI implementation.

    Website Redirects

    There are four subdomains which redirect to The C++ Alliance. The redirects act as shortcuts to quickly reach the Slack invitations page, or the main homepage. This section provides implementation details.

    +
    +
    +
    +

    Doc Builds

    +
    +
    +

    There a two main areas of documentation that are built for this website:

    +
    +
    +
      +
    1. +

      Antora Docs on the website : including this Contributor Guide, along with the User Guide and Formal Review Guide.

      +
    2. +
    3. +

      Boost Docs on the website : covering the documentation for each individual library.

      +
    4. +
    +
    +
    +

    In addition to these there are also Boost Archives created by Python scripts, and automated Doc Previews that are built by Jenkins.

    +
    +
    +

    These build processes are outlined in Doc Builds, which includes links to more details of the build processes.

    +
    +
    +
    +
    +

    Boost Release Reports

    +
    +
    +

    The purpose of a Boost Release Report is to inspire and credit all of the volunteer contributors who put the work in for the release. A significant audience for the report are these contributors. It is a "feel-good" document by design.

    +
    +
    +

    The introductory text for each release will depend on the priorities and new content for the release. For example, refer to: Boost 1.87 Release Report.

    +
    +
    +

    Leave it to the technical documentation for each library, tool or process to go into such things as limitations, known issues, performance considerations, and so on.

    +
    +
    +

    Write this report in such a way as to inspire our contributors to re-engage for a future release!

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/oversight-committee.html b/preview/contributor-guide/oversight-committee.html new file mode 100644 index 0000000..5e334ec --- /dev/null +++ b/preview/contributor-guide/oversight-committee.html @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + The Fiscal Sponsorship Committee :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    The Fiscal Sponsorship Committee

    +
    +
    +
    +

    The Fiscal Sponsorship Committee plays a custodial and oversight role rather than being actively involved in guiding the technical direction of the Boost C++ Libraries. Its primary function is to look after Boost’s organizational, legal, and logistical assets, ensuring the community and its resources are well-supported for the long-term sustainability of the project.

    +
    +
    +

    Boost operates with a decentralized and community-driven development model, where individual contributors and maintainers have the autonomy to drive their libraries' progress. The committee supports this by ensuring the ecosystem remains healthy and sustainable for current and future contributors.

    +
    + +
    +
    +
    +

    Boost Assets

    +
    +
    +

    When referring to Boost "assets", these assets fall into five broad categories:

    +
    +
    +

    Trademark and Branding

    +
    +

    The Boost name and logo are recognized worldwide within the C++ development community. The committee ensures that these are protected and used appropriately to maintain the reputation of the project. The Boost website, its domain (boost.org), and associated online content are managed to ensure accessibility and credibility.

    +
    +
    +
    +

    Intellectual Property

    +
    +

    The libraries themselves represent a significant intellectual asset, as they include contributions from many developers under the Boost Software License (BSL), or a similar open-source license. The committee ensures the letter and spirit of the license terms are upheld and remains compatible with Boost’s goals of being free and open-source. The extensive and detailed documentation accompanying Boost libraries is an important part of the codebase, ensuring that developers can effectively use the libraries.

    +
    +
    +
    +

    Infrastructure

    +
    +

    Boost’s GitHub repositories are a critical part of its infrastructure. The committee helps ensure these resources are properly maintained and accessible to contributors. Boost’s Test Matrix and automated build systems, particularly the Continuous Integration (CI) systems, are essential for quality assurance. The committee supports the infrastructure that allows library authors to ensure compatibility across compilers and platforms, and oversees the mailing lists and communication channels used by the Boost community for development discussions.

    +
    +
    +
    +

    Community and Governance

    +
    +

    Boost’s community of contributors and users is one of its most valuable assets. The committee provides governance to maintain the open, collaborative, and meritocratic culture of the project. This includes a role in the C++ community, including participation in conferences like C++ Now, and other events.

    +
    +
    +
    + +
    +

    Boost operates as part of the C++ Alliance, a non-profit organization that ensures proper legal and financial management of Boost resources. The committee collaborates with the Alliance on these matters. If funding or sponsorships are received (for example, for infrastructure or events), the committee helps ensure these are used appropriately.

    +
    +
    +
    +
    +
    +

    Contact Information

    +
    +
    +

    Currently, to contact the committee either post on the #boost Slack channel, or email the Boost Developers Mailing List, clearly mentioning the "Fiscal Sponsorship Committee" as the intended recipient.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/release-notes.html b/preview/contributor-guide/release-notes.html new file mode 100644 index 0000000..f1d6842 --- /dev/null +++ b/preview/contributor-guide/release-notes.html @@ -0,0 +1,643 @@ + + + + + + + + + + + + + + Release Notes :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Release Notes

    +
    +
    +
    +

    Writing release notes is crucial for informing users about the changes made in the latest version of your library.

    +
    +
    +

    Two versions of your release notes need to be prepared: one for your library’s own documentation, one for a Boost history that covers all libraries added or updated in a release.

    +
    +
    +

    For the former, the Boost community does not have a strict format for your libraries' version of release notes (and some libraries refer to release notes as a change log or history). Follow the Checklist.

    +
    +
    +

    For the latter, you will need to update a Boost history file with a succinct version of your completed release notes. These files do have a specified format, described in Update Boost History.

    +
    + +
    +
    +
    +

    Checklist

    +
    +
    +

    When writing release notes for your library remember that the main goal is to effectively communicate the changes to the end-users. It’s always a good practice to put yourself in the mind set of your developers, and think about what information they would need and appreciate. Be brief, but not so brief that only a seasoned user of your library will understand the context.

    +
    +
    +

    1. Header Information

    +
    +

    Make sure the version number, and date of release are mentioned.

    +
    +
    +
    +

    2. Summary

    +
    +

    If this release addresses particular topics, provide a brief overview of the main changes, enhancements, or the theme of this release if there’s one.

    +
    +
    +
    +

    3. Breaking Changes

    +
    +

    Before detailing other updates, immediately inform users of any backward-incompatible changes. This is crucial as these changes can directly impact existing code. The process for breaking changes is covered in detail in Version Control.

    +
    +
    +
    +

    4. API Parameters

    +
    +

    If you have added additional parameters (or changed a return value, or similar API change) to a function that are not breaking changes, then list them separately. If an API change might break an existing application, then ensure to list it under [_breaking_changes].

    +
    +
    +
    +

    5. New Features

    +
    +

    Describe any new features or major enhancements. For complex features, consider adding a brief example or pointing to updated documentation. If the feature is referenced in an Issue, then consider adding a link to that issue.

    +
    +
    +
    +

    6. Bug Fixes

    +
    +

    List the fixed bugs, ideally with a brief description. If you’re using a bug tracking system (like GitHub issues), provide links to the bug reports described in the issues. Include the identifier or number of the bug if available.

    +
    +
    +
    +

    7. Deprecations

    +
    +

    Mention any functions, classes, or features that are deprecated and might be removed in future releases.

    +
    +
    +
    +

    8. Performance Improvements

    +
    +

    Detail any optimizations or performance-related changes, ideally with metrics or benchmarks if they are significant.

    +
    +
    +
    +

    9. Documentation Updates

    +
    +

    Highlight and link to any significant updates in documentation, new examples, or tutorials.

    +
    +
    +
    +

    10. Acknowledgements

    +
    +

    Credit contributors or those who reported crucial bugs. Recognize any person or organization that played a special role in this release.

    +
    +
    +
    +

    11. Known Issues

    +
    +

    Briefly describe any known limitations or issues that are still unresolved in the current release. Include known compatibility issues - including with compilers and tools, and other libraries.

    +
    +
    +
    +

    12. Upgrade Notes

    +
    +

    Provide any specific instructions or recommendations for users upgrading from a previous version, especially if there are any manual steps involved.

    +
    +
    +
    +
    +
    +

    Consistency and Formatting

    +
    +
    +

    Use clear and concise language. Experience has shown that short release notes are read, long files much less so. Do not add into release notes extensive text that should be in your main library documentation.

    +
    +
    +
      +
    • +

      Be consistent in the formatting. If you’re using bullet points for one section, maintain that for others.

      +
    • +
    • +

      Use headers and sub-headers to clearly differentiate sections.

      +
    • +
    • +

      Provide links to:

      +
      +
        +
      • +

        Your main library documentation, if there is updated text, examples or tutorials

        +
      • +
      • +

        Relevant issues, discussions or threads

        +
      • +
      +
      +
    • +
    +
    +
    +
    +
    +

    Release Note Macros

    +
    +
    +

    Various macros are available to library authors and maintainers to help keep release notes consistent between libraries, and easier to both write and read. Absolute links can be added to release notes, if necessary, though use of the following macros is encouraged and recommended.

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescriptionExamples

    boost_phrase:library[ <library name> , <library path>]

    Shows the library title in a consistent format, and links to the library on Git.

    boost_phrase:library[Asio,/libs/asio/], boost_phrase:library[Beast,/libs/beast/], boost_phrase:library[OpenMethod,/libs/openmethod]

    boost_at:<path to file>[ <title>]

    The specified "title" becomes a link to the file.

    Consult the boost_at:/doc/libs/1_90_0/doc/html/boost_asio/history.html[Revision History] for further details., boost_at:/doc/libs/1_90_0/[Documentation]

    boost_gh:pr[ <library name>, <PR number]

    Provides a link to a GitHub PR for the specified library.

    Conform to std::pointer_traits requirements (boost_gh:pr[interprocess,32])., boost_gh:pr[core,205]

    boost_gh:issue[<library name>, <ISSUE number>]

    Provides a link to the GitHub Issue for the specified library.

    Fixed named_condition_any fails to notify (boost_gh:issue[interprocess,62]).

    +
    +
    +
    +

    Release Note Examples

    +
    +
    +

    Checking out the release notes from fellow library authors and maintainers is good practice:

    +
    + +
    +
    +
    +

    Update Boost History

    +
    +
    +

    When you have completed the library release notes, add the required information to the [section New Libraries] or [section Updated Libraries] of the Boostorg History. Copy the formatting of the examples below, which for reference is Quickbook format.

    +
    +
    +

    The examples below come from the boost_1_83_0.qbk file:

    +
    +
    +
    +
    [section New Libraries]
    +
    +[/ Example:
    +* [phrase library..[@/libs/accumulators/ Accumulators]:] Framework for
    +  incremental calculation, and collection of statistical accumulators, from Eric Niebler.
    +]
    +
    +* [phrase library..[@/libs/compat/ Compat]:] A repository of C++11 implementations of
    +  standard components added in later C++ standards, from Peter Dimov and contributors.
    +
    +[endsect]
    +
    +[section Updated Libraries]
    +
    +[/ Example:
    +* [phrase library..[@/libs/interprocess/ Interprocess]:]
    +  * Added anonymous shared memory for UNIX systems.
    +  * Move semantics for shared objects ([ticket 1932]).
    +  * Conform to `std::pointer_traits` requirements ([github_pr interprocess 32])
    +  * Fixed `named_condition_any` fails to notify ([github interprocess 62])
    +]
    +
    +* [phrase library..[@/libs/any/ Any]:]
    +  * New `boost::anys::unique_any` C++11 class - an alternative to
    +    `boost::any` (or to `std::any`) that does not require copy
    +    or move construction from the held type.
    +  * Ported documentation to Quickbook, Doxygen comments now used in code.
    +
    +  ....
    +
    +  [endsect]
    +
    +
    +
    +
    +
    Note
    +
    +

    The macros used in Quickbook format for the history sections differ in detail from the macros available for the Release Notes.

    +
    +
    +
    +
    +
    +
    +

    Best Practices

    +
    +
    +

    Experience has shown the following layout works well when writing release notes and having your users actually read them.

    +
    +
    +

    The first three (or less) bullet points should briefly explain the most impactful changes to your library. If new functionality has been added, this is the place for it.

    +
    +
    +

    The next bullet points, at most seven, but perhaps five is better, contain concise changes that affect the use of your library. This will include functions that have been improved, functions removed or deprecated, and other pertinent changes say to an API’s parameters, errors, return values and similar.

    +
    +
    +

    If documentation has been updated, comments cleaned up, examples improved or removed, a single bullet point describing this has occurred is enough.

    +
    +
    +

    The rule of thumb here is to keep the number of bullet points to ten or less, as adding more is a good way of ensuring your users will skip or skim your release notes - a classic example of information "hiding in plain sight"!

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/release-process.html b/preview/contributor-guide/release-process.html new file mode 100644 index 0000000..d90a2cb --- /dev/null +++ b/preview/contributor-guide/release-process.html @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + Release Process :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Release Process

    +
    +
    +
    +

    The Boost libraries are released publicly three times per year:

    +
    +
    +
      +
    • +

      Second week of April

      +
    • +
    • +

      Second week of August

      +
    • +
    • +

      Second week of December

      +
    • +
    +
    +
    +

    Each release will contain updates to existing libraries, and some releases will contain new libraries. The release is built from the master branch of Boost’s GitHub site: https://github.com/boostorg/boost.

    +
    + +
    +
    +
    +

    Preparing for a Boost Release

    +
    +
    +

    The release managers set the release timeline, which involves planning deadlines for library submissions, reviews, and incorporation into the repository.

    +
    +
    +

    Once the release timeline is set, library maintainers work to prepare their libraries for the release. This involves updating documentation, fixing bugs, and addressing any compatibility issues. Additionally, library maintainers ensure that their libraries pass the Boost regression tests, which help identify potential problems before the release.

    +
    +
    +
    +
    +

    Boost Regression Testing

    +
    +
    +

    Boost regression testing is an essential part of the release process, ensuring the quality and compatibility of the libraries. The Boost community maintains a set of regression tests, which are run on a diverse range of platforms and compilers. The tests are performed by volunteers who contribute their computing resources to the project.

    +
    +
    +

    The results of the regression tests are published on the Boost website, providing library maintainers and users with up-to-date information about the library’s compatibility and performance. Library maintainers use this information to identify and fix any issues before the release.

    +
    +
    +
    +
    +

    Milestones in the Release Cycle

    +
    +
    +

    There is a strict countdown to a public release.

    +
    +
    +
    +
    7 Weeks Prior to Release Date
    +
    +

    The master branch is closed to all check ins, except bug fixes and quality checks.

    +
    +
    6 Weeks Prior to Release Date
    +
    +

    The master branch is closed to major code changes. There can be no rewrites of code, even to fix issues.

    +
    +
    5 Weeks Prior to Release Date
    +
    +

    The master branch is closed to all check ins, except with permission from the release committee.

    +
    +
    4 days Prior to Beta Release Date
    +
    +

    The master branch is closed. Beta release candidates are built.

    +
    +
    4 Weeks Prior to Release Date
    +
    +

    The Beta release is published to the Boost site. The master branch is opened to small bug fixes and documentation changes. Permission from the release committee is required for larger changes.

    +
    +
    1 Week Prior to Release Date
    +
    +

    The master branch is closed to all check ins, except high-priority fixes.

    +
    +
    4 Days Prior to Release Date
    +
    +

    The master branch is closed. Release candidates are built.

    +
    +
    Day of Release
    +
    +

    The release candidate is published to the Boost site. The master branch is opened for all check ins.

    +
    +

    If issues are found with a release candidate that are important enough to address quickly (that is, before the next full public release), then a point release will be built when fixes are available and tested. This will not typically result in the master branch being closed to other check ins.

    +
    +
    +
    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    For details of the Release Process that are pertinent to users, refer to the +User Guide Release Process.

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/requirements/library-metadata.html b/preview/contributor-guide/requirements/library-metadata.html new file mode 100644 index 0000000..a171ae1 --- /dev/null +++ b/preview/contributor-guide/requirements/library-metadata.html @@ -0,0 +1,691 @@ + + + + + + + + + + + + + + Library Metadata :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Library Metadata

    +
    +
    +
    +

    The sources for each library, or possibly a number of related libraries, is contained in a sub-module of the Boost super-project. +Each sub-module must contain a file which describes the libraries that it contains. This is located at meta/libraries.json.

    +
    +
    +
    +
    +

    Json Objects

    +
    +
    +

    If the sub-module contains a single library, libraries.json should contain a single object, for example:

    +
    +
    +
    +
    {
    +    "key": "unordered",
    +    "name": "Unordered",
    +    "authors": [
    +        "Daniel James"
    +    ],
    +    "maintainers": [
    +        "Daniel James <dnljms -at- gmail.com>"
    +    ],
    +    "description": "Unordered associative containers.",
    +    "std": [
    +        "tr1"
    +    ],
    +    "category": [
    +        "Containers"
    +    ],
    +    "cxxstd": "03"
    +}
    +
    +
    + +
    +

    Multiple Libraries

    +
    +

    If the sub-module contains multiple libraries, libraries.json should contain a list of objects, for example:

    +
    +
    +
    +
    [
    +    {
    +        "key": "algorithm",
    +        "name": "Algorithm",
    +        "authors": [
    +            "Marshall Clow"
    +        ],
    +        "description": "A collection of useful generic algorithms.",
    +        "category": [
    +            "Algorithms"
    +        ],
    +        "maintainers": [
    +            "Marshall Clow <marshall -at- idio.com>"
    +        ],
    +        "cxxstd": "03"
    +    },
    +    {
    +        "key": "algorithm/minmax",
    +        "name": "Min-Max",
    +        "authors": [
    +            "Hervé Brönnimann"
    +        ],
    +        "description": "Standard library extensions for simultaneous min/max and min/max element computations.",
    +        "documentation": "minmax/",
    +        "category": [
    +            "Algorithms"
    +        ],
    +        "maintainers": [
    +            "Marshall Clow <marshall -at- idio.com>"
    +        ],
    +        "cxxstd": "03"
    +    },
    +    {
    +        "key": "algorithm/string",
    +        "name": "String Algo",
    +        "authors": [
    +            "Pavol Droba"
    +        ],
    +        "description": "String algorithms library.",
    +        "documentation": "string/",
    +        "category": [
    +            "Algorithms",
    +            "String"
    +        ],
    +        "maintainers": [
    +            "Marshall Clow <marshall -at- idio.com>"
    +        ],
    +        "cxxstd": "03"
    +    }
    +]
    +
    +
    + +
    +
    +
    +
    +

    Json Fields

    +
    +
    +

    All meta files should contain key, name, description, authors, maintainers, and category. The other fields are optional.

    +
    +
    +

    key

    +
    +

    This is a unique identifier for the library, typically the path to it from the libs directory.

    +
    +
    +
    +

    boost-version

    +
    +

    The Boost version where the library was first added, such as: "boost-version": "1.33.0".

    +
    +
    +
    +

    name

    +
    +

    Human friendly name of the library.

    +
    +
    +
    +

    status

    +
    +

    Used for libraries with special statuses, currently can have the value deprecated for deprecated libraries, and hidden for libraries which shouldn’t be displayed to the user. Hidden libraries include detail and winapi, both of which are hidden because they are used as components of other libraries, and not intended as stand-alone libraries themselves.

    +
    +
    +

    The library coroutine is marked as "deprecated", though this does not mean full deprecation as this library is part of the Boost super-project, and will be tested each time the super-project is tested.

    +
    +
    +
    +

    authors

    +
    +

    Strings containing the names of the authors.

    +
    +
    +
    +

    description

    +
    +

    A brief description of the purpose of the library.

    +
    +
    +
    +

    maintainers

    +
    +

    One, or more, strings containing both the names and, usually, email addresses of the maintainers.

    +
    +
    +
    +

    std

    +
    +

    This is now an unused field.

    +
    +
    +
    +

    category

    +
    +

    A list of one or more of the Categories that the library belongs to.

    +
    +
    +
    +

    documentation

    +
    +

    Path to the documentation, defaults to the root of the module.

    +
    +
    +
    +

    cxxstd

    +
    +

    The minimum C++ standard compilation level at which all, or the large majority, of the functionality in the library is usable. The possible values are:

    +
    +
    +
      +
    • +

      98 = C++98

      +
    • +
    • +

      03 = C++03

      +
    • +
    • +

      11 = C++11

      +
    • +
    • +

      14 = C++14

      +
    • +
    • +

      17 = C++17

      +
    • +
    • +

      20 = C++20

      +
    • +
    • +

      23 = C++23

      +
    • +
    +
    +
    +

    The level only indicates the minimum level, which means that the functionality of the library can be used when compiling at that level or at a higher level. There may be some functionality in the library which will need a higher C++ standard compilation level than is indicated by this value, but the information about that specific functionality will be provided for the end-user within the documentation for that library. If a library does not have this field it indicates that the end-user will have to read the library documentation to understand what C++ standard compilation level is needed to use the library.

    +
    +
    +

    Note that 11 and 14 are commonly set minimum levels.

    +
    +
    +
    +
    +
    +

    Categories

    +
    +
    +

    A library can be in one or more categories. The string is not case-sensitive. In some cases, the string used to describe the category on our website is slightly more descriptive than the string used in the category field.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Metadata CategoryWebsite Category

    Algorithms

    Algorithms

    Concurrent

    Concurrent Programming

    Containers

    Containers

    Correctness

    Correctness and testing

    Data

    Data structures

    Domain

    Domain Specific

    Emulation

    Language Features Emulation

    Error-handling

    Error handling and recovery

    Function-objects

    Function objects and higher-order programming

    Generic

    Generic Programming

    Image-processing

    Image processing

    IO

    Input/Output

    Inter-language

    Inter-language support

    Iterators

    Iterators

    Math

    Math and numerics

    Memory

    Memory

    Metaprogramming

    Template Metaprogramming

    Miscellaneous

    Miscellaneous

    Parsing

    Parsing

    Patterns

    Patterns and Idioms

    Preprocessor

    Preprocessor Metaprogramming

    Programming

    Programming Interfaces

    State

    State Machines

    String

    String and text processing

    System

    System

    Workarounds

    Broken compiler workarounds

    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/requirements/library-requirements.html b/preview/contributor-guide/requirements/library-requirements.html new file mode 100644 index 0000000..a94b2a6 --- /dev/null +++ b/preview/contributor-guide/requirements/library-requirements.html @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + Library Requirements :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Library Requirements

    +
    +
    +
    +

    This section describes the requirements and guidelines for the content of a library submitted to Boost.

    +
    +
    +

    Boost developers constitute a wide array of people throughout much of the world. Over the years much work has gone into the quantity and quality of the C++ libraries and tools that make up Boost. There are many ways to become part of the Boost developer community, all starting with getting involved in the development discussion. But if you are looking for an + easier place to start than developing a library, consider volunteering as a tester.

    +
    +
    +

    As a first step to developing a library, read the Requirements Overview for Boost.

    +
    +
    +
    +
    +

    Requirements Overview

    +
    +
    +

    To avoid a proposed library being rejected, it must meet these requirements:

    +
    +
    +
      +
    1. +

      The license must meet the License Requirements. Restricted licenses like the GPL and LGPL are not acceptable.

      +
    2. +
    3. +

      The Ownership (copyright) must be clear.

      +
    4. +
    5. +

      The library should be useful to a general audience.

      +
    6. +
    7. +

      The library must meet the Portability Requirements.

      +
    8. +
    9. +

      The library should preferably meet the Organization Requirements. But is only required to meet them after acceptance.

      +
    10. +
    11. +

      The library must come reasonably close to meeting the Design Best Practices.

      +
    12. +
    13. +

      The library must be well documented, refer to Documentation Guidelines.

      +
    14. +
    15. +

      The author must be willing to participate in discussions on the mailing list, and to refine the library accordingly.

      +
      +
      +
      TIP
      +
      +

      There’s no requirement that an author read the mailing list for a time before making a submission. It has been noted, however, that submissions which begin "I just started to read this mailing list …​" seem to fail, often embarrassingly.

      +
      +
      +
      +
    16. +
    +
    +
    +
    +
    +

    Ownership

    +
    +
    +

    Before proceeding, are you sure you own the library you are thinking of submitting? In the book How to Copyright Software" by MJ Salone, Nolo Press, 1990 says:

    +
    +
    +

    "Doing work on your own time that is very similar to programming you do for your employer on company time can raise nasty legal problems. In this situation, it’s best to get a written release from your employer in advance."

    +
    +
    +

    Place a copyright notice in all the important files you submit. Boost won’t accept libraries without clear copyright information.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/requirements/license-requirements.html b/preview/contributor-guide/requirements/license-requirements.html new file mode 100644 index 0000000..fbcc10f --- /dev/null +++ b/preview/contributor-guide/requirements/license-requirements.html @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + License Requirements :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    License Requirements

    +
    +
    +
    +

    The preferred way to meet the license requirements is to use The Boost Software License. See license information. If for any reason you do not intend to use the Boost Software License, please discuss the issues on the Boost developers mailing list first.

    +
    +
    +

    The license requirements:

    +
    +
    +
      +
    • +

      Must be simple to read and understand.

      +
    • +
    • +

      Must grant permission without fee to copy, use and modify the software for any use (commercial and non-commercial).

      +
    • +
    • +

      Must require that the license appear on all copies of the software source code.

      +
    • +
    • +

      Must not require that the license appear with executables or other binary uses of the library.

      +
    • +
    • +

      Must not require that the source code be available for execution or other binary uses of the library.

      +
    • +
    • +

      May restrict the use of the name and description of the library to the standard version found on the Boost web site.

      +
    • +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/requirements/organization-requirements.html b/preview/contributor-guide/requirements/organization-requirements.html new file mode 100644 index 0000000..0340071 --- /dev/null +++ b/preview/contributor-guide/requirements/organization-requirements.html @@ -0,0 +1,758 @@ + + + + + + + + + + + + + + Organization Requirements :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Organization Requirements

    +
    +
    +
    +

    The quality of the Boost libraries is not just about the APIs and code design, but also about presenting a consistent view to users of the libraries as a whole. Upon acceptance libraries should adhere to this directory and file structure.

    +
    +
    +
    +
    +

    Boost Repository Library Organization

    +
    +
    +

    Referring to accepted libraries is a great way to educate yourself on the library directory structure. In the examples given below, Boost.Atomic, Boost.Json, and Boost.Serialization are examples of libraries that requires building, and Boost.Asio, Boost.Geometry, and Boost.Hana are examples of libraries that are header-only.

    +
    +
    +

    Sub-Directory

    +
    +

    The following directories should appear, along with others specific to the library, as top-level sub-directories for the library.

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Sub-DirectoryContentsRequiredExamples

    build

    Library build files such as a Jamfile, IDE projects, Makefiles, Cmake files, etc.

    Required if the library has sources to build.

    config

    Files used for build-time configuration checks. This directory may contain source files and build system scripts to be used when building the library, tests or examples to check if the target system satisfies certain conditions. For example, a check may test if the compiler implements a certain feature, or if the target system supports a certain API.

    Optional.

    + +

    doc

    Sources to build with and built documentation for the library. If the library needs to build documentation from non-HTML files this location must be build-able with Boost Build.

    Required for all libraries.

    + +

    doc/html

    Documentation (HTML) files.

    Required for all libraries with pregenerated documentation. And generated documentation must be generated here.

    example

    Sample program files.

    Required if library has sample files. Which is highly recommended.

    include/boost/<library-name>

    Header files for the library.

    Required for all libraries.

    meta

    Meta-data about the library.

    Required for all libraries.

    + +

    src

    Source files which must be compiled to build the library.

    Required if the library has source files to build.

    + +

    test

    Regression or other test programs or scripts. This is the only location considered for automated testing. If you have additional locations that need to be part of automated testing it is required that this location refer to the additional test locations.

    Required for all libraries.

    + +

    test/cmake_test

    CMake sub-folders can be named for the type of Continuous Integration tests they contain (cmake_install_test for example). The structure of your tests should match that in boostorg/boost-ci, and refer to the Boost.CI Readme for process details.

    Not required, though most new libraries include these tests.

    tools

    Tools used, or offered, by the library. The structure within this is up to the library, but it’s recommended to use similar structure as a regular Boost library or tool.

    Required for libraries that have run-able tools.

    + +
    +
    +

    To reference the existing master repo, refer to boost/libs/.

    +
    +
    +

    For a list of libraries that require building, refer to Required Compiled Binaries.

    +
    +
    +
    +

    Files

    +
    +

    There are some individual files that are also required, or are optional and recognized by the build system.

    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FileContentsRequiredExamples

    build.jam

    Top level jamfile.

    Required if the library has sources to build.

    CMakeLists.txt

    Refer to CMake for Boost Developers.

    Required for all libraries.

    index.html

    Redirection to HTML documentation. Refer to Design Guide/Redirection for a template for this file.

    Required for all libraries.

    meta/libraries.json

    A JSON file containing information about the library, which is used to generate website and documentation for the Boost Libraries collection. Refer to Library Metadata.

    Required for all libraries.

    meta/explicit-failures-markup.xml

    XML file describing expected test failures, used to generate the test report.

    Optional

    +
    +
    +
    +
    +

    Integration

    +
    +
    +

    After a library is accepted as part of the Boost Libraries it is required that it integrate properly into the development, testing, documentation, and release processes. This integration increases the eventual quality of all the libraries and is integral to the expected quality of the whole of the Boost C++ Libraries from users. In addition to the organization requirements above the following integration is required:

    +
    +
    +

    Building Sources

    +
    +

    The library needs to provide a Boost Build project that the user, and the top level Boost project, can use to build the library if it has sources to build. The Jamfile for the source build needs to minimally declare the project, the library targets, and register the targets for installation. For example:

    +
    +
    +
    +
    project boost/my_lib ;
    +
    +lib boost_my_lib : a.cpp ;
    +
    +boost-install boost_my_lib ;
    +
    +
    +
    +
    +

    Testing

    +
    +

    The library needs to provide a Boost Build project that the user, and the root Boost test script, can use to build and run the tests for the library. The testing build project must reside in the project-root/test directory and must be build-able from this or another directory, for example, b2 libs/library/test from the Boost root must work.

    +
    +
    +

    An example test/Jamfile is given below:

    +
    +
    +
    +
    import testing ;
    +
    +run default_constructor.cpp ;
    +run copy_constructor.cpp ;
    +compile nested_value_type.cpp ;
    +compile-fail invalid_conversion_1.cpp ;
    +
    +
    +
    +
    +
    WARNING
    +
    +

    This is the only location considered for testing by the top level testing script. If you want to test additional locations you must declare such that they are built as dependencies or by using build-project.

    +
    +
    +
    +
    +

    If the library requires a level of C++ conformance that precludes certain compilers or configurations from working, it’s recommended to declare these requirements in the test Jamfile. This ensures that unnecessary tests aren’t run, to conserve test resources, as given in the example below:

    +
    +
    +
    +
    import testing ;
    +import ../../config/checks/config : requires ;
    +
    +project : requirements [ requires cxx11_variadic_templates cxx11_template_aliases ] ;
    +
    +run cpp11_test.cpp ;
    +
    +
    +
    +

    For more information, see the documentation for Boost.Config.

    +
    +
    +
    +

    Building Documentation

    +
    +

    The library needs to provide a Boost Build project for building the documentation for the library. The project-root/doc project is the only location referred to by the top level documentation build scripts and the release building scripts. The documentation build project must have the following two features:

    +
    +
    +

    Define a boostrelease target. This target should likely be an alias that looks roughly like:

    +
    +
    +
    +
    alias boostrelease  : my_boostbook_target
    +    : : : <implicit-dependency>my_boostbook_target ;
    +
    +
    +
    +

    But if your project doesn’t integrate into the global documentation book you can use an empty alias like:

    +
    +
    +
    +
    alias boostrelease  ;
    +
    +
    +
    +

    The project must default to building standalone documentation if it has any. The release scripts build this default so as to guarantee all projects have up to date documentation.

    +
    +
    +
    +
    Note
    +
    +

    Integrated documentation, using the boostdoc target (instead of the boostrelease target) is now considered legacy, and should be avoided for new library documentation.

    +
    +
    +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/requirements/portability-requirements.html b/preview/contributor-guide/requirements/portability-requirements.html new file mode 100644 index 0000000..deeec54 --- /dev/null +++ b/preview/contributor-guide/requirements/portability-requirements.html @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + Portability Requirements :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Portability Requirements

    +
    +
      +
    • +

      A library’s interface must be portable and not restricted to a particular compiler or operating system.

      +
    • +
    • +

      A library’s implementation must if possible be portable and not restricted to a particular compiler or operating system. If a portable implementation is not possible, non-portable constructions are acceptable if reasonably easy to port to other environments, and implementations are provided for at least two popular operating systems (such as UNIX and Windows).

      +
    • +
    • +

      A library runs on at least two C++ compilers implementing the latest ISO standard.

      +
    • +
    • +

      There is no requirement that a library run on C++ compilers which do not conform to the ISO standard.

      +
    • +
    • +

      There is no requirement that a library run on any particular C++ compiler. Boost contributors often try to ensure their libraries work with popular compilers. The boost/config.hpp configuration header is the preferred mechanism for working around compiler deficiencies.

      +
    • +
    +
    +
    +

    Since there is no absolute way to prove portability, many boost submissions demonstrate practical portability by compiling and executing correctly with two different C++ compilers, often under different operating systems. Otherwise reviewers may disbelieve that porting is in fact practical.

    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/site-docs-style-guide.html b/preview/contributor-guide/site-docs-style-guide.html new file mode 100644 index 0000000..f546d97 --- /dev/null +++ b/preview/contributor-guide/site-docs-style-guide.html @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + Site-docs Style Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Site-docs Style Guide

    +
    +
    +
    +

    This document outlines the style guidelines for the site-docs. Adhering to these guidelines will help ensure consistency and cohesion across all pages of the website.

    +
    + +
    +
    +
    +

    Color Guidelines

    +
    +
    +
      +
    • +

      Boost Mustard

      +
      +
        +
      • +

        only use for one or two key top level headings

        +
      • +
      • +

        never on inactive UI controls

        +
      • +
      • +

        OK to use for hover state

        +
      • +
      • +

        never use large areas of this color in illustrations

        +
      • +
      • +

        never used as an endpoint of a color blend

        +
      • +
      +
      +
    • +
    +
    +
    +
    +
    +

    Wording Guidelines

    +
    +
    +
      +
    • +

      The word "Boost" should occur no more than once per page, not counting logo, but logo should not be visible in two places.

      +
      +
        +
      • +

        user generated content excluded

        +
      • +
      +
      +
    • +
    • +

      The word "C++" should occur no more than once on a page

      +
      +
        +
      • +

        user-generated content excluded

        +
      • +
      +
      +
    • +
    +
    +
    +

    We want to minimize the number of times we use the word "Boost" on a page. Since the logo in the header has the word "Boost" in it, sometimes we will have no choice but to use the word at least twice on a page. But we should try to minimize the repetitions.

    +
    +
    +
    +
    +

    URL Display

    +
    +
    +
      +
    • +

      Per-library links (e.g. GitHub or docs) should use a schemeless URL:

      +
    • +
    +
    +
    +
    +url style guide image +
    +
    +
    +
    +
    +

    Image Display

    +
    +
    +
      +
    • +

      User avatars should never be displayed squared, always with rounded corners

      +
    • +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/superproject/getting-started.html b/preview/contributor-guide/superproject/getting-started.html new file mode 100644 index 0000000..b6f6944 --- /dev/null +++ b/preview/contributor-guide/superproject/getting-started.html @@ -0,0 +1,522 @@ + + + + + + + + + + + + + + Getting Started with the Super-Project :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Getting Started with the Super-Project

    +
    +
    +
    +

    Boost libraries reside in subdirectories under the libs directory. For example, the contents of the Boost.Filesystem library are in libs/filesystem. This includes the build scripts (in libs/filesystem/build), the source files (in libs/filesystem/src), the tests (in libs/filesystem/test), the documentation (in libs/filesystem/doc), and so on.

    +
    +
    +

    In the past, when Boost used SVN as its version control system, the header files were an exception. The header files of all libraries resided in the boost subdirectory, and it wasn’t possible to accurately determine which header belonged to which library.

    +
    +
    +

    When Boost moved to Git for version control, header files were moved to their corresponding libraries, into an include subdirectory. The header files of Boost.Filesystem are now in libs/filesystem/include.

    +
    +
    +

    For compatibility, boost is now a "virtual" directory, containing links to the headers. It’s maintained automatically by B2. The command b2 creates or recreates the contents of the boost directory.

    +
    +
    +

    This structure allows us to determine that, when faced with an #include <boost/filesystem.hpp> directive, that this header is part of Boost.Filesystem, and that therefore, the current library being scanned depends on Boost.Filesystem.

    +
    +
    +
    +
    Note
    +
    +

    Unfortunately, Boost releases do not have this structure. For backward compatibility, they have an old-style boost directory containing all header files, whereas the per-library include subdirectories are missing.

    +
    +
    +
    +
    +
    +
    +

    Clone and Install the Super-project

    +
    +
    +

    To work within the Super-project, you will have to clone the Boost Git repository. To do that, execute the following command:

    +
    +
    +
    +
    git clone https://github.com/boostorg/boost.git boost
    +
    +
    +
    +

    This will download the Super-project (the master project, without any libraries) and place it into the subdirectory boost of the current directory. To override the directory name, pass it as a second argument instead of boost:

    +
    +
    +
    +
    git clone https://github.com/boostorg/boost.git mydir
    +
    +
    +
    +

    You can now cd into the newly created directory with cd mydir. This directory is called the "Boost root". All of the commands below assume that it is the current directory.

    +
    +
    +

    The above git clone commands download the default branch of the Boost Git repository, which is master. This is the current stable version of Boost. To verify this, issue the command git status from the Boost root. This will output

    +
    +
    +
    +
    # On branch master
    +nothing to commit, working directory clean
    +
    +
    +
    +

    To download a specific release instead, such as 1.58.0, issue the following command after git clone, from the Boost root:

    +
    +
    +
    +
    git checkout boost-1.58.0
    +
    +
    +
    +

    git status will now say"

    +
    +
    +
    +
    # HEAD detached at boost-1.58.0
    +nothing to commit, working directory clean
    +
    +
    +
    +

    Then, download all the libraries:

    +
    +
    +
    +
    git submodule update --init
    +
    +
    +
    +

    This step will take a while.

    +
    +
    +

    If all goes well, you will now have the complete contents of Boost’s latest master branch (if you didn’t checkout a specific release by name) or the corresponding Boost release (if you did).

    +
    +
    +

    You can switch between the master branch, the develop branch, and a release, by issuing the following commands:

    +
    +
    +

    For the master branch:

    +
    +
    +
    +
    git checkout master
    +git pull
    +git submodule update --init
    +
    +
    +
    +
    +
    Note
    +
    +

    git pull updates your local copy of the master branch from the server, in case it has changed since your initial checkout.

    +
    +
    +
    +
    +

    For the develop branch:

    +
    +
    +
    +
    git checkout develop
    +git pull
    +git submodule update --init
    +
    +
    +
    +

    For the boost-1.58.0 release:

    +
    +
    +
    +
    git checkout boost-1.58.0
    +git submodule update --init
    +
    +
    +
    +

    For the boost-1.57.0 release:

    +
    +
    +
    +
    git checkout boost-1.57.0
    +git submodule update --init
    +
    +
    +
    +
    +
    Note
    +
    +

    While the initial git submodule update is quite slow, as it needs to download all the libraries, the subsequent invocations are a lot faster.

    +
    +
    +
    +
    +

    Also note that if a new Boost library (libs/convert, for example) is present in, say, master, and you have it checked out, when you later switch to boost-1.58.0, where this library doesn’t exist, Git will not delete libs/convert. In this case, git status will output

    +
    +
    +
    +
    # HEAD detached at boost-1.58.0
    +# Untracked files:
    +#   (use "git add <file>..." to include in what will be committed)
    +#
    +#       libs/convert/
    +nothing added to commit but untracked files present (use "git add" to track)
    +
    +
    +
    +

    and you will have to remove libs/convert by hand.

    +
    +
    +

    Now, you have successfully installed the Super-project.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/superproject/library-maintenance.html b/preview/contributor-guide/superproject/library-maintenance.html new file mode 100644 index 0000000..cbaddee --- /dev/null +++ b/preview/contributor-guide/superproject/library-maintenance.html @@ -0,0 +1,829 @@ + + + + + + + + + + + + + + Getting Started with Super-Project Library Maintenance :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Getting Started with Super-Project Library Maintenance

    +
    +
    +
    +

    This page briefly sketches the mechanics of maintaining a Boost library using Git. The intended audience is developers getting started with the maintenance of an existing Super-project library.

    +
    +
    +

    This page is intended to get you started only; it does not provide in-depth coverage. See links below for that.

    +
    +
    +

    Illustrations of how to perform various actions are given using the Git command line client.

    +
    +
    +
    +
    +

    The Big Picture

    +
    +
    +

    Library maintenance occurs in the context of how Boost repositories are organized. Study the Super-Project Layout before continuing, since a Boost developer needs to be familiar with how Boost organizes its repositories.

    +
    +
    +

    The examples given on this page follow Boost recommended workflow practices, but keep workflow discussion simple for this introduction. To better understand workflow recommendations and rationale before continuing, read Super-Project Library Workflow.

    +
    +
    +
    +
    +

    Prerequisites

    +
    +
    +
      +
    1. +

      A recent release of the Git command line client installed.

      +
    2. +
    3. +

      A GitHub account.

      +
    4. +
    5. +

      A C++ compiler and development environment installed and working smoothly.

      +
    6. +
    7. +

      The Super-project installed, as described in Getting Started with the Super-Project.

      +
    8. +
    9. +

      b2 in your path. That allows the command line examples given here to work as shown on both Windows and POSIX-like systems.

      +
    10. +
    +
    +
    +
    +
    +

    Typical Maintenance Tasks

    +
    +
    +

    Getting Ready to Work on a Library

    +
    +

    The preferred environment library maintenance is to checkout the library’s develop branch, or some other development branch, while other Boost libraries are as defined by the Super-project master branch. This causes local tests of your library to run against master for other Boost libraries at the point in time referenced by the Super-project.

    +
    +
    +

    This is a more realistic test environment in than testing against the possibly unstable develop branch of other Boost libraries or against the master branch of other libraries at a different point in time than that referenced by the Super-project. Robert Ramey has advocated this approach to testing for years, and the Super-project makes this approach relatively easy and fast.

    +
    +
    +
    +
    Note
    +
    +

    The following examples assume you have installed the Super-project to a folder called boost-root.

    +
    +
    +
    +
    +
    +
    cd boost-root
    +git checkout master
    +git pull
    +git submodule update
    +
    +
    +
    +

    The git submodule update` will fail if it would result in uncommitted changes being overwritten.

    +
    +
    +

    The git submodule update may switch submodules back to the detached state, depending on the working copy’s exact situation.

    +
    +
    +

    See Effects of git submodule update for details.

    +
    +
    +

    To get more information about a submodule:

    +
    +
    +
    +
    cd boost-root
    +git submodule summary
    +
    +
    +
    +

    If for some reason you wanted to test against the current head of master for all libraries, disregarding the Super-project state, the git submodule update command would be changed to:

    +
    +
    +
    +
    git submodule foreach --recursive "git checkout master; git pull"
    +
    +
    +
    +

    If modules are added, these should be added to your project too, which is not done by the commands above. Run:

    +
    +
    +
    +
    git submodule update --init
    +
    +
    +
    +

    Note that if you use the --init option, the already-initialized submodules will not be updated. You might have to run the command without --init afterwards.

    +
    +
    +
    +

    Check out the Development Branch of your Library

    +
    +

    You can see what branch mylib is currently on like this:

    +
    +
    +
    +
    cd boost-root/libs/mylib
    +git branch
    +
    +
    +
    +

    Then if you need to change the branch to a development branch such as develop, do this:

    +
    +
    +
    +
    cd boost-root/libs/mylib
    +git checkout develop
    +
    +
    +
    +

    You only have to do that once; your local repo working copy will sit on the branch until it is explicitly changed by a command you give.

    +
    +
    +

    Of course, you don’t have to change the directory before every command, and from here on this tutorial will assume the directory has not been changed since the prior example.

    +
    +
    +

    If there is any possibility the branch head content in the public upstream repo has changed, you also will want to update content:

    +
    +
    +
    +
    cd boost-root/libs/mylib
    +git pull
    +
    +
    +
    +

    From this point on, it is assumed you have already done a cd boost-root/libs/mylib.

    +
    +
    +
    +

    Testing Locally

    +
    +

    Unless you are 100% sure of the state of your library’s regression tests, it is a good idea to run the regression tests before making any changes to the library:

    +
    +
    +
    +
    pushd test
    +b2
    +popd
    +
    +
    +
    +
    +

    Checking Status

    +
    +

    Before making changes, it is a good idea to check status. Here is what that looks like on Windows; the message you get may vary somewhat:

    +
    +
    +
    +
    >git status
    +# On branch develop
    +nothing to commit, working directory clean
    +
    +
    +
    +
    +

    Fix a Simple Bug Directly on develop

    +
    +

    For simple bugs, particularly in projects with a single maintainer, it is common practice to fix bugs directly in the develop branch. Creating a test case with your favorite editor, testing the test case, fixing the bug, testing the fix, and then iterating if necessary is no different than with any programming environment.

    +
    +
    +

    Once the fix is complete, you then commit the fix locally and push from your local repo up to your public boostorg repo on GitHub. These same commands would be used for any Git project, so hopefully you are already somewhat familiar with them:

    +
    +
    +
    +
    cd boost-root/libs/mylib
    +git commit -a -m "my bug fix"
    +git push
    +
    +
    +
    +

    There are some significant disadvantages to this simple approach:

    +
    +
    +
      +
    • +

      The fix is now made to develop but you must remember to merge it to a release branch or directly to master. It is very easy to forget to do that merge, particularly if this is a mature library you are not working with very often.

      +
    • +
    • +

      Users who need the bug fix right away are forced to jump through hoops to retrieve the fix from develop. +Putting out a point release solves both of those problems. Read on…​

      +
    • +
    +
    +
    +
    +

    Fix a Bug using a Hot-fix Branch

    +
    +

    Fixing a bug directly on the develop branch is fine, if that’s the library’s policy, but if the bug is messy, multiple maintainers are involved, interruptions are expected, or other complexities are present, then it is better practice to work on the bug in a separate branch. And doing that on a hot-fix branch solves the problems mentioned at the end of the prior section.

    +
    +
    +

    The operational distinction between a bug-fix branch and a hot-fix branch is that a bug-fix branch is branched from develop and then at completion merged back to develop, while a hot-fix branch is branched from master and then at completion is merged to both master and develop. With either approach, the branch is deleted after it has been merged.

    +
    +
    +
    +
    git checkout master
    +git checkout -b hotfix/complex-boo-boo
    +
    +
    +
    +

    This creates the branch hotfix/complex-boo-boo, and switches to it. Incidentally, hotfix/ is part of the name, not a directory specifier. The new branch is based on branch master because the working copy was on branch master at the time of the branch.

    +
    +
    +

    Since the bug is complex, it may take some time to fix and may go through several cycles of fixes, tests, and commits.

    +
    +
    +

    Once the bug is fixed and a final commit is done, then it is time to merge the hotfix/complex-boo-boo branch into master and develop:

    +
    +
    +
    +
    git checkout master
    +git merge hotfix/complex-boo-boo
    +git push
    +git checkout develop
    +git merge hotfix/complex-boo-boo
    +git push
    +git branch -d hotfix/complex-boo-boo
    +
    +
    +
    +
    +

    Start Work on a New Feature

    +
    +

    Developers are encouraged to create a (possibly private) branch to work on new features, even simple ones, since development of new features on the develop branch might leave it unstable for longer that expected. Using the Git Flow convention, the branch will be named feature/add-checksum-option.

    +
    +
    +
    +
    git checkout develop
    +git checkout -b feature/add-checksum-option
    +
    +
    +
    +

    When you create the branch, or perhaps later, you may decide the branch should be public (i.e. be present in the library’s public boostorg repo) so that you can share the branch with others or just to back it up. If so, set that up by running:

    +
    +
    +
    +
    git push --set-upstream origin feature/add-checksum-option
    +
    +
    +
    +

    Whether or not --set-upstream origin bugfix/complex-boo-boo is actually needed depends on the branch.autosetupmerge configuration variable that isn’t discussed here. If you don’t supply --set-upstream origin bugfix/complex-boo-boo on your first push and it turns out to be needed, you will get an error message explaining that.

    +
    +
    +

    The usual cycle of coding, testing, commits, and pushes (if public) then begins. If other work needs to be done, a stash or commit may be done to save work-in-progress, and the working copy switched to another branch for awhile. If significant fixes or other enhancements have been made to develop over time, it may be useful to merge develop into the feature branch so that the eventual merge back to develop has less conflicts. Here is how to merge from develop to feature/add-checksum-option:

    +
    +
    +
    +
    git checkout feature/add-checksum-option
    +git merge develop
    +
    +
    +
    +
    +

    Lightweight Library Release

    +
    +

    Small, simple libraries and simple releases just merge the development branch, such as develop, into master, and test like this:

    +
    +
    +
    +
    git checkout master
    +git merge --no-ff develop
    +pushd test
    +b2
    +popd
    +
    +
    +
    +
    +
    Warning
    +
    +

    If there are any test failures, correct the problem, retest, and commit the fixes before proceeding with the release.

    +
    +
    +
    +
    +

    If there are no test failures, tag for release and declare victory:

    +
    +
    +
    +
    git push                            # push merge results
    +git tag -a -m "tag for release" mylib-2014-06-02
    +git push origin mylib-2014-06-02    # push specific tag to avoid pushing all local tags
    +
    +
    +
    +

    See Super-Project Library Workflow for release tag naming conventions.

    +
    +
    +
    +

    Heavyweight Library Release

    +
    +

    Large, complex libraries, particularly those with multiple developers working in parallel, need to use a release procedure that scales up better than the lightweight procedure. The Git Flow approach is recommended. Find out more at Super-Project Library Workflow and be sure to study the examples given in Vincent Driessen’s original blog post.

    +
    +
    +
    +
    +
    +

    Effects of git submodule update

    +
    +
    +

    The following table, based on actual tests run using git version 1.8.4.msysgit.0, shows the effects on a submodule of:

    +
    +
    +
    +
    cd boost-root
    +git checkout master
    +git pull
    +git submodule update
    +
    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Submodule BranchSubmodule ContentsSubmodule relative to Super-projectEffects on Submodule

    Detached

    Unmodified

    Up-to-date

    None

    Detached

    Unmodified

    Behind

    git pull

    Detached

    Uncommitted change

    Up-to-date

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA…​) in submodule path '…​'

    Detached

    Uncommitted change

    Behind

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA …​) in submodule path '…​'

    Detached

    Committed change

    Up-to-date

    git checkout --detach

    Detached

    Committed change

    Behind

    git checkout --detach; git pull

    master

    Unmodified

    Up-to-date

    git checkout --detach

    master

    Unmodified

    Behind

    git pull (but no detach)

    master

    Uncommitted change

    Up-to-date

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA…​) in submodule path '…​'

    master

    Uncommitted change

    Behind

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA…​) in submodule path '…​'

    master

    Committed change

    Up-to-date

    git checkout --detach

    master

    Committed change

    Behind

    git checkout --detach; git pull

    develop

    Unmodified

    Up-to-date

    git checkout --detach

    develop

    Unmodified

    Behind

    git checkout --detach; git pull

    develop

    Uncommitted change

    Up-to-date

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA…​) in submodule path '…​'

    develop

    Uncommitted change

    Behind

    error: Your local changes to the following files would be overwritten by checkout: …​ Please, commit your changes or stash them before you can switch branches. Aborting Unable to checkout (SHA…​) in submodule path '…​'

    develop

    Committed change

    Up-to-date

    git checkout --detach

    develop

    Committed change

    Behind

    git checkout --detach; git pull

    +
    +
    +
    Note
    +
    +

    Be aware that git checkout --detach; and git pull are used as shorthand to describe the apparent effects. The actual git implementation may differ.

    +
    +
    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    Beman Dawes created and maintained this page. The content has been revised many times based on comments and list postings from Andrey Semashev, John Maddock, Daniel James, Michael Cox, Pete Dimov, Edward Diener, Bjørn Roald, Klaim - Joël Lamotte, Peter A. Bigot, and others.

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/superproject/library-workflow.html b/preview/contributor-guide/superproject/library-workflow.html new file mode 100644 index 0000000..b885d0d --- /dev/null +++ b/preview/contributor-guide/superproject/library-workflow.html @@ -0,0 +1,486 @@ + + + + + + + + + + + + + + Super-Project Library Workflow :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Super-Project Library Workflow

    +
    +
    +
    +

    Workflow is the term used to describe the steps a Boost library developer follows to create, maintain, and release a library. The workflow presented here is designed for Boost’s individual libraries. The workflow for the Super-project may differ.

    +
    +
    +
    +
    +

    Git Flow

    +
    +
    +

    The workflow model Boost recommends is called Git Flow. It was introduced as a simple blog posting by Vincent Driessen on January 5th, 2010, that went viral and has become a widely used software engineering practice.

    +
    +
    +

    This workflow has arguably become so successful because it scales well from very small to very large projects, and that’s one of the reasons it is recommended (but not required) for Boost libraries.

    +
    +
    +
      +
    • +

      An unusually simple, single developer library would have only the permanent develop and master branches that are required for all Boost libraries.

      +
    • +
    • +

      A more typical library would occasionally add temporary feature branches, either private or public. Feature branch names follow the feature/x model, where x names the specific feature being developed.

      +
    • +
    • +

      A larger library, particularly if it has multiple developers, would always have some active public feature branches, and at least occasionally employ release staging branches and hotfix branches. Individual developers would often use private branches.

      +
    • +
    +
    +
    +

    Many Git Flow model diagrams are available online - print one out and hang it on your wall!

    +
    +
    +
    +
    +

    Command Line Tools

    +
    +
    +

    For those who use Git from the command line, git-flow command line tools are available to automate common operations. See git-flow wiki for more information, including installation instructions for various platforms.

    +
    +
    +
    +
    +

    Branch Names

    +
    +
    +

    All Boost libraries are required to have two branches:

    +
    +
    +
      +
    1. +

      master is always the library’s latest release. It should always be stable.

      +
    2. +
    3. +

      develop is always the main development branch. Whether it is always stable or not is up to the individual library.

      +
    4. +
    +
    +
    +

    These branches are required so that Boost release management and other scripts know the branch names.

    +
    +
    +

    While Boost libraries are not required to use the following branches, these naming conventions are recommended if the branches are present.

    +
    +
    +
      +
    • +

      feature/descriptive-name for feature branches. For example, feature/add-roman-numeral-math.

      +
    • +
    • +

      bugfix/descriptive-name for problem fix branches of develop that will be merged back to develop after the fix. For example, bugfix/ticket-1234-error-msg-not-clear.

      +
    • +
    • +

      hotfix/descriptive-name for problem fix branches of master that will be merged back to master and also to develop after the fix. For example, hotfix/ticket-5678-crash-if-result-negative.

      +
    • +
    • +

      release/n.n.n for release staging branches. For example, release/1.56.2.

      +
    • +
    +
    +
    +
    +
    +

    Release Names

    +
    +
    +

    Individual Boost libraries are free to choose their own release numbers, and these library release numbers are normally unrelated to the release numbers for the Super-project. The recommended release naming convention is the traditional three unsigned integers separated by periods (for example: 1.2.3) where:

    +
    +
    +
      +
    • +

      The first integer is the major version number, with each major version, with 0 being used for initial development and 1 for the first production-usable version. A change in version number is recommended when there are breaking changes.

      +
    • +
    • +

      The middle integer is the release number, reset to 0 with each version update and otherwise increasing monotonically.

      +
    • +
    • +

      The last integer is the patch level, reset to 0 with each revision and otherwise increasing monotonically. A patch level greater than 1 indicates a so-called point releases, normally containing bug fixes but not new features.

      +
    • +
    +
    +
    +
    +
    +

    Release Tags

    +
    +
    +

    A release tag is usually the library name, a hyphen, the release number, and then possibly "-beta#" or "-rc#" if applicable. Thus the second release candidate for Boost.Timer release 1.2.3 would be "timer-1.2.3-rc2".

    +
    +
    +

    Peter A. Bigot suggested library name prefixes for tags to avoid tag namespace pollution. Without the prefix, local tags could be overwritten.

    +
    +
    +

    Libraries choose their own release numbers. A simple library that does not require a complex release numbering convention might just use the date, such as "system-2014-06-02".

    +
    +
    +
    +
    +

    Rationale for Choice of Git Flow

    +
    +
    +

    Git Flow scales well from very small to very large projects. The same overall workflow model serves the whole spectrum of Boost libraries, even though the details differ. +Git Flow has become widely known and widely used. Boost doesn’t have to pioneer a new workflow.

    +
    +
    +
    +
    +

    Aside: Deleting Merged Branches

    +
    +
    +

    The usual culture with Git is to delete feature branches as soon as they are merged to some other branch, and is followed by Git Flow. This approach is also recommended for Boost developers. After all, the merged-to branch keeps the commit history alive and there’s no longer any need to keep the old label around. If you delete a branch without merging it, of course, any content and commit history exclusive to that branch is lost.

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/superproject/overview.html b/preview/contributor-guide/superproject/overview.html new file mode 100644 index 0000000..dad4692 --- /dev/null +++ b/preview/contributor-guide/superproject/overview.html @@ -0,0 +1,466 @@ + + + + + + + + + + + + + + Super-Project Layout :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Super-Project Layout

    +
    +
    +
    +

    This section covers the organization of the Boost C++ Libraries into separate, independently developable modules, each residing in its own repository, to facilitate development, integration, and selective inclusion of individual libraries.

    +
    +
    +

    This section provides an overview of how the Super-project is organized.

    +
    +
    +
    +
    +

    Overall Organization

    +
    +
    +

    The Boost Super-project consists of separate projects for each individual library. In terms of Git, the Super-project treats the individual libraries as submodules.

    +
    +
    +

    All public repositories are hosted at GitHub boostorg.

    +
    +
    +

    Releases of individual libraries occur asynchronously from releases of the Super-project.

    +
    +
    +
    +
    +

    Repositories

    +
    +
    +
      +
    • +

      The Super-project has its own public repository within boostorg. It treats each individual library as a submodule, i.e. a link to a particular release in the library’s public GitHub repository. The Super-project is maintained by the Boost release managers, and most library developers do not have write access.

      +
    • +
    • +

      Each individual library has its own public repository within boostorg. For example, Boost.Config has a public repository here. The maintainer of a library decides who has write access to the public repository. Release managers and their helpers also have write access for administrative purposes.

      +
    • +
    • +

      As with any Git project, a library’s developers do day-to-day work using private repositories on their local machines. When they push changes from these local private repositories up to the library’s public repository is up to them, as is when the library issues releases. As usual with Git, the local repositories may have private branches that are never pushed to the public repository.

      +
    • +
    • +

      Libraries are required to follow certain naming conventions for branches and directories, so that both humans and automatic test and management tools know where to find commonly referenced components. But beyond those requirements, each library is free to use whatever branch and directory strategies they wish.

      +
    • +
    +
    +
    +
    +
    +

    Branches

    +
    +
    +

    Boost requires all libraries have at least the two branches master and develop.

    +
    +
    +

    Releases for both the Super-project and individual libraries are always on branch master. master in the library’s boostorg public repo should be stable at all times, so should only be pushed to the library’s public repository when it is stable and ready to ship.

    +
    +
    +

    Branch develop is the main development branch. Whether or not develop is stable in the library’s public boostorg repository is up to the library maintainer.

    +
    +
    +

    Additional branches, if any, are up to the library maintainer. See Git Flow for Workflow.

    +
    +
    +
    +
    +

    Directory Structure

    +
    +
    +

    Your library’s directory structure conforms to Boost directory structure conventions, so both users and automatic processes can find header files, test files, build configurations, and the like. Beyond the conventions, your library’s directory structure is up to you.

    +
    +
    +

    The Super-project header files are placed in an include/boost directory hierarchy within the library’s top-level directory. Here is what a very simple header-only library named simple would look like:

    +
    +
    +
    +
         simple
    +       include
    +         boost
    +           simple
    +             twice.hpp
    +       test
    +         twice_test.cpp
    +         Jamfile.v2
    +       index.html
    +
    +
    +
    +
    +
    Note
    +
    +

    The sub-directory hierarchy include/boost/…​ (where …​ represents the library’s directories and header files) ensures that the library is entirely self-contained within the top-level directory.

    +
    +
    +
    +
    +

    A real library would also have additional sub-directories such as doc, example, and src, as described in the directory conventions, but they are left out of simple for the sake of brevity.

    +
    +
    +
    +
    +

    Git Flow for Workflow

    +
    +
    +

    Boost recommends, but does not require, the approach to library workflow that has come to be known as Git Flow. For more about how this applies to Boost libraries, see Super-Project Library Workflow.

    +
    + +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/boost-test-matrix.html b/preview/contributor-guide/testing/boost-test-matrix.html new file mode 100644 index 0000000..e9c801e --- /dev/null +++ b/preview/contributor-guide/testing/boost-test-matrix.html @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + Test Matrix :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Test Matrix

    + +
    +

    Introduction

    +
    +
    +

    The Boost Test Matrix is an automated testing system that runs tests on Boost libraries across a wide range of platforms, compiler versions, and configurations. Its primary purpose is to ensure that the libraries work correctly under various conditions and to identify any compatibility issues.

    +
    +
    +

    The Test Matrix includes tests run on different operating systems (Windows, Linux, macOS) and with various compilers (such as GCC, Clang, MSVC). This diversity helps in catching issues that might only appear in specific environments.

    +
    +
    +

    For information on running regression tests locally, refer to Local Regression Tests.

    +
    +
    +
    +
    +

    Regression Dashboard

    +
    +
    +

    The results of library tests are published on the +Boost Regression Testing Dashboard:

    +
    + +++++ + + + + + + + + + + + + + + + + + + + +
    VersionResultsIssues

    Develop branch

    Summary

    Unresolved Issues

    Master branch

    Summary

    Unresolved Issues

    +
    +

    This dashboard is publicly accessible and provides detailed information about the test results for most libraries.

    +
    +
    +
    +
    +

    Handling Test Failures

    +
    +
    +

    If your contribution causes test failures, it’s expected that you take responsibility for fixing them. This might involve making code adjustments or collaborating with others if the issue is complex, or affects multiple parts of Boost.

    +
    +
    +

    On the dashboard, you will find a matrix of test results. The columns represent different test runners (which correspond to different platforms, compiler versions, etc.), and the rows represent individual libraries.

    +
    +
    +

    When you click on the Dashboard URL, you will see the test Summary.

    +
    +
    +
    +test matrix summary +
    +
    +
    +

    The table is large, and you will need to scroll up and down and left and right to view all relevant results. Note that some entries are underlined (even OK entries) which indicates they are links to further information.

    +
    +
    +
    +test matrix sample +
    +
    +
    +

    Dashboard Legend

    +
    +

    The dashboard uses different colors or labels to indicate the status of the tests (such as 'pass', 'fail', or 'unresolved'). Understanding these labels is key to interpreting the test results correctly. Note that some tests are expected to fail.

    +
    +
    +
    +test matrix legend +
    +
    +
    +

    By clicking on specific cells in the matrix, you can view detailed results for a particular library and test runner. This includes information about which tests passed, which failed, and often detailed logs of the test runs.

    +
    +
    +
    +test matrix sample 2 +
    +
    +
    +
    +

    Example

    +
    +

    For example, click on the Boost.Asio entry in the left-hand column, and you will bring up the test matrix for the Asio/Master library.

    +
    +
    +
    +test matrix asio +
    +
    +
    +

    Go deeper by clicking on the entries in the left-hand column, which are now individual tests, to bring up the test code. For example, click on any_completion_handler to view its source.

    +
    +
    +
    +test matrix asio completion handler +
    +
    +
    +

    Selecting the column headers will bring up the configuration information that is being specified before each test in the column is run.

    +
    +
    +
    +test matrix teeks +
    +
    +
    +
    +

    Developer Report

    +
    +

    If you select the Report info entry, top left on the left-hand column, you can see some metrics for the overall test process:

    +
    +
    +
    +test matrix developer report +
    +
    +
    +
    +
    +
    +

    Boost Build

    +
    +
    +

    The Test Matrix uses B2 as its build system. Understanding how to write and modify Jamfiles (Boost.Build scripts) can be helpful for integrating your tests into the matrix.

    +
    +
    +
    +
    +

    Test Process Feedback

    +
    +
    +

    If you encounter issues with the testing infrastructure or have suggestions for improvement, engage with the Boost community (refer to Getting Involved). The testing process is continually evolving, and contributions to the testing infrastructure itself are valuable.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/continuous-integration.html b/preview/contributor-guide/testing/continuous-integration.html new file mode 100644 index 0000000..be2d3f4 --- /dev/null +++ b/preview/contributor-guide/testing/continuous-integration.html @@ -0,0 +1,1039 @@ + + + + + + + + + + + + + + Continuous Integration :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Continuous Integration

    + +
    +

    Introduction

    +
    +
    +

    The Boost project uses Continuous Integration(CI) to ensure the quality and integrity of its code. CI is the practice of merging all developers' working copies into a shared mainline several times a day. The main aim is to prevent integration issues, which can be identified and addressed as early as possible.

    +
    +
    +

    Boost uses several CI services for testing on different platforms and compilers. Many libraries use two or three of the systems described here, as does the Super-project itself.

    +
    +
    +
    +
    Notes
    +
    +

    It is a requirement for a new library submission to Boost to include an appropriate CI system. Refer to the examples for each CI system to better understand what is involved.

    +
    +

    Currently, Boost does not use Continuous Deployment(CD) - the release schedule is fixed and libraries are not continuously updated. This is to ensure complete testing and code reliability before any release for public use.

    +
    +
    +
    +
    +
    +
    +
    +

    New Library CI Framework

    +
    +
    +

    A recommended process to start a new Boost library is to clone the contents of the boost-ci repo. This repo contains the basic CI framework for a new library. Clone it, then adjust and edit it appropriately.

    +
    +
    +

    This repository contains scripts that enable CI with:

    +
    + +
    +

    For step-by-step processes, and tables of supported compilers, refer to the boost-ci README.md.

    +
    +
    +

    Testing Trouble Spots

    +
    +

    There are a few areas of CI testing that are fairly unique to Boost, and can present difficulties to newcomers:

    +
    +
    +
      +
    1. +

      You test with the Super-project, cloning it and placing your library inside a submodule. This is unique to Boost, you might expect to consume Boost as a dependency, but this is not how it works.

      +
    2. +
    3. +

      You test with the develop or master branches of the Super-project Repository, not with the latest stable release.

      +
    4. +
    5. +

      The CMake workflows are not trivial, nor are they the usual CMake steps.

      +
    6. +
    +
    +
    +

    Refer to the sections:

    +
    +
    + +
    +
    +

    When tackling CI issues, it is expected that you will ask questions on the Boost developers mailing list.

    +
    +
    +
    +
    +
    +

    GitHub Actions

    +
    +
    +

    Boost has been incorporating GitHub Actions into its testing workflows. This is a CI/CD system platform provided directly by GitHub. It can run tests on a variety of platforms and configurations. Here’s a basic outline of how GitHub Actions works for Boost:

    +
    +
    +
      +
    1. +

      GitHub Actions uses YAML files stored in a directory called .github/workflows/ at the root of the repository to define the build environment and steps. For instance, a workflow file might specify which operating systems and compilers to use, any dependencies to install, and the commands to run for building and testing the code.

      +
    2. +
    3. +

      When changes are pushed to the repository, or at scheduled intervals, GitHub Actions automatically initiates the actions defined in the workflow file. This might include building the project and running the test suite.

      +
    4. +
    5. +

      After the workflow runs, GitHub Actions reports the result. If any step in the workflow fails, the failure is reported, which helps developers to quickly identify and address issues. The status of each workflow run is displayed on the GitHub interface, allowing anyone to quickly check the status of the project.

      +
    6. +
    +
    +
    +

    Boost also uses GitHub Actions support for matrix builds (allowing Boost to run the same build steps on multiple combinations of operating systems, compilers, etc.), caching of dependencies to speed up builds, and the ability to create custom actions.

    +
    +
    +
    +
    Note
    +
    +

    As there are a lot of libraries under boostorg, the quota of GitHub Actions can be reached, and they can take some time to complete.

    +
    +
    +
    +
    +

    Example GitHub Workflows

    +
    +

    Refer to:

    +
    +
    + +
    +
    +
    +
    +
    +

    Drone

    +
    +
    +

    Drone is an open-source CI system built on container technology. Each step in a Drone build usually runs in its own Docker container, allowing it to use any language, tool, or service that can run inside a Docker container. This offers excellent environment consistency and isolation between steps. You can run your Drone pipelines locally on your machine for testing purposes before pushing changes to your repository.

    +
    +
    +

    Drone can use a simple YAML configuration file, .drone.yml, placed at the root of your git repository. However, as pipelines grow in complexity, managing them with YAML can become challenging. This is where .drone.jsonnet and .drone.star files come in, which are associated with the Jsonnet and Starlark scripting languages respectively. They both serve the purpose of creating more dynamic, reusable, and maintainable pipeline configurations.

    +
    +
    +
      +
    • +

      Jsonnet is a data templating language for app configuration. It is a superset of JSON and allows for custom scripting to dynamically produce JSON (and by extension, YAML). With .drone.jsonnet, you can create advanced pipeline configurations that aren’t feasible with static YAML files.

      +
    • +
    • +

      Starlark is a Python-inspired language that was created by Google and is used for configuring Bazel build systems. Similar to Jsonnet, it allows you to create more complex and maintainable pipeline configurations.

      +
    • +
    +
    +
    +

    Both Jsonnet and Starlark allow you to use logic like conditionals and loops in your configuration files, making them a powerful tool for complex CI/CD pipelines. If you have solid Python experience, for example, Starlark’s Python-like syntax might be a better choice. If you’re working in a JSON-heavy environment, Jsonnet might be more suitable.

    +
    +
    +
      +
    1. +

      Drone uses a file named .drone.yml, .drone.jsonnet or .drone.star, and a .drone folder, at the root of the repository to define the build pipeline, including the environment, build steps, and notification settings. The environment is typically a Docker container, allowing for a high degree of flexibility and customization.

      +
    2. +
    3. +

      When changes are pushed to the repository, Drone automatically runs the build pipeline defined in the .drone file. This involves building the software and running a suite of tests.

      +
    4. +
    5. +

      After the pipeline finishes, Drone reports the results. If any step fails, developers can be notified immediately, helping to catch and fix issues early. The status of each pipeline run can also be seen on the Drone dashboard and optionally on the GitHub interface.

      +
    6. +
    +
    +
    +

    Drone also includes support for matrix builds, secrets management (for handling sensitive data), and plugins (for extending functionality).

    +
    +
    +
    +
    Note
    +
    +

    Drone will not be available to a new library developer until the project is whitelisted. This whitelisting is not required for GitHub Actions and for the other CI systems listed in this section. Refer to Drone-ci for specific details.

    +
    +
    +
    +
    +

    Example .drone.jsonnet Files

    +
    +

    Refer to:

    +
    + +
    +
    +

    Example .drone.star Files

    +
    +

    Refer to:

    +
    + +
    +
    +
    +
    +

    Travis CI

    +
    +
    +

    Travis CI is used for testing on Linux and macOS environments. It is a hosted, distributed continuous integration service used to build and test software projects hosted at GitHub. Here’s the overall process:

    +
    +
    +
      +
    1. +

      Travis CI uses a file named .travis.yml in the root of the repository to define the build environment and the build steps. This file lists the operating systems and compilers to use, any dependencies to install, and the commands to run for building and testing the code.

      +
    2. +
    3. +

      Whenever changes are pushed to the repository on GitHub, Travis CI automatically initiates a build and runs the tests according to the instructions in .travis.yml. Boost libraries usually have extensive test suites, and Travis CI helps ensure that changes do not break existing functionality.

      +
    4. +
    5. +

      After each build, Travis CI reports the results. If the build or any tests fail, it can notify the developers so that they can fix the issue. On GitHub, the status of the latest build is shown next to each commit, so anyone can quickly see whether the current version of the code is passing all tests.

      +
    6. +
    +
    +
    +

    Boost also uses Travis CI’s features for more complex workflows, using the matrix feature to test code with multiple versions of compilers or dependencies, and uses stages to structure their build pipeline into phases like build, test, and deploy.

    +
    +
    +
    +
    Note
    +
    +

    Although a fair number of libraries use Travis CI, it is not recommended for new libraries, due to some instances of stalling test builds.

    +
    +
    +
    +
    +

    Example .travis.yml Files

    +
    +

    Refer to:

    +
    + +
    +
    +
    +
    +

    AppVeyor

    +
    +
    +

    Appveyor is used for testing on Windows. It is a continuous integration service which can be configured to build projects for various systems, including MSVC, MinGW, and Cygwin. The overall process is:

    +
    +
    +
      +
    1. +

      AppVeyor uses a file named appveyor.yml in the root of the repository to define the build environment and the steps for building and testing. This file describes which Windows images to use, any dependencies that need to be installed, and the commands to run for building and testing the code.

      +
    2. +
    3. +

      When changes are pushed to the GitHub repository, AppVeyor automatically initiates a build and runs the tests according to the instructions in appveyor.yml. The goal of this is to catch and fix any failures or issues that occur in the Windows environment.

      +
    4. +
    5. +

      After each build, AppVeyor reports the result. If the build or any tests fail, it notifies the developers, allowing them to address the issues. The status of the latest build can also be seen on GitHub, providing an at-a-glance view of the code’s health.

      +
    6. +
    +
    +
    +

    AppVeyor also supports parallel testing, a build cache to speed up builds, and the ability to deploy built artifacts.

    +
    +
    +

    Example appveyor.yml Files

    +
    +

    Refer to:

    +
    + +
    +
    +
    +
    +

    CircleCI

    +
    +
    +

    CircleCI is a CI/CD platform that supports a wide range of languages, tools, and services, making it flexible for different testing requirements. It is less commonly used than GitHub Actions or AppVeyor, but is used by the Super-project Repository and a few libraries.

    +
    +
    +
      +
    1. +

      CircleCI uses a file named config.yml stored in a directory called .circleci at the root of the repository. This file defines the build environment and steps, such as which Docker images to use, dependencies to install, and the commands for building and testing.

      +
    2. +
    3. +

      Upon changes being pushed to the repository or on a schedule, CircleCI automatically executes the instructions in the config.yml file. This usually includes building the project and running the test suite.

      +
    4. +
    5. +

      After the workflow completes, CircleCI reports the results. If any part of the workflow fails, developers are notified, which allows them to address the issues swiftly. The status of the workflow run is visible on the GitHub interface, providing at-a-glance insights into the project’s health.

      +
    6. +
    +
    +
    +

    CircleCI also supports parallel testing, caching of dependencies, and matrix builds.

    +
    +
    +

    Example config.yml Files

    +
    +

    Refer to:

    +
    + +
    +
    +
    +
    +

    Azure Pipelines

    +
    +
    +

    Azure Pipelines is a cloud service provided by Microsoft to automatically build, test, and deploy applications. Here’s how it generally works:

    +
    +
    +
      +
    1. +

      Azure Pipelines uses a file named .azure-pipelines.yml at the root of the repository to define the build environment and steps. This file specifies the operating systems and compilers to use, any dependencies to install, and the commands to run for building and testing the code.

      +
    2. +
    3. +

      When changes are pushed to the repository, Azure Pipelines automatically triggers a build and runs the tests according to the instructions in the azure-pipelines.yml file. This helps ensure that changes do not break existing functionality.

      +
    4. +
    5. +

      After each build, Azure Pipelines reports the results. If the build or any tests fail, it notifies the developers, allowing them to address the issues. The status of the latest build can also be seen on GitHub, providing an at-a-glance view of the code’s health.

      +
    6. +
    +
    +
    +

    Azure Pipelines provides several additional features, such as support for parallel testing, a build cache to speed up builds, and the ability to deploy built artifacts.

    +
    +
    +

    Example azure-pipelines.yml Files

    + +
    +
    +
    +
    +

    Coverage

    +
    +
    +

    Code coverage is a measure used to describe the degree to which the source code of a program is executed when a particular test suite runs. A program with high code coverage, measured as a percentage, has had more of its source code executed during testing, which generally means it has a lower chance of containing undetected bugs compared to a program with low code coverage.

    +
    +
    +

    Code coverage analysis can uncover areas of a library not covered by existing tests, so developers can write new tests to cover these blind spots. It can also highlight areas of over-testing, where the same code is tested redundantly, which could lead to slower test times without providing extra benefit.

    +
    +
    +

    There are several types of code coverage, including:

    +
    +
    +
      +
    • +

      Function Coverage measures if each function or method in the codebase has been called.

      +
    • +
    • +

      Statement Coverage measures if each statement or instruction in the codebase has been executed.

      +
    • +
    • +

      Branch Coverage measures if each possible branch from each decision point has been executed. For example, both true and false branches from an if statement.

      +
    • +
    • +

      Condition Coverage measures if each boolean sub-expression has been evaluated to both true and false. For example, given if (A==B || C==D), there are two boolean sub-expressions to evaluate.

      +
    • +
    • +

      Path Coverage measures if all possible paths (sequence of statements, branches) have been covered. This is generally considered the most comprehensive, but also the most challenging to achieve, especially in complex programs.

      +
    • +
    +
    +
    +

    In a CI pipeline, code coverage is typically measured (by Codecov.io or Coverity Scan) after each change to the codebase. Coverage reports can be generated and reviewed to spot areas of the code that are not well-tested.

    +
    +
    +

    Codecov.io

    +
    +

    Codecov.io is a tool that provides insights about code coverage in a software project. Code coverage is a measure of how much of your code is actually executed when your test suite runs. By highlighting parts of your code that aren’t tested, code coverage tools like Codecov help you write better tests and thus improve the quality of your software.

    +
    +
    +

    Here’s an overview of how Codecov works in the context of a CI pipeline:

    +
    +
    +
      +
    1. +

      Codecov integrates with GitHub. When you push code to your repository or create a pull request, it triggers your CI pipeline. Codecov uses a .codecov.yml (or codecov.yml) file to manage its settings. It’s placed at the root of your repository.

      +
      +
        +
      • +

        You can set minimum coverage thresholds that must be met, and configure how Codecov should behave if the thresholds aren’t met. For example, you might want Codecov to fail the status checks if the coverage drops by a certain percentage.

        +
      • +
      • +

        You can specify files or directories that should be ignored by Codecov. And you can customize the comments that Codecov makes on your pull requests. For example, you can change the layout of the comment, or disable comments entirely.

        +
      • +
      • +

        Codecov flags allow you to segregate coverage reports for different parts of your project or for different types of tests. Flags can be useful for projects that have multiple test suites or modules. Carryforward Flags help to handle reports for parts of the project that are not included in every CI run.

        +
      • +
      +
      +
    2. +
    3. +

      In your CI pipeline, after your tests run, you’ll generate a coverage report. The report is in XML or JSON format.

      +
    4. +
    5. +

      The generated coverage report is then uploaded to Codecov. This is usually done by a command-line tool provided by Codecov, which you’ll add as a step in your CI pipeline. The tool takes care of finding the report, compressing it, and sending it to Codecov’s servers.

      +
    6. +
    7. +

      Codecov processes the uploaded report and provides detailed coverage information on its dashboard. It shows overall project coverage, coverage changes over time, coverage for individual files, and more. Codecov can also comment on pull requests, showing how the changes would affect overall coverage.

      +
    8. +
    +
    +
    +

    Codecov also provides a browser extension that overlays coverage data directly on GitHub, so you can see coverage information as you browse your code.

    +
    +
    +

    Example .codecov.yml Files

    + +
    +
    +
    +

    Coverity Scan

    +
    +

    Coverity Scan is a static analysis tool that detects defects and vulnerabilities in your source code. It is provided as a free service for open source projects, but there’s also a commercial version for private projects. Here’s a general workflow of how you can use Coverity Scan:

    +
    +
    +
      +
    1. +

      First, you need to register your project with Coverity Scan. This involves providing some basic information about your project and agreeing to their terms of service.

      +
    2. +
    3. +

      The next step is to build your code and upload it to the Coverity Scan servers. This is typically done in your development environment, and there are a few steps involved:

      +
      +
        +
      1. +

        Install the Coverity Scan Tool. This tool is used to "build" your code and analyze it for defects.

        +
      2. +
      3. +

        Instead of building with your usual build tool (like CMake or Maven), you build with the Coverity tool. This produces a file that contains all the information Coverity needs to analyze your code.

        +
      4. +
      5. +

        You then upload this file to the Coverity servers. You can automate this step as part of your CI pipeline.

        +
      6. +
      +
      +
    4. +
    5. +

      Once your code is uploaded, Coverity analyzes it for defects and vulnerabilities. This process can take some time, depending on the size of your codebase.

      +
    6. +
    7. +

      Once the analysis is complete, you can review the results on the Coverity Scan website. Defects are categorized by type and severity, and you can drill down to see the exact lines of code that are affected.

      +
    8. +
    9. +

      Based on the results, you can then fix the defects in your code. After making changes, you’ll typically run the Coverity Scan process again to verify the fixes and find any new defects.

      +
    10. +
    +
    +
    +

    Coverity Scan is a powerful tool that can help improve the quality of your code. It’s particularly good at finding complex defects that are hard to catch with regular testing. However, it does require some setup and learning to use effectively, particularly when integrating it with a CI pipeline.

    +
    +
    +

    Example Coverity Calls

    +
    +

    Coverity Scan does not directly use a .yml or .yaml file for configuration like the other CI tools discussed here. Instead, Coverity Scan primarily relies on the build commands and Coverity Scan command-line tools to analyze the source code. You include the necessary Coverity Scan commands within the .yml files of your other CI tools, for example:

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

    Your CI test matrix should include one or more of the most popular compilers for each supported OS.

    +
    +
    +

    Windows

    +
    +
      +
    • +

      Microsoft Visual C++ (MSVC): This is Microsoft’s own compiler that comes with Visual Studio. It has excellent support for Windows-specific development and great debugging tools.

      +
    • +
    • +

      MinGW - Minimalist GNU for Windows: MinGW includes a port of the GCC (GNU Compiler Collection), which includes a C++ compiler. It’s useful for open-source projects and cross-platform development.

      +
    • +
    • +

      Clang: Clang is a compiler front end for the C, C++, and Objective-C programming languages. It uses LLVM as its back end and has been part of the LLVM release cycle since LLVM 2.6.

      +
    • +
    +
    +
    +
    +

    Linux

    +
    +
      +
    • +

      GCC, the GNU Compiler Collection: GCC is one of the most popular compilers for Linux. It supports multiple programming languages but is most often used as a C++ compiler. It’s open-source and is the default compiler on most Linux distributions.

      +
    • +
    • +

      Clang: Clang, part of the LLVM project, is a C++ compiler that provides a number of advantages over GCC, such as faster compile times and improved performance. It’s also known for providing more understandable compile errors.

      +
    • +
    • +

      Intel Compiler: While not as common for general use as GCC or Clang, the Intel C++ Compiler can produce highly optimized code, especially for parallel computation and vector operations. It’s often used in high-performance computing scenarios.

      +
    • +
    +
    +
    +
    +

    MacOS

    +
    +
      +
    • +

      Clang is the default compiler for macOS and is provided with Xcode, Apple’s integrated development environment. It’s known for providing more understandable compile errors and faster compile times compared to GCC.

      +
    • +
    • +

      GCC, the GNU Compiler Collection: While not the default, GCC can also be used on macOS. It’s typically installed via a package manager like Homebrew. However, it’s worth noting that when you install GCC on a Mac, the default "gcc" command often still points to Clang for compatibility reasons, so you might need to use a version-specific command like "gcc-9" to use the real GCC.

      +
    • +
    • +

      Intel Compiler: The Intel C++ Compiler is also available on macOS and can produce highly optimized code, especially for parallel computation and vector operations. Like on Linux, it’s often used in high-performance computing scenarios.

      +
    • +
    +
    +
    +
    +
    +
    +

    Docker Containers

    +
    +
    +

    Docker can be used to provide isolation, which can be very useful with certain development environments. For example, when there is a need to replicate an environment which could not be replicated otherwise. For example, we use Ubuntu 16 frequently, but there’s no GitHub image for it. As a workaround, the Ubuntu 22 image is used, and a Ubuntu 16 Docker container is run on it.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/fuzzing.html b/preview/contributor-guide/testing/fuzzing.html new file mode 100644 index 0000000..cf0128c --- /dev/null +++ b/preview/contributor-guide/testing/fuzzing.html @@ -0,0 +1,693 @@ + + + + + + + + + + + + + + Fuzz Testing :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Fuzz Testing

    + +
    +

    Introduction

    +
    +
    +

    What is fuzz testing? Fuzzing is a testing technique that injects random pieces of data to a software function to uncover crashes and vulnerabilities. It helps improving code security and reliability, since it can trigger edge cases that went unnoticed during unit testing.

    +
    +
    +

    How does it work? Fuzz testing relies on a fuzzing engine, a library that runs your code in a loop, injecting different inputs at each iteration. The fuzzing engine will instrument your code to measure coverage, and use this information to drive the generation of samples. Most of the samples will contain malformed input, and will test your code’s tolerance to ill-formed inputs.

    +
    +
    +

    Which kind of errors does fuzzing detect? The fuzzing engine will monitor your code for crashes. Fuzzing is often used with the address and undefined sanitizers. In short, fuzzing will make sure that your code doesn’t crash, leak or incur in undefined behavior, regardless of how malformed the input is. A lot of vulnerabilities in C++ code are related to the former kind of errors, so fuzzing can make your code more secure.

    +
    +
    +

    Should I use it? Fuzz testing is specially relevant for libraries that process potentially untrusted, user-controlled input, like network data. Libraries that implement parsers, decoders or network protocols usually benefit from fuzz testing.

    +
    +
    +

    Which Boost libraries use it? Libraries like Boost.Json, Boost.URL and Boost.Mysql use this technique - if you’re about to implement it in your library, have a look at what these libraries do.

    +
    +
    +

    Should I still write unit tests? Yes. Absolutely. Fuzzing does not replace unit tests, but complements them. Unit tests verify that your code produces the intended results by providing known inputs and running assertions on the outputs. In fuzz testing, inputs are generated randomly by the fuzzing engine, so no assertions are usually run on the outputs - fuzzing will only monitor for crashes and memory errors.

    +
    +
    +

    How can I add fuzzing to my library? We recommend using LibFuzzer, since it’s the easiest fuzzing engine to use, and the one that other Boost libraries use. You can use other fuzzing engines if you prefer.

    +
    +
    +
    +
    +

    LibFuzzer Basics

    +
    +
    +

    Quoting documentation, "LibFuzzer is an in-process, coverage-guided, evolutionary fuzzing engine". LibFuzzer will run your code multiple times with different, random inputs. It will instrument your code to measure coverage, and will attempt to generate inputs that maximize it, effectively trying to discover new paths in your code.

    +
    +
    +

    LibFuzzer is included in clang, so you don’t need to install anything to get started.

    +
    +
    +

    Let’s say we want to fuzz a function that parses JSON data, like parse_json(string_view input). We will create a source file with the following code:

    +
    +
    +
    +
    #include <string_view>
    +#include <your/parsing/function.hpp>
    +
    +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
    +{
    +    // The range [data, data+size) contains the data generated by the fuzzer
    +    std::string_view input_data (reinterpret_cast<const char*>(data), size);
    +    parse_json(input_data);
    +    return 0;
    +}
    +
    +
    +
    +

    We can build a fuzzer executable by adding -fsanitize=fuzzer to clang’s compile and link flags. This will automatically link LibFuzzer to your code. It’s advised to also enable the address and undefined sanitizers, which increases the range of errors detected by the fuzzer. We recommend building in release mode with debug symbols enabled, so crashes are symbolized correctly.

    +
    +
    +

    From the command line:

    +
    +
    +
    +
    clang++ -g -O3 -fsanitize=fuzzer,address,undefined -o fuzzer fuzzer.cpp
    +
    +
    +
    +

    As a Jamfile target:

    +
    +
    +
    +
    exe fuzzer : fuzzer.cpp : requirements
    +    <debug-symbols>on
    +    <optimization>speed
    +    <address-sanitizer>norecover
    +    <undefined-sanitizer>norecover
    +    <cxxflags>-fsanitize=fuzzer
    +    <linkflags>-fsanitize=fuzzer
    +;
    +
    +
    +
    +

    Or as a CMake target:

    +
    +
    +
    +
    add_executable(fuzzer fuzzer.cpp)
    +target_compile_options(
    +    fuzzer
    +    PRIVATE
    +    -fsanitize=fuzzer,address,undefined
    +    -fno-sanitize-recover=address,undefined
    +    -g
    +    -O3
    +)
    +target_link_options(
    +    fuzzer
    +    PRIVATE
    +    -fsanitize=fuzzer,address,undefined
    +    -fno-sanitize-recover=address,undefined
    +)
    +
    +
    +
    +

    Note that you must not define a main function - LibFuzzer will do it for you. The LLVMFuzzerTestOneInput function will be invoked repeatedly, with different input ranges.

    +
    +
    +

    You can run your fuzzer with no arguments, which will fuzz until you stop it with Ctrl+C. The executable will print a lot of messages to stdout. This section contains a reference to what they mean, if you’re curious.

    +
    +
    +

    To run the fuzzer for a limited period of time (for example, 30 seconds), use:

    +
    +
    +
    +
    ./fuzzer -max_total_time=30
    +
    +
    +
    +
    +
    +

    Corpus

    +
    +
    +

    A corpus is a collection of input samples to be used by the fuzzer. LibFuzzer uses these samples to create random mutations to use as new inputs. If a newly created sample triggers extra coverage, this sample is stored in the corpus.

    +
    +
    +

    Until now, we’ve been running our fuzzer without an initial corpus. The fuzzer will try random inputs, without any guidance, and will generate a corpus. Doing this is not advisable, though, since it reduces the effectiveness of your fuzzing - the fuzzer may fail to find some relevant inputs.

    +
    +
    +

    We always advise to provide an initial corpus (often called a seed corpus) to the fuzzer, to provide some guidance. The seed corpus should contain a variety of valid and invalid samples. You can reuse samples from your unit tests. In our JSON example, we could create a seedcorpus directory and copy all JSON files we use for unit testing.

    +
    +
    +

    Assuming that your seed corpus resides in your-lib/test/fuzzing/seedcorpus, we can run the fuzzer like this:

    +
    +
    +
    +
    ./fuzzer /tmp/corpus your-lib/test/fuzzing/seedcorpus -max_total_time=30
    +
    +
    +
    +

    The two positional arguments are understood as corpus directories. The first one is an empty directory, and the second one is our seed corpus. The fuzzer will use the first corpus directory we provide (/tmp/corpus in our case) to write all the samples it finds relevant. Using separate directories allows us to keep the seed corpus clean, since it may reside in source control.

    +
    +
    +

    When running your fuzzer as part of your CI builds, you’ll likely want to persist this new corpus to make the newly generated samples available to subsequent fuzzer runs. This section digs deeper on running fuzzers during CI builds.

    +
    +
    +
    +
    +

    Verifying the Effectiveness of your Fuzzer

    +
    +
    +

    Once you’ve written a fuzzer and run it with an adequate corpus, you should have a look at the code coverage that your fuzzer triggered. This will help you verify that your fuzzing code is correct and that your corpus is in shape. The authors have found cases where some paths were missed due to errors in the seed corpus samples. Better check!

    +
    +
    +

    We recommend to use clang’s source-based coverage for this task. To get coverage info, you should build your fuzzer with the -fprofile-instr-generate and -fcoverage-mapping compile and link flags, and then run the fuzzer normally. This will create a default.profraw file in your current directory, containing raw coverage data.

    +
    +
    +

    To visualize your coverage, run:

    +
    +
    +
    +
    llvm-profdata merge -sparse default.profraw -o fuzzer.profdata (1)
    +llvm-cov show path/to/fuzzer -instr-profile=fuzzer.profdata (2)
    +
    +
    +
    + + + + + + + + + +
    1Converts from the raw profile format emitted by the binary to something llvm-cov can understand. This command can be used to merge several coverage files from different runs, too.
    2Prints a report with line coverage for your fuzzer and any headers it uses. Replace path/to/fuzzer with the path to your compiled fuzzer. llvm-cov requires it to properly understand coverage data.
    +
    +
    +

    This may generate a lot of output. You can use the -sources argument to scope which files are presented. Pay attention to the header path printed by the above command, since Boost creates symlinks for headers. For example, if you’re in the Boost super-project root, you can scope the report to Boost.Json headers by running:

    +
    +
    +
    +
    llvm-cov show path/to/fuzzer -instr-profile=fuzzer.profdata -sources=boost/json/
    +
    +
    +
    +
    +
    +

    Corpus Minimization

    +
    +
    +

    As we’ve mentioned, it’s advisable to persist the corpus generated by your fuzzer between runs. However, it can become very big as new samples are added. Before saving the corpus, we recommend performing corpus minimization.

    +
    +
    +

    This process is run by the same fuzzer executable we’ve been using. It will run the different samples in your corpus and discard "repeated" ones, based on the code paths they trigger.

    +
    +
    +

    To run corpus minimization, use the -merge=1 flag:

    +
    +
    +
    +
    ./fuzzer /tmp/mincorpus /tmp/corpus -merge=1
    +
    +
    +
    +

    This will minimize the samples in /tmp/corpus, writing the results to /tmp/mincorpus. Note that no actual fuzzing is performed by this command.

    +
    +
    +
    +
    +

    Handling Crashes

    +
    +
    +

    If your fuzzer finds an input that makes your code crash, it will report the error and exit immediately, creating a file named crash-<id> containing the sample that caused the problem. Similarly, if an input takes too long to process, or a memory leak is found, a file timeout-<id> or leak-<id> will be written.

    +
    +
    +

    When a crash is detected, you should save the offending sample to source control, reproduce the crash, and fix your code. +During regression testing, you should make your fuzzer run that specific sample, to verify that the crash doesn’t happen again.

    +
    +
    +

    You can make your fuzzer run a single sample by specifying it as a positional command-line argument. For example, if the sample that caused the crash is your-lib/test/fuzzing/old_crashes/crash-abc:

    +
    +
    +
    +
    ./fuzzer your-lib/test/fuzzing/old_crashes/crash-abc
    +
    +
    +
    +

    This will run your fuzzer only with crash-abc. It will not perform actual fuzzing.

    +
    +
    +
    +
    +

    Running the Fuzzer in CIs

    +
    +
    +

    Your fuzzer won’t be really useful unless you run it continuously. CI platforms are a good way to achieve this. We recommend using GitHub Actions for fuzzing jobs, although other platforms with similar functionality should work, too.

    +
    +
    +

    Your fuzzing CI job should, at least:

    +
    +
    +
      +
    • +

      Attempt to restore corpus samples from previous runs.

      +
    • +
    • +

      Build the fuzzers.

      +
    • +
    • +

      Run them with any old crash samples, to prevent regressions.

      +
    • +
    • +

      Run the actual fuzzing for some time. Most libraries run each fuzzer for 30 seconds.

      +
    • +
    • +

      Minimize the corpus generated by the previous step.

      +
    • +
    • +

      Persist the minimized corpus so that it can be used by subsequent CI runs.

      +
    • +
    • +

      Archive any crashes, timeouts and leaks, so you can recover them later.

      +
    • +
    +
    +
    +

    If you’re using GitHub actions, corpus persistance can be achieved using the cache action. Building the fuzzers should be part of your B2 or CMake builds. You can use Boost.MySQL’s Jamfile as inspiration. It’s a good practice to run the fuzzers both nightly and on push/pull request events.

    +
    +
    +
    +
    +

    Best Practices for Writing Fuzzers

    +
    +
    +

    It is advisable to keep your fuzzers as targeted as possible. For example, if you have functions to parse JSON and BSON (binary JSON) files, you should write two different fuzzers, instead of a single one that invokes one or the other based on the input.

    +
    +
    +

    Your fuzzing code should be as efficient as possible. The faster it is, the more iterations the fuzzer will do, and the better the results. Avoid logging, cubic or greater complexity, and anything else that may slow down your code.

    +
    +
    +

    Try to avoid any randomness in your code. LibFuzzer works best with deterministic functions - that is, functions that, for a certain input, take always the same code paths.

    +
    +
    +

    Aside from the raw input data, you may need some extra input to configure your parsing function. For example, a JSON parser may be configured to allow comments or not. You may use part of the raw input data to configure flags like this and boost your coverage.

    +
    +
    +
    +
    +

    Boost Examples

    +
    +
    +
      +
    • +

      Boost.Mysql fuzzes all its message deserialization routines. Fuzzers are located under test/fuzzing. The seed corpus is composed of multiple binary files, compressed and stored in the same directory. Fuzzers are built and run from test/fuzzing/Jamfile. Targets in this directory are built using b2 from the fuzz.yml GitHub Actions workflow.

      +
    • +
    • +

      Boost.Json fuzzes its JSON parsing functions. Fuzzers are stored under fuzzing/. The seed corpus is generated dynamically, by copying all JSON files used for unit testing. Fuzzers are built and run from fuzzing/Jamfile. Targets in this directory are built using b2 from the run_fuzzer.yml GitHub Actions workflow.

      +
    • +
    • +

      Boost.URL is similar to to JSON, but doesn’t use a seed corpus.

      +
    • +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/intro.html b/preview/contributor-guide/testing/intro.html new file mode 100644 index 0000000..8936cf8 --- /dev/null +++ b/preview/contributor-guide/testing/intro.html @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + Introduction to Testing :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Introduction to Testing

    +
    +
    +
    +

    The Boost libraries are intended to be both reliable and portable. Every experienced programmer knows that means each library must be tested against a suitable number of test cases, on a range of platforms and compilers, and then tested again (regression tested) every time a change is made. The regression tests are run again before every public release.

    +
    +
    +

    There are three broad dimensions to Boost library testing:

    +
    +
    +
      +
    1. +

      The actual test codes - unit tests, regression tests, new feature and bug tests. Refer to Writing Tests.

      +
    2. +
    3. +

      Tests that are integrated with the primary build systems, B2 and CMake.

      +
    4. +
    5. +

      Continuous Integration

      +
    6. +
    +
    +
    +

    The new library developer needs to consider all three, however the initial focus on a new library will be the first in this list. Or, to put it another way, "Quality assurance based on a wide range of targeted tests" as one of the key answers to Professor Hoare’s question:

    +
    +
    +

    "How did software get so reliable without proof?"

    +
    + +
    +
    +
    +

    Define a Test Matrix

    +
    +
    +

    When you’re looking to submit a library to the Boost collection, it’s essential to ensure broad compatibility with various compilers, platforms, and configurations. Create a test matrix of what you intend to support, and document what you do not intend to support, and consider:

    +
    +
    +
      +
    1. +

      Testing with multiple versions of each compiler. Popular compilers to consider include:

      +
      +
        +
      • +

        GCC (GNU Compiler Collection)

        +
      • +
      • +

        Clang

        +
      • +
      • +

        MSVC (Microsoft Visual C++)

        +
        +

        The Boost user base can be using older versions of these compilers, so strive for compatibility with a reasonable range of versions if possible.

        +
        +
        +

        If your library depends on other Boost libraries or external libraries, ensure they are compatible with the compilers you are targeting. Be clear about any dependencies or prerequisites in your documentation.

        +
        +
        +

        Be wary of non-standard compiler features or extensions. If you must use them, guard them with appropriate preprocessor checks. +Boost provides its own set of configuration macros to help with this.

        +
        +
      • +
      +
      +
    2. +
    3. +

      Compatibility with various versions of the C++ Standard: C++11, C++14, C++17, C++20, and C++23. Some Boost libraries support many of the standards, while others target only more recent ones.

      +
      +
      +
      Note
      +
      +

      Supporting C++03 is no longer considered good practice.

      +
      +
      +
      +
    4. +
    5. +

      Different operating systems, including Linux, Windows, macOS, and others like various BSDs.

      +
    6. +
    7. +

      Different architectures: x86, x64, ARM, MIPS. Architecture can affect word size (usually 32 or 64 bit), endianness, memory alignment, inline assembly, cache sizes, latency, and other memory and performance issues.

      +
    8. +
    +
    +
    +

    When you have outlined your test matrix, study the predefined macros available to assist you, and make adjustments to your matrix appropriately.

    +
    +
    +
    +
    +

    Use Predefined Macros from Boost.Config

    +
    +
    +

    There are a set of macros in the Boost.Config library that can be used to identify compiler capabilities, platform specifics, and other configuration details. These macros are designed to smooth out differences between compilers and platforms, allowing for more portable code, for example:

    +
    +
    +

    Compiler Identification

    +
    +
      +
    • +

      BOOST_COMP_GNUC: Defined if the compiler is GCC.

      +
    • +
    • +

      BOOST_COMP_MSVC: Defined if the compiler is Microsoft Visual C++.

      +
    • +
    +
    +
    +
    +

    Compiler Version Checks

    +
    +
      +
    • +

      BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(19, 0, 0): Checks if the MSVC version is 19 or greater.

      +
    • +
    +
    +
    +
    +

    Platform Checks

    +
    +
      +
    • +

      BOOST_OS_LINUX: Defined if the operating system is Linux.

      +
    • +
    • +

      BOOST_ARCH_X86_64: Defined if the architecture is x86_64.

      +
    • +
    +
    +
    +
    +

    Standard Library Checks

    +
    +
      +
    • +

      BOOST_LIB_C_GNU: Defined if the C standard library is from GNU.

      +
    • +
    • +

      BOOST_LIB_STD_DINKUMWARE: Defined if the standard library is from Dinkumware (often associated with MSVC).

      +
    • +
    +
    +
    +
    +

    Feature Checks

    +
    +
      +
    • +

      BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION: Defined if the compiler does not support return type deduction introduced in C++14.

      +
    • +
    • +

      BOOST_NO_CXX11_AUTO_DECLARATIONS: Defined if the compiler does not support auto declarations from C++11. For example:

      +
      +
      +
      #include <boost/config.hpp>
      +
      +// ...
      +#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
      +// Use traditional type declaration
      +int x = 42;
      +#else
      +// Use C++11 auto
      +auto x = 42;
      +#endif
      +// ...
      +
      +
      +
      +

      Use this same coding structure for any of the other macros.

      +
      +
    • +
    +
    +
    +
    +
    +
    +

    Regression Testing

    +
    +
    +

    Boost releases are run through regression tests which automatically generates compiler status HTML tables for various platforms. Unless otherwise indicated, the C++ Standard Library implementation is the one shipped with the compiler. Refer to Generating Library Status Tables.

    +
    +
    +
    +
    Note
    +
    +

    The HTML tables are not a good indication of a particular compiler’s compliance with the C++ Standard. The Boost libraries often contain workarounds which mask compiler deficiencies.

    +
    +

    Some regression tests are run only occasionally, and might be relatively out-of-date. Check the date and revision in the column headings.

    +
    +
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    First, familiarize yourself with the Boost Test Policy.

    +
    +
    +

    Then, read the documentation for the following libraries, which support the writing of unit, feature and regression tests:

    +
    +
    + +
    +
    +

    Start small and develop a good understanding of how these testing libraries work, before writing more than a few tests.

    +
    +
    +

    Advanced Testing

    +
    +

    When you have a good understanding of the basic testing procedures, look into more advanced techniques, such as Fuzz Testing.

    +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/regression-tests.html b/preview/contributor-guide/testing/regression-tests.html new file mode 100644 index 0000000..1751df4 --- /dev/null +++ b/preview/contributor-guide/testing/regression-tests.html @@ -0,0 +1,701 @@ + + + + + + + + + + + + + + Local Regression Tests :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Local Regression Tests

    +
    +
    +
    +

    This section describes how to run regression tests on your local machine, by downloading and running a Python command-line tool.

    +
    +
    +

    For information on the regression tests run on all libraries, refer to Test Matrix.

    +
    + +
    +
    +
    +

    Running Regression Tests Locally

    +
    +
    +

    It’s easy to run regression tests on your Boost clone.

    +
    +
    +

    To run a library’s regression tests, run Boost’s b2 utility from the <boost-root>/libs/<library>/test directory. To run a single test, specify its name (as found in <boost-root>/libs/<library>/test/Jamfile.v2) on the command line.

    +
    +
    +

    See the Building BJam guide for help building or downloading bjam for your platform, and navigating your Boost distribution.

    +
    +
    +

    To run every library’s regression tests, run b2 from the <boost-root>/status directory.

    +
    +
    +

    To run Boost.Build’s regression tests, run python test_all.py from the <boost-root>/tools/build/v2/test directory.

    +
    +
    +
    +
    +

    The Run.py Tool

    +
    +
    +

    This tool runs all Boost regression tests and reports the results back to the Boost community.

    +
    +
    +

    Requirements

    +
    +
      +
    • +

      Python (2.3 ≤ version < 3.0)

      +
    • +
    • +

      Git (recent version)

      +
    • +
    • +

      At least 5 gigabytes of disk space per compiler to be tested

      +
    • +
    +
    +
    +
    +

    Step by Step Instructions

    +
    +
      +
    1. +

      Create a new directory for the branch you want to test.

      +
    2. +
    3. +

      Download the run.py script into that directory:

      +
    4. +
    5. +

      Open the run.py script in your browser.

      +
    6. +
    7. +

      Click the Raw button.

      +
    8. +
    9. +

      Save as run.py in the directory you just created.

      +
    10. +
    +
    +
    +

    The syntax to run the tool is python run.py <options>…​ [<commands>] with the following three required options, plus any others you wish to employ (for a full list, refer to Commands and Options):

    +
    +
    +
      +
    • +

      --runner=: Your choice of name that identifies your results in the reports.

      +
      +

      If you are running regressions interlacingly with a different set of compilers (e.g. for Intel in the morning and GCC at the end of the day), you need to provide a different runner ID for each of these runs, e.g. "your_name-intel", and "your_name-gcc".

      +
      +
      +

      The limitations of the report format imposes a direct dependency between the number of compilers you are testing with and the amount of space available for your runner ID. If you are running regressions for a single compiler, make sure to choose a short enough ID that does not significantly disturb the report layout. You can also use spaces in the runner ID to allow the reports to wrap the name to fit.

      +
      +
    • +
    • +

      --toolsets=: The toolsets you want to test with.

      +
      +

      If the --toolsets option is not provided, the script will try to use the platform’s default toolset (gcc for most Unix-based systems).

      +
      +
      +

      For supported toolsets, refer to toolset.

      +
      +
    • +
    • +

      --tag=: The tag you want to test. The only tags that currently make sense are develop and master.

      +
    • +
    +
    +
    +

    For example:

    +
    +
    +
    +
    python run.py --runner=Metacomm --toolsets=gcc-4.2.1,msvc-8.0 --tag=develop
    +
    +
    +
    +
    +
    Note
    +
    +

    If you are behind a firewall/proxy server, everything should still "just work". In the rare cases when it doesn’t, you can explicitly specify the proxy server parameters through the --proxy option. For example:

    +
    +
    +
    python run.py ... --proxy=http://www.someproxy.com:3128
    +
    +
    +
    +
    +
    +
    +
    +

    Commands and Options

    +
    +

    The following commands are available: cleanup, collect-logs, get-source, get-tools, patch, regression, setup, show-revision, test, test-boost-build, test-clean, test-process, test-run, update-source, and upload-logs.

    +
    +
    +

    The following options are available:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    OptionDescription

    -h, --help

    show this help message and exit

    --runner=RUNNER

    runner ID (e.g. 'Metacomm')

    --comment=COMMENT

    an HTML comment file to be inserted in the reports

    --tag=TAG

    the tag for the results

    --toolsets=TOOLSETS

    comma-separated list of toolsets to test with

    --libraries=LIBRARIES

    comma separated list of libraries to test

    --incremental

    do incremental run (do not remove previous binaries). Refer to Incremental Runs.

    --timeout=TIMEOUT

    specifies the timeout, in minutes, for a single test run/compilation

    --bjam-options=BJAM_OPTIONS

    options to pass to the regression test

    --bjam-toolset=BJAM_TOOLSET

    bootstrap toolset for 'bjam' executable

    --pjl-toolset=PJL_TOOLSET

    bootstrap toolset for 'process_jam_log' executable

    --platform=PLATFORM

    --user=USER

    Boost SVN user ID

    --local=LOCAL

    the name of the boost tarball

    --force-update

    do an SVN update (if applicable) instead of a clean checkout, even when performing a full run

    --have-source

    do neither a tarball download nor an SVN update; used primarily for testing script changes

    --ftp=FTP

    FTP URL to upload results to.

    --proxy=PROXY

    HTTP proxy server address and port (e.g.'http://www.someproxy.com:3128')

    --ftp-proxy=FTP_PROXY

    FTP proxy server (e.g. 'ftpproxy')

    --dart-server=DART_SERVER

    the dart server to send results to

    --debug-level=DEBUG_LEVEL

    debugging level; controls the amount of debugging output printed

    --send-bjam-log

    send full bjam log of the regression run

    --mail=MAIL

    email address to send run notification to

    --smtp-login=SMTP_LOGIN

    STMP server address/login information, in the following form: <user>:<password>@<host>[:<port>]

    --skip-tests

    do not run bjam; used for testing script changes

    +
    +
    +

    Output

    +
    +

    The regression run procedure will:

    +
    +
    +
      +
    1. +

      Download the most recent regression scripts.

      +
    2. +
    3. +

      Download the designated testing tool sources including Boost.Jam, Boost.Build, and the various regression programs.

      +
    4. +
    5. +

      Download the most recent from the Boost Git Repository into the subdirectory boost.

      +
    6. +
    7. +

      Build b2 and process_jam_log if needed. (process_jam_log is a utility, which extracts the test results from the log file produced by Boost.Build).

      +
    8. +
    9. +

      Run regression tests, process and collect the results.

      +
    10. +
    11. +

      Upload the results to a common FTP server.

      +
    12. +
    +
    +
    +

    The report merger process running continuously will merge all submitted test runs and publish them at various locations.

    +
    +
    +
    +

    Advanced Use

    +
    +

    Providing Detailed Information about your Environment

    +
    +

    Once you have your regression results displayed in the Boost-wide reports, you may consider providing a bit more information about yourself and your test environment. This additional information will be presented in the reports on a page associated with your runner ID.

    +
    +
    +

    By default, the page’s content is just a single line coming from the comment.html file in your run.py directory, specifying the tested platform. You can put online a more detailed description of your environment, such as your hardware configuration, compiler builds, and test schedule, by altering the file’s content. Also, consider providing your name and email address for cases where Boost developers have questions specific to your particular set of results.

    +
    +
    +
    +

    Incremental Runs

    +
    +

    By default, the script runs in what is known as full mode: on each run.py invocation all the files that were left in place by the previous run — including the binaries for the successfully built tests and libraries — are deleted, and everything is rebuilt once again from scratch. By contrast, in incremental mode the already existing binaries are left intact, and only the tests and libraries which source files has changed since the previous run are re-built and re-tested.

    +
    +
    +

    The main advantage of incremental runs is a significantly shorter turnaround time, but unfortunately incremental runs don’t always produce reliable results. Some type of changes to the codebase (changes to the b2 testing subsystem in particular) often require switching to a full mode for one cycle in order to produce trustworthy reports.

    +
    +
    +

    Run run.py in incremental mode by passing it the identically named command-line flag: python run.py …​ --incremental.

    +
    +
    +

    As a general guideline, if you can afford it, testing in full mode is preferable.

    +
    +
    +
    +

    Patching Boost Sources

    +
    +

    You might encounter an occasional need to make local modifications to the Boost codebase before running the tests, without disturbing the automatic nature of the regression process. To implement this under regression.py:

    +
    +
    +
      +
    1. +

      Codify applying the desired modifications to the sources located in the ./boost_root subdirectory in a single executable script named patch_boost (patch_boost.bat on Windows).

      +
    2. +
    3. +

      Place the script in the run.py directory.

      +
    4. +
    +
    +
    +

    The driver will check for the existence of the patch_boost script, and, if found, execute it after obtaining the Boost sources.

    +
    +
    +
    +
    +
    +
    +

    Feedback

    +
    +
    +

    Send all comments/suggestions regarding this document and the testing procedure itself to the Boost developers' mailing list.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/sanitizers.html b/preview/contributor-guide/testing/sanitizers.html new file mode 100644 index 0000000..0068470 --- /dev/null +++ b/preview/contributor-guide/testing/sanitizers.html @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + Sanitize Your Code :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Sanitize Your Code

    +
    +
    +
    +

    Consider using a code sanitizer to check for some of the more mundane, but nevertheless real, bugs and inefficiencies in your library.

    +
    +
    +

    All the tools listed have different strengths and are useful in different scenarios, so you might want to use several of them in combination.

    +
    +
    + +
    +
    +
    +
    +

    AddressSanitizer

    +
    +
    +

    Clang AddressSanitizer (ASan) is a fast memory error detector built into LLVM/Clang, gcc and other compilers. As such, it works on Windows, Linux, and MacOS. It can detect out-of-bounds accesses to heap, stack, and globals, use-after-free and use-after-return bugs, and other memory-related errors. AddressSanitizer is generally faster than Valgrind and can be used in continuous integration without significantly slowing down the test suite.

    +
    +
    +
      +
    • +

      To use ASAN, pass the -fsanitize=address switch to Clang, or set the address-sanitizer=on B2 flag. Under CMake, you need to add the flags manually.

      +
    • +
    • +

      The LeakSanitizer (LSan) runs with ASAN, and is a memory leak detector. It’s integrated into AddressSanitizer.

      +
    • +
    +
    +
    +

    The sanitizer suite also includes:

    +
    +
    +
      +
    • +

      UndefinedBehaviorSanitizer (UBSan), which is a runtime undefined behavior detector that can catch misaligned or null pointers, integer overflows, and invalid bit shifts. Set -fsanitize=undefined in Clang, or undefined-sanitizer=on in B2. For details on the usage and output, refer to Clang UndefinedBehaviorSanitizer.

      +
    • +
    • +

      MemorySanitizer (MSan) detects uninitialized reads. This tool is similar to Valgrind, but it’s generally faster and can catch some bugs that Valgrind might miss. The New Library CI Framework doesn’t include any build for MSAN, and B2 doesn’t have a feature for it, so for either you need to manually specify the setting: -fsanitize=memory in Clang, or memory-santizer=on in B2. Refer to Clang MemorySanitizer.

      +
    • +
    • +

      ThreadSanitizer (TSan) detects data races. It’s available in Clang and gcc. Set -fsanitize=thread in Clang, or thread-sanitizer=on in B2. Refer to Clang ThreadSanitizer.

      +
    • +
    +
    +
    +
    +
    +

    Valgrind

    +
    +
    +

    For Linux based systems, Valgrind is an open-source software tool suite that helps in debugging memory management and threading bugs, and profiling programs. It is often used to detect memory leaks and uninitialised memory blocks in C++ programs, among other things.

    +
    +
    +

    Here’s how you can set it up for your project:

    +
    +
    +
      +
    1. +

      Depending on your OS, the command will differ. For Ubuntu or Debian, you can use:

      +
      +
      +
      sudo apt-get install valgrind
      +
      +
      +
      +

      For CentOS or Fedora, you can use:

      +
      +
      +
      +
      sudo yum install valgrind
      +
      +
      +
    2. +
    3. +

      After Valgrind is installed, you can use it to run your program. Here’s an example:

      +
      +
      +
      valgrind --leak-check=yes ./your_program
      +
      +
      +
      +

      The --leak-check=yes option tells Valgrind to perform memory leak checks. Your program runs as usual, but with Valgrind checking its memory usage in the background.

      +
      +
    4. +
    +
    +
    +

    Setting up Valgrind in a CI environment depends on your CI system and might look something like this:

    +
    +
    +
      +
    1. +

      In your CI configuration file, such as .github/workflows/workflow.yml for GitHub Actions, you would add a step to install Valgrind in your build environment.

      +
    2. +
    3. +

      Next, in your script steps, instead of running your test executable directly, you’d use Valgrind to run it. This will generate a report of any memory issues detected by Valgrind.

      +
      +
      +
      NOTE
      +
      +

      Valgrind can significantly slow down your program, so it might not be suitable for all CI use cases, especially for large projects or tests that need to run quickly.

      +
      +
      +
      +
    4. +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/test-policy.html b/preview/contributor-guide/testing/test-policy.html new file mode 100644 index 0000000..25ee47e --- /dev/null +++ b/preview/contributor-guide/testing/test-policy.html @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + Test Policy :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Test Policy

    +
    +
    +
    +

    There are required and optional (though highly recommended) tests for libraries.

    +
    + +
    +
    +
    +

    Required

    +
    +
    +

    Boost uses an automatic regression test suite which generates HTML compiler status tables. Boost also uses Continuous Integration to ensure these tests are regularly run. Ensure your library testing includes the following:

    +
    +
    +
      +
    1. +

      Every Boost library should supply one or more suitable test programs to be exercised by the Boost regression test suite. In addition to the usual compile-link-run tests expecting successful completion, compile-only or compile-and-link-only tests may be performed, and success for the test may be defined as failure of the steps.

      +
    2. +
    3. +

      Test program execution must report errors by returning a non-zero value. They may also write to stdout or stderr, but that output should be relatively brief. Regardless of other output, a non-zero return value is the only way the regression test framework will recognize an error has occurred. Note that test programs to be included in the status tables must compile, link, and run quickly since the tests are executed many times.

      +
    4. +
    5. +

      Libraries with time consuming tests should be divided into a fast-execution basic test program for the status tables, and a separate full-coverage test program for exhaustive test cases. The basic test should concentrate on compilation issues so that the status tables accurately reflect the library’s likelihood of correct compilation on a platform.

      +
    6. +
    7. +

      If for any reason the usual test policies do not apply to a particular library, an alternate test strategy must be described and implemented.

      +
    8. +
    9. +

      Authors should supply a Jamfile to drive the regression tests for the library.

      +
    10. +
    +
    +
    +
    +
    +

    Optional

    +
    +
    + +
    +
    +
    +
    +

    Protocol for Fixing Bugs or Adding Features

    +
    +
    +
      +
    1. +

      Before fixing the bug, or adding the feature, add regression test cases that detect the bug or tests the feature. Sometimes adding one case suggests similar untested cases, and add those too.

      +
    2. +
    3. +

      For bugs, run the regression test and verify that the bug is detected.

      +
    4. +
    5. +

      Now, fix the bug or add the feature.

      +
    6. +
    7. +

      Rerun the full regression tests, as sometimes the change breaks something else.

      +
    8. +
    +
    +
    +
    +
    +

    Snapshots

    +
    +
    +

    Snapshots are used for quality control checks, and are posted to Archives. Because the snapshots represent work-in-process, they may not be suitable for production use.

    +
    +
    +

    The Unix tarballs and Windows zipballs are identical except for the line endings exported from Git.

    +
    + ++++ + + + + + + + + + + + + + + + + +
    VersionDownload

    Master branch

    Index of /master/

    Develop branch

    Index of /develop/

    +
    +

    The Git master branch can be checked out from boostorg/boost.

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/testing/writing-tests.html b/preview/contributor-guide/testing/writing-tests.html new file mode 100644 index 0000000..69371ed --- /dev/null +++ b/preview/contributor-guide/testing/writing-tests.html @@ -0,0 +1,1016 @@ + + + + + + + + + + + + + + Writing Tests :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Writing Tests

    + +
    +

    Guidelines for Contributors

    +
    +
    +

    By following these guidelines and examples, contributors can write effective and maintainable unit tests that ensure the robustness and reliability of their Boost library contributions.

    +
    +
    +
      +
    1. +

      Tests should be neatly organized into test suites to maintain clarity about which aspect of the library is being tested.

      +
    2. +
    3. +

      When testing features that are compiler or platform-specific, use Boost.Config to ensure portability.

      +
    4. +
    5. +

      Test names should be descriptive enough to understand the purpose without diving deep into the test logic.

      +
    6. +
    7. +

      If a test contains non-trivial logic or checks for edge cases, include comments explaining the rationale.

      +
    8. +
    9. +

      Ensure that the tests cover all corner cases, edge conditions, and typical usage scenarios.

      +
    10. +
    11. +

      Each test should be independent, not relying on the state or outcome of another test.

      +
    12. +
    13. +

      Well-commented unit tests not only describe the "what" but also the "why" behind certain checks, making them invaluable for both current developers and future maintainers. It’s crucial for unit tests to be self-explanatory, and while descriptive names play a significant role, comments can further elucidate complex or non-obvious logic.

      +
    14. +
    +
    +
    +
    +
    +

    Unit Tests

    +
    +
    +

    Writing good unit tests is crucial. Boost.Test provides the facilities needed to write unit tests, and Boost.Config can be used to adjust code depending on the platform and compiler features. The following are some examples to help contributors get started:

    +
    +
    +

    Basic Unit Testing using Boost.Test

    +
    +

    To begin, contributors should include the necessary headers and use the right macros.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE MyLibraryTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_case1)
    +{
    +    BOOST_TEST(2 + 2 == 4);
    +}
    +
    +
    +
    +

    In this example, a test module named MyLibraryTest is defined, and a single test case (test_case1) checks a trivial arithmetic operation.

    +
    +
    +
    +

    Testing Suite

    +
    +

    For a library with multiple functionalities, it’s a good idea to organize tests into test suites.

    +
    +
    +
    +
    #include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_SUITE(MathTestSuite)
    +
    +BOOST_AUTO_TEST_CASE(test_addition)
    +{
    +    BOOST_TEST(2 + 2 == 4);
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_subtraction)
    +{
    +    BOOST_TEST(4 - 2 == 2);
    +}
    +
    +BOOST_AUTO_TEST_SUITE_END()
    +
    +
    +
    +
    +

    Using Boost.Config

    +
    +

    Let’s say a certain test is only valid for compilers supporting C++14. Boost.Config can be used to conditionally include or exclude that test.

    +
    +
    +
    +
    #include <boost/test/included/unit_test.hpp>
    +#include <boost/config.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_cpp14_feature)
    +{
    +#if !defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
    +    auto lambda = [](auto x) { return x * x; };
    +    BOOST_TEST(lambda(3) == 9);
    +#endif
    +}
    +
    +
    +
    +

    In the above test, we ensure that the lambda (which uses a C++14 feature) only gets compiled if the compiler supports C++14 generic lambdas. The BOOST_NO_CXX14_GENERIC_LAMBDAS macro is provided by Boost.Config.

    +
    +
    +
    +

    Testing with Floating Point

    +
    +

    Boost.Test has special support for floating-point comparison to handle rounding errors.

    +
    +
    +
    +
    BOOST_AUTO_TEST_CASE(test_floating_point)
    +{
    +    double result = 0.1 * 0.1;
    +    BOOST_TEST(result == 0.01, boost::test_tools::tolerance(1e-9));
    +}
    +
    +
    +
    +

    In this test, the boost::test_tools::tolerance call specifies the allowed difference between the computed result and the expected result.

    +
    +
    +
    +

    Testing Exceptions

    +
    +

    Boost.Test provides facilities to check if the right exceptions are thrown.

    +
    +
    +
    +
    #include <stdexcept>
    +
    +void foo() { throw std::runtime_error("Error!"); }
    +
    +BOOST_AUTO_TEST_CASE(test_exception)
    +{
    +    BOOST_CHECK_THROW(foo(), std::runtime_error);
    +}
    +
    +
    +
    +

    Here is an example that works around expectations.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE ExceptionTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +void mightThrow(bool doThrow)
    +{
    +    if (doThrow)
    +        throw std::runtime_error("An error occurred!");
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_exception_handling)
    +{
    +    // This call should not throw any exceptions.
    +    mightThrow(false);
    +
    +    // Testing if the function throws the expected exception when asked to.
    +    // This is especially useful when certain conditions in the application
    +    // logic are expected to trigger specific exceptions.
    +    BOOST_CHECK_THROW(mightThrow(true), std::runtime_error);
    +}
    +
    +
    +
    +
    +
    +
    +

    Test Edge Cases

    +
    +
    +

    Testing edge cases is crucial in ensuring the robustness and reliability of any software component. Edge cases often arise from boundary conditions, interactions of features, or uncommon input scenarios. The following examples demonstrate some common edge cases and how they can be tested using Boost.Test. In practice, understanding the problem domain and potential pitfalls of the library/component being developed is crucial in identifying and effectively testing edge cases.

    +
    +
    +

    Test Array Boundaries

    +
    +

    When working with arrays or data structures with a fixed size, it’s crucial to test both lower and upper boundaries.

    +
    +
    +
    +
    #include <array>
    +#define BOOST_TEST_MODULE ArrayBoundaryTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +std::array<int, 5> data = {1, 2, 3, 4, 5};
    +
    +BOOST_AUTO_TEST_CASE(test_lower_boundary)
    +{
    +    BOOST_TEST(data[0] == 1);
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_upper_boundary)
    +{
    +    BOOST_TEST(data[4] == 5);
    +}
    +
    +// This should fail if accessing out of bounds
    +BOOST_AUTO_TEST_CASE(test_out_of_bounds)
    +{
    +    BOOST_CHECK_THROW(data.at(5), std::out_of_range);
    +}
    +
    +
    +
    +
    +

    Test List Boundaries

    +
    +

    Comments help identify the purpose of the tests in this example of testing list size and boundaries.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE BoundaryTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_list_boundary_conditions)
    +{
    +    std::list<int> myList;
    +
    +    // Testing the lower boundary. An empty list should have a size of 0.
    +    BOOST_TEST(myList.size() == 0);
    +
    +    myList.push_back(1);
    +    myList.push_back(2);
    +
    +    // When two items are added, size should reflect that.
    +    BOOST_TEST(myList.size() == 2);
    +
    +    myList.clear();
    +
    +    // After clearing, the list should return to its initial empty state.
    +    BOOST_TEST(myList.size() == 0);
    +}
    +
    +
    +
    +
    +

    Test Numeric Limits

    +
    +

    When working with numerical operations, it’s vital to test the smallest, largest, and other boundary values.

    +
    +
    +
    +
    #include <limits>
    +#define BOOST_TEST_MODULE NumericLimitsTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_integer_overflow)
    +{
    +    int max_int = std::numeric_limits<int>::max();
    +    BOOST_CHECK_THROW([&](){
    +        int result = max_int + 1;
    +    }(), std::overflow_error);
    +}
    +
    +
    +
    +
    +

    Test Numerical Algorithms

    +
    +

    Numerical algorithms often have trouble with 0!

    +
    +
    +
    +
    #define BOOST_TEST_MODULE AlgorithmTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +double divide(double a, double b)
    +{
    +    if (b == 0.0)
    +        throw std::domain_error("Denominator cannot be zero.");
    +    return a / b;
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_division)
    +{
    +    // Regular division scenario: 10 divided by 2 should give 5.
    +    BOOST_TEST(divide(10.0, 2.0) == 5.0);
    +
    +    // Division by zero should throw an error. We're ensuring that our
    +    // function correctly handles this edge case and provides meaningful feedback.
    +    BOOST_CHECK_THROW(divide(10.0, 0.0), std::domain_error);
    +}
    +
    +
    +
    +
    +

    String Edge Cases

    +
    +

    When working with strings, some common edge cases include empty strings, strings with special characters, and extremely long strings.

    +
    +
    +
    +
    #include <string>
    +#define BOOST_TEST_MODULE StringTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +std::string concatenate(const std::string &a, const std::string &b)
    +{
    +    return a + b;
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_empty_string)
    +{
    +    BOOST_TEST(concatenate("", "world") == "world");
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_special_characters)
    +{
    +    BOOST_TEST(concatenate("hello", "\n\t!") == "hello\n\t!");
    +}
    +
    +// Use this test cautiously as it can consume a lot of memory
    +// BOOST_AUTO_TEST_CASE(test_extremely_long_string)
    +// {
    +//     std::string long_string(1e7, 'a');  // 10 million 'a's
    +//     BOOST_TEST(concatenate(long_string, "b").back() == 'b');
    +// }
    +
    +
    +
    +
    +

    Test for NULL or nullptr

    +
    +

    For libraries that might work with pointers, always check for null pointer scenarios.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE PointerTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +int dereference(int* ptr)
    +{
    +    return *ptr;
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_null_pointer)
    +{
    +    int* null_ptr = nullptr;
    +    BOOST_CHECK_THROW(dereference(null_ptr), std::runtime_error);
    +}
    +
    +
    +
    +
    +

    Test Recursive Functions

    +
    +

    For recursive algorithms, consider the maximum depth and base cases.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE RecursionTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +int factorial(int n)
    +{
    +    if (n < 0) throw std::runtime_error("Negative input not allowed");
    +    if (n == 0) return 1;
    +    return n * factorial(n - 1);
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_negative_input)
    +{
    +    BOOST_CHECK_THROW(factorial(-1), std::runtime_error);
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_base_case)
    +{
    +    BOOST_TEST(factorial(0) == 1);
    +}
    +
    +BOOST_AUTO_TEST_CASE(test_general_case)
    +{
    +    BOOST_TEST(factorial(5) == 120);
    +}
    +
    +
    +
    +
    +

    Testing with Mocks

    +
    +

    A "mock" is a hypothetical example. Mocks are useful in isolating units of code and simulating external interactions without actually invoking them.

    +
    +
    +
    +
    #define BOOST_TEST_MODULE MockTest
    +#include <boost/test/included/unit_test.hpp>
    +#include <mock_database.hpp>  // hypothetical mock database header
    +
    +BOOST_AUTO_TEST_CASE(test_database_read)
    +{
    +    MockDatabase db;  // Creating a mock database instance
    +
    +    // Presetting the mock to return specific data when read is called.
    +    db.setMockData("sample_data");
    +
    +    // The data returned from our mock should match the preset data.
    +    BOOST_TEST(db.read() == "sample_data");
    +}
    +
    +
    +
    +
    +
    +
    +

    Testing Features of Boost.Core

    +
    +
    +

    Boost.Core provides a set of core utility components intended for use by other libraries. Features include utility classes like noncopyable, type traits like is_same, and low-level functions like addressof.

    +
    +
    +

    In each of the following tests, the Boost.Test framework is used to verify the behavior of components based on Boost.Core:

    +
    +
    +

    Testing noncopyable

    +
    +

    Suppose you have a class that inherits from boost::noncopyable to ensure it can’t be copied.

    +
    +
    +
    +
    #include <boost/core/noncopyable.hpp>
    +
    +class MyClass : private boost::noncopyable {
    +    // class contents
    +};
    +
    +
    +
    +

    To test this:

    +
    +
    +
    +
    #define BOOST_TEST_MODULE NonCopyableTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_noncopyable)
    +{
    +    MyClass instance1;
    +
    +    // The following lines should result in compile-time errors because copy
    +    // constructor and assignment operator are deleted for noncopyable.
    +    // Uncommenting these lines will cause the test to fail at compilation.
    +    //
    +    // MyClass instance2(instance1);  // Copy construction
    +    // instance1 = instance2;         // Copy assignment
    +
    +    BOOST_TEST(true);  // If we reach here, it means the class is noncopyable
    +}
    +
    +
    +
    +
    +

    Testing is_same

    +
    +

    Using boost::is_same type trait:

    +
    +
    +
    +
    #include <boost/type_traits/is_same.hpp>
    +
    +template <typename T, typename U>
    +bool are_same_type() {
    +    return boost::is_same<T, U>::value;
    +}
    +
    +
    +
    +

    To test this:

    +
    +
    +
    +
    #define BOOST_TEST_MODULE IsSameTest
    +#include <boost/test/included/unit_test.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_is_same)
    +{
    +    BOOST_TEST(are_same_type<int, int>());
    +    BOOST_TEST(!are_same_type<int, double>());
    +}
    +
    +
    +
    +
    +

    Testing boost::addressof

    +
    +

    This function obtains the memory address of an object, even if its operator& is overloaded.

    +
    +
    +
    +
    struct OverloadedAddress {
    +    OverloadedAddress* operator&() {
    +        return nullptr;
    +    }
    +};
    +
    +
    +
    +

    Testing it:

    +
    +
    +
    +
    #define BOOST_TEST_MODULE AddressOfTest
    +#include <boost/test/included/unit_test.hpp>
    +#include <boost/core/addressof.hpp>
    +
    +BOOST_AUTO_TEST_CASE(test_addressof)
    +{
    +    OverloadedAddress obj;
    +    BOOST_TEST(boost::addressof(obj) != nullptr);
    +}
    +
    +
    +
    +
    +
    +
    +

    Descriptive Test Names

    +
    +
    +

    Descriptive test names are crucial for several reasons:

    +
    +
    +
      +
    • +

      When a test fails, a good test name instantly conveys what was expected and what aspect of the system was being tested.

      +
    • +
    • +

      As the software evolves, descriptive test names make it easier for developers to update tests or understand the impact of a code change.

      +
    • +
    • +

      Tests often serve as a form of living documentation for a system. Good test names provide an outline of the system’s behavior.

      +
    • +
    • +

      Test names should often start with a verb to indicate the action or condition being tested.

      +
    • +
    • +

      It’s usually better to have a longer, descriptive name than a short, vague one.

      +
    • +
    • +

      If you’re using a test framework that already prefixes methods with test_, you don’t need to start every test name with test_. Consider using a more descriptive prefix.

      +
    • +
    • +

      If there’s a naming convention in the existing test suite, stick to it.

      +
    • +
    • +

      The name should describe the expected behavior or outcome, not just the input conditions. For instance, test_negative_balance doesn’t tell us what to expect, while test_withdrawing_more_than_balance_throws_error is much clearer.

      +
    • +
    +
    +
    +

    Let’s delve into some more examples:

    +
    +
    +

    Example Good Test Names

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription

    test_empty_list_has_size_of_zero

    This name is clear about the context (empty list) and the expectation (size is zero).

    test_user_cannot_withdraw_more_than_balance

    Clear and specific about the business rule being enforced.

    test_connection_throws_timeout_after_10_seconds

    Indicates that a connection should time out, and also specifies the expected time frame.

    test_sorting_preserves_original_order_of_equal_elements

    Describes a specific characteristic (stability) of a sorting function.

    test_password_must_contain_at_least_one_special_character

    Clear about the rule being checked.

    +
    +
    +

    Example Poor Test Names

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription

    test1 or test_function1

    Vague. Does not tell anything about the purpose or expected outcome.

    test_errors

    Too broad. What kind of errors? Under what conditions?

    test_logic

    Ambiguous. What specific logic? Why is it being tested?

    test_against_spec

    What spec? How? This name doesn’t give a clear picture of what’s being tested or what to expect.

    test_flag

    Too vague. What about the flag? Are we testing its default value, its behavior when set, or something else?

    test_issue576

    Will a future maintainer know how to access Issue 576?

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/tweeting.html b/preview/contributor-guide/tweeting.html new file mode 100644 index 0000000..7de1b14 --- /dev/null +++ b/preview/contributor-guide/tweeting.html @@ -0,0 +1,513 @@ + + + + + + + + + + + + + + Tweeting :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Tweeting

    +
    +
    +
    +

    The collection is represented on social media by the @BoostLibraries +X (formerly Twitter) account, where news and information about our libraries in particular and C++ in general are shared +with the community.

    +
    + +
    +
    +
    +

    What gets Posted

    +
    +
    +

    The account publishes two types of posts:

    +
    +
    +
      +
    • +

      Official posts: These inform the community about new releases and libraries, library proposals, +review schedules and results, and generally all the events associated to the evolution and deployment of the project. +Official posts have a Boost brand imagery with watermark, and are produced by volunteers.

      +
    • +
    • +

      Non-official posts: Everything else. Imagery for these posts is not branded so that they can be told from +the former. Anyone from the community can propose a non-official post for publication; if you’re interested in +doing so, follow these simple guidelines:

      +
    • +
    +
    +
    +
    +
    +

    Topics of Interest

    +
    +
    +
      +
    • +

      Upcoming C++ events, meetups, conferences, etc.

      +
    • +
    • +

      Talks about some particular library, or where such library is put to good effect.

      +
    • +
    • +

      Boost-related articles, blogposts, C++ Committee papers.

      +
    • +
    • +

      Interesting discussions ongoing on Reddit or some other online forums.

      +
    • +
    +
    +
    +

    The list is not exhaustive: if in doubt, just go with your submission or ask +for guidance using the same submission channel.

    +
    +
    +
    +
    +

    Post Structure

    +
    +
    +
    +Structure of an X post +
    +
    +
    +

    Text: Make it short and attractive. Posts in X are currently capped at +280 characters, but you should strive for even less than that: one or two sentences +should suffice. Go straight to the point and phrase your sentences with a +clear call to action ("learn about", "watch", "contribute", you get the idea).

    +
    +
    +

    Link(s): After the text, the post must include a link (or maybe more) to the +piece of news, talk, etc. you’re posting about. Links can be provided as-is +or with a short introductory text (like "Check it out: link"). There’s no +need to pass the links through an URL shortener: X does it automatically +with its own shortening service.

    +
    +
    +

    Hashtags: The post should end with the following:

    +
    +
    +

    #boost #boostcpp #cpp #cplusplus

    +
    +
    +

    plus other hashtags specific to the post you’re proposing. Experiment with +different hashtags to see what X search brings on them.

    +
    +
    +

    Image: Always provide an image to go with the text —this dramatically +increases the visibility and reach of your post. The image should be +as large as possible. X accepts any aspect ratio, but given that +the majority of accesses will be through a mobile device, consider +ratios close to 1:1 or even taller than wider. +In our era of constant fight for attention and +information overload, the actual content of the image is less important +than how it will stand out amidst X infinite scroll: so, favor +colorful, original images that will make readers pause for a moment +and read the post (which is where the real info is shared).

    +
    +
    +

    Making the perfect post is not trivial: if you need inspiration, +go to @BoostLibraries for actual +post examples.

    +
    +
    +
    +
    +

    Post Submission

    +
    +
    +

    Log into the C++ Language Slack Workspace +(or join it if you’re not a member yet) +and post a message in the +#boost channel, including:

    +
    +
    +
      +
    • +

      Main text

      +
    • +
    • +

      Link(s), with or without introductory texts

      +
    • +
    • +

      Hashtags

      +
    • +
    • +

      Attached image (or link to it)

      +
    • +
    +
    +
    +

    The team in charge of @BoostLibraries +may make some editorial adjustments +to your submission or get back to you to help them polish the final post. +Also, they will schedule the publication date and time for +maximum impact (typically, on weekday mornings with an eye to +catching readers both sides of the Atlantic, but this may be adjusted +for events specific to some country or geographical area).

    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/contributor-guide/version-control.html b/preview/contributor-guide/version-control.html new file mode 100644 index 0000000..6da9cd5 --- /dev/null +++ b/preview/contributor-guide/version-control.html @@ -0,0 +1,659 @@ + + + + + + + + + + + + + + Version Control :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Version Control

    +
    +
    +
    +

    Boost uses the Git version control system for its development. This allows multiple contributors to work on the libraries concurrently, while keeping track of the changes that each person makes. Git is a distributed version control system, which means each contributor has their own local copy of the entire project, including its history.

    +
    +
    +

    This section covers:

    +
    + +
    +
    +
    +

    Library Repositories

    +
    +
    +

    The Boost libraries are modular, and each library has its own separate repository. This makes it easier to work with the entire collection of Boost libraries.

    +
    +
    +

    The official Boost repositories are hosted in GitHub under the https://github.com/boostorg/ account. Each library has its own repository under this organization. For example, https://github.com/boostorg/json for Boost.Json, or https://github.com/boostorg/date_time/ for Boost.DateTime.

    +
    +
    +

    As with any Git-based project, you can clone the repositories, make changes, commit those changes to your local repository, and push your changes back to the server. If you want to contribute changes to the official Boost libraries, refer to Contribute to an Existing Library.

    +
    +
    +
    +
    +

    The Super-project Repository

    +
    +
    +

    The Boost Super-project repository includes all the libraries as submodules.

    +
    +
    +

    In addition to the libraries, you’ll find many other repositories under boostorg that handle other tasks, for example:

    +
    +
    + +
    +
    +

    The Super-project has both master and develop branches, which operate somewhat differently than for individual libraries.

    +
    +
    +

    New features are added and bugs are fixed in library develop branches. When the develop branch passes its' merging criteria (Continuous Integration, projects are built correctly, other test processes run without errors, etc.), it is merged with the library master branch.

    +
    +
    +

    For the Super-project, the develop and master branches are independent. Both branches track the latest changes in the corresponding library branch, for all libraries. The Super-project branches are never merged, as this strategy prevents merging. In other words, the Super-project master branch is created from the library master branches, not from the Super-project develop branch (which is primarily used for testing).

    +
    +
    +

    When there is a public release of Boost, it is built from the master branch after that branch has been closed to updates (refer to the Release Process).

    +
    +
    +

    Working with the Super-project

    +
    +

    Usually, a submodule in the Super-project will be created for a library developer by a staff member of Boost.

    +
    +
    +
      +
    • +

      Recall that, in Git, when a submodule is added to a project, the submodule references a particular commit. This means that, when developers update their sub-projects, the Super-project doesn’t get immediately updated. For this reason, there is a commit bot that runs every 15 minutes and updates the commit to which each submodule references in the Super-project. This happens for both the develop and master branches.

      +
    • +
    • +

      As you update your library, and the Super-project develop branch is updated by the commit bot, you may affect other developers. For example, if a mistake is made to the MySQL library develop branch, then it will affect the CMake module, because this module runs tests to verify that you can use MySQL via CMake.

      +
    • +
    • +

      As part of Boost testing, Continuous Integration (CI) usually clones the Super-project and any required submodules.

      +
      +
        +
      • +

        When testing any branch that is not master, the develop branch of the Super-project is cloned.

        +
      • +
      • +

        When you’re testing master (which could be for a release), the master branch of the Super-project is cloned.

        +
        +

        While this cloning process is not a requirement, most libraries follow it.

        +
        +
      • +
      +
      +
    • +
    +
    +
    +

    If you need to look at the code for the 1.82.0 release, navigate to the relevant repo, and enter:

    +
    +
    +
    +
    git checkout boost-1.82.0
    +
    +
    +
    +
    +
    NOTE
    +
    +

    Developers don’t directly create Tags under repositories, when working with Boost. Tags are created by the release scripts, both in the Super-project and the individual repos, so do not add any of your own. This differs from the usual workflow in other non-Boost projects.

    +
    +
    +
    +
    +
    +
    +
    +

    Breaking Changes

    +
    +
    +

    Boost maintains its release versions with Tags, where the tag is always the boost- prefix followed by a major.minor.patch number string that matches the Semantic Versioning string format. The string format is useful because it’s something many tools understand, and for most users who just want to find a certain Boost version, that’s enough information. However, there is a unique Boost interpretation of the string.

    +
    +
    +

    Major Version

    +
    +

    Boost has not to date increased its' major version number. This is reserved for when something "big" happens, not for feature improvements nor API breaks.

    +
    +
    +
    +

    Minor Version

    +
    +

    While library maintainers try hard not to break anything, the minor version is increased when:

    +
    +
    +
      +
    • +

      Three months have passed since the last release.

      +
    • +
    • +

      New features have been added because they always are.

      +
    • +
    • +

      A few things might have been broken. Details on new features and discontinued features have to be consulted in the individual libraries' Release Notes.

      +
    • +
    +
    +
    +
    +

    Patch Version

    +
    +

    The patch number is rarely used, but will be incremented from zero if there is a need for a quick update following a scheduled release. For example, boost-1.65.1 followed less than one month after boost-1.65.0.

    +
    +
    +
    +

    Planning for Breaking Changes

    +
    +

    One thing library maintainers do to mitigate problems is announce their intention to break something two releases (or six months) in advance. Some maintainers keep a parallel versioning system for their library, for example:

    +
    + +
    +

    Ultimately though, even after checking both a library readme file, and for library announcements, some testing may be necessary to be certain of whether a breaking change occurred, or not.

    +
    +
    +
    +
    +
    +

    Bugs, Issues, Feature Requests and Discussions

    +
    +
    +

    The repositories use the built-in GitHub issue tracker. With Boost, users are encouraged to use the issue tracker for discussions and feature requests, as well as to report bugs and other issues.

    +
    +
    +

    Consider creating custom templates for your library. The goal of these templates is to ensure that contributors provide enough context and information that you, and the other library authors and maintainers, can understand and reproduce the issue, or fully understand what is being discussed.

    +
    +
    +
    +
    Note
    +
    +

    Currently, the Boost Super-project does not use the GitHub Discussion feature. If filing an issue does not seem appropriate, users are encouraged to post on the Boost developers mailing list.

    +
    +
    +
    +
    +

    How to Create an Issue Template

    +
    +

    Creating an issue template in GitHub can help guide contributors to provide the necessary information when they create new issues with your library.

    +
    +
    +

    Here are the steps to create an issue template:

    +
    +
    +
      +
    1. +

      Navigate to the main page of your repository.

      +
    2. +
    3. +

      In the menu bar (Code, Pull Requests, etc.), click on Settings.

      +
    4. +
    5. +

      In the Features section, ensure that the Issues checkbox is selected.

      +
    6. +
    7. +

      In the section Get organized with issue templates, click on Set up templates.

      +
    8. +
    9. +

      Click on the down arrow of Add template: select, then select Custom template.

      +
    10. +
    11. +

      Click on Preview and edit for your custom template. Then select the pen icon to bring up the template fields.

      +
    12. +
    13. +

      Give your template a descriptive name, perhaps the name of your library followed by "feature request", "performance issue", "bug report" or "discussion". Remember you can enter as many templates as you think appropriate.

      +
    14. +
    15. +

      Give the template a full description in the About box.

      +
    16. +
    17. +

      Then add the meat of the template to the Template content. Consider adding the following, in the form of Markdown syntax and example text, to ask your users to enter:

      +
      +
        +
      • +

        Boost version number

        +
      • +
      • +

        The OS, compiler, hardware they are using

        +
      • +
      • +

        A brief summary of the issue/request/discussion topic

        +
      • +
      • +

        In the case of a bug or issue:

        +
        +
          +
        • +

          Steps to reproduce the issue

          +
        • +
        • +

          Expected behavior

          +
        • +
        • +

          Actual behavior

          +
        • +
        • +

          Screenshots, error messages, output

          +
        • +
        +
        +
      • +
      • +

        In the case of a feature request or discussion:

        +
        +
          +
        • +

          Accurately describe the purpose of the request (the use case, not the implementation)

          +
        • +
        • +

          Describe what they are currently doing to address the issue

          +
        • +
        +
        +
      • +
      • +

        Any other relevant context or information

        +
      • +
      +
      +
    18. +
    19. +

      Add the Optional additional items if they fit the purpose of the template, and perhaps add yourself as one of the Assignees.

      +
    20. +
    21. +

      When you’re done editing, at the top right of the page, click Propose changes.

      +
    22. +
    23. +

      Click Commit changes and create a Pull Request to update your repo.

      +
    24. +
    +
    +
    +

    Once the template is added, users who create new issues in your repository can choose to use one of your templates.

    +
    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    For the user’s perspective on issues, refer to Reporting Issues.

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/contributor-checklist.html b/preview/formal-reviews/contributor-checklist.html new file mode 100644 index 0000000..49c6fd9 --- /dev/null +++ b/preview/formal-reviews/contributor-checklist.html @@ -0,0 +1,549 @@ + + + + + + + + + + + + + + Contributor Checklist :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Contributor Checklist

    +
    +
    +
    +

    Before submitting a library for review, work through this checklist to help polish the library to a high standard.

    +
    + +
    +
    +
    +

    Code Quality and Design

    +
    +
    +

    Examining your code, can you verify:

    +
    +
    +
      +
    • +

      [] Consistent Coding Style - naming conventions, indentation, spacing. Consider using clang-format for consistency.

      +
    • +
    • +

      [] Modular Design - the code should be broken down into small, manageable, and reusable components, and fit into the structure of the Boost Super-Project.

      +
    • +
    • +

      [] Avoid Code Smells - eliminate dead code, redundant logic, overly complex functions, and other common red-flag issues.

      +
    • +
    • +

      [] Adherence to C++ Standards - ensure the library is compatible with a current standard (for example, C++17 or later).

      +
    • +
    • +

      [] Template Usage - are templates appropriately used, and consider the potential impact on compile times.

      +
    • +
    • +

      [] Exception Safety - make sure the library has well-defined behavior when exceptions are thrown. Aim for strong or basic exception safety guarantees.

      +
    • +
    • +

      [] Thread Safety - if relevant, ensure thread safety or clearly document any multi-threading limitations.

      +
    • +
    • +

      [] Minimize Dependencies - use other Boost components when appropriate - ideally the latest incarnation, and avoid unnecessary external and circular dependencies.

      +
    • +
    +
    +
    +

    Refer to Design Best Practices for considerably more detail.

    +
    +
    +
    +
    +

    Documentation

    +
    +
    +

    Documentation should be on a website (rather than, say, a downloadable pdf file) so that it can be regularly and easily be updated. It should also be a single document as many reviewers will not explore beyond one link.

    +
    +
    +
      +
    • +

      [] The Introduction or Overview should compel an interested developer to read further. The purpose of the library - in not-too-technical terms - should be clear as daylight. What kind of task this library is the solution for should be well understood by reading the introduction completely, but no further. Remember that it is not experts, but developers struggling, who most often turn to documentation for help.

      +
    • +
    • +

      [] Have a developer unfamiliar with the library read the introduction. If they struggle to understand it, revise accordingly.

      +
    • +
    • +

      [] Include a sub-section on testimonials, if you have any that are noteworthy.

      +
    • +
    • +

      [] Include information on how long the library has been stable, especially if it has been used for a significant period before the submission to Boost.

      +
    • +
    +
    +
    +

    Divide the rest of the documentation into sections:

    +
    +
    +

    1. Comprehensive User Guide

    +
    +
      +
    • +

      [] how to install the library - mentioning B2 and CMake as appropriate

      +
    • +
    • +

      [] the dependencies

      +
    • +
    • +

      [] the requirements - compilers, operating systems, hardware, etc.

      +
    • +
    • +

      [] a "hello world" example

      +
    • +
    • +

      [] architecture and rationale - include historical information and timelines if they impacted the design

      +
    • +
    • +

      [] license

      +
    • +
    • +

      [] references

      +
    • +
    • +

      [] acknowledgements

      +
    • +
    +
    +
    +
    +

    2. Examples and Tutorials

    +
    +
      +
    • +

      [] how to get started

      +
    • +
    • +

      [] common use cases

      +
    • +
    • +

      [] advanced use cases

      +
    • +
    • +

      [] corner cases

      +
    • +
    • +

      [] common patterns - for example, how to handle common errors

      +
    • +
    +
    +
    +
    +

    3. Complete Reference Documentation

    +
    +

    Provide detailed descriptions of all:

    +
    +
    +
      +
    • +

      [] classes

      +
    • +
    • +

      [] interfaces

      +
    • +
    • +

      [] functions

      +
    • +
    • +

      [] properties

      +
    • +
    • +

      [] macros

      +
    • +
    • +

      [] types

      +
    • +
    • +

      [] constants

      +
    • +
    • +

      [] error codes - ensure that error messages are clear and helpful for debugging

      +
    • +
    • +

      [] exceptions

      +
    • +
    +
    +
    +

    It can be helpful to use tools like Doxygen or QuickBook.

    +
    +
    +
    +

    4. Guidelines for Contribution

    +
    +

    Make it easy for others to understand the codebase and, in the course of time, enable them to contribute their own issues, proposals and code.

    +
    +
    +
      +
    • +

      [] Provide links to the library source where appropriate.

      +
    • +
    +
    +
    +
    +
    +
    +

    Testing

    +
    +
    +

    Ensure comprehensive test coverage for all functionalities.

    +
    +
    +
      +
    • +

      [] Unit Tests - use Boost.Test or another test framework.

      +
    • +
    • +

      [] Edge Cases and Boundary Conditions - especially for algorithms and data structures.

      +
    • +
    • +

      [] Cross-Platform Compatibility - verify that the library works on different platforms (Windows, Linux, macOS). Consider using CI tools like GitHub Actions or Travis CI to automate this process.

      +
    • +
    • +

      [] Build Configurations - test with different compilers (GCC, Clang, MSVC) and optimization levels.

      +
    • +
    • +

      [] Stress Tests - add stress tests (low memory, high CPU usage, etc.) to see how the library performs under heavy loads.

      +
    • +
    +
    +
    +
    +
    +

    Efficiency and Performance

    +
    +
    +

    As a minimum for validating your library performance, consider:

    +
    +
    +
      +
    • +

      [] Including benchmarks to demonstrate the library’s performance. Compare against existing solutions if possible.

      +
    • +
    • +

      [] Optimizing for memory usage and consider using std::move and std::unique_ptr where appropriate to minimize allocations.

      +
    • +
    • +

      [] Avoiding unnecessary copies by using const &, std::move, and std::forward properly to avoid unnecessary data copying.

      +
    • +
    +
    +
    +
    +
    +

    Boost-Specific Requirements

    +
    +
    +

    Boost library technical requirements are laid out in detail:

    +
    +
    + +
    +
    +
    +
    +

    Usability and API Design

    +
    +
    +

    For usability, verify that you have:

    +
    +
    +
      +
    • +

      [] A Simple and Intuitive Interface - avoid unnecessarily complex APIs.

      +
    • +
    • +

      [] A Consistent API - consistent naming conventions, argument orders, and return types across the library.

      +
    • +
    • +

      [] Clear Error Handling - clearly define and handle error cases. Use exceptions where appropriate and document expected exceptions.

      +
    • +
    • +

      [] Template Type Deduction - ensure templates are designed to support type deduction and intuitive usage.

      +
    • +
    +
    +
    +
    +
    +

    Pre-Review Feedback

    +
    +
    +

    Before submitting for a formal review, have you:

    +
    +
    +
      +
    • +

      [] Sought feedback from a smaller group of developers. Consider hosting the code on GitHub to get initial feedback from your community.

      +
    • +
    • +

      [] Addressed all feedback from the pre-submission review.

      +
    • +
    +
    +
    +
    +
    +

    Examples of Successful Libraries

    +
    +
    +

    Consider a brief study of some existing popular Boost libraries and use them as benchmarks for quality and completeness. Recommended libraries for study include:

    +
    +
    + +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/index.html b/preview/formal-reviews/index.html new file mode 100644 index 0000000..14d2965 --- /dev/null +++ b/preview/formal-reviews/index.html @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + Formal Review Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Formal Review Guide

    +
    +
    +
    +

    The Boost library collection is known for the formal review process. A process that needs to be carefully navigated before a new library is accepted for inclusion.

    +
    +
    +
    +
    +

    Introduction

    +
    +
    +

    This guide provides detailed information on the main roles in library submission:

    +
    +
    +
      +
    1. +

      The Authors who wish to submit the library to the Boost collection: refer to Library Submission Process, and Contributor Checklist.

      +
    2. +
    3. +

      The Review Manager who’s job it is to lead and coordinate the review process: refer to Managing Reviews.

      +
    4. +
    5. +

      The Reviewers who test the submission, or elements of it, and write up their findings: refer to Writing Reviews.

      +
    6. +
    +
    +
    +

    This guide also includes a comprehensive history of submissions, most with links to the rationale and announcements made during the evaluation process: refer to the Formal Review Schedule.

    +
    +
    +
    +
    +

    Feedback

    +
    +
    +

    Feedback on any aspect of this documentation is encouraged, and is available by creating a New Issue.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/managing-reviews.html b/preview/formal-reviews/managing-reviews.html new file mode 100644 index 0000000..efe62e1 --- /dev/null +++ b/preview/formal-reviews/managing-reviews.html @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + Managing Reviews :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Managing Reviews

    +
    +
    +
    +

    Before a library can be scheduled for formal review, an active Boost member (not connected with the library submission) must volunteer to be the Review Manager for the library. Members may contact a library author on- or off-list to express interest in managing the review. The library author has to accept a person as a review manager.

    +
    +
    +

    Before submitting a library, it will help to understand the role of the review manager.

    +
    + +
    +
    +
    +

    The Role of Review Manager

    +
    +
    +

    The review manager works through the following process:

    +
    +
    +
      +
    1. +

      Checks the submission to make sure it really is complete enough to warrant formal review. For full requirements, refer to the Library Requirements. If necessary, work with the submitter to verify the code compiles and runs correctly on several compilers and platforms.

      +
    2. +
    3. +

      Finalizes the schedule with the Review Wizards and the submitter.

      +
    4. +
    5. +

      Posts a notice of the review schedule on both the Boost developers' mailing list and the Boost-announce mailing list.

      +
      +
        +
      1. +

        The notice should include a brief description of the library and what it does, to let readers know if the library is one they are interested in reviewing.

        +
      2. +
      3. +

        If the library is known to fail with certain compilers, mention them in the review notice so reviewers with those compilers won’t waste time diagnosing known problems.

        +
      4. +
      5. +

        It is advised to send the notice to each mailing list in a separate e-mail, otherwise online e-mail to news gateways could get confused.

        +
      6. +
      +
      +
    6. +
    7. +

      Inspects the Boost library catalogue for libraries which may interact with the new submission. These potential interactions should be pointed out in the review announcement, and the authors of these libraries should be privately notified and urged to participate in the review.

      +
    8. +
    9. +

      Urges people to do reviews if they aren’t forthcoming.

      +
    10. +
    11. +

      Follows review discussions regarding the library, moderating or answering questions as needed. It is the review manager’s job to give reviewers the benefit of the doubt and to try to coax a serious review out of participants, by asking pertinent questions.

      +
    12. +
    13. +

      Asks the Review Wizards for permission to extend the review schedule if it appears that too few reviews will be submitted during the review period.

      +
    14. +
    15. +

      Decides if there is consensus to accept the library and if there are any conditions attached. Consensus is not the same as a vote. The review manager has discretion to weigh opinions based on authority or thoughtfulness.

      +
    16. +
    17. +

      Posts a notice of the review results on the Boost users mailing list as well as the Boost developers' mailing list and Boost-announce mailing list. A rationale is also helpful, but its extent is up to the review manager. If there are suggestions, or conditions that must be met before final inclusion, they should be stated. Concerns about the timeliness or quality of the review report should be brought to the Review Wizards off-list.

      +
      +

      Ideally, the review summary should contain all the information the manager has taken into account when coming to a decision. If there were discussions out of band, they need to be summarized. If there were discussions on the list that haven’t made their way into the formal reviews, they should be summarized too. Refer to the Best Practices section on Writing Reviews for some issues to look out for.

      +
      +
    18. +
    +
    +
    +

    Reality Check

    +
    +

    The review manager is not supposed to impartially reflect the community opinion, as expressed in the form of formal reviews. Instead, the review manager’s role is to decide whether the library should be accepted, and the reviews help them with this, rather than decide for them. Simply put, the review manager does not impartially tally votes - reviews are not votes.

    +
    +
    +
      +
    • +

      A review manager can write a review themselves, though this process is independent of their role of review manager.

      +
    • +
    • +

      The review process is more like a court - with the judge (the review manager) asking "Does the library meet the required standards for acceptance as a Boost library?". This question is resolved by various advocates presenting their cases, criticizing other advocates cases, presenting facts, logical arguments, their own experiences, and so on. The judge’s job is to weigh all this and reach a decision. And they may add conditions on acceptance, or not. If consensus between judge and authors cannot be reached on meeting any conditions - the process ends without a resolution (the mistrial).

      +
    • +
    • +

      The review manager is - for better or worse - personally responsible for making the decision, defending the results, and dealing with future criticism. Their name will be public. This is not a job for everyone.

      +
    • +
    • +

      Sometimes the judging process is going to produce irreconcilable differences, and continued discussions about the "verdict" are a fact of life. With any process there will be "winners" and "losers". So it’s not about everyone being happy at the end of the day.

      +
    • +
    • +

      If, years from now, someone would like to know why a library was accepted or rejected, they only needs to read the court documents (the review posts and the review summary), and should come away with the correct understanding of what happened and why.

      +
    • +
    +
    +
    +
    +

    Rejecting a Library

    +
    +

    One of the challenging tasks a review manager might have to take on is to write rejection rationale for a submitted library. For reference, here are links to the rationale of several libraries that were rejected in recent years.

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SubmissionReview DatesResult Rationale

    Mustache

    February 5, 2023 - February 14, 2023

    Rejected

    Text

    June 11, 2020 - June 20, 2020

    Rejected

    out_ptr

    June 16, 2019 - July 10, 2019

    Rejected

    Timsort

    June 3, 2017 - June 12, 2017

    Rejected

    Synapse

    December 2, 2016 - December 11, 2016

    Rejected

    +
    +

    For links to all available acceptance and rejection rationales, refer to Past Review Results and Milestones.

    +
    +
    +
    +
    +
    +

    Becoming a Review Manager

    +
    +
    +

    To manage a review, you should have experience with the review process and ideally expert knowledge of the library’s domain. To volunteer to become a review manager, contact the current Review Wizards.

    +
    +
    +

    Review Wizards

    +
    +

    Currently the review wizards are: Matt Borland (matt@mattborland.com), Mateusz Łoskot (mateusz@loskot.net) and John Phillips (johnphillipsithaca@gmail.com).

    +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/review-results.html b/preview/formal-reviews/review-results.html new file mode 100644 index 0000000..2da5b82 --- /dev/null +++ b/preview/formal-reviews/review-results.html @@ -0,0 +1,2315 @@ + + + + + + + + + + + + + + Formal Review Schedule :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Formal Review Schedule

    +
    +
    +
    +

    Reviews are scheduled when the Review Wizards approve a review manager and agree with the manager and author on dates. See Library Submission Process for more information.

    +
    +
    +
    +
    Note
    +
    +

    The review results include recent completed reviews - where the library may have been accepted but is not yet part of Boost. There is often a lag between acceptance and site posting as authors address issues raised in the formal review.

    + +
    +
    +
    +
    +
    +
    +

    Current Schedule

    +
    + ++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SubmissionSubmitterLinksReview ManagerReview DatesResult

    Multi

    Alfredo Correa

    Docs Lib

    Matt Borland

    March 5, 2025 - March 15, 2025

    TBD

    boost::container::hub

    Joaquín M López Muñoz

    Docs Lib

    Ion Gaztañaga

    April 16, 2025 - April 26, 2025

    TBD

    +
    +

    Review Managers

    +
    +

    In order for a review to proceed, a Boost member must volunteer to manage the review. This should be someone with experience with the review process and knowledge of the library’s domain. If you would like to volunteer to become a review manager, refer to Managing Reviews.

    +
    +
    +
    +
    +
    +

    Past Review Results and Milestones

    +
    + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SubmissionSubmitterReview ManagerReview/Release DatesResult

    Boost 1.90.0 Released

    -

    Marshall Clow

    December 10, 2025

    Notes

    Decimal Re-Review

    Matt Borland and Chris Kormanyos

    John Maddock

    October 6, 2025 - October 15, 2025

    Accepted

    SQLite Re-Review

    Klemens Morgenstern

    Mohammad Nejati

    August 22, 2025 - August 31, 2025

    Rejected

    Boost 1.89.0 Released

    -

    Marshall Clow

    August 14, 2025

    Notes

    Bloom

    Joaquin M Lopez Munoz

    Arnaud Becheler

    May 13, 2025 - May 22, 2025

    Accepted Added in 1.89.0

    OpenMethod

    Jean-Louis Leroy

    Dmitry Arkhipov

    April 28, 2025 - May 07, 2025

    Accepted Added in 1.90.0

    Boost 1.88.0 Released

    -

    Marshall Clow

    April 10, 2025

    Notes

    Decimal

    Matt Borland and Chris Kormanyos

    John Maddock

    January 15, 2025 - January 22, 2025

    Indeterminate

    Hash2

    Peter Dimov and Christian Mazakas

    Matt Borland

    December 7, 2024 - December 15, 2024

    Accepted Added in 1.88.0

    Boost 1.87.0 Released

    -

    Marshall Clow

    December 11, 2024

    Notes

    SQLite

    Klemens Morgenstern

    Richard Hodges

    November 13, 2024 - November 22, 2024

    Indeterminate

    MQTT5

    Ivica Siladic

    Klemens Morgenstern

    October 16, 2024 - October 25, 2024

    Conditionally Accepted Added in 1.88.0

    Boost Fiscal Sponsorship

    Vinnie Falco

    Glen Fernandes

    September 3, 2024 - September 22, 2024

    Accepted

    Boost 1.86.0 Released

    -

    Marshall Clow

    August 14, 2024

    Notes

    Boost 1.85.0 Released

    -

    Marshall Clow

    April 15, 2024

    Notes

    Parser

    Zach Laine

    Marshall Clow

    February 19, 2024 - February 28, 2024

    Pending Conditionally Accepted Added in 1.87.0

    CharConv

    Matt Borland

    Christopher Kormanyos

    January 15, 2024 - January 25, 2024

    Pending Accepted Added in 1.85

    Boost 1.84.0 Released

    -

    Marshall Clow

    December 13, 2023

    Notes

    Cobalt (fka Async)

    Klemens Morgenstern

    Niall Douglas

    September 22, 2023 - October 2, 2023 repeated due lack of reviews

    Pending Conditionally Accepted — Added in 1.84

    Scope

    Andrey Semashev

    Dmitry Arkhipov

    November 26, 2023 - December 5, 2023

    Pending Conditionally Accepted — Added in 1.85

    Boost 1.83.0 Released

    -

    Marshall Clow

    August 11, 2023

    Notes

    Boost 1.82.0 Released

    -

    Marshall Clow

    April 14, 2023

    Notes

    Mustache

    Peter Dimov

    Klemens Morgenstern

    February 5, 2023 - February 14, 2023

    Pending Rejected

    Redis (fka Aedis)

    Marcelo Zimbres Silva

    Klemens Morgenstern

    January 15, 2023 - January 24, 2023

    Pending Conditionally Accepted — Added in 1.84

    Boost 1.81.0 Released

    -

    Marshall Clow

    December 14, 2022

    Notes

    URL

    Vinnie Falco, Alan de Freitas

    Klemens Morgenstern

    August 13, 2022 - August 22, 2022

    Pending Accepted Added in 1.81

    Boost 1.80.0 Released

    -

    Marshall Clow

    August 10, 2022

    Notes

    MySQL

    Ruben Perez

    Richard Hodges

    May 9, 2022 - May 18, 2022

    Pending Accepted Added in 1.82

    Boost 1.79.0 Released

    -

    Marshall Clow

    April 13, 2022

    Notes

    Boost 1.78.0 Released

    -

    Marshall Clow

    December 8, 2021

    Notes

    Boost 1.77.0 Released

    -

    Marshall Clow

    August 11, 2021

    Notes

    Boost 1.76.0 Released

    -

    Marshall Clow

    April 16, 2021

    Notes

    Lambda2

    Peter Dimov

    Joel de Guzman

    March 22, 2021 - March 31, 2021

    Pending Accepted Added in 1.77

    Describe

    Peter Dimov

    Richard Hodges

    March 1, 2021 - March 10, 2021

    Pending Accepted Added in 1.77

    Boost 1.75.0 Released

    -

    Marshall Clow

    December 11, 2020

    Notes

    PFR(Precise and Flat Reflection)

    Antony Polukhin

    Benedek Thaler

    September 28, 2020 - October 7, 2020

    Pending Accepted Added in 1.75

    JSON

    Vinnie Falco, Krystian Stasiowski

    Pranam Lashkari

    September 14, 2020 - September 23, 2020

    Pending Accepted Added in 1.75

    Boost 1.74.0 Released

    -

    Marshall Clow

    August 14, 2020

    Notes

    LEAF(Lightweight Error Augmentation Framework)

    Emil Dotchevski

    Michael Caisse

    May 22, 2020 - May 31, 2020

    Pending Accepted Added in 1.75

    Text

    Zach Laine

    Glen Fernandes

    June 11, 2020 - June 20, 2020

    Pending Rejected

    Review Wizard Status Report

    Mateusz Loskot

    May 20, 2020

    Report

    Boost 1.73.0 Released

    -

    Marshall Clow

    April 28, 2020

    Notes

    Boost 1.72.0 Released

    -

    Marshall Clow

    December 11, 2019

    Notes

    STLInterfaces

    Zach Laine

    Barrett Adair

    December 10, 2019 - December 19, 2019

    Pending + Conditionally Accepted — Added in 1.74

    StaticString (was FixedString)

    Krystian Stasiowski and Vinnie Falco

    Joaquin M López Muñoz

    November 25, 2019 - December 4, 2019

    Pending + Accepted — Added in 1.73

    Boost 1.71.0 Released

    -

    Marshall Clow

    August 19, 2019

    Notes

    out_ptr

    JeanHeyd Meneide

    Zach Laine

    June 16, 2019 - July 10, 2019

    Pending

    +

    Rejected

    Boost 1.70.0 Released

    -

    Marshall Clow

    April 12, 2019

    Notes

    Variant2

    Peter Dimov

    Michael Caisse

    April 1, 2019 - April 15, 2019

    Ongoing + Accepted Added in 1.71

    Boost 1.69.0 Released

    -

    Marshall Clow

    December 11, 2018

    Notes

    Histogram

    Hans Dembinski

    Mateusz Loskot

    September 17, 2018 - September 26, 2018

    Pending Accepted Added in 1.70

    Boost 1.68.0 Released

    -

    Marshall Clow

    August 09, 2018

    Notes

    Boost 1.67.0 Released

    -

    Daniel James

    April 16, 2018

    Notes

    YAP

    Zach Laine

    Louis Dionne

    February 5, 2018 - February 14, 2018

    Ongoing Conditionally Accepted Accepted Added in 1.70

    Outcome

    Niall Douglas

    Charley Bay

    January 19, 2018 - January 28, 2018

    Pending Accepted — Added in 1.70

    Boost 1.66.0 Released

    -

    Daniel James

    December 19, 2017

    Notes

    Double-Ended

    Benedek Thaler

    Thorsten Ottosen

    September 21, 2017 - October 7, 2017

    Pending + Conditionally Accepted

    Fit (now HOF)

    Paul Fultz

    Matt Calabrese

    September 8, 2017 - September 20, 2017

    Pending + Accepted Added in 1.67

    Boost 1.65.1 Released

    -

    Daniel James

    September 7, 2017

    Notes

    Boost 1.65.0 Released

    -

    Daniel James

    August 21, 2017

    Notes

    mp11

    Peter Dimov

    Bjorn Reese

    July 15, 2017 - July 24, 2017

    Ongoing + Accepted Added in 1.66

    Beast

    Vinnie Falco

    Michael Caisse

    July 1, 2017 - July 10, 2017

    Pending + Accepted Added in 1.66

    pdqsort

    Orson Peters

    Steven Ross

    June 21, 2017 - June 30, 2017

    Accepted

    Nowide

    Artyom Beilis

    Frédéric Bron

    June 12, 2017 - June 21, 2017

    Pending + Accepted Added in 1.73

    Timsort

    Alexander Zaitsev

    Steven Ross

    June 3, 2017 - June 12, 2017

    Ongoing + Rejected

    Outcome

    Niall Douglas

    Charley Bay

    May 19, 2017 - May 28, 2017

    Pending + Rejected

    PolyCollection

    Joaquín Mª López Muñoz

    Ion Gaztañaga

    May 3, 2017 - May 12, 2017

    Ongoing Accepted Added in 1.65

    Boost 1.64.0 Released

    -

    Rene Rivera

    April 19, 2017

    Notes

    CallableTraits

    Barrett Adair

    Louis Dionne

    April 3, 2017 - April 12, 2017

    Ongoing + Conditionally Accepted — Added in 1.66

    Stacktrace

    Antony Polukhin

    Niall Douglas

    March 17, 2017 - March 26, 2017

    Ongoing + Accepted Added in 1.65

    Safe Numerics

    Robert Ramey

    Andrzej Krzemienski

    March 2, 2017 - March 16, 2017

    Ongoing + Conditionally Accepted — Added in 1.69

    Boost 1.63.0 Released

    -

    Marshall Clow

    December 26, 2016

    Notes

    Stacktrace

    Antony Polukhin

    Niall Douglas

    December 14, 2016 - December 23, 2016

    Pending + Conditionally Accepted

    Synapse

    Emil Dotchevski

    Edward Diener

    December 2, 2016 - December 11, 2016

    Pending +Rejected

    Parallel Sorting Sub-library

    Francisco José Tapia

    Steven Ross

    November 11, 2016 - November 20, 2016

    Pending + Accepted

    Process

    Klemens Morgenstern

    Antony Polukhin

    October 27, 2016 - November 5, 2016

    Pending + Accepted — Added in 1.64

    Boost 1.62.0 Released

    -

    Rene Rivera

    September 28, 2016

    Notes

    Fiber (mini-review)

    Oliver Kowalke

    Nat Goodspeed

    May 23, 2016 - June 2, 2016

    Pending + Accepted Added in 1.62

    Review Wizard Status Report

    -

    Ronald Garcia

    May 19, 2016

    Report

    Boost 1.61.0 Released

    -

    Rene Rivera

    May 13, 2016

    Notes

    Fit

    Paul Fultz

    Vicente Botet

    March 2, 2016 - March 13, 2016

    Ongoing + Rejected

    Quaternions, Vectors, Matrices (QVM)

    Emil Dotchevski

    Adam Wulkiewicz

    December 7, 2015 - December 23, 2015

    Ongoing +Accepted Added in 1.62

    Boost 1.60.0 Released

    -

    Marshall Clow

    December 17, 2015

    Notes

    Fiber (mini-review)

    Oliver Kowalke

    Nat Goodspeed

    September 4, 2015 - September 13, 2015

    Pending +Continuing Conditionally Accepted

    Asynchronous File I/O

    Niall Douglas and + Paul Kirth

    Ahmed Charles

    August 21, 2015 - August 31, 2015

    Pending + Rejected (no result posted)

    Boost 1.59.0 Released

    -

    Marshall Clow

    August 13, 2015

    Notes

    Http

    Vinícius dos Santos Oliveira

    Bjorn Reese

    August 7, 2015 - August 16, 2015

    Pending + Rejected

    DLL

    Antony Polukhin

    Vladimir Prus

    June 29, 2015 - July 12, 2015

    Pending Accepted Added in 1.61

    Hana

    Louis Dionne

    Glen Fernandes

    June 10, 2015 - June 24, 2015

    Accepted Added in 1.61

    Metaparse

    Abel Sinkovics

    Christophe Henry

    May 25, 2015 - June 7, 2015

    Pending Accepted Added in 1.61

    Boost 1.58.0 Released

    -

    Marshall Clow

    April 17, 2015

    Notes

    Endian Mini-Review

    Beman Dawes

    Joel Falcou

    January 23, 2015 - February 1, 2015

    Ongoing Accepted — Added in 1.58

    Review Wizard Status Report

    -

    Ronald Garcia

    January 22, 2015

    Report

    Compute

    Kyle Lutz

    Antony Polukhin

    December 15, 2014 - December 30, 2014

    Ongoing Accepted — Added in 1.61

    Sort

    Steven Ross

    Edward Diener

    November 10, 2014 - November 19, 2014

    Pending Accepted — Added in 1.58

    Boost 1.57.0 Released

    -

    Marshall Clow

    November 3, 2014

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    August 30, 2014

    Report

    Variadic Macro Data

    Edward Diener

    Steven Watanabe

    August 21, 2014 - August 30, 2014

    Pending Accepted Added in 1.60

    Boost 1.56.0 Released

    -

    Marshall Clow

    August 7, 2014

    Notes

    Convert

    Vladimir Batov

    Edward Diener

    May 12, 2014 - May 25, 2014

    Pending Accepted

    TypeIndex Mini-Review

    Antony Polukhin

    Niall Douglas

    April 21, 2014 - April 30, 2014

    Pending Accepted — Added in 1.56

    Align

    Glen Fernandes

    Ahmed Charles

    April 11, 2014 - April 20, 2014

    Pending Accepted — Added in 1.56

    Fiber

    Oliver Kowalke

    Nat Goodspeed

    January 6, 2014 - January 15, 2014

    Pending Conditionally Accepted

    TypeIndex

    Antony Polukhin

    Niall Douglas

    November 11, 2013 - November 20, 2013

    Conditionally Accepted

    Boost 1.55.0 Released

    -

    Marshall Clow

    November 11, 2013

    Notes

    Boost 1.54.0 Released

    -

    Marshall Clow

    July 1, 2013

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    March 14, 2013

    Report

    Boost 1.53.0 Released

    -

    Marshall Clow

    February 4, 2013

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    November 10, 2012

    Report

    Boost 1.52.0 Released

    -

    Marshall Clow

    October 5, 2012

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    September 27, 2012

    Report

    ODEint

    Karsten Ahnert and + Mario Mulansky

    Steven Watanabe

    September 19, 2012 - September 28, 2012

    Pending Accepted — Added in 1.53

    Coroutine

    Oliver Kowalke

    Hartmut Kaiser

    September 3, 2012 - September 12, 2012

    Pending Accepted — Added in 1.53

    Contract

    Lorenzo Caminiti

    Dave Abrahams

    August 22, 2012 - August 31, 2012

    Pending Accepted Added in 1.67

    Boost 1.51.0 Released

    -

    Marshall Clow

    August 20, 2012

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    August 15, 2012

    Report

    Type Erasure

    Steven Watanabe

    Lorenzo Caminiti

    July 18, 2012 - July 27, 2012

    Pending Accepted — Added in 1.54

    Review Wizard Status Report

    -

    Ronald Garcia

    July 13, 2012

    Report

    Boost 1.50.0 Released

    -

    Beman Dawes

    June 28, 2012

    Notes

    Multiprecision Arithmetic

    John Maddock

    Jeffrey Hellrung

    June 8, 2012 - June 17, 2012

    Pending Accepted — Added in 1.53

    Boost 1.49.0 Released

    -

    Beman Dawes

    February 24, 2012

    Notes

    Predef

    Rene Rivera

    Joel Falcou

    February 20, 2012 - February 29, 2012

    Pending Accepted — Added in 1.55

    Review Wizard Status Report

    -

    Ronald Garcia

    January 10, 2012

    Report

    Context (mini-review)

    Oliver Kowalke

    Giovanni Deretta

    January 2, 2012 - January 11, 2012

    Pending Accepted — Added in 1.51.0

    Boost 1.48.0 Released

    -

    Beman Dawes

    November 16, 2011

    Notes

    Local

    Lorenzo Caminiti

    Jeffrey Hellrung

    November 10, 2011 - November 19, 2011

    Pending Accepted — Added in 1.50

    Atomic

    Helge Bahmann

    Tim Blechmann

    October 17, 2011 - October 26, 2011

    Accepted — Added in 1.53

    Algorithm

    Marshall Clow

    Dave Abrahams

    September 22, 2011 - October 1, 2011

    Pending Accepted — Added in 1.50

    Endian

    Beman Dawes

    Joel Falcou

    September 5, 2011 - September 14, 2011

    Conditionally Accepted

    Conversion

    Vicente Botet

    Gordon Woodhull

    August 20, 2011 - August 29, 2011

    Pending Rejected

    Containers

    Ion Gaztañaga

    John Maddock

    August 3, 2011 - August 12, 2011

    Pending Accepted — Added in 1.48.0

    Lockfree

    Tim Blechmann

    Hartmut Kaiser

    July 18, 2011 - July 27, 2011

    Pending Accepted — Added in 1.53

    Boost 1.47.0 Released

    -

    Beman Dawes

    July 12, 2011

    Notes

    Type Traits Introspection

    Edward Diener

    Joel Falcou

    July 1, 2011 - July 10, 2011

    Pending +Pending Accepted — Added in 1.54

    Assign v2

    Erwann Rogard, + Thorsten Ottosen

    John Bytheway

    June 15, 2011 - June 24, 2011

    Pending +Pending Rejected

    Heaps

    Tim Blechmann

    Andrew Sutton

    May 30, 2011 - June 8, 2011

    Pending Accepted — Added in 1.49

    Review Wizard Status Report

    -

    Ronald Garcia

    May 23, 2011

    Report

    AutoIndex (Tool)

    John Maddock

    Daniel James

    May 5, 2011 - May 14, 2011

    Pending Accepted — Added in 1.48.0

    Convert

    Vladimir Batov

    Edward Diener

    April 23, 2011 - May 2, 2011-

    Pending Withdrawn Report

    Locale

    Artyom Beilis

    Chad Nelson

    April 7, 2011 - April 16, 2011

    Pending +Pending Accepted — Added in 1.48.0

    Context

    Oliver Kowalke

    Vicente Botet

    March 21, 2011 - March 30, 2011

    Pending +Accepted Provisionally Accepted — Added in 1.51.0

    Type Traits Extensions (Fast-Track)

    Frédéric Bron

    Joel Falcou

    March 14, 2011 - March 18, 2011

    Accepted — Added in 1.48.0

    Boost 1.46.1 Released

    -

    Beman Dawes

    March 21, 2011

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    March 4, 2011

    Report

    XInt

    Chad Nelson

    Vladimir Prus

    March 2, 2011 - March 12, 2011

    Pending Rejected

    Boost 1.46 Released

    -

    Beman Dawes

    February 21, 2011

    Notes

    Phoenix (mini-review)

    Joel de Guzmann

    Hartmut Kaiser

    February 20, 2011 - March 2, 2011

    Accepted — Added in 1.47.0

    Process

    Boris Schaeling

    Marshall Clow

    February 7. 2011 - February 16, 2011

    Rejected

    GIL.IO

    Christian Henning

    Mateusz Loskot

    December 1, 2010 - December 10, 2010

    Accepted — Added in 1.68.0

    Boost 1.45 Released

    -

    Beman Dawes

    November 20, 2010

    Notes

    Chrono

    Vicente Botet

    Anthony Williams

    November 6, 2010 - November 15, 2010

    Accepted — Added in 1.47.0

    Ratio

    Vicente Botet

    Anthony Williams

    October 2, 2010 - October 11, 2010

    Accepted — Added in 1.47.0

    Boost 1.44 Released

    -

    Beman Dawes

    August 17, 2010

    Notes

    Boost.Assign Extensions (Mini-Review)

    Erwann Rogard

    Thorsten Ottosen

    June 13, 2010 - June 19, 2010

    Rejected

    Review Wizard Status Report

    -

    Ronald Garcia

    May 26, 2010

    Report

    Move

    Ion Gaztañaga

    OvermindDL1 Michael Caisse

    May 10, 2010 - May 24, 2010

    Accepted — Added in 1.48.0

    Boost 1.43 Released

    -

    Beman Dawes

    May 6, 2010

    Notes

    Log

    Andrey Semashev

    Vladimir Prus

    March 8, 2010 - March 17, 2010

    Accepted Provisionally Accepted — Added in 1.54

    Interval Containers

    Joachim Faulhaber

    Hartmut Kaiser

    February 18, 2010 - February 27, 2010

    Accepted — Added in 1.46

    Boost 1.42 Released

    -

    Beman Dawes

    February 2, 2010

    Notes

    Review Wizard Status Report

    -

    John Phillips

    December 7, 2009

    Report

    Meta State Machine (MSM)

    Christophe Henry

    Dave Abrahams

    November 23, 2009 - December 13, 2009

    Accepted — Added in 1.44

    Boost 1.41 Released

    -

    Beman Dawes

    November 18, 2009

    Notes

    Geometry

    Barend Gehrels, Bruno Lalande, and Mateusz Loskot

    Hartmut Kaiser

    November 5, 2009 - November 22, 2009

    Accepted — Added in 1.47.0

    Boost 1.40 Released

    -

    Beman Dawes

    August 27, 2009

    Notes

    Polygon

    Lucanus Simonson

    Fernando Cacciola

    August 24, 2009 - September 2, 2009

    Accepted — Added in 1.44

    Review Wizard Status Report

    -

    Ronald Garcia

    June 4, 2009

    Report

    Boost 1.39 Released

    -

    Beman Dawes

    May 3, 2009

    Notes

    Polynomial

    Paweł Kieliszczyk

    John Maddock

    March 10, 2009 - March 19, 2009

    Rejected

    Boost.Range (Update)

    Neil Groves

    Thorsten Ottosen

    February 20, 2009 - March 3, 2009

    Accepted — Added in 1.43

    Boost 1.38 Released

    -

    Beman Dawes

    February 9, 2009

    Notes

    Futures (1st candidate)

    Anthony Williams

    Tom Brinkman

    January 5, 2009 - January 20, 2009

    Accepted — Added in 1.41

    Futures (2nd candidate)

    Braddock Gaskill

    Tom Brinkman

    January 5, 2009 - January 20, 2009

    Rejected

    Constrained Value

    Robert Kawulak

    Jeff Garland Gordon Woodhull

    December 1, 2008 - December 10, 2008

    Accepted Orphaned

    Review Wizard Status Report

    -

    John Phillips

    November 25, 2008

    Report

    Globally Unique Identifier (mini-review) (now UUID)

    Andy Tompkins

    Hartmut Kaiser

    November 23, 2008 - November 29, 2008

    Accepted — Added in 1.42

    Boost 1.37 Released

    -

    Beman Dawes

    November 3, 2008

    Notes

    Thread-Safe Signals (now Signals2)

    Frank Hess

    Stjepan Rajko

    November 1, 2008 - November 10, 2008

    Accepted — Added in 1.39

    Phoenix

    Joel de Guzman

    Hartmut Kaiser

    September 21, 2008 - September 30, 2008

    Accepted Conditionally Under Development Accepted — Added in 1.47.0

    DataFlow Signals

    Stjepan Rajko

    Jaakko Järvi

    September 1, 2008 - September 10, 2008

    Rejected

    Boost 1.36 Released

    -

    Beman Dawes

    August 14, 2008

    Notes

    Finite State Machines

    Andrey Semashev

    Martin Vuille

    August 11, 2008 - August 27, 2008

    Rejected (Notes )

    Review Wizard Status Report

    -

    John Phillips

    2008 May 16

    Report

    Egg

    Shunsuke Sogame

    Dan Marsden

    March 31, 2008 - April 13, 2008

    Rejected

    Boost 1.35 Released

    -

    Beman Dawes

    March 29, 2007

    Notes

    Proto

    Eric Niebler

    Hartmut Kaiser

    March 1, 2008 - March 14, 2008

    Accepted — Added in 1.37

    Floating Point Utilities

    Johan Råde

    John Maddock

    February 18, 2008 - February 27, 2008

    Accepted — Added in 1.??

    Logging

    John Torjo

    Gennadiy Rozental

    February 4, 2008 - February 13, 2008

    Rejected

    Flyweight

    Joaquín Mª López Muñoz

    Ion Gaztañaga

    January 21, 2008 - January 30, 2008

    Accepted — Added in 1.38

    Singleton (fast-track)

    Tobias Schwinger

    John Torjo

    January 14, 2008 - January 18, 2008

    Rejected

    Switch

    Steven Watanabe

    Stejpan Rajko

    January 5, 2008 - January 13, 2008

    Accepted Provisionally Orphaned

    Factory (fast-track)

    Tobias Schwinger

    John Torjo

    December 17, 2007 - December 21, 2007

    Accepted — Added in 1.43

    Unordered Containers

    Daniel James

    Ion Gaztañaga

    December 7, 2007 - December 16, 2007

    Accepted — Added in 1.36

    Forward (fast-track)

    Tobias Schwinger

    John Torjo

    December 3, 2007 - December 7, 2007

    Accepted — Added in 1.43

    Review Wizard Status Report

    -

    Ronald Garcia

    2007 November 16

    Report

    Exception

    Emil Dotchevski

    Tobias Schwinger

    September 27, 2007 - October 7, 2007

    Accepted  — Added in 1.36

    Review Wizard Status Report

    -

    Ronald Garcia

    2007 September 14

    Report

    Scope Exit

    Alexander Nasonov

    Jody Hagins John R. Phillips

    August 13, 2007 - August 22, 2007-

    Accepted — Added in 1.38

    Time Series

    Eric Niebler

    John R. Phillips

    July 30, 2007 - August 13, 2007

    Accepted Orphaned

    Boost 1.34.1 Released

    -

    Thomas Witt

    July 24, 2007

    Notes

    Boost 1.34.0 Released

    -

    Thomas Witt

    May 12, 2007

    Notes

    Globally Unique Identifier

    Andy Tompkins

    Hartmut Kaiser

    April 30, 2007 - May 10, 2007

    Accepted Provisionally Accepted — Added in 1.42

    Math Toolkit

    John Maddock

    Matthias Schabel

    April 11, 2007 - April 27, 2007

    Accepted — Added in 1.35

    Quantitative Units

    Matthias Schabel

    John R. Phillips

    March 26, 2007 - April 4, 2007

    Accepted — Added in 1.36

    Intrusive Containers

    Ion Gaztañaga

    Joaquín Mª López Muñoz

    March 12, 2007 - March 21, 2007

    Accepted — Added in 1.35

    Bimap

    Matias Capeletto

    Ion Gaztañaga

    February 15 2007- March 2, 2007

    Accepted — Added in 1.35

    Accumulators

    Eric Niebler

    John R. Phillips

    January 29, 2007 - February 7, 2007

    Accepted — Added in 1.36

    Function Types (Re-review)

    Tobias Schwinger

    Tom Brinkman

    2006 November 6 - 2006 November 17

    Accepted — Added in 1.35

    Generic Image Library

    Lubomir Bourdev

    Tom Brinkman

    2006 October 5 - 2006 October 25

    Accepted — Added in 1.35

    Message Passing

    Doug Gregor

    Jeremy Siek

    2006 September 6 - 2006 September 15

    Accepted — Added in 1.35

    Physical Quantities System

    Andy Little

    Fred Bertsch

    2006 May 31 - 2006 June 9

    Rejected

    Pimpl Pointer

    Asger Mangaard

    Rene Rivera

    2006 May 15 - 2006 May 24

    Rejected

    Fusion

    Joel de Guzman

    Ronald Garcia

    2006 May 1 - 2006 May 10

    Accepted — Added in 1.35

    Property Tree

    Marcin Kalicinski

    Thorsten Ottosen

    2006 April 18 - 2006 April 30

    Accepted — Added in 1.41

    Promotion Traits (fast-track)

    Alexander Nasonov

    Tobias Schwinger

    2006 April 1 - 2006 April 9

    Accepted — Added in 1.35

    Review Wizard Status Report

    -

    Tom Brinkman

    2006 March 30

    Report

    Shmem (now Interprocess)

    Ion Gaztañaga

    Fred Bertsch

    2006 February 6 - 2006 February 15

    Accepted — Added in 1.35

    Fixed Strings

    Reece Dunn

    Harmut Kaiser

    2006 January 19 - 2006 February 5

    Rejected

    Review Wizard Status Report

    -

    Ronald Garcia

    2006 January 19

    Report

    asio

    Christopher Kohlhoff

    Jeff Garland

    2005 December 10 - 2005 December 30

    Accepted — Added in 1.35

    Boost 1.33.1 Released

    -

    Doug Gregor

    2005 December 5

    Notes

    Review Wizard Status Report

    -

    Ronald Garcia

    2005 December 1

    Report

    Logging Library

    John Torjo

    Hartmut Kaiser

    2005 November 7 - 2005 November 16th

    Rejected

    Boost 1.33.1 Beta Released

    -

    Doug Gregor

    2005 November 9

    Notes

    binary_int

    Scott Schurr and Matt Calabrese

    Pavel Vozenilek

    2005 October 13 - 2005 October 20

    Accepted — Added in 1.37.

    TR1

    John Maddock

    Beman Dawes

    2005 September 24 - 2005 October 5

    Accepted — Added in 1.34

    Xpressive

    Eric Niebler

    Thomas Witt

    2005 September 8 - 2005 September 18

    Accepted — Added in 1.34

    Boost 1.33.0 Released

    -

    Doug Gregor

    17 August 2005

    Notes

    Function Types

    Tobias Schwinger

    John Maddock

    2005-Jun-6 to 2005-June-16

    Accepted Provisionally, Accepted — Added in 1.35

    Typeof

    Arkadiy Vertleyb and + Peder Holt

    Andy Little

    2005 May 20 - 2005 May 30

    Accepted — Added in 1.34

    Singleton

    Jason Hise

    Pavel Vozenilek

    2005 May 5 - 2005 May 15

    Rejected

    FOREACH Macro

    Eric Niebler

    Gennadiy Rozental

    2005 April 25 - 2005 May 1

    Accepted — Added in 1.34

    Hash

    Daniel James

    Thorsten Ottosen

    2005 Mar 21 - 2005 March 12

    Accepted — Added in 1.33

    State Chart

    Andreas Huber

    Pavel Vozenilek

    2005 Feb 23 - 2005 March 9

    Accepted — Added in 1.34

    Wave

    Hartmut Kaiser

    Tom Brinkman

    2005 Feb 7 - 2005 Feb 20

    Accepted — Added in 1.33

    Pointer Containers

    Thorsten Ottosen

    Pavol Droba

    2004 Sept 26 - Oct 5

    Accepted — Added in 1.33

    Named Params

    David Abrahams & + Daniel Wallin

    Doug Gregor

    2004 Nov 1 - 2004 Nov 20

    Accepted — Added in 1.33

    Output Formatters

    Reece Dunn

    John Torjo

    2004 Sept 11 - Sept 25

    Rejected

    Iostreams

    Jonathan Turkanis

    Jeff Garland

    2004 Aug 28 - Sep 11

    Accepted — Added in 1.33

    More IO

    Daryle Walker

    Tom Brinkman

    2004 Aug 21 - 28

    Rejected

    Tribool

    Douglas Gregor

    Thomas Witt

    2004 May 19-29

    Accepted — Added in 1.32

    Assignment

    Thorsten Ottosen

    Tom Brinkman

    2004 Apr 1 - 11

    Accepted — Added in 1.32

    Serialization (re-review)

    Robert Ramey

    Jeff Garland

    2004 Apr 13 - 26

    Accepted — Added in 1.32

    Container Traits (now Range)

    Thorsten Ottosen

    Hartmut Kaiser

    2004 Apr 28 - May 7

    Accepted — Added in 1.32

    Indexed Set (now MultiIndex)

    Joaquín Mª López Muñoz

    Pavel Vozenilek

    2004 Mar 20 - 30

    Accepted — Added in 1.32

    Circular Buffer

    Jan Gaspar

    Pavel Vozenilek

    2004 Mar 5 - 15

    Accepted — Added in 1.35

    enable_if

    Jaakko Järvi & Jeremiah Willcock & Andrew Lumsdaine

    (fasttrack)

    Dec 2003

    Accepted — added in 1.31

    FC++

    Brian McNamara & Yannis Smaragdakis

    Mat Marcus

    2004 Feb 14 - Mar 1

    Rejected

    Numeric Conversions Library

    Fernando Cacciola

    Thorsten Ottosen

    8 - 22 Dec 2003

    Accepted — added in 1.32

    String Algorithm Library

    Pavol Droba

    Thorsten Ottosen

    17 - 30 Oct 2003

    Accepted — added in 1.32

    Shifted Pointer

    Philippe A. Bouchard

    Doug Gregor

    24 - 30 Sep 2003

    Rejected

    Fixed-Point Decimal

    Bill Seymour

    Jens Maurer

    11 - 21 Jul 2003

    Rejected

    Math Constants

    Paul A. Bristow

    Jaap Suter

    06 - 15 Jun 2003

    Rejected

    Command Line & Config

    Vladimir Prus

    Aleksey Gurtovoy

    21 May - 03 Jun 2003

    Accepted — added in 1.32

    I/O Manipulators and Adaptors

    Daryle Walker

    Ed Brey

    27 Feb - 11 Mar 2003

    -

    Variant

    Eric Friedman & Itay Maman

    Jeff Garland

    16 - 25 Feb 2003

    Accepted — added in 1.31

    Optional

    Fernando Cacciola

    Douglas Gregor

    09 - 18 Dec 2002

    Accepted — added in 1.30

    Serialization

    Robert Ramey

    Dave Abrahams

    02 - 11 Nov 2002

    Rejected

    Spirit

    Joel de Guzman

    John Maddock

    11 - 20 Oct 2002

    Accepted — added in 1.30

    Minmax

    Hervé Bronnimann

    Thomas Witt

    28 Sep - 07 Oct 2002

    Accepted — added in 1.32

    Filesystem

    Beman Dawes

    William Kempf

    14 - 23 Sep 2002

    Accepted — added in 1.30

    Interval Arithmetic Library

    Hervé Bronnimann & Guillaume Melquiond & Sylvain Pion

    Beman Dawes

    31 Aug - 09 Sep 2002

    Accepted — added in 1.30

    Template Meta Programming Library MPL

    Aleksey Gurtovoy

    Douglas Gregor

    15 - 29 Jul 2002

    Accepted — added in 1.30

    uBLAS

    Joerg Walter & Mathias Koch

    Ed Brey

    21 Jun - 01 Jul 2002

    Accepted — added in 1.29

    Dynamic Bitset

    Chuck Alison & Jeremy Siek

    Mat Marcus

    08 - 17 Jun 2002

    Accepted — added in 1.29

    Date / Time

    Jeff Garland

    Darin Adler

    15 - 24 Apr 2002

    Accepted — added in 1.29

    Lambda

    Jaakko Järvi & Gary Powell

    Aleksey Gurtovoy

    08 - 20 Mar 2002

    Accepted and added

    Signals

    Douglas Gregor

    William Kempf

    18 - 27 Feb 2002

    Accepted — added in 1.29

    I/O State Saver

    Daryle Walker

    Beman Dawes

    06 - 16 Feb 2002

    Accepted and added

    printf-like formatting for iostreams

    Samuel Krempp

    Jens Maurer

    13 - 23 Jan 2002

    Accepted — added in 1.29

    Multi-array

    Ron Garcia

    John Maddock

    02 - 12 Jan 2002

    Accepted — added in 1.29

    Unit Test Library

    Gennadiy Rozental

    Jeremy Siek

    01 - 13 Dec 2001

    Accepted and added

    GCD Library plus integer additions

    Daryle Walker

    Dave Abrahams

    17 - 26 Sep 2001

    -

    Thread Library

    Bill Kempf

    Ed Brey

    Aug 30 - Sep 8

    Accepted and added

    Config System

    John Maddock

    Doug Gregor

    Aug 20 - 29

    Accepted and added

    Bind Library

    Peter Dimov

    Darin Adler

    Aug 10 - 19

    Accepted and added

    Base from Member Library

    Daryle Walker

    Beman Dawes

    Jul 30 - Aug 9

    -

    Coding Guidelines

    Dave Abrahams

    Aleksey Gurtovoy

    Jul 20 - 29

    -

    Preprocessor Library

    Vesa Karvonen

    Jeremy Siek

    Jun 28 - Jul 9

    Accepted and added

    Tuples Library

    Jaakko Järvi

    Beman Dawes

    Jun 17 - 26

    Accepted and added

    Function Library

    Doug Gregor

    John Maddock

    Jun 6 - 16

    Accepted and added

    Tokenizer

    John Bandela

    Doug Gregor

    May 28 - Jun 6

    Accepted and added

    Special Functions

    Hubert Holin

    Jens Maurer

    May 18 - 27

    Accepted and added

    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/submissions.html b/preview/formal-reviews/submissions.html new file mode 100644 index 0000000..870c032 --- /dev/null +++ b/preview/formal-reviews/submissions.html @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + Library Submission Process :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Library Submission Process

    + +
    +

    Steps for Getting a Library Accepted by Boost

    +
    +
    +

    1. Learn about Boost

    +
    +

    Follow posts on the Boost developers' mailing list for a while, or look through the message archives. Explore this website. Learn the Library Requirements. Read the rest of this page to learn about the process. Search the web to get an idea of the commitment required to get a library into Boost.

    +
    +
    +

    There is a culture associated with Boost, aimed at encouraging high quality libraries by a process of discussion and refinement. Some libraries get past community review in less than two years from first concept, but most take longer, sometimes a lot longer. Five to ten years to get a library past review and into Boost is not unheard of, and you should prepare yourself for the personal investment required.

    +
    +
    +
    +

    2. Determine Interest

    +
    +

    While participation in reviews for other submissions is not a prerequisite for submitting a library to Boost, it is highly recommended; it will acquaint you with the process and the emotional demands of a formal review. There’s nothing that quite deflates the ego like having brilliant members of the C++ community critiquing your work, but, alas, it’s worth it!

    +
    +
    +

    Potential library submitters should be careful to research the prior art before beginning to design a new library. Unfortunately, now and then folks arrive at Boost with a new library into which they have invested many hours, only to find that Boost already has that functionality, and sometimes has had it for years. Candidates should also research libraries being developed by others intended for Boost - if you have an itch to scratch, often so have had others and collaboration developing their library is usually considerably more efficient than going at it alone.

    +
    +
    +

    Potential library submitters should also be careful to publicize, canvas for, and gauge interest in their library, ideally before beginning it, but certainly before submitting it for review. Even a superbly designed library can fail review if there isn’t enough interest in the subject matter; We can only review libraries with enough appeal to form a viable peer review. Ensuring that enough people are interested in your potential library goes a long way to ensure that.

    +
    +
    +

    There are many places to publicize and canvas for a library. The Boost developers' mailing list ought to be your first stop in gauging interest in a possible new C++ library. Be prepared to pivot your design and focus until your proposed library finds traction. Other places useful for gauging interest in a library might be Reddit/r/cpp.

    +
    +
    +

    A message to the Boost developers mailing list might be as simple as "Is there any interest in a library which solves Traveling Salesperson problems in linear time?"

    +
    +
    +

    A bit of further description or snippet of code may be helpful. By the way, the preferred format for messages on the mailing list is plain text; not rich text, HTML, etc.

    +
    +
    +

    Avoid posting lengthy descriptions, documentation, or code to the mailing list, and, please, no attachments. The best place to provide lengthy material is via. a web link. Project hosting services such as sourceforge, github, google code, and bitbucket serve well for this purpose.

    +
    +
    +
    +

    3. Start Development

    +
    +

    If response to an initial query indicates interest, then by all means make your library publicly available if you haven’t already done so.

    +
    +
    +

    Please commit your code to a version control system such as Git, and make your documentation available in HTML format on a public website such as Github. An issue tracker such as the one provided by Github is also highly recommended.

    +
    +
    +

    Your library should contain material as if it were on the boost.org web site. The closer your library reflects the final directory structure and format of the web site, the better. This makes it possible for reviewers to simply copy your code into the Boost distribution for testing.

    +
    +
    +

    Please verify that your library compiles and runs under at least two compilers. This flushes out obvious portability problems.

    +
    +
    +

    It is recommended that you release your code under the Boost Software License.

    +
    +
    +
    +

    4. Make Refinements

    +
    +

    Discuss, refine, rewrite. Repeat until satisfied.

    +
    +
    +

    The exact details of this process varies a lot. Usually it is public, on the mailing list, but frequently discussion happens in private emails. For some libraries the process is over quickly, but for others it goes on for months. It’s often challenging, and sometimes veers in completely unexpected directions.

    +
    +
    +

    The mailing list archives of past messages is one way to see how this process worked for other Boost libraries.

    +
    +
    +

    Alternatively, follow the status links in the previously submitted libraries listed in Past Review Results and Milestones.

    +
    +
    +
    +

    5. Get Seconded for Review

    +
    +

    When you feel that your library is ready for entry into Boost, you need to find at least one member (but preferably several) of the Boost community who is willing to publicly endorse your library for entry into Boost. A simple method of achieving this is to post to the Boost developers' mailing list a short description of your library, links to its github and documentation, and a request for endorsements.

    +
    +
    +

    It is expected that those who endorse a library for review will have performed at least a cursory check of the library’s suitability for Boost in terms of documentation, fit with the rest of Boost and usefulness. A public endorsement of a library for review means that from an initial glance, they believe that the library has a reasonable chance to be accepted during a formal review. The expectation is that these endorsers will themselves review of the library during formal review period, though this is not binding.

    +
    +
    +

    Once you have a list of people who have publicly endorsed your library for review, email the Boost developers' mailing list to request that your library be added to the Current Schedule where the following information will be shown:

    +
    +
    +
      +
    • +

      Submission (Library name)

      +
    • +
    • +

      Submitter (author or authors)

      +
    • +
    • +

      Review Manager

      +
    • +
    • +

      Review Dates (start and end dates of the review period)

      +
    • +
    • +

      Links to the status of the review, given as announcements.

      +
    • +
    +
    +
    +
    +

    6. Seek a Review Manager

    +
    +

    In order to schedule a formal review, the author must find a capable volunteer to manage the review. This should be someone with knowledge of the library domain, and experience with the review process. See Managing Reviews for the responsibilities of the review manager.

    +
    +
    +

    Authors can find community members interested in managing reviews through discussion of the library on the developer list. If no one steps forward to volunteer to manage the review, it is appropriate to contact an experienced Boost member who showed interest in the library. Be considerate that managing a review is a serious commitment; for this reason, it’s better to contact the member off-list.

    +
    +
    +

    If you cannot find a review manager after three weeks using the means above, and your submission is targeting eventual standardization, there is a list of Boost regulars who are also WG21 committee members who have volunteered to act as review managers in such cases. Try them in the order listed. They are: Zach Laine, Micheal Caisse, Matt Calabrese, Edward Diener, Louis Dionne, Vinnie Falco, Glen Fernandes, and David Sankel.

    +
    +
    +

    Once a potential review manager has been identified, contact the Review Wizards for approval. The wizards approve review managers based on their level of participation in the Boost community.

    +
    +
    +

    The review wizards will coordinate with both the author and review manager to schedule a date convenient for both.

    +
    +
    +
    +

    7. Participate in the Formal Review

    +
    +

    Before your formal review begins, double-, triple-, and quadruple-check your library. Verify that every code example works, that all unit tests pass on at least two compilers on at least two major operating systems, and run your documentation through a spelling and grammar checker.

    +
    +
    +

    Please do not modify your library on its master branch during a review. Instead, modify a separate develop branch in response to feedback and reviews. For bigger ticket items of work, open issues on your issue tracker so interested people can track the fixing of specific issues raised.

    +
    +
    +

    The review manager will consider all the reviews made by members of the community and arrive at a decision on whether your library is rejected, conditionally accepted or unconditionally accepted. They will post a report summarizing the decision publicly. If conditions are attached to acceptance, you will need to implement those conditions or else undergo an additional formal review.

    +
    +
    +

    Fast Track Reviews

    +
    +

    To qualify for a fast track review:

    +
    +
    +
      +
    • +

      The component must be small.

      +
    • +
    • +

      The technique must be already in use in Boost libraries and the new component provides a common implementation.

      +
    • +
    • +

      A full Boost-conformant implementation is available in the sandbox.

      +
    • +
    • +

      The review wizard determines that the proposal qualifies for fast track review.

      +
    • +
    +
    +
    +
    +

    Fast Track Procedure

    +
    +
      +
    1. +

      The Boost review wizard posts a review announcement to the main Boost developer’s list. The fast track review period will normally last for 5 days. No two fast-track reviews will run in parallel. Fast track reviews may run during full reviews, though generally, this is to be avoided.

      +
    2. +
    3. +

      After the review period ends, the submitter will post a review summary containing proposed changes to the reviewed implementation.

      +
    4. +
    5. +

      The review wizard will accept or reject the proposed library and proposed changes.

      +
    6. +
    7. +

      After applying the proposed changes, the component is checked into the repository like any other library.

      +
    8. +
    +
    +
    +
    +
    +

    8. Respond to Mini-Review Requests

    +
    +

    It is possible that in the review process some issues might need to be fixed as a requirement for acceptance. If a review does result in conditions on acceptance, the review manager may request a Mini-Review, at a later date, to determine if the conditions have been met. The Mini-Review is usually conducted by the same review manager.

    +
    +
    +
    +

    9. Check-in to the Boost Website

    +
    +

    Once an accepted library is ready for inclusion on the Boost web site, the submitter is typically given Boost repository write access, and expected to check-in and maintain the library there. Contact the moderators if you need write access or direct use of the repository isn’t possible for you.

    +
    +
    +
    +

    10. Update the People Page

    +
    +

    If the boost.org web site doesn’t already have your capsule biography and picture (optional, with not-too-serious pictures preferred!), please send them to the Boost webmaster. It is up to you as to whether or not the biography includes your email address or other contact information. The preferred picture format is .jpg, but other common formats are acceptable. The preferred image size is 500x375 but the webmaster has photo editing software and can do the image preparation if necessary.

    +
    +
    +
    +
    +
    +

    Lifecycle

    +
    +
    +

    Libraries are software; they lose their value over time if not maintained. Postings on the Boost developers or users mailing lists can alert you to potential maintenance needs; please plan to maintain your library over time. If you no longer can or wish to maintain your library, please post a message on the Boost developers mailing list asking for a new maintainer to volunteer and then spend the time to help them take over.

    +
    +
    +

    Orphaned libraries will be put in the care of a maintenance team, pending a search for a new maintainer.

    +
    +
    +
    +
    +

    Rights and Responsibilities

    +
    +
    +

    By submitting a library to Boost, you accept responsibility for maintaining your library, or finding a qualified volunteer to serve as maintainer. You must be willing to put your library and documentation under a Boost-compatible license.

    +
    +
    +

    You will be expected to respond to reasonable bug reports and questions on time and to participate as needed in discussions of your library on the Boost mailing lists.

    +
    +
    +

    You are free to change your library in any way you wish, and you are encouraged to actively make improvements. However, peer review is an important part of the Boost process and as such you are also encouraged to get feedback from the Boost community before making substantial changes to the interface of an accepted library.

    +
    +
    +

    If at some point you no longer wish to serve as maintainer of your library, it is your responsibility to make this known to the Boost community, and to find another individual to take your place.

    +
    +
    +

    Libraries which have been abandoned will be put in care of a maintenance team.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/formal-reviews/writing-reviews.html b/preview/formal-reviews/writing-reviews.html new file mode 100644 index 0000000..fe404b4 --- /dev/null +++ b/preview/formal-reviews/writing-reviews.html @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + Writing Reviews :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Writing Reviews

    +
    +
    +
    +

    The goal of a Boost library review is to improve a candidate library through constructive criticism. At the end a decision must be made: is the candidate library good enough at this point to accept into Boost? If not, we hope to have provided enough constructive criticism for it to be improved and accepted at a later time. The Boost.Serialization library is a good example of a library that was originally rejected, but constructive criticism led to revisions resulting in an excellent library that was accepted in its second review.

    +
    +
    +

    Your comments may be brief or lengthy. The review manager needs your evaluation of the library. If you identify problems during your evaluation, try to categorize them as minor, serious, or showstoppers.

    +
    +
    +

    Ask questions for the library authors, on the Boost Developers Mailing List, so all interested parties can see it. Authors are interested in defending their library. If you don’t get a response to your question quickly, be patient; if it takes too long or you don’t get an answer you feel is sufficient, ask again or try to rephrase the question. Clarity is important, English is not the native language of many Boost developers. Try to get your questions answered before you submit your review.

    +
    +
    +

    Here’s a structured approach to writing a review of a library, covering all the bases:

    +
    + +
    +
    +
    +

    Introduction

    +
    +
    +

    Introduce yourself, and your knowledge of the problem domain. Remember that input from a newcomer to a domain is valuable. Briefly introduce the library and its purpose as you see it.

    +
    +
    +

    Scope

    +
    +

    Describe the scope of your review, such as a focus on any particular area of the API, or any particular type of problem within the domain. Be clear on the level of commitment you made to the evaluation (a quick reading, in-depth testing of the API or a subset of it, focus on any particular area such as documentation, tutorials, portability, or similar).

    +
    +
    +
    +

    Affiliation

    +
    +

    Make it clear if you are affiliated with any organization involved with C++.

    +
    +
    +
    +
    +
    +

    Design and Architecture

    +
    +
    +

    Evaluate the design principles and architectural decisions of the library. Discuss the modularity, extensibility, and flexibility of the library’s design. Assess how well the design aligns with Boost’s guidelines and best practices.

    +
    +
    +

    Similar Libraries

    +
    +

    Discuss other Boost, or Standard, libraries that cover similar areas to this library. Note the differences, improvements, regressions, that the design suggests.

    +
    +
    +
    +
    +
    +

    Implementation

    +
    +
    +

    Provide an overview of the key functionality and features offered by the library. Evaluate the completeness and robustness of the feature set. Discuss any unique or innovative features that differentiate this library from existing alternatives.

    +
    +
    +

    Evaluate the usability of the library from your developer’s perspective. Discuss the ease of integration, API usability, and critically the learning curve.

    +
    +
    +

    Performance

    +
    +

    If you wrote some test code, which is highly recommended, assess the performance characteristics of the library, including not only runtime efficiency but resource usage. Include code snippets from your test code in your evaluation, in particular highlighting the code you wrote to prepare for an API call into the library, and the code following the call to handle the result/data/errors appropriately.

    +
    +
    +

    If possible, benchmark the library against similar solutions or existing libraries in terms of speed, memory footprint, and scalability.

    +
    +
    +
    +

    Testing and Reliability

    +
    +

    Assess the reliability and stability of the library, including error handling and corner case handling. Discuss any known issues, limitations, or areas for improvement in terms of reliability. It is key to address the clarity and usefulness of error messages, and how they helped or hindered you in locating any particular problem.

    +
    +
    +
    +

    Portability and Compatibility

    +
    +

    If you are able, evaluate the portability of the library across different platforms, compilers, and environments. Give precise details on the tools or environment you used. Assess the library’s compatibility with relevant C++ standards and other Boost libraries. Discuss any platform-specific issues, considerations or dependencies that you encountered.

    +
    +
    +
    +
    +
    +

    Documentation

    +
    +
    +

    Assess the quality and comprehensiveness of the documentation, including tutorials, examples, and API reference materials. Include comments on the ease of navigation within the documentation, the structure of the documentation, and how easy or difficult it was to find what you were looking for.

    +
    +
    +
    +
    +

    Conclusion

    +
    +
    +

    Briefly summarize the strengths and weaknesses of the candidate library. Critically, provide a recommendation regarding the suitability of the library for inclusion in Boost. If the library falls short in some way, offer suggestions for improvements or areas of focus that would bring the library up to the standard for a positive recommendation for inclusion.

    +
    +
    +

    Community and Adoption

    +
    +

    Assess the likelihood of adoption by developers and organizations within the C++ community.

    +
    +
    +
    +
    +
    +

    Review Template

    +
    +
    +

    If it’s helpful, cut and paste the following template into your email text when you have completed your review:

    +
    +
    +
    +
    1. Introduce yourself
    +* Are you knowledgeable about the problem domain?
    +* How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
    +* Do you have an affiliation to disclose?
    +
    +2. What is your evaluation of the design and architecture?
    +* What is your evaluation of the potential usefulness of the library?
    +* Is the feature set, or subset, of the library available in another Boost or Standard library?
    +
    +3. What is your evaluation of the implementation?
    +* Did you try to use the library? With what compiler? Did you have any problems (minor, series, showstoppers)?
    +* Can you highlight any performance issues?
    +* Any feedback on testing and reliability?
    +* Did you investigate portability and compatibility?
    +
    +4. What is your evaluation of the documentation?
    +* Any thoughts on the introduction, tutorials, API reference, completeness, helpfulness?
    +
    +5. My conclusion
    +* How do you think the community will react?
    +* What is your verdict: Yes, No, or Yes with changes?
    +
    +
    +
    +
    +
    +

    Best Practices

    +
    +
    +

    From experience, there a number of more common pitfalls when writing reviews and engaging in review feedback discussions, so keep the following in mind:

    +
    +
    +
      +
    • +

      Literally, keep on the same page. Submissions, discussions, comment should always be on the Boost Developers Mailing List and not on Slack, Reddit, in personal email, or any other media.

      +
    • +
    • +

      Elaborate in full. If you have series technical feedback on a library then explain yourself in detail. Try to avoid "teaser" type comments where other developers might feel you are onto something, but they are just not sure what.

      +
    • +
    • +

      Reviews needs to be self-contained. It’s not a starting point for a discussion. Nobody is obligated to ask you clarifying questions, and there should be no missing parts that you fill in later in subsequent posts. This means that if you have questions about the library that you feel need to be answered by the author or review manager, you should ask these questions before you submit your review.

      +
    • +
    • +

      Do not expect complete agreement. Too much compromise, consensus, in engineering endeavors leads to poorer design.

      +
    • +
    • +

      Refer to the Reality Check section in the topic on Review Managers for clarity on the role of your review.

      +
    • +
    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/index.html b/preview/index.html index c144026..7a10f33 100644 --- a/preview/index.html +++ b/preview/index.html @@ -1,622 +1,143 @@ - - - - - - - - - - - - Capy :: Boost Libraries Documentation - - - - - - - - - - - - - - - - - -
    -
    -
    - -

    Capy

    -
    -
    -
    -

    Capy abstracts away sockets, files, and asynchrony with type-erased streams and buffer sequences—code compiles fast because the implementation is hidden. It provides the framework for concurrent algorithms that transact in buffers of memory: networking, serial ports, console, timers, and any platform I/O. This is only possible because Capy is coroutine-only, enabling optimizations and ergonomics that hybrid approaches must sacrifice.

    -
    -
    -
    -
    -

    What This Library Does

    -
    -
    -
      -
    • -

      Lazy coroutine taskstask<T> with forward-propagating stop tokens and automatic cancellation

      -
    • -
    • -

      Buffer sequences — taken straight from Asio and improved

      -
    • -
    • -

      Stream conceptsReadStream, WriteStream, ReadSource, WriteSink, BufferSource, BufferSink

      -
    • -
    • -

      Type-erased streamsany_stream, any_read_stream, any_write_stream for fast compilation

      -
    • -
    • -

      Concurrency facilities — executors, strands, thread pools, when_all, when_any

      -
    • -
    • -

      Test utilities — mock streams, mock sources/sinks, error injection

      -
    • -
    -
    -
    -
    -
    -

    What This Library Does Not Do

    -
    -
    -
      -
    • -

      Networking — no sockets, acceptors, or DNS; that’s what Corosio provides

      -
    • -
    • -

      Protocols — no HTTP, WebSocket, or TLS; see the Http and Beast2 libraries

      -
    • -
    • -

      Platform event loops — no io_uring, IOCP, epoll, or kqueue; Capy is the layer above

      -
    • -
    • -

      Callbacks or futures — coroutine-only means no other continuation styles

      -
    • -
    • -

      Sender/receiver — Capy uses the IoAwaitable protocol, not std::execution

      -
    • -
    -
    -
    -
    -
    -

    Target Audience

    -
    -
    -
      -
    • -

      Users of Corosio — portable coroutine networking

      -
    • -
    • -

      Users of Http — sans-I/O HTTP/1.1 clients and servers

      -
    • -
    • -

      Users of Websocket — sans-I/O WebSocket

      -
    • -
    • -

      Users of Beast2 — high-level HTTP/WebSocket servers

      -
    • -
    • -

      Users of Burl — high-level HTTP client

      -
    • -
    -
    -
    -

    All of these are built on Capy. Understanding its concepts—tasks, buffer sequences, streams, executors—unlocks the full power of the stack.

    -
    -
    -
    -
    -

    Design Philosophy

    -
    -
    -
      -
    • -

      Use case first. Buffer sequences, stream concepts, executor affinity—these exist because I/O code needs them, not because they’re theoretically elegant.

      -
    • -
    • -

      Coroutines-only. No callbacks, futures, or sender/receiver. Hybrid support forces compromises; full commitment unlocks optimizations that adapted models cannot achieve.

      -
    • -
    • -

      Address the complaints of C++. Type erasure at boundaries, minimal dependencies, and hidden implementations keep builds fast and templates manageable.

      -
    • -
    -
    -
    -
    -
    -

    Requirements

    -
    -
    -

    Assumed Knowledge

    -
    -
      -
    • -

      C++20 coroutines, concepts, and ranges

      -
    • -
    • -

      Basic concurrent programming

      -
    • -
    -
    -
    -
    -

    Compiler Support

    -
    -
      -
    • -

      GCC 12+

      -
    • -
    • -

      Clang 17+

      -
    • -
    • -

      Apple-Clang (macOS 14+)

      -
    • -
    • -

      MSVC 14.34+

      -
    • -
    • -

      MinGW

      -
    • -
    -
    -
    -
    -

    Dependencies

    -
    -

    None. Capy is self-contained and does not require Boost.

    -
    -
    -
    -

    Linking

    -
    -

    Capy is a compiled library. Link against capy.

    -
    -
    -
    -
    -
    -

    Code Convention

    -
    -
    - - - - - -
    - - -
    -

    Unless otherwise specified, all code examples in this documentation assume the following:

    -
    -
    -
    -
    #include <boost/capy.hpp>
    -using namespace boost::capy;
    -
    -
    -
    -
    -
    -
    -
    -

    Quick Example

    -
    -
    -

    This example demonstrates a minimal coroutine that reads from a stream and echoes the data back:

    -
    -
    -
    -
    #include <boost/capy.hpp>
    -
    -using namespace boost::capy;
    -
    -task<> echo(any_stream& stream)
    -{
    -    char buf[1024];
    -    for(;;)
    -    {
    -        auto [ec, n] = co_await stream.read_some(mutable_buffer(buf));
    -        if(ec.failed())
    -            co_return;
    -        auto [wec, wn] = co_await write(stream, const_buffer(buf, n));
    -        if(wec.failed())
    -            co_return;
         }
    -}
    +    html.light {
    +      --bg: #f9fafb; --fg: #1a1a1a; --muted: #6b7280;
    +      --link: #1a6fb5; --border: #e5e7eb; --card-bg: #ffffff;
    +    }
    +    html.dark {
    +      --bg: #111214; --fg: #e5e7eb; --muted: #9ca3af;
    +      --link: #60a5fa; --border: #2a2d32; --card-bg: #1a1c20;
    +    }
    +    * { margin: 0; padding: 0; box-sizing: border-box; }
    +    body {
    +      font-family: system-ui, -apple-system, sans-serif;
    +      background: var(--bg); color: var(--fg);
    +      max-width: 640px; margin: 0 auto;
    +      padding: 3rem 1.5rem;
    +    }
    +    header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.5rem; }
    +    h1 { font-size: 1.375rem; font-weight: 600; }
    +    .theme-btn {
    +      background: none; border: none; cursor: pointer;
    +      padding: 0.25rem; color: var(--muted); display: flex; align-items: center;
    +    }
    +    .theme-btn:hover { color: var(--fg); }
    +    .theme-btn svg { width: 18px; height: 18px; fill: currentColor; }
    +    .icon-sun { display: none; }
    +    .icon-moon { display: block; }
    +    html.dark .icon-sun { display: block; }
    +    html.dark .icon-moon { display: none; }
    +    @media (prefers-color-scheme: dark) {
    +      .icon-sun { display: block; }
    +      .icon-moon { display: none; }
    +    }
    +    html.light .icon-sun { display: none; }
    +    html.light .icon-moon { display: block; }
    +    .subtitle { color: var(--muted); margin-bottom: 2.5rem; font-size: 0.9375rem; }
    +    h2 { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); margin-bottom: 0.5rem; margin-top: 1.75rem; }
    +    .links { display: flex; flex-direction: column; gap: 0.25rem; margin-bottom: 0.5rem; }
    +    .link-row { display: flex; align-items: baseline; gap: 0.5rem; padding: 0.375rem 0; }
    +    a { color: var(--link); text-decoration: none; }
    +    a:hover { text-decoration: underline; }
    +    .tag { font-size: 0.75rem; color: var(--muted); }
    +    .desc { font-size: 0.8125rem; color: var(--muted); }
    +    hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
    +    footer { font-size: 0.8125rem; color: var(--muted); }
    +    footer a { color: var(--muted); }
    +  
    +
    +
    +  
    +

    Boostlook v3

    + +
    +

    Preview builds for the new Boost C++ Libraries site design, in collaboration with MetaLab.

    -int main() -{ - thread_pool pool; - // In a real application, you would obtain a stream from Corosio - // and call: run_async(pool.get_executor())(echo(stream)); - return 0; -}
    -
    -
    -
    -

    The echo function accepts an any_stream&—a type-erased wrapper that works with any concrete stream implementation. The function reads data into a buffer, then writes it back. Both operations use co_await to suspend until the I/O completes.

    -
    -
    -

    The task<> return type (equivalent to task<void>) creates a lazy coroutine that does not start executing until awaited or launched with run_async.

    -
    -
    -
    -
    -

    Next Steps

    -
    -
    - -
    -
    -
    - - -
    -
    - -
    - +

    Design System

    + + +

    Library Docs

    + + +

    Site Docs

    + + +
    + + + + diff --git a/preview/style-guide/index.html b/preview/style-guide/index.html index d2da18a..f63d2fb 100644 --- a/preview/style-guide/index.html +++ b/preview/style-guide/index.html @@ -80,6 +80,10 @@ + - - - diff --git a/preview/user-guide/_images/Boost_Brandmark_WhiteBoost_Transparent.svg b/preview/user-guide/_images/Boost_Brandmark_WhiteBoost_Transparent.svg new file mode 100644 index 0000000..ec743ab --- /dev/null +++ b/preview/user-guide/_images/Boost_Brandmark_WhiteBoost_Transparent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/preview/user-guide/_images/a-sunset-over-the-mountain.png b/preview/user-guide/_images/a-sunset-over-the-mountain.png new file mode 100644 index 0000000..294d198 Binary files /dev/null and b/preview/user-guide/_images/a-sunset-over-the-mountain.png differ diff --git a/preview/user-guide/_images/additional-include-directories.png b/preview/user-guide/_images/additional-include-directories.png new file mode 100644 index 0000000..be193aa Binary files /dev/null and b/preview/user-guide/_images/additional-include-directories.png differ diff --git a/preview/user-guide/_images/additional-library-directories.png b/preview/user-guide/_images/additional-library-directories.png new file mode 100644 index 0000000..044787b Binary files /dev/null and b/preview/user-guide/_images/additional-library-directories.png differ diff --git a/preview/user-guide/_images/aerospace-design.png b/preview/user-guide/_images/aerospace-design.png new file mode 100644 index 0000000..0e2cd89 Binary files /dev/null and b/preview/user-guide/_images/aerospace-design.png differ diff --git a/preview/user-guide/_images/aerospace-gear.png b/preview/user-guide/_images/aerospace-gear.png new file mode 100644 index 0000000..de8720f Binary files /dev/null and b/preview/user-guide/_images/aerospace-gear.png differ diff --git a/preview/user-guide/_images/beman_dawes.jpg b/preview/user-guide/_images/beman_dawes.jpg new file mode 100644 index 0000000..cdb8952 Binary files /dev/null and b/preview/user-guide/_images/beman_dawes.jpg differ diff --git a/preview/user-guide/_images/bio-tech-luca.png b/preview/user-guide/_images/bio-tech-luca.png new file mode 100644 index 0000000..0ab096b Binary files /dev/null and b/preview/user-guide/_images/bio-tech-luca.png differ diff --git a/preview/user-guide/_images/bloch-sphere.png b/preview/user-guide/_images/bloch-sphere.png new file mode 100644 index 0000000..fa09761 Binary files /dev/null and b/preview/user-guide/_images/bloch-sphere.png differ diff --git a/preview/user-guide/_images/bloom-filter.png b/preview/user-guide/_images/bloom-filter.png new file mode 100644 index 0000000..aac9a43 Binary files /dev/null and b/preview/user-guide/_images/bloom-filter.png differ diff --git a/preview/user-guide/_images/boost.png b/preview/user-guide/_images/boost.png new file mode 100644 index 0000000..7edba68 Binary files /dev/null and b/preview/user-guide/_images/boost.png differ diff --git a/preview/user-guide/_images/cartoon-volcanic-eruption.png b/preview/user-guide/_images/cartoon-volcanic-eruption.png new file mode 100644 index 0000000..0655758 Binary files /dev/null and b/preview/user-guide/_images/cartoon-volcanic-eruption.png differ diff --git a/preview/user-guide/_images/client-server-layers.png b/preview/user-guide/_images/client-server-layers.png new file mode 100644 index 0000000..8068056 Binary files /dev/null and b/preview/user-guide/_images/client-server-layers.png differ diff --git a/preview/user-guide/_images/cluster_plot.png b/preview/user-guide/_images/cluster_plot.png new file mode 100644 index 0000000..97b0054 Binary files /dev/null and b/preview/user-guide/_images/cluster_plot.png differ diff --git a/preview/user-guide/_images/cpp-programmer-at-work.png b/preview/user-guide/_images/cpp-programmer-at-work.png new file mode 100644 index 0000000..a8cb4fe Binary files /dev/null and b/preview/user-guide/_images/cpp-programmer-at-work.png differ diff --git a/preview/user-guide/_images/cpp-runtime-error.png b/preview/user-guide/_images/cpp-runtime-error.png new file mode 100644 index 0000000..0052380 Binary files /dev/null and b/preview/user-guide/_images/cpp-runtime-error.png differ diff --git a/preview/user-guide/_images/database-persistent-memory.png b/preview/user-guide/_images/database-persistent-memory.png new file mode 100644 index 0000000..be7fc9d Binary files /dev/null and b/preview/user-guide/_images/database-persistent-memory.png differ diff --git a/preview/user-guide/_images/deformation.png b/preview/user-guide/_images/deformation.png new file mode 100644 index 0000000..74e44d1 Binary files /dev/null and b/preview/user-guide/_images/deformation.png differ diff --git a/preview/user-guide/_images/digital-wallet-empty.png b/preview/user-guide/_images/digital-wallet-empty.png new file mode 100644 index 0000000..4df0011 Binary files /dev/null and b/preview/user-guide/_images/digital-wallet-empty.png differ diff --git a/preview/user-guide/_images/digital-wallet.png b/preview/user-guide/_images/digital-wallet.png new file mode 100644 index 0000000..832947f Binary files /dev/null and b/preview/user-guide/_images/digital-wallet.png differ diff --git a/preview/user-guide/_images/entanglement.png b/preview/user-guide/_images/entanglement.png new file mode 100644 index 0000000..5d33274 Binary files /dev/null and b/preview/user-guide/_images/entanglement.png differ diff --git a/preview/user-guide/_images/first-app-running.png b/preview/user-guide/_images/first-app-running.png new file mode 100644 index 0000000..e12064a Binary files /dev/null and b/preview/user-guide/_images/first-app-running.png differ diff --git a/preview/user-guide/_images/gcd-equations.png b/preview/user-guide/_images/gcd-equations.png new file mode 100644 index 0000000..47f6769 Binary files /dev/null and b/preview/user-guide/_images/gcd-equations.png differ diff --git a/preview/user-guide/_images/get-boost-button.png b/preview/user-guide/_images/get-boost-button.png new file mode 100644 index 0000000..1302046 Binary files /dev/null and b/preview/user-guide/_images/get-boost-button.png differ diff --git a/preview/user-guide/_images/grovers1.png b/preview/user-guide/_images/grovers1.png new file mode 100644 index 0000000..4968e7a Binary files /dev/null and b/preview/user-guide/_images/grovers1.png differ diff --git a/preview/user-guide/_images/grovers2.png b/preview/user-guide/_images/grovers2.png new file mode 100644 index 0000000..a39cda1 Binary files /dev/null and b/preview/user-guide/_images/grovers2.png differ diff --git a/preview/user-guide/_images/highly-respected-quote.png b/preview/user-guide/_images/highly-respected-quote.png new file mode 100644 index 0000000..ef88bf8 Binary files /dev/null and b/preview/user-guide/_images/highly-respected-quote.png differ diff --git a/preview/user-guide/_images/iris-photo.png b/preview/user-guide/_images/iris-photo.png new file mode 100644 index 0000000..3f07c42 Binary files /dev/null and b/preview/user-guide/_images/iris-photo.png differ diff --git a/preview/user-guide/_images/jet-engine-with-text.png b/preview/user-guide/_images/jet-engine-with-text.png new file mode 100644 index 0000000..de91a5f Binary files /dev/null and b/preview/user-guide/_images/jet-engine-with-text.png differ diff --git a/preview/user-guide/_images/json-example-running.png b/preview/user-guide/_images/json-example-running.png new file mode 100644 index 0000000..bbbe557 Binary files /dev/null and b/preview/user-guide/_images/json-example-running.png differ diff --git a/preview/user-guide/_images/logging-trace-to-fatal.png b/preview/user-guide/_images/logging-trace-to-fatal.png new file mode 100644 index 0000000..eb1a186 Binary files /dev/null and b/preview/user-guide/_images/logging-trace-to-fatal.png differ diff --git a/preview/user-guide/_images/message-queue.png b/preview/user-guide/_images/message-queue.png new file mode 100644 index 0000000..ebf1814 Binary files /dev/null and b/preview/user-guide/_images/message-queue.png differ diff --git a/preview/user-guide/_images/natural-language-parsing.png b/preview/user-guide/_images/natural-language-parsing.png new file mode 100644 index 0000000..f8e7787 Binary files /dev/null and b/preview/user-guide/_images/natural-language-parsing.png differ diff --git a/preview/user-guide/_images/quantum-circuit.png b/preview/user-guide/_images/quantum-circuit.png new file mode 100644 index 0000000..2a17f38 Binary files /dev/null and b/preview/user-guide/_images/quantum-circuit.png differ diff --git a/preview/user-guide/_images/quantum-teleportation.png b/preview/user-guide/_images/quantum-teleportation.png new file mode 100644 index 0000000..f6d8552 Binary files /dev/null and b/preview/user-guide/_images/quantum-teleportation.png differ diff --git a/preview/user-guide/_images/quantum-walk-simulation.png b/preview/user-guide/_images/quantum-walk-simulation.png new file mode 100644 index 0000000..663f3b2 Binary files /dev/null and b/preview/user-guide/_images/quantum-walk-simulation.png differ diff --git a/preview/user-guide/_images/rev-string-test.png b/preview/user-guide/_images/rev-string-test.png new file mode 100644 index 0000000..91ebdd6 Binary files /dev/null and b/preview/user-guide/_images/rev-string-test.png differ diff --git a/preview/user-guide/_images/stochastic-equation.png b/preview/user-guide/_images/stochastic-equation.png new file mode 100644 index 0000000..40cf67e Binary files /dev/null and b/preview/user-guide/_images/stochastic-equation.png differ diff --git a/preview/user-guide/_images/system-timing.png b/preview/user-guide/_images/system-timing.png new file mode 100644 index 0000000..f2fe407 Binary files /dev/null and b/preview/user-guide/_images/system-timing.png differ diff --git a/preview/user-guide/_images/template-time-machine.png b/preview/user-guide/_images/template-time-machine.png new file mode 100644 index 0000000..bae3474 Binary files /dev/null and b/preview/user-guide/_images/template-time-machine.png differ diff --git a/preview/user-guide/advanced-builds.html b/preview/user-guide/advanced-builds.html new file mode 100644 index 0000000..8d2efb6 --- /dev/null +++ b/preview/user-guide/advanced-builds.html @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + Advanced Builds :: Boost Site Docs + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + + diff --git a/preview/user-guide/advanced-introduction.html b/preview/user-guide/advanced-introduction.html new file mode 100644 index 0000000..af698f5 --- /dev/null +++ b/preview/user-guide/advanced-introduction.html @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + Advanced Scenarios :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Advanced Scenarios

    +
    +

    Introduction

    +
    +
    +

    Advanced scenarios require deep understanding of software programming concepts and working practices.

    +
    +
    +

    Developing a High-Performance Database Engine is a critical area of software focused on the design, development, implementation, and maintenance of databases. It involves designing database schemas, optimizing queries, managing database servers, and ensuring data integrity and security. Database engineering often requires knowledge of SQL, though NoSQL databases have become increasingly popular.

    +
    +
    +

    Machine Learning is a subset of artificial intelligence (AI) that enables systems to learn from data and improve their performance over time without being explicitly programmed. This process involves training algorithms on large datasets and using these models to make predictions or decisions. It’s widely used in areas like image recognition, natural language processing, and recommendation systems. While Python is a popular language for machine learning C++ can be used, especially when performance is critical.

    +
    +
    +

    Metaprogramming involves writing code that generates or manipulates other code. It can be used to create more flexible, reusable, and efficient software. The C++ template system is a form of compile-time metaprogramming, allowing programmers to write generic code.

    +
    +
    +

    Natural Language Processing (NLP) is another branch of artificial intelligence, this time focusing on the interaction between computers and human language. It involves teaching machines to understand, interpret, generate, and manipulate human language. This can be used in applications like chatbots, translation services, sentiment analysis, and more.

    +
    +
    +

    Parallel Computation is a type of computation in which multiple calculations or processes are carried out simultaneously, leveraging multiple cores or processors. It’s particularly useful for tasks that can be broken down into independent subtasks and run concurrently, often leading to significant performance improvements.

    +
    +
    +

    Quantum Computing is still in the research stage. However, this topic is an educational tutorial on what we might expect from quantum applications, simulating quantum algorithms in C++ where we can.

    +
    +
    +

    Aeronautical Engineering and Bio-Tech Engineering are computation-intensive and regulatory-intensive engineering disciplines where the Boost libraries quiet superpower of correctness comes into its own.

    +
    +
    +

    These areas each represent advanced fields of software development, requiring a deep understanding of specific concepts and techniques. However, they also offer exciting opportunities to build cutting-edge software applications.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/boost-history.html b/preview/user-guide/boost-history.html new file mode 100644 index 0000000..09aea74 --- /dev/null +++ b/preview/user-guide/boost-history.html @@ -0,0 +1,586 @@ + + + + + + + + + + + + + + History of Boost :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    History of Boost

    +
    +
    +
    +

    This topic provides an overview of the origins, growth, and impact of Boost on the programming community.

    +
    +
    +
    +
    +

    Introduction

    +
    +
    +

    Boost is a highly influential and widely used collection of libraries, designed to extend and complement the functionality provided by the C++ Standard Library. Since its original Proposal in 1998, Boost has played a significant role in shaping the evolution of the C++ language and its ecosystem.

    +
    +
    +
    +
    +

    Origins

    +
    +
    +

    The story of Boost began when Robert Klarer and Beman Dawes discussed the idea at the March 1998 meeting of the C++ Standards Committee in Sophia Antipolis, France. Joined by Dave Abrahams, they convened the first Boost mailing list to facilitate discussions on the creation of high-quality, peer-reviewed libraries for the C++ programming language. At the time, the C++ Standard Library was limited in its functionality, and many developers felt the need for additional libraries to support the growing demands of software development. The name "Boost" was chosen to represent the goal of boosting the C++ language and its library ecosystem to new heights.

    +
    +
    +
      +
    • +

      Dave Abrahams has made extensive contributions to the C++ Standard Library, in particular in the areas of generic programming and standard algorithms, and co-authored Boost.Iterator and Boost.Python. He is also one of the authors of the seminal book C++ Template Metaprogramming, which has inspired many developers to adopt advanced template techniques.

      +
    • +
    • +

      The late Beman Dawes made significant contributions to the language, particularly in the area of file systems. He was the original author of the Boost.Filesystem library, which provided robust support for cross-platform file handling and later became the foundation for the std::filesystem library in C++17. Dawes emphasized the importance of creating a testing culture within Boost and was pivotal in establishing Boost’s peer-review process.

      +
    • +
    • +

      Robert Klarer is the least publicly documented of the founders, though as an idea’s man he was particularly involved in discussions around best practices for high-quality library development and was instrumental in helping shape the early vision of Boost as a community-driven project.

      +
    • +
    +
    +
    +
    +
    +

    Early Development

    +
    +
    +

    The first few libraries that formed the basis of Boost were created by a group of dedicated and talented C++ programmers. Early libraries included the Boost.SmartPtr library, which provided support for reference counting and garbage collection, and the Boost.Regex library, which added regular expression support to the language. The first official release was in the year 1999, and contained 24 libraries. Version numbers were started in December 1999, with version 1.10.3.

    +
    +
    +

    Boost quickly gained traction and attracted more contributors who shared a common vision of improving the C++ language through high-quality, portable, and reusable code.

    +
    +
    +
    +
    +

    Peer Review Process

    +
    +
    +

    One of the defining characteristics of Boost is its strict peer review process. Before a library is accepted into Boost, it must undergo a thorough review by other experienced C++ developers. This process ensures that only high-quality libraries, adhering to the best programming practices, are included in the collection. The peer review process not only maintains the quality of Boost but also fosters a sense of community and encourages collaboration among its contributors.

    +
    +
    +
    +
    +

    Influence on the C++ Language and Community

    +
    +
    +

    Boost has had a profound impact on the C++ language and its community. Many of the libraries and concepts introduced by Boost have been adopted into the C++ Standard Library, including smart pointers, regular expressions, and the Boost.Lambda function syntax. Boost has also been a fertile ground for experimenting with new ideas and techniques, which have later made their way into the C++ language itself, such as Boost.TypeTraits and Boost.Mpl.

    +
    +
    +

    Developer Conference

    +
    +

    BoostCon, initiated in 2007, was a conference dedicated to the discussion and improvement of both Boost libraries and C++ software development in general. In 2012, BoostCon was rebranded as C++ Now (https://cppnow.org/) to reflect a broader scope. While Boost libraries remained a crucial part of the discussion, the conference expanded to cover popular and advanced C++ techniques.

    +
    +
    +

    C++ Now featured topics ranging from "Building a Modern C++ HTTP Server with Boost.Beast" and "Exploring New Functionalities in Boost.Geometry", to +"C++in Game Development: Best Practices" and "Advanced Template Metaprogramming Techniques", among many other presentations.

    +
    +
    +

    The conference is primarily held in May, in the picturesque and tranquil setting of Aspen, Colorado. The promotion of the location includes the warning "Mild-mannered black bears live in the area. Please close doors behind you in the evenings."

    +
    +
    +

    Boost maintainers, contributors, and users often participate in the conference, sharing their expertise, discussing best practices, and exploring new directions for Boost libraries. The conference has a reputation for interruptions and comments from the audience - it is very much a collaborative conference!

    +
    +
    +
    +
    +
    +

    Migration to Git

    +
    +
    +

    Boost libraries transitioned their source code management from Subversion (SVN), and issue tracking from Trac, to Git, and GitHub Issues, throughout 2013-2014.

    +
    +
    +

    This migration was in line with broader trends in open-source software development. Git and GitHub appeared to offer a more flexible and collaborative environment, and many open-source projects started adopting them to manage their source code and facilitate community contributions.

    +
    +
    +

    By transitioning to these platforms, Boost aimed to improve its development workflow, make it easier for new contributors to get involved, and leverage the powerful collaboration features offered by GitHub. However, as with many major changes, there was a lot of discussion on the issues at the time, some favorable and some not so much. For example (from mailing list archives):

    +
    + +
    +
    +
    +

    A Timeline of Boost Exclusivity

    +
    +
    +

    While many Boost libraries have been incorporated into the C++ Standard Library, most others remain exclusive to Boost, and are highly regarded for their capabilities and performance. Some of these noteworthy libraries include:

    +
    +
    +
      +
    • +

      Boost.Graph : An extensive library for graph data structures and algorithms, enabling developers to work with graphs and network structures, while providing efficient implementations of popular graph algorithms like Dijkstra’s, Kruskal’s, and more. Developed by Jeremy Siek, Lie-Quan Lee and Andrew Lumsdaine of Indiana University and released in September 2000.

      +
    • +
    • +

      Boost.Spirit : A powerful and flexible parser and generator framework, which uses expression templates and template metaprogramming to create parsers at compile-time. This results in efficient and type-safe parsing code. Developed by Joel de Guzman and Hartmut Kaiser and added to Boost March 2003.

      +
    • +
    • +

      Boost.Asio : A cross-platform library for network and low-level I/O programming, offering a consistent asynchronous model that allows developers to write efficient and highly-scalable applications. Developed by Christopher Kohlhoff and added to Boost March 2008.

      +
    • +
    • +

      Boost.Geometry : A library providing a collection of algorithms and data structures for working with geometrical objects, such as points, lines, polygons, and more. It also supports spatial indexing, coordinate system transformations, and various distance calculations. Developed by Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Menelaos Karavelas and Vissarion Fisikopoulos and added to Boost July 2011.

      +
    • +
    • +

      Boost.Coroutine : A library providing templates for generalized subroutines which allow for suspending and resuming execution at certain locations. The idea is to enable cooperative programming. Developed by Oliver Kowalke and added to Boost February 2013.

      +
    • +
    • +

      Boost.Hana : A modern metaprogramming library for C++ that employs cutting-edge C++ features to facilitate powerful and expressive metaprogramming techniques, such as heterogeneous containers, compile-time algorithms, and type introspection. Developed by Louis Dionne and added to Boost May 2016.

      +
    • +
    • +

      Boost.Mp11 : A metaprogramming library for compile-time manipulation of data structures that contain types, based on template aliases and variadic templates. Developed by Peter Dimov and added to Boost in December 2017.

      +
    • +
    • +

      Boost.Json : A JSON library for encoding, decoding, and manipulating JSON data. Developed by Vinnie Falco, Krystian Stasiowski and Dmitry Arkhipov and added to Boost in December 2020.

      +
    • +
    • +

      Boost.Describe : This reflection library enables authors of user-defined types (enums, structs and classes) to describe their enumerators, base classes, data members and member functions. This information can later be queried by other code portions, possibly written by a different author, using the supplied primitives. Developed by Peter Dimov and added to Boost in August 2021.

      +
    • +
    +
    +
    +

    These libraries, among many others, showcase the value and versatility of Boost in providing advanced functionality beyond the scope of the C++ Standard Library. Refer to Boost Version History for a chronology of releases since 1999.

    +
    +
    +

    As well as the Common and Advanced scenarios highlighted in this documentation, Boost libraries are used in highly specialized applications, ranging from probability theory to astronomy to mass spectroscopy. Open source isn’t just for nerds and researchers. Real world programming challenges, irrespective of whether they are open or closed source, can benefit enormously from the thought and experience that has gone into the libraries.

    +
    +
    +

    The source code is always distributed as open source, and released under the Boost Software License, which allows anyone to use, modify, and distribute the libraries for free. The libraries are platform independent and support most popular compilers, as well as many that are less well known.

    +
    +
    +
    +
    +

    Current Status

    +
    +
    +

    Boost has evolved into a widely used and influential collection of over 180 libraries since its inception in 1998. Currently, the Boost mission is threefold:

    +
    +
    +
      +
    1. +

      Develop high-quality, expert-reviewed, open-source C++ libraries.

      +
    2. +
    3. +

      Incubate C++ Standard Library enhancements.

      +
    4. +
    5. +

      Advance and disseminate C++ software development best practices. This is accomplished by facilitating C++ community engagement, providing necessary financial/legal support, and breaking rare directional decision-making deadlocks while upholding our shared values of engineering excellence, technocratic leadership, and a federated library authorship model.

      +
    6. +
    +
    +
    +

    The formation of the CppAlliance brought an organizational structure to Boost. It provides legal and financial oversight, manages assets like the Boost trademark, and helps fund the hosting infrastructure.

    +
    +
    +
    +get boost button +
    +
    +
    +

    The Get Boost download button actually originated by replacing the word ALARMA from a Spanish operational manual photograph.

    +
    +
    +
    +highly respected quote +
    +
    +
    +

    Early praise from well-known C++ gurus in their book: C++ Coding Standards: 101 Rules, Guidelines, and Best Practices, published in 2004".

    +
    +
    +
    + +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/boost-macros.html b/preview/user-guide/boost-macros.html new file mode 100644 index 0000000..7067cb9 --- /dev/null +++ b/preview/user-guide/boost-macros.html @@ -0,0 +1,931 @@ + + + + + + + + + + + + + + Boost Macros :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Boost Macros

    +
    +
    +
    +

    Boost provides many useful macros that help with configuration, debugging, portability, and convenience when working with the libraries.

    +
    +
    +

    There are thousands of defined macros (refer to the Boost Macro Reference). However, here are some of the most commonly used, and some sample code showing how to work them into your code.

    +
    + +
    +
    +
    +

    Library Inclusion and Linking

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_ALL_NO_LIB

    Disables automatic linking for all Boost libraries.

    BOOST_LIB_DIAGNOSTIC

    Enables diagnostic output for automatic linking.

    BOOST_INCLUDE_LIBRARIES(libs…​)

    Used to specify which libraries should be included when using B2.

    BOOST_ALL_DYN_LINK

    Forces all Boost libraries to be linked dynamically.

    +
    +

    Example

    +
    +

    The BOOST_ALL_NO_LIB macro prevents automatic linking of Boost libraries.

    +
    +
    +
    +
    #define BOOST_ALL_NO_LIB  // Disable auto-linking
    +
    +#include <boost/filesystem.hpp>
    +#include <iostream>
    +
    +int main() {
    +    std::cout << "Boost Filesystem is included, but auto-linking is disabled.\n";
    +}
    +
    +
    +
    +
    +
    +
    +

    Configuration and Compiler Detection

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_VERSION

    Defines the Boost version as an integer (for example, 107800 for Boost 1.78.0).

    BOOST_PLATFORM

    Identifies the platform (for example, Windows, Linux).

    BOOST_COMPILER

    Identifies the compiler in use (for example, gcc, msvc).

    BOOST_STDLIB

    Identifies the standard library (for example, libstdc++, msvc).

    BOOST_SP_USE_QUICK_ALLOCATOR

    Optimizes memory allocation for shared_ptr.

    BOOST_NO_CXX11_SMART_PTR

    Defined if C++11 std::shared_ptr and std::unique_ptr are not available, so Boost’s smart pointers are used as a fallback.

    BOOST_STATIC_CONSTANT

    Defines compile-time constants in a way that is compatible with older C++ versions, so ensures compatibility with pre-C++11 compilers.

    BOOST_FILESYSTEM_VERSION

    Defines the version of the Boost.Filesystem library being used, to ensure compatibility between different versions of that library.

    BOOST_NO_CXX11_LAMBDAS

    Defined if C++11 lambda expressions are not available, so allows for providing alternative function objects for compatibility.

    BOOST_FILESYSTEM_NO_DEPRECATED

    Disables deprecated features in Boost.Filesystem.

    +
    +

    Examples

    +
    +

    The BOOST_STDLIB macro is part of Boost.Config and identifies the standard library implementation being used (for example, GNU libstdc++, Microsoft STL, or libc++). This is useful when writing code that needs to adapt to different standard library behaviors. BOOST_STDLIB expands to a string representing the detected standard library.

    +
    +
    +
    +
    #include <boost/config.hpp>
    +#include <iostream>
    +
    +int main() {
    +    std::cout << "Detected Standard Library: " << BOOST_STDLIB << std::endl;
    +
    +#ifdef BOOST_LIBSTD_GNU
    +    std::cout << "Using GNU libstdc++" << std::endl;
    +#elif defined(BOOST_LIBSTD_MSVC)
    +    std::cout << "Using Microsoft STL (MSVC Standard Library)" << std::endl;
    +#elif defined(BOOST_LIBSTD_LIBCXX)
    +    std::cout << "Using libc++ (Clang Standard Library)" << std::endl;
    +#else
    +    std::cout << "Using an unknown or unsupported standard library" << std::endl;
    +#endif
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Using BOOST_PLATFORM, BOOST_COMPILER, and BOOST_STDLIB for diagnostics by identifing the system’s platform, compiler, and standard library.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/config.hpp>
    +
    +int main() {
    +    std::cout << "Platform: " << BOOST_PLATFORM << std::endl;
    +    std::cout << "Compiler: " << BOOST_COMPILER << std::endl;
    +    std::cout << "Standard Library: " << BOOST_STDLIB << std::endl;
    +    return 0;
    +}
    +
    +
    +
    +

    Using BOOST_VERSION to ensure version compatibility when using Boost.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/version.hpp>
    +
    +int main() {
    +    std::cout << "Boost version: "
    +              << (BOOST_VERSION / 100000) << "."   // Major version
    +              << (BOOST_VERSION / 100 % 1000) << "." // Minor version
    +              << (BOOST_VERSION % 100) << std::endl; // Patch version
    +    return 0;
    +}
    +
    +
    +
    +

    Using BOOST_SP_USE_QUICK_ALLOCATOR to optimize shared_ptr.

    +
    +
    +
    +
    #define BOOST_SP_USE_QUICK_ALLOCATOR // Define before including Boost.SmartPtr
    +
    +#include <boost/smart_ptr.hpp>
    +#include <iostream>
    +
    +int main() {
    +    boost::shared_ptr<int> ptr1(new int(42));
    +    boost::shared_ptr<int> ptr2 = ptr1;
    +
    +    std::cout << "Shared pointer value: " << *ptr1 << std::endl;
    +    return 0;
    +}
    +
    +
    +
    +
    +
    +
    +

    Debugging and Assertions

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_ASSERT(expr)

    Asserts an expression, throwing an error in debug builds.

    BOOST_STATIC_ASSERT(expr)

    Performs a compile-time assertion.

    BOOST_STATIC_ASSERT_MSG(expr, msg)

    Performs a compile-time assertion, with an added message.

    BOOST_VERIFY(expr)

    Like BOOST_ASSERT, but always evaluates the expression, even in release mode.

    BOOST_ENABLE_ASSERT_HANDLER

    Enables a custom assertion handler.

    BOOST_ASIO_ENABLE_HANDLER_TRACKING

    Enables the debugging of handlers when using Boost.Asio.

    +
    +

    Examples

    +
    +

    Using BOOST_ASSERT, BOOST_STATIC_ASSERT, and BOOST_VERIFY for debugging.

    +
    +
    +
    +
    #include <boost/assert.hpp>
    +#include <boost/static_assert.hpp>
    +#include <iostream>
    +
    +void process(int value) {
    +    BOOST_ASSERT(value > 0 && "Value must be positive");  // Runtime assertion
    +}
    +
    +int main() {
    +    BOOST_STATIC_ASSERT(sizeof(int) == 4);  // Compile-time assertion
    +
    +    int x = 10;
    +    BOOST_VERIFY(x != 0);  // Always checks in release mode
    +
    +    process(-1);  // Will trigger an assertion failure
    +}
    +
    +
    +
    +

    Using BOOST_ASIO_ENABLE_HANDLER_TRACKING to help debug asynchronous operations by tracking handlers.

    +
    +
    +
    +
    #define BOOST_ASIO_ENABLE_HANDLER_TRACKING // Enable debugging before including Boost.Asio
    +
    +#include <boost/asio.hpp>
    +#include <iostream>
    +
    +int main() {
    +    boost::asio::io_context io;
    +    std::cout << "Boost.Asio handler tracking enabled!\n";
    +    return 0;
    +}
    +
    +
    +
    +
    +
    +
    +

    Preprocessor Utilities

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_PP_REPEAT(count, macro, data)

    Repeats a macro expansion a specified number of times.

    BOOST_PP_IF(cond, then, else)

    Implements an if-like construct at preprocessing time.

    BOOST_PP_ENUM_PARAMS(count, param)

    Expands into a comma-separated list of parameters.

    +
    +

    Example

    +
    +

    Using BOOST_PP_REPEAT to generate repeated code.

    +
    +
    +
    +
    #include <boost/preprocessor/repetition/repeat.hpp>
    +#include <iostream>
    +
    +#define PRINT_N(z, n, text) std::cout << text << " " << n << "\n";
    +
    +int main() {
    +    BOOST_PP_REPEAT(5, PRINT_N, "Iteration");
    +}
    +
    +
    +
    +
    +
    +
    +

    Cross-Platform Compatibility

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_WINDOWS

    Defined when compiling on Windows.

    BOOST_LINUX

    Defined when compiling on Linux.

    BOOST_UNIX

    Defined when compiling on a Unix-like system.

    BOOST_LITTLE_ENDIAN

    Define when the system is byte-order little-endian.

    BOOST_BIG_ENDIAN

    Define when the system is byte-order big-endian.

    +
    +

    Examples

    +
    +

    Using BOOST_WINDOWS, BOOST_LINUX, and BOOST_UNIX for platform-specific code.

    +
    +
    +
    +
    #include <iostream>
    +
    +int main() {
    +#ifdef BOOST_WINDOWS
    +    std::cout << "Running on Windows\n";
    +#elif defined(BOOST_LINUX)
    +    std::cout << "Running on Linux\n";
    +#elif defined(BOOST_UNIX)
    +    std::cout << "Running on a Unix-like system\n";
    +#else
    +    std::cout << "Unknown platform\n";
    +#endif
    +}
    +
    +
    +
    +

    Using Using BOOST_LITTLE_ENDIAN and BOOST_BIG_ENDIAN for proper handling of byte order in serialization.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/config.hpp>
    +
    +int main() {
    +#if defined(BOOST_LITTLE_ENDIAN)
    +    std::cout << "System is little-endian.\n";
    +#elif defined(BOOST_BIG_ENDIAN)
    +    std::cout << "System is big-endian.\n";
    +#else
    +    std::cout << "Unknown endianness.\n";
    +#endif
    +    return 0;
    +}
    +
    +
    +
    +
    +
    +
    +

    Threading and Synchronization

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_DISABLE_THREADS

    Disables multi-threading support in Boost.

    BOOST_HAS_THREADS

    Indicates if Boost is built with threading support.

    BOOST_THREAD_USE_LIB

    Forces Boost.Thread to be used as a static library.

    BOOST_THREAD_USE_DLL

    Forces Boost.Thread to be used as a shared library.

    BOOST_THREAD_PROVIDES_FUTURE

    Enables std::future-like functionality in Boost.Thread.

    +
    +

    Example

    +
    +

    Using BOOST_HAS_THREADS to ensure threading support is enabled.

    +
    +
    +
    +
    #include <boost/thread.hpp>
    +#include <iostream>
    +
    +void threadFunc() {
    +    std::cout << "Hello from thread!\n";
    +}
    +
    +int main() {
    +#ifdef BOOST_HAS_THREADS
    +    boost::thread myThread(threadFunc);
    +    myThread.join();
    +#else
    +    std::cout << "Threads are not supported.\n";
    +#endif
    +}
    +
    +
    +
    +
    +
    +
    +

    Exception Handling

    +
    + ++++ + + + + + + + + + + + + + + + + +
    MacroDescription

    BOOST_THROW_EXCEPTION(e)

    A portable way to throw exceptions that integrates with BOOST_NO_EXCEPTIONS.

    BOOST_NO_EXCEPTIONS

    Disables exception handling.

    +
    +

    Examples

    +
    +

    Using BOOST_THROW_EXCEPTION to throw exceptions in a portable way.

    +
    +
    +
    +
    #include <boost/exception/exception.hpp>
    +#include <boost/exception/all.hpp>
    +#include <iostream>
    +
    +struct MyException : virtual boost::exception, virtual std::exception {
    +    const char* what() const noexcept override {
    +        return "A Boost exception occurred!";
    +    }
    +};
    +
    +void riskyOperation() {
    +    BOOST_THROW_EXCEPTION(MyException());
    +}
    +
    +int main() {
    +    try {
    +        riskyOperation();
    +    } catch (const MyException& e) {
    +        std::cout << "Caught exception: " << e.what() << "\n";
    +    }
    +}
    +
    +
    +
    +

    Using BOOST_NO_EXCEPTIONS to ensure compatibility with exception-free environments.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/config.hpp>
    +
    +void safe_function() {
    +#ifndef BOOST_NO_EXCEPTIONS
    +    throw std::runtime_error("Something went wrong!");
    +#else
    +    std::cerr << "Exceptions are disabled. Handling error manually.\n";
    +#endif
    +}
    +
    +int main() {
    +    try {
    +        safe_function();
    +    } catch (const std::exception& e) {
    +        std::cerr << "Caught exception: " << e.what() << std::endl;
    +    }
    +}
    +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/bsl.html b/preview/user-guide/bsl.html new file mode 100644 index 0000000..b3c3659 --- /dev/null +++ b/preview/user-guide/bsl.html @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + The Boost Software License :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    The Boost Software License

    +
    +
    +
    +

    This section contains the current Boost Software License verbatim, and is followed by a rationale on why using this license is recommended.

    +
    +
    +
    +
    +

    Boost Software License - Version 1.0 - August 17th, 2003

    +
    +
    +
    +
    +

    Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following:

    +
    +
    +

    The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor.

    +
    +
    +

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.

    +
    +
    +
    +
    +
    +
    +

    Rationale

    +
    +
    +

    Why You Should Use the Boost Software License? Because it doesn’t require attribution for binaries.

    +
    +
    +

    All popular licenses - MIT, Apache, BSD - contain language similar to the following:

    +
    +
    +
      +
    • +

      "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software."

      +
    • +
    +
    +
    +

    And, in fact, so does the Boost license, except it continues with:

    +
    +
    +
      +
    • +

      "unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor."

      +
    • +
    +
    +
    +

    The others contain no such exemption.

    +
    +
    +

    For the purposes of copyright law, when you compile the source text, the resulting object code, library code or executable program is considered a derived work. That is, the original license terms still apply to it as they would have applied to a copy of the source code, processed in some other way (reformatted, for instance.)

    +
    +
    +

    What this means is that the requirement to include the copyright notice still applies. This, in practice, is met by either including the copyright notice in the documentation, having a dialog box or a --license command line option that displays the license, or sometimes both (lawyers like to be on the safe side.)

    +
    +
    +

    If you’re writing an open source C++ library, it’s much more convenient for your users if you don’t impose this attribution requirement for binaries. You still want it to apply to copies in source code form, just not to compiled code.

    +
    +
    +

    This is what the Boost Software License was created to enable, and this is why you should use it for your open source libraries.

    +
    +
    +

    The Boost Software License is not just for Boost libraries. Everyone can, and should, use it.

    +
    +
    +

    It’s true that it’s a requirement to get your code in Boost, but that’s not the only benefit. It can also get your code in standard library implementations. Microsoft’s STL, for example, is now open source on Github, but since Microsoft’s customers cannot abide by a binary attribution clause, code inside the STL can only use a license that doesn’t impose one. As explained by Stephan T. Lavavej in this Reddit comment, the two licenses that meet this requirement are the Boost Software License and the Apache 2.0 License with LLVM Exception, and the Boost license is simpler, clearer, better known, and already pre-approved in many organizations.

    +
    +
    +

    Use it. The C++ community will appreciate your generosity.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/building-with-cmake.html b/preview/user-guide/building-with-cmake.html new file mode 100644 index 0000000..54544d0 --- /dev/null +++ b/preview/user-guide/building-with-cmake.html @@ -0,0 +1,590 @@ + + + + + + + + + + + + + + Building with CMake :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Building with CMake

    +
    +
    +
    +

    CMake is a powerful and widely-used cross-platform build system generator, designed to simplify the process of building and managing complex software projects. Unlike traditional build systems like Make, which relies on platform-specific Makefiles, CMake acts as a meta-build system: it generates platform-specific build files (such as Makefiles for Unix or Visual Studio project files for Windows) from a single set of configuration files.

    +
    +
    +

    CMake is an alternative to using the Boost-specific B2 system, or the build options available in development environments such as Microsoft Visual Studio.

    +
    +
    +

    In this section, the main concepts of CMake are described, then some examples of how to use the system with one or more Boost libraries.

    +
    +
    +
    +
    +

    The CMakeLists file

    +
    +
    +

    The core of any CMake project is the CMakeLists.txt file, which defines the structure of the project and the build rules. This file allows developers to specify the source files, include directories, compiler flags, and dependencies required to build the project. CMake’s syntax is declarative and procedural, allowing developers to set options, define targets, and specify dependencies in a structured way. The build configuration is organized around “targets,” which can represent executables, libraries, or custom commands. This target-based approach makes CMake highly flexible, as it enables complex dependency management and configuration, all while keeping platform-specific details abstracted away.

    +
    +
    +
    +
    +

    Handling External Dependencies

    +
    +
    +

    One of the key strengths of CMake is its handling of external dependencies. Instead of manually specifying the paths to libraries or include directories, developers can use CMake’s find_package command, which searches for installed libraries and frameworks. This is particularly useful when managing complex dependencies across different platforms, as CMake knows how to find libraries on Windows, macOS, and Linux systems without requiring separate configuration files. CMake also supports package management tools such as Conan and vcpkg, allowing developers to integrate and manage third-party libraries more easily.

    +
    +
    +
    +
    +

    Separate Build and Source Locations

    +
    +
    +

    CMake’s “out-of-source” build feature is another significant advantage, allowing developers to keep build artifacts separate from the source code. By creating a dedicated build directory, developers can avoid cluttering the source tree with generated files, which makes it easier to manage source code and switch between different build configurations (such as debug and release builds) without affecting the original source files.

    +
    +
    +
    +
    +

    Handling Complex Projects

    +
    +
    +

    For projects that span multiple modules or dependencies, CMake provides convenient mechanisms to handle this complexity. Projects can be organized into subdirectories, each with its own CMakeLists.txt, which can then be included in the main configuration file using add_subdirectory. This modularity is beneficial for larger projects with multiple libraries or executables, as it allows each component to define its build rules independently.

    +
    +
    +

    In recent years, CMake has also introduced features like “Modern CMake” syntax, which promotes best practices, improves readability, and enhances maintainability. With Modern CMake, target-based commands like target_include_directories and target_link_libraries are emphasized, encouraging developers to specify dependencies and configurations directly on targets rather than globally. This approach makes it easier to manage dependencies in complex projects, as the configuration for each target is self-contained, reducing the risk of unintended interactions between targets.

    +
    +
    +

    By learning CMake, you unlock the ability to handle cross-platform builds with ease and embrace a more structured, modular approach to software development.

    +
    +
    +
    +
    +

    Using CMake with Boost

    +
    +
    +

    Using CMake with the Boost C++ Libraries makes it straightforward to include Boost’s powerful functionality in your C++ projects. CMake has built-in support for Boost, allowing you to easily find and link Boost libraries to your project, whether you’re using header-only libraries (like Boost.Range) or the compiled ones (like Boost.Filesystem or Boost.Thread).

    +
    +
    +

    To determine whether a library is header-only or requires compilation, refer to Required Compiled Binaries.

    +
    +
    +

    Header-Only Library

    +
    +

    For header-only libraries, you don’t need to link against compiled Boost libraries. Instead, you simply need to locate Boost and add the include directories:

    +
    +
    +
    +
    cmake_minimum_required(VERSION 3.10)
    +project(BoostExample)
    +
    +find_package(Boost REQUIRED)
    +
    +add_executable(my_app main.cpp)
    +target_include_directories(my_app PRIVATE ${Boost_INCLUDE_DIRS})
    +
    +
    +
    +

    Here, find_package(Boost REQUIRED) locates Boost, and target_include_directories adds the Boost headers to your project. This configuration is enough if you’re using only header-only parts of Boost.

    +
    +
    +
    +
    +
    +

    Compiled Library

    +
    +
    +

    For Boost libraries that require linking, we need to specify the components and link them to the target:

    +
    +
    +
    +
    cmake_minimum_required(VERSION 3.10)
    +project(BoostExample)
    +
    +find_package(Boost REQUIRED COMPONENTS filesystem)
    +
    +add_executable(my_app main.cpp)
    +target_link_libraries(my_app PRIVATE Boost::filesystem)
    +
    +
    +
    +

    In this example, find_package(Boost REQUIRED COMPONENTS filesystem) locates only the Boost.Filesystem library. Then, target_link_libraries links the compiled Boost library to the target executable. This approach makes it easy to build complex applications that depend on multiple Boost libraries.

    +
    +
    +

    By using find_package and CMake’s target-based commands, you can effectively manage Boost dependencies in both simple and complex scenarios.

    +
    +
    +
    +
    +

    Multiple Compiled Libraries

    +
    +
    +

    Assume we have this project structure:

    +
    +
    +
    +
    MyProject/
    +├── CMakeLists.txt
    +├── libA/
    +│   ├── CMakeLists.txt
    +│   └── libA.cpp
    +├── libB/
    +│   ├── CMakeLists.txt
    +│   └── libB.cpp
    +├── libC/
    +│   ├── CMakeLists.txt
    +│   └── libC.cpp
    +└── src/
    +    ├── CMakeLists.txt
    +    └── main.cpp
    +
    +
    +
    +

    Each library (libA, libB, and libC) is in its own folder with its own CMakeLists.txt file, and there’s a main application (main.cpp) in the src directory that links to these libraries.

    +
    +
    +

    Top-Level CMakeLists.txt

    +
    +

    The root CMakeLists.txt file defines the project and includes the subdirectories for each library and the main executable.

    +
    +
    +
    +
    cmake_minimum_required(VERSION 3.10)
    +project(MyProject)
    +
    +# Include each library's subdirectory
    +add_subdirectory(libA)
    +add_subdirectory(libB)
    +add_subdirectory(libC)
    +add_subdirectory(src)
    +
    +
    +
    +
    +

    libA/CMakeLists.txt

    +
    +

    This file defines libA as a static library.

    +
    +
    +
    +
    add_library(libA STATIC libA.cpp)
    +
    +# Optionally specify include directories if needed
    +target_include_directories(libA PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    +
    +
    +
    +
    +

    libB/CMakeLists.txt

    +
    +

    This file defines libB as a static library.

    +
    +
    +
    +
    add_library(libB STATIC libB.cpp)
    +
    +# Optionally specify include directories if needed
    +target_include_directories(libB PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    +
    +
    +
    +
    +

    libC/CMakeLists.txt

    +
    +

    This file defines libC as a static library.

    +
    +
    +
    +
    add_library(libC STATIC libC.cpp)
    +
    +# Optionally specify include directories if needed
    +target_include_directories(libC PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    +
    +
    +
    +
    +

    src/CMakeLists.txt

    +
    +

    This file defines the main executable and links it to the three libraries (libA, libB, and libC).

    +
    +
    +
    +
    add_executable(main_app main.cpp)
    +
    +# Link the main executable to the three libraries
    +target_link_libraries(main_app PRIVATE libA libB libC)
    +
    +
    +
    +
    +

    Summary of the Pre-Build Process

    +
    +
      +
    1. +

      Each library (libA, libB, libC) is defined in its respective CMakeLists.txt file and added as a STATIC library. Alternatively, you could change STATIC to SHARED if you want dynamic libraries instead.

      +
    2. +
    3. +

      In` src/CMakeLists.txt`, the main executable main_app is linked to libA, libB, and libC using target_link_libraries.

      +
    4. +
    5. +

      By using add_subdirectory, each library and executable has its own configuration, which keeps the project modular and organized.

      +
    6. +
    +
    +
    +
    +
    +
    +

    Building the Project

    +
    +
    +

    From the top-level directory (MyProject), you can build the entire project with the following commands:

    +
    +
    +
    +
    mkdir build
    +cd build
    +cmake ..
    +make
    +
    +
    +
    +

    This will compile each library and link them to the main_app executable.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/common-introduction.html b/preview/user-guide/common-introduction.html new file mode 100644 index 0000000..e8cf7b9 --- /dev/null +++ b/preview/user-guide/common-introduction.html @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + Common Scenarios :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Common Scenarios

    +
    +

    Introduction

    +
    +
    +

    There are many common use-cases for the Boost libraries.

    +
    +
    +

    Finance can be relatively simple in terms of numerical operations - additions for deposits, subtractions for withdrawals, and multiplications for interest calculation and foreign currency trading - but delving into secure networking and cryptography makes this scenario a serious challenge.

    +
    +
    +

    In the realm of software development, Networking involves the communication and data exchange between different software systems across networks. Networking code often deals with protocols like HTTP, FTP, TCP/IP, UDP, and WebSockets, to name a few. Networking tasks might include creating a web server, crafting a custom protocol for communication between distributed parts of an application, or designing software that interacts with REST APIs.

    +
    +
    +

    For a variation of the client/server scenario, the AI Client examples show how to make requests and parse responses from an AI model. Certainly fun, it’s usefulness can vary.

    +
    +
    +

    Real-Time Simulation in software is about creating a virtual model of a system in order to understand or predict its behavior. It’s often used in areas such as physics, engineering, biology, and finance to model complex real-world systems. Simulation code can involve heavy computations, data analysis, and often makes use of concurrent programming to speed up execution.

    +
    +
    +

    Developing System Components involves writing software that interfaces closely with the underlying operating system, offering a platform for other software to run. This can include designing and implementing operating systems, device drivers, system utilities, and servers. It often involves lower-level programming, managing system resources, process control, and inter-process communication.

    +
    +
    +

    Testing and Debugging is a crucial part of the development process, aimed at evaluating the functionality of software applications to ensure they meet the specified requirements and to identify any bugs or issues. This might include writing unit tests for individual components, integration tests that evaluate how these components work together, and end-to-end tests that assess the system as a whole.

    +
    +
    +

    Text Processing involves the manipulation and analysis of text data in software applications. This can include tasks like parsing, searching, modifying, tokenization, or extracting information from text. It often requires a strong understanding of string manipulation, regular expressions, and character encodings.

    +
    +
    +

    Each of these areas is a significant field in its own right, with specific techniques, practices, and tools that can be used to effectively tackle the challenges they present.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/counted-body.html b/preview/user-guide/counted-body.html new file mode 100644 index 0000000..84bdbc2 --- /dev/null +++ b/preview/user-guide/counted-body.html @@ -0,0 +1,907 @@ + + + + + + + + + + + + + + Counted Body Techniques :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Counted Body Techniques

    +
    +
    +
    +

    Reference counting techniques? Nothing new, you might think. Every good C++ text that takes you to an intermediate or advanced level will introduce the concept. It has been explored with such thoroughness in the past that you might be forgiven for thinking that everything that can be said has been said. Well, let’s start from first principles and see if we can unearth something new…​.

    +
    +
    +
    +
    +

    And Then There Were None…​

    +
    +
    +

    The principle behind reference counting is to keep a running usage count of an object so that when it falls to zero we know the object is unused. This is normally used to simplify the memory management for dynamically allocated objects: keep a count of the number of references held to that object and, on zero, delete the object.

    +
    +
    +

    How to keep a track of the number of users of an object? Well, normal pointers are quite dumb, and so an extra level of indirection is required to manage the count. This is essentially the proxy pattern described in Design Patterns [Gamma, Helm, Johnson & Vlissides, Addison-Wesley, ISBN 0-201-63361-2]. The intent is given as "Provide a surrogate or placeholder for another object to control access to it."

    +
    +
    +

    Advanced C++ Programming Styles and Idioms [Coplien, Addison-Wesley, ISBN 0-201-56365-7] defines a set of idioms related to this essential separation of a handle and a body part. The Taligent Guide to Designing Programs [Addison-Wesley, ISBN 0-201-40888-0] identifies a number of specific categories for proxies (aka surrogates). Broadly speaking they fall into two general categories:

    +
    +
    +
      +
    1. +

      Hidden: The handle is the object of interest, hiding the body itself. The functionality of the handle is obtained by delegation to the body, and the user of the handle is unaware of the body. Reference counted strings offer a transparent optimization. The body is shared between copies of a string until such a time as a change is needed, at which point a copy is made. Such a copy-on-write pattern (a specialization of lazy evaluation) requires the use of a hidden reference counted body.

      +
    2. +
    3. +

      Explicit: Here the body is of interest and the handle merely provides intelligence for its access and housekeeping. In C++ this is often implemented as the smart pointer idiom. One such application is that of reference-counted smart pointers that collaborate to keep a count of an object, deleting it when the count falls to zero.

      +
    4. +
    +
    +
    +
    +
    +

    Attached vs Detached

    +
    +
    +

    For reference counted smart pointers there are two places the count can exist, resulting in two different patterns, both outlined in Software Patterns [Coplien, SIGS, ISBN 0-884842-50-X]:

    +
    +
    +
      +
    • +

      Counted body or attached counted handle/body places the count within the object being counted. The benefits are that countability is a part of the object being counted, and that reference counting does not require an additional object. The drawbacks are clearly that this is intrusive, and that the space for the reference count is wasted when the object is not heap-based. Therefore the reference counting ties you to a particular implementation and style of use.

      +
    • +
    • +

      Detached counted handle/body places the count outside the object being counted, such that they are handled together. The clear benefit of this is that this technique is completely unintrusive, with all of the intelligence and support apparatus in the smart pointer, and therefore can be used on classes created independently of the reference counted pointer. The main disadvantage is that frequent use of this can lead to a proliferation of small objects, i.e. the counter, being created on the heap.

      +
    • +
    +
    +
    +

    Even with this simple analysis, it seems that the Detached counted handle/body approach is ahead. Indeed, with the increasing use of templates this is often the favorite, and is the principle behind the common - but not standard - counted_ptr.

    +
    +
    +
    +
    Note
    +
    +

    The Boost name is shared_ptr rather than counted_ptr.

    +
    +
    +
    +
    +

    A common implementation of counted body is to provide the counting mechanism in a base class that the counted type is derived from. Either that, or the reference counting mechanism is provided anew for each class that needs it. Both of these approaches are unsatisfactory because they are quite closed, coupling a class into a particular framework. Added to this the non-cohesiveness of having the count lying dormant in a non-counted object, and you get the feeling that excepting its use in widespread object models such as COM and CORBA the counted body approach is perhaps only of use in specialized situations.

    +
    +
    +
    +
    +

    A Requirements Based Approach

    +
    +
    +

    It is the question of openness that convinced me to revisit the problems with the counted body idiom. Yes, there is a certain degree of intrusion expected when using this idiom, but is there anyway to minimize this and decouple the choice of counting mechanism from the smart pointer type used?

    +
    +
    +

    In recent years the most instructive body of code and specification for constructing open general purpose components has been the Stepanov and Lee’s STL (Standard Template Library), now part of the C++ standard library. The STL approach makes extensive use of compile time polymorphism based on well defined operational requirements for types. For instance, each container, contained and iterator type is defined by the operations that should be performable on an object of that type, often with annotations describing additional constraints. Compile time polymorphism, as its name suggests, resolves functions at compile time based on function name and argument usage, i.e. overloading. This is less intrusive, although less easily diagnosed if incorrect, than runtime polymorphism that is based on types, names and function signatures.

    +
    +
    +

    This requirements based approach can be applied to reference counting. The operations we need for a type to be countable are loosely:

    +
    +
    +
      +
    1. +

      An acquire operation that registers interest in a countable object.

      +
    2. +
    3. +

      A release operation unregisters interest in a countable object.

      +
    4. +
    5. +

      An acquired query that returns whether or not a countable object is currently acquired.

      +
    6. +
    7. +

      A dispose operation that is responsible for disposing of an object that is no longer acquired.

      +
      +
      +
      Note
      +
      +

      The count is deduced as a part of the abstract state of this type, and is not mentioned or defined in any other way. The openness of this approach derives in part from the use of global functions, meaning that no particular member functions are implied; a perfect way to wrap up an existing counted body class without modifying the class itself. The other aspect of openness comes from a more precise specification of the operations.

      +
      +
      +
      +
    8. +
    +
    +
    +

    For a type to be countable it must satisfy the following requirements, where ptr is a non-null pointer to a single object (i.e. not an array) of the type, and #function indicates number of calls to function(ptr):

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ExpressionReturn typeSemantics and notes

    acquire(ptr)

    no requirement

    post: acquired(ptr)

    release(ptr)

    no requirement

    pre: acquired(ptr) post: acquired(ptr) == #acquire - #release

    acquired(ptr)

    convertible to bool

    return: #acquire > #release

    dispose(ptr, ptr)

    no requirement

    pre: !acquired(ptr) post: *ptr no longer usable

    +
    +
    +
    Note
    +
    +

    The two arguments to dispose are to support selection of the appropriate type-safe version of the function to be called. In the general case the intent is that the first argument determines the type to be deleted, and would typically be templated, while the second selects which template to use, for example: by conforming to a specific base class.

    +
    +
    +
    +
    +

    In addition the following requirements must also be satisfied, where null is a null pointer to the countable type:

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ExpressionReturn typeSemantics and notes

    acquire(null)

    no requirement

    action: none

    release(null)

    no requirement

    action: none

    acquired(null)

    convertible to bool

    return: false

    dispose(null, null)

    no requirement

    action: none

    +
    +
    +
    Note
    +
    +

    There are no requirements on these functions in terms of exceptions thrown or not thrown, except that if exceptions are thrown the functions themselves should be exception-safe.

    +
    +
    +
    +
    +
    +
    +

    Getting Smart

    +
    +
    +

    Given the countable requirements for a type, it is possible to define a generic smart pointer type that uses them for reference counting:

    +
    +
    +
    +
    template<typename countable_type>
    +class countable_ptr
    +{
    +public: // construction and destruction
    +
    +    explicit countable_ptr(countable_type *);
    +    countable_ptr(const countable_ptr &);
    +    ~countable_ptr();
    +
    +public: // access
    +
    +    countable_type *operator->() const;
    +    countable_type &operator*() const;
    +    countable_type *get() const;
    +
    +public: // modification
    +
    +    countable_ptr &clear();
    +    countable_ptr &assign(countable_type *);
    +    countable_ptr &assign(const countable_ptr &);
    +    countable_ptr &operator=(const countable_ptr &);
    +
    +private: // representation
    +
    +    countable_type *body;
    +
    +};
    +
    +
    +
    +

    The interface to this class has been kept intentionally simple, for example: member templates and throw specs have been omitted, for exposition. The majority of the functions are quite simple in implementation, relying very much on the assign member as a keystone function:

    +
    +
    +
    +
    template<typename countable_type>
    +countable_ptr<countable_type>::countable_ptr(countable_type *initial)
    +  : body(initial)
    +{
    +    acquire(body);
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type>::countable_ptr(const countable_ptr &other)
    +  : body(other.body)
    +{
    +    acquire(body);
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type>::~countable_ptr()
    +{
    +    clear();
    +}
    +
    +template<typename countable_type>
    +countable_type *countable_ptr<countable_type>::operator->() const
    +{
    +    return body;
    +}
    +
    +template<typename countable_type>
    +countable_type &countable_ptr<countable_type>::operator*() const
    +{
    +    return *body;
    +}
    +
    +template<typename countable_type>
    +countable_type *countable_ptr<countable_type>::get() const
    +{
    +    return body;
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type> &countable_ptr<countable_type>::clear()
    +{
    +    return assign(0);
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type> &countable_ptr<countable_type>::assign(countable_type *rhs)
    +{
    +    // set to rhs (uses Copy Before Release idiom which is self assignment safe)
    +    acquire(rhs);
    +    countable_type *old_body = body;
    +    body = rhs;
    +
    +    // tidy up
    +    release(old_body);
    +    if(!acquired(old_body))
    +    {
    +        dispose(old_body, old_body);
    +    }
    +
    +    return *this;
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type> &countable_ptr<countable_type>::assign(const countable_ptr &rhs)
    +{
    +    return assign(rhs.body);
    +}
    +
    +template<typename countable_type>
    +countable_ptr<countable_type> &countable_ptr<countable_type>::operator=(const countable_ptr &rhs)
    +{
    +    return assign(rhs);
    +}
    +
    +
    +
    +
    +
    +

    Public Accountability

    +
    +
    +

    Conformance to the requirements means that a type can be used with countable_ptr. Here is an implementation mix-in class that confers countability on its derived classes through member functions. This class can be used as a class adaptor:

    +
    +
    +
    +
    class countability
    +{
    +public: // manipulation
    +
    +    void acquire() const;
    +    void release() const;
    +    size_t acquired() const;
    +
    +protected: // construction and destruction
    +
    +    countability();
    +    ~countability();
    +
    +private: // representation
    +
    +    mutable size_t count;
    +
    +private: // prevention
    +
    +    countability(const countability &);
    +    countability &operator=(const countability &);
    +
    +};
    +
    +
    +
    +
    +
    Note
    +
    +

    The manipulation functions are const and that the count member itself is mutable. This is because countability is not a part of an object’s abstract state: memory management does not depend on the const-ness or otherwise of an object. I won’t include the definitions of the member functions here as you can probably guess them: increment, decrement, and return the current count, respectively for the manipulation functions. In a multithreaded environment, you should ensure that such read and write operations are atomic.

    +
    +
    +
    +
    +

    So how do we make this class countable? A simple set of forwarding functions does the job:

    +
    +
    +
    +
    void acquire(const countability *ptr)
    +{
    +    if(ptr)
    +    {
    +        ptr->acquire();
    +    }
    +}
    +
    +void release(const countability *ptr)
    +{
    +    if(ptr)
    +    {
    +        ptr->release();
    +    }
    +}
    +
    +size_t acquired(const countability *ptr)
    +{
    +    return ptr ? ptr->acquired() : 0;
    +}
    +
    +template<class countability_derived>
    +void dispose(const countability_derived *ptr, const countability *)
    +{
    +    delete ptr;
    +}
    +Any type that now derives from countability may now be used with countable_ptr:
    +
    +class example : public countability
    +{
    +    ...
    +};
    +
    +void simple()
    +{
    +    countable_ptr<example> ptr(new example);
    +    countable_ptr<example> qtr(ptr);
    +    ptr.clear(); // set ptr to point to null
    +}   // allocated object deleted when qtr destructs
    +
    +
    +
    +
    +
    +

    Runtime Mixin

    +
    +
    +

    The challenge is to apply counted body in a non-intrusive fashion, such that there is no overhead when an object is not counted. What we would like to do is confer this capability on a per object rather than on a per class basis. Effectively we are after countability on any object, i.e. anything pointed to by a void *! It goes without saying that void is perhaps the least committed of any type.

    +
    +
    +

    The forces to resolve this are quite interesting, to say the least. Interesting, but not insurmountable. Given that the class of a runtime object cannot change dynamically in any well defined manner, and the layout of the object must be fixed, we have to find a new place and time to add the counting state. The fact that this must be added only on heap creation suggests the following solution:

    +
    +
    +
    +
    struct countable_new;
    +extern const countable_new countable;
    +
    +void *operator new(size_t, const countable_new &);
    +void operator delete(void *, const countable_new &);
    +
    +
    +
    +

    We have overloaded operator new with a dummy argument to distinguish it from the regular global operator new. This is comparable to the use of the std::nothrow_t type and std::nothrow object in the standard library. The placement operator delete is there to perform any tidy up in the event of failed construction. Note that this is not yet supported on all compilers.

    +
    +
    +

    The result of a new expression using countable is an object allocated on the heap that has a header block that holds the count, i.e. we have extended the object by prefixing it. We can provide a couple of features in an anonymous namespace (not shown) in the implementation file for supporting the count and its access from a raw pointer:

    +
    +
    +
    +
    struct count
    +{
    +    size_t value;
    +};
    +
    +count *header(const void *ptr)
    +{
    +    return const_cast<count *>(static_cast<const count *>(ptr) - 1);
    +}
    +
    +
    +
    +

    An important constraint to observe here is the alignment of count should be such that it is suitably aligned for any type. For the definition shown this will be the case on almost all platforms. However, you may need to add a padding member for those that don’t, for example: using an anonymous union to co-align count and the most aligned type. Unfortunately, there is no portable way of specifying this such that the minimum alignment is also observed - this is a common problem when specifying your own allocators that do not directly use the results of either new or malloc.

    +
    +
    +

    Again, note that the count is not considered to be a part of the logical state of the object, and hence the conversion from const to non-const - count is in effect a mutable type.

    +
    +
    +

    The allocator functions themselves are fairly straightforward:

    +
    +
    +
    +
    void *operator new(size_t size, const countable_new &)
    +{
    +    count *allocated = static_cast<count *>(::operator new(sizeof(count) + size));
    +    *allocated = count(); // initialise the header
    +    return allocated + 1; // adjust result to point to the body
    +}
    +
    +void operator delete(void *ptr, const countable_new &)
    +{
    +    ::operator delete(header(ptr));
    +}
    +
    +
    +
    +

    Given a correctly allocated header, we now need the countable functions to operate on const void * to complete the picture:

    +
    +
    +
    +
    void acquire(const void *ptr)
    +{
    +    if(ptr)
    +    {
    +        ++header(ptr)->value;
    +    }
    +}
    +
    +void release(const void *ptr)
    +{
    +    if(ptr)
    +    {
    +        --header(ptr)->value;
    +    }
    +}
    +
    +size_t acquired(const void *ptr)
    +{
    +    return ptr ? header(ptr)->value : 0;
    +}
    +
    +template<typename countable_type>
    +void dispose(const countable_type *ptr, const void *)
    +{
    +    ptr->~countable_type();
    +    operator delete(const_cast<countable_type *>(ptr), countable);
    +}
    +
    +
    +
    +

    The most complex of these is the dispose function that must ensure that the correct type is destructed and also that the memory is collected from the correct offset. It uses the value and type of first argument to perform this correctly, and the second argument merely acts as a strategy selector, i.e. the use of const void * distinguishes it from the earlier dispose shown for const countability *.

    +
    +
    +
    +
    +

    Getting Smarter

    +
    +
    +

    Now that we have a way of adding countability at creation for objects of any type, what extra is needed to make this work with the countable_ptr we defined earlier? Good news: nothing!

    +
    +
    +
    +
    class example
    +{
    +    ...
    +};
    +
    +void simple()
    +{
    +    countable_ptr<example> ptr(new(countable) example);
    +    countable_ptr<example> qtr(ptr);
    +    ptr.clear(); // set ptr to point to null
    +}   // allocated object deleted when qtr destructs
    +
    +
    +
    +

    The new(countable) expression defines a different policy for allocation and de-allocation and, in common with other allocators, any attempt to mix your allocation policies, for example: call delete on an object allocated with new(countable), results in undefined behavior. This is similar to what happens when you mix new[] with delete or malloc with delete. The whole point of countable conformance is that countable objects are used with countable_ptr, and this ensures the correct use.

    +
    +
    +

    However, accidents will happen, and inevitably you may forget to allocate using new(countable) and instead use new. This error and others can be detected in most cases by extending the code shown here to add a check member to the count, validating the check on every access. A benefit of ensuring clear separation between header and implementation source files mean that you can introduce a checking version of this allocator without having to recompile your code.

    +
    +
    +
    +
    +

    Conclusion

    +
    +
    +

    There are two key concepts that this article has introduced:

    +
    +
    +
      +
    • +

      The use of a generic requirements based approach to simplify and adapt the use of the counted body pattern.

      +
    • +
    • +

      The ability, through control of allocation, to dynamically and non-intrusively add capabilities to fixed types using the runtime mixin pattern.

      +
    • +
    +
    +
    +

    The application of the two together gives rise to a new variant of the essential counted body pattern: unintrusive counted body. You can take this theme even further and contrive a simple garbage collection system for C++.

    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    This topic was originally written as a paper by Kevlin Henney, and first published in Overload 25, April 1998, ISSN 1354-3172.

    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    For different approaches to reference counting in Boost libraries, refer to:

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/diagnostics.html b/preview/user-guide/diagnostics.html new file mode 100644 index 0000000..98f6339 --- /dev/null +++ b/preview/user-guide/diagnostics.html @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + Introduction to Boost Diagnostics :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Introduction to Boost Diagnostics

    +
    +
    +
    +

    Diagnostics in C++ programming refers to the set of tools, techniques, and facilities that help developers detect, report, and investigate errors and unexpected behavior in their code. While the C++ Standard Library provides a minimal set of mechanisms—most notably assert, std::error_code, and exception handling—these are intentionally simple. For serious application development, especially in large-scale or cross-platform projects, many developers turn to the Boost C++ Libraries.

    +
    +
    +

    Boost offers a rich collection of utilities that significantly improve diagnostic capabilities, making it easier to identify the root causes of problems, provide better runtime feedback, and write robust, maintainable code. This introduction highlights some of the most important diagnostic facilities Boost provides, focusing on four pillars:

    +
    +
    +
      +
    1. +

      BOOST_ASSERT - a configurable replacement for std::assert. See Configurable Assertions.

      +
    2. +
    3. +

      BOOST_VERIFY - a unique runtime verification macro with no Standard equivalent. See Release-Mode Expression Checking.

      +
    4. +
    5. +

      boost::throw_exception - an exception throwing facility that captures more diagnostic information and supports no-exception builds. See Exception Handling with Context.

      +
    6. +
    7. +

      boost::system::error_code - an enriched error reporting type that improves upon std::error_code by attaching source location information. See Richer Error Reporting.

      +
    8. +
    +
    +
    +

    Each of these features demonstrates why Boost remains an invaluable companion to modern C++ developers concerned with diagnostics and instrumentation.

    +
    +
    +
    +
    Note
    +
    +

    The code in this topic was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0. Refer to libraries Boost.Assert, Boost.Exception, and Boost.System.

    +
    +
    +
    +
    +
    +
    +

    Configurable Assertions

    +
    +
    +

    Assertions are one of the oldest diagnostic tools in programming. They allow developers to state conditions that must hold true at runtime. If the condition is false, the program halts immediately, signaling a bug.

    +
    +
    +

    The C++ Standard Library provides the macro assert(expr), defined in <cassert>. While useful, it is limited. If the assertion fails, the program usually prints a simple message including the failed expression, the file, and line number, and then aborts. Crucially, the behavior of assert is fixed. There is no standard way to intercept an assertion failure, customize the reporting, or change what happens afterward.

    +
    +
    +

    Boost addresses this with BOOST_ASSERT, a macro that behaves like assert by default but is fully configurable. By defining the macro BOOST_ENABLE_ASSERT_HANDLER, developers can redirect failed assertions to a custom handler. This handler can log the error to a file, throw an exception, integrate with a testing framework, or trigger application-specific recovery code.

    +
    +
    +

    For example:

    +
    +
    +
    +
    #define BOOST_ENABLE_ASSERT_HANDLER   // Must be defined before including <boost/assert.hpp>
    +
    +#include <boost/assert.hpp>
    +#include <iostream>
    +
    +// Provide your own handler
    +namespace boost {
    +    void assertion_failed(char const* expr, char const* function,
    +        char const* file, long line) {
    +        std::cerr << "Custom assert failed:\n"
    +            << "  Expression: " << expr << "\n"
    +            << "  Function:   " << function << "\n"
    +            << "  Location:   " << file << ":" << line << "\n";
    +
    +        // Maybe throw an exception here
    +    }
    +}
    +
    +int main() {
    +    int x = -1;
    +    BOOST_ASSERT(x >= 0);  // This calls the custom handler
    +}
    +
    +
    +
    +

    Run the program:

    +
    +
    +
    +
    Custom assert failed:
    +  Expression: x >= 0
    +  Function:   int __cdecl main(void)
    +  Location:   <PATH TO YOUR SOURCE FILE>
    +
    +
    +
    +

    Here, rather than letting the system’s default behavior decide what happens, the programmer gains full control. This flexibility makes BOOST_ASSERT far more suitable for production systems, where diagnostic output must be carefully managed.

    +
    +
    +
    +
    Note
    +
    +

    As an alternative to #define BOOST_ENABLE_ASSERT_HANDLER, you can pass -DBOOST_ENABLE_ASSERT_HANDLER as a compiler flag.

    +
    +
    +
    +
    +

    You can take customization one step further with BOOST_ASSERT_MSG. This call is designed to work in Debug builds (when NDEBUG is not defined). In Release builds (when NDEBUG is defined) the macro compiles to nothing so there is no runtime cost, not even an evaluation of the condition.

    +
    +
    +

    In the following example, the library function is designed to safely index into a container, and we need to guard against invalid indices.

    +
    +
    +
    +
    #define BOOST_ENABLE_ASSERT_DEBUG_HANDLER
    +
    +#include <boost/assert.hpp>
    +#include <iostream>
    +#include <vector>
    +
    +// Custom handler for BOOST_ASSERT_MSG
    +namespace boost {
    +    void assertion_failed_msg(char const* expr, char const* msg,
    +        char const* function,
    +        char const* file, long line) {
    +        std::cerr << "[Boost assert triggered]\n"
    +            << "  Expression: " << expr << "\n"
    +            << "  Message:    " << msg << "\n"
    +            << "  Function:   " << function << "\n"
    +            << "  File:       " << file << ":" << line << "\n";
    +        throw std::out_of_range(msg);
    +    }
    +}
    +
    +// A "Boost-style" utility: Safe access with asserts
    +template <typename T>
    +T& safe_at(std::vector<T>& v, std::size_t idx) {
    +    BOOST_ASSERT_MSG(idx < v.size(),
    +        "safe_at: Index out of range");
    +    return v[idx];
    +}
    +
    +int main() {
    +    std::vector<int> numbers{ 10, 20, 30 };
    +
    +    try {
    +        std::cout << "numbers[1] = " << safe_at(numbers, 1) << "\n";  // valid
    +        std::cout << "numbers[5] = " << safe_at(numbers, 5) << "\n";  // invalid
    +    }
    +    catch (const std::exception& e) {
    +        std::cerr << "Caught exception: " << e.what() << "\n";
    +    }
    +}
    +
    +
    +
    +

    Run the program:

    +
    +
    +
    +
    numbers[1] = 20
    +[Boost assert triggered]
    +  Expression: idx < v.size()
    +  Message:    safe_at: Index out of range
    +  Function:   int &__cdecl safe_at<int>(class std::vector<int,class std::allocator<int> > &,unsigned __int64)
    +  File:        <PATH TO YOUR SOURCE FILE>
    +Caught exception: safe_at: Index out of range
    +
    +
    +
    +
    +
    +

    Release-Mode Expression Checking

    +
    +
    +

    The macro BOOST_VERIFY is another diagnostic tool unique to Boost, with no direct Standard Library equivalent. At first glance, it looks similar to BOOST_ASSERT, but it serves a different purpose.

    +
    +
    +

    Whereas both assert and BOOST_ASSERT are disabled in Release mode (when NDEBUG is defined), BOOST_VERIFY always evaluates its expression, even in Release builds. The purpose is to ensure that any side effects in the expression are not accidentally compiled out.

    +
    +
    +

    Consider this example:

    +
    +
    +
    +
    #include <boost/assert.hpp>
    +#include <iostream>
    +
    +int main() {
    +    const char* filename = "temp.txt";
    +
    +    // Create a file safely using fopen_s
    +    FILE* f = nullptr;
    +    errno_t err = fopen_s(&f, filename, "w"); // "w" = write mode
    +    if (err == 0 && f != nullptr) {
    +        std::fputs("temporary data", f);
    +        std::fclose(f);
    +    }
    +    else {
    +        std::cerr << "Failed to create file: " << filename << "\n";
    +        return 1;
    +    }
    +
    +    BOOST_VERIFY(std::remove(filename) == 0);
    +
    +    std::cout << "File removal attempted.\n";
    +    return 0;
    +}
    +
    +
    +
    +

    To show the mechanism at work, we’ll write some broken code, and run it in Debug then Release modes. The following example tries to remove a file twice.

    +
    +
    +
    +
    //#define NDEBUG
    +
    +#include <boost/assert.hpp>
    +#include <iostream>
    +
    +int main() {
    +    const char* filename = "nonexistent_file.txt";
    +
    +    // Try opening a file in write mode (this will succeed, so we create it)
    +    FILE* f = nullptr;
    +    errno_t err = fopen_s(&f, filename, "w");
    +    if (err == 0 && f != nullptr) {
    +        std::fputs("temporary data", f);
    +        std::fclose(f);
    +    } else {
    +        std::cerr << "Failed to create file: " << filename << "\n";
    +        return 1;
    +    }
    +
    +    // First removal works
    +    if (std::remove(filename) == 0) {
    +        std::cout << "File successfully removed the first time.\n";
    +    }
    +
    +    // Second removal should fail (file no longer exists)
    +    std::cout << "Now trying to remove the file again...\n";
    +
    +    // This will assert in Debug mode, because std::remove() != 0
    +    BOOST_VERIFY(std::remove(filename) == 0);
    +
    +    std::cout << "If you see this line in Release mode, BOOST_VERIFY still ran remove().\n";
    +    return 0;
    +}
    +
    +
    +
    +

    Run the code as is, and you should get an assertion:

    +
    +
    +
    +
    File successfully removed the first time.
    +Now trying to remove the file again...
    +Assertion failed: std::remove(filename) == 0, file <PATH TO YOUR SOURCE FILE>
    +
    +
    +
    +

    Next, uncomment the first line (//#define NDEBUG), and run the program in Release mode:

    +
    +
    +
    +
    File successfully removed the first time.
    +Now trying to remove the file again...
    +If you see this line in Release mode, BOOST_VERIFY still ran remove().
    +
    +
    +
    +

    The second attempt to remove the file still went ahead, but the program continued to run normally. This kind of behavior can be required in embedded processes, systems, and similar, low-level programming.

    +
    +
    +

    In short, BOOST_VERIFY lets developers combine the clarity of an assertion with the necessity of always executing safety-critical expressions. This is particularly useful in resource acquisition, API contract validation, and error-sensitive code paths where skipping checks in Release mode would be unacceptable.

    +
    +
    +
    +
    +

    Exception Handling with Context

    +
    +
    +

    Exception handling is another diagnostic cornerstone of C++. Throwing exceptions with throw is straightforward, but the Standard Library’s mechanism offers limited control. For example, there is no standard way to automatically attach additional diagnostic information, such as the function in which the exception originated.

    +
    +
    +

    Boost improves this with boost::throw_exception. This utility function throws exceptions in a controlled manner, with two major advantages:

    +
    +
    +
      +
    1. +

      Function name capture: when throwing an exception, boost::throw_exception automatically records the name of the function from which it was thrown. This provides better traceability when diagnosing runtime errors.

      +
    2. +
    3. +

      Support for no-exception builds: some embedded or performance-critical environments disable exceptions entirely. In these cases, boost::throw_exception can be configured to take alternative actions, such as calling std::terminate or invoking a user-supplied handler. This allows the same codebase to be used in both exception-enabled and exception-disabled builds.

      +
    4. +
    +
    +
    +

    For example, let’s write a file loader with fallback behavior:

    +
    +
    +
    +
    //#define BOOST_NO_EXCEPTIONS
    +
    +#include <boost/throw_exception.hpp>
    +#include <fstream>
    +#include <iostream>
    +
    +// ===============================================
    +// Custom handler when exceptions are disabled
    +// ===============================================
    +#ifdef BOOST_NO_EXCEPTIONS
    +namespace boost {
    +    [[noreturn]] void throw_exception(std::exception const& e,
    +        boost::source_location const& loc = BOOST_CURRENT_LOCATION)
    +    {
    +        // This could log the error in a file
    +        std::cerr << "FATAL ERROR: " << e.what() << "\n"
    +            << "  at " << loc.file_name() << ":" << loc.line() << "\n"
    +            << "  in function " << loc.function_name() << "\n";
    +
    +        // Consider a graceful shutdown instead of throw
    +    }
    +}
    +#endif
    +
    +// ===============================================
    +// Function that might fail
    +// ===============================================
    +std::string load_file(const std::string& filename) {
    +    std::ifstream file(filename);
    +    if (!file) {
    +
    +        // Instead of `throw std::runtime_error(...)`, use Boost
    +        boost::throw_exception(
    +            std::runtime_error("Failed to open file: " + filename),
    +            BOOST_CURRENT_LOCATION
    +        );
    +    }
    +
    +    std::string content((std::istreambuf_iterator<char>(file)),
    +        std::istreambuf_iterator<char>());
    +    return content;
    +}
    +
    +// ===============================================
    +// Demo
    +// ===============================================
    +int main() {
    +    try {
    +        std::string data = load_file("missing.txt");
    +        std::cout << "File contents: " << data << "\n";
    +    }
    +    catch (const std::exception& e) {
    +
    +        // Normal C++ exception handling if enabled
    +        std::cerr << "Caught exception: " << e.what() << "\n";
    +    }
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    The macro BOOST_CURRENT_LOCATION, used twice in the code above, is defined in <boost/throw_exception.hpp> to return the current file location.

    +
    +
    +
    +
    +

    Run this program as is:

    +
    +
    +
    +
    Caught exception: Failed to open file: missing.txt
    +
    +
    +
    +

    Now, uncomment the first line (//#define BOOST_NO_EXCEPTIONS), and run the program again:

    +
    +
    +
    +
    FATAL ERROR: Failed to open file: missing.txt
    +  at <PATH TO YOUR SOURCE FILE>
    +  in function class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl load_file(const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)
    +File contents:
    +
    +
    +
    +

    Notice the last line (File contents:) is output as the exception is caught but the program continues, which may well be a better situation in an embedded system (flight control software, for example) or kernel code - which should just keep running.

    +
    +
    +

    By using boost::throw_exception, developers gain additional context in their diagnostics, making it much easier to identify the precise source of an error during debugging.

    +
    +
    +
    +
    +

    Richer Error Reporting

    +
    +
    +

    Error codes remain a lightweight alternative to exceptions, particularly in performance-sensitive or low-level programming. Both Boost and the Standard Library provide an error_code type, but the Boost version has some critical advantages.

    +
    +
    +

    While std::error_code simply associates an integer value with an error category, boost::system::error_code can attach a boost::source_location, providing details such as file, line, and function where the error originated. This makes error codes far more useful in diagnostics, since they carry not only the “what went wrong” but also the “where it happened.”

    +
    +
    +

    For example:

    +
    +
    +
    +
    #include <boost/system/error_code.hpp>
    +#include <iostream>
    +
    +void simulate_error(boost::system::error_code& ec,
    +    boost::source_location loc = BOOST_CURRENT_LOCATION) {
    +    ec.assign(5, boost::system::system_category());
    +    std::cerr << "Error at " << loc.file_name()
    +        << ":" << loc.line() << " in "
    +        << loc.function_name() << "\n";
    +}
    +
    +int main() {
    +    boost::system::error_code ec;
    +    simulate_error(ec);
    +    if (ec) {
    +        std::cerr << "Error value: " << ec.value() << "\n";
    +    }
    +}
    +
    +
    +
    +

    Run this program:

    +
    +
    +
    +
    Error at <PATH TO YOUR SOURCE FILE> in int __cdecl main(void)
    +Error value: 5
    +
    +
    +
    +

    This capability goes far beyond what std::error_code offers. By associating source locations with error codes, Boost enables a hybrid model: the lightweight efficiency of error codes with much of the traceability typically reserved for exceptions.

    +
    +
    +
    +
    +

    Conclusion

    +
    +
    +

    Diagnostics are the lifeblood of reliable software. Without effective tools to check assumptions, verify behavior, throw meaningful exceptions, and track error codes, debugging becomes guesswork. While the C++ Standard Library provides the bare essentials, the Boost C++ Libraries offer a suite of powerful enhancements tailored for serious development.

    +
    +
    +
      +
    • +

      BOOST_ASSERT gives you control over assertions, allowing custom handlers instead of being locked into the system’s defaults.

      +
    • +
    • +

      BOOST_VERIFY ensures critical expressions are always executed, even in Release mode — a feature absent in the Standard Library.

      +
    • +
    • +

      boost::throw_exception enriches exception handling with function name capture and configurable behavior for no-exception environments.

      +
    • +
    • +

      boost::system::error_code extends the Standard’s error codes with the ability to attach source locations, dramatically improving traceability.

      +
    • +
    +
    +
    +

    Together, these facilities form a compelling case for using Boost in diagnostic and instrumentation work. They bring flexibility, consistency, and depth that the Standard Library alone does not provide. For developers committed to building robust C++ applications, Boost’s diagnostic utilities are not just helpful—they are often essential.

    +
    +
    +

    Diagnostics Summary

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Boost FacilityStandard EquivalentDescription

    BOOST_ASSERT(expr)

    assert(expr)

    Configurable: can redirect to custom handler (BOOST_ENABLE_ASSERT_HANDLER). Standard assert is fixed.

    BOOST_VERIFY(expr)

    None

    Always evaluates expression, even in Release mode. Ensures side effects (like fopen()) are not lost.

    BOOST_ASSERT_MSG(expr, msg)

    None (C++ has no assert_msg)

    Adds developer-supplied diagnostic message for clarity. Standard assert lacks this.

    boost::throw_exception(e)

    throw e; (no wrapper)

    Captures function name; configurable for no-exception builds. Standard throw gives no extra context.

    boost::system::error_code

    std::error_code

    Can attach boost::source_location for “where it happened.” Standard only provides value + category.

    boost::source_location

    std::source_location (C++20)

    Available earlier than C++20; integrates with other Boost diagnostics (for example, error_code, throw_exception).

    BOOST_STATIC_ASSERT(expr)

    static_assert(expr)

    Historically portable pre-C++11; still useful in legacy builds. Functionally superseded by Standard now.

    BOOST_STATIC_ASSERT_MSG(expr,msg)

    None

    Debug mode equivalent of BOOST_STATIC_ASSERT.

    BOOST_THROW_EXCEPTION(e)

    None

    Macro that adds source location info to exceptions automatically. Easier than manually passing context.

    boost::exception

    std::exception

    Can store arbitrary diagnostic data (file, line, errno, custom info). Standard exceptions lack extensibility.

    BOOST_ERROR(code)

    None

    Reports runtime errors without aborting the test suite. Standard testing needs external frameworks.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/discussion-policy.html b/preview/user-guide/discussion-policy.html new file mode 100644 index 0000000..e243082 --- /dev/null +++ b/preview/user-guide/discussion-policy.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + Boost Discussion Policy :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Boost Discussion Policy

    +
    +
    +
    +

    Email discussion is the tie that binds Boost members together into a community. If the discussion is stimulating and effective, the community thrives. If the discussion degenerates into name-calling and ill will, the community withers and dies.

    +
    +
    +
    +
    +

    Acceptable Topics

    +
    +
    +

    Try to focus email discussion on the following:

    +
    +
    +
      +
    • +

      Queries to determine interest in a possible library submission

      +
    • +
    • +

      Technical discussions about a proposed or existing library, including bug reports and requests for help

      +
    • +
    • +

      Formal Reviews of proposed libraries

      +
    • +
    • +

      Reports of user experiences with Boost libraries

      +
    • +
    • +

      Boost administration or policies

      +
    • +
    • +

      Compiler specific workarounds as applied to Boost libraries

      +
    • +
    +
    +
    +

    Other topics related to Boost development may be acceptable, at the discretion of moderators. If unsure, go ahead and post. The moderators will let you know.

    +
    +
    +
    +
    +

    Unacceptable Topics

    +
    +
    +

    Posts on the following topics will probably not be accepted by the moderators:

    +
    +
    +
      +
    • +

      Advertisements for commercial products

      +
    • +
    • +

      Requests for help getting non-Boost code to compile with your compiler (try Stack Overflow: C++)

      +
    • +
    • +

      Requests for help interpreting the C++ standard (try C++ FAQ)

      +
    • +
    • +

      Job offers

      +
    • +
    • +

      Requests for solutions to homework assignments

      +
    • +
    • +

      Any posting noted as Prohibited Behavior

      +
    • +
    +
    +
    +
    +
    +

    Effective Posting

    +
    +
    +

    Most Boost mailing lists host a great deal of traffic, so your post is usually competing for attention with many other communications. This section describes how to make sure it has the desired impact.

    +
    +
    +

    Well-Crafted Posting is Worth the Effort

    +
    +

    Don’t forget, you’re a single writer but there are many readers, and you want them to stay interested in what you’re saying. Saving your readers a little time and effort is usually worth the extra time you spend when writing a message. Also, Boost discussions are saved for posterity, as rationales and history of the work we do. A post’s usefulness in the future is determined by its readability.

    +
    +
    +
    +

    Put the Library Name in the Subject Line

    +
    +

    When your post is related to a particular Boost library, it’s helpful to put the library name in square brackets at the beginning of the subject line, e.g.

    +
    +
    +
    +
    Subject: [Regex] Why doesn't this pattern match?
    +
    +
    +
    +

    The Boost developers' mailing list is a high-volume mailing list, and most maintainers don’t have time to read every message. A tag on the subject line will help ensure the right people see your post.

    +
    +
    +
    +

    Don’t Use Tabs

    +
    +

    If you use tabs to indent your source code, convert them to spaces before inserting the code in a posting. Something in the processing chain usually strips all the indentation and leaves a mess behind.

    +
    +
    +
    +

    Limit Line Length

    +
    +

    If you put source code in your postings and your mailer wraps long lines automatically, either keep the code narrow or insert the code as an (inline, if possible) attachment. That will help ensure others can read what you’ve posted.

    +
    +
    +
    +

    Don’t Over-quote, Don’t Top-Post, and Do Use Inline Replies for Readable Quotations

    +
    +

    Prune extraneous quoted text from replies so that only the relevant parts are included. It will save time and make your post more valuable when readers do not have to find out which exact part of a previous message you are responding to.

    +
    +
    +

    Don’t top-post (where the original message is included verbatim, with the reply above it); inline replies are the appropriate posting style for Boost lists.

    +
    +
    +

    The common and very useful inline approach cites the small fractions of the message you are actually responding to and puts your response directly beneath each citation, with a blank line separating them for readability:

    +
    +
    +

    Person-you’re-replying-to wrote:

    +
    +
    +
    +
    > Some part of a paragraph that you wish to reply to goes
    +> here; there may be several lines.
    +
    +Your response to that part of the message goes here.
    +There may, of course, be several lines.
    +
    +> The second part of the  paragraph that is relevant to your
    +> reply goes here; again there may be several lines.
    +
    +Your response to the second part of the message goes here.
    +
    +
    +
    +

    For more information about effective use of quotation in posts, see How do I quote correctly in Usenet?.

    +
    +
    +
    +

    Keep the Formatting of Quotations Consistent

    +
    +

    Some email and news clients use poor word wrapping algorithms that leave successive lines from the same quotation with differing numbers of leading ">" characters. Microsoft Outlook and Outlook Express, and some web clients, are especially bad about this. If your client offends in this way, please take the effort to clean up the mess it makes in quoted text. Remember, even if you didn’t write the original text, it’s your posting; whether you get your point across depends on its readability.

    +
    +
    +

    The Microsoft clients also create an unusually verbose header at the beginning of the original message text and leave the cursor at the beginning of the message, which encourages users to write their replies before all of the quoted text rather than putting the reply in context. Search online for "Quotefix" and you may find a utility that fixes this issue automatically for your email client.

    +
    +
    +
    +

    Summarizing and Referring to Earlier Messages

    +
    +

    A summary of the foregoing thread is only needed after a long discussion, especially when the topic is drifting or a result has been achieved in a discussion. The mail system will do the tracking that is needed to enable mail readers to display message threads (and every decent mail reader supports that).

    +
    +
    +

    If you ever have to refer to single message earlier in a thread or in a different thread then you can use a URL to the message archives. Citing the relevant portion of the message you link to is often helpful (if the citation is small).

    +
    +
    +
    +

    Maintain the Integrity of Discussion Threads

    +
    +

    When starting a new topic, always send a fresh message, rather than beginning a reply to some other message and replacing the subject and body. Many mailers can detect the thread you started with and will show the new message as part of the original thread, which probably isn’t what you intended. Follow this guideline for your own sake as well as for others'. Often, people scanning for relevant messages will decide they’re done with a topic and hide or kill the entire thread: your message will be missed, and you won’t get the response you’re looking for.

    +
    +
    +

    By the same token, when replying to an existing message, use your mailer’s Reply function, so that the reply shows up as part of the same discussion thread.

    +
    +
    +

    Do not reply to digests if you are a digest delivery subscriber. Your reply will not be properly threaded and will probably have the wrong subject line.

    +
    +
    +
    +

    Keep The Size of Your Posting Manageable

    +
    +

    The mailing list software automatically limits message and attachment size to a reasonable amount, typically 75K, which is adjusted from time-to-time by the moderators. This limit is a courtesy to those who rely on dial-up Internet access and let’s face it, no one wants to read a posting that consists of 75K of error message text.

    +
    +
    +
    +

    Avoid Corporate and Confidentiality Footers in Your Emails

    +
    +

    Remember that mailing lists are publicly viewable, including by people not subscribed to the list. The responsibility of not posting any confidential information is always on the sender, and any confidentiality notice you may have in your email is void. Sending an email with a confidentiality footer is a one-way action by the sender, and the receiver has no way to accept or reject the terms specified in the footer. As such, the footer is not binding, but may come across as imposing on the receiver. This negative reception will reduce the likelihood of your message being answered.

    +
    +
    +

    Additionally, if your footer contains corporate information, such as company name, logo, marketing slogans, contacts, and your position within the company, this may be taken as advertisement, which is explicitly forbidden. If your message requires you to expose your corporate affiliation, please include this information in the body of your message instead of attaching it to your every post in the corporate footer.

    +
    +
    +

    If the footer is a mandatory corporate policy then please avoid using corporate email accounts for sending posts to the mailing lists. Use a non-corporate email account instead.

    +
    +
    +
    +
    +
    +

    Prohibited Behavior

    +
    +
    +

    Prohibited behavior will not be tolerated. The moderators will ban postings by abusers.

    +
    +
    +

    Flame Wars

    +
    +

    Personal insults, argument for the sake of argument, and all the other behaviors which fall into the "flame war" category are prohibited. Discussions should focus on technical arguments, not the personality traits or motives of participants.

    +
    +
    +
    +

    Third-party Attacks

    +
    +

    Attacks on third parties such as software vendors, hardware vendors, or any other organizations, are prohibited. Boost exists to unite and serve the entire C++ community, not to disparage the work of others.

    +
    +
    +

    Does this mean that we ban the occasional complaint or wry remark about a troublesome compiler? No, but be wary of overdoing it.

    +
    +
    +
    +

    Off-topic Posts

    +
    +

    Discussions that stray from the acceptable topics are strongly discouraged. While off-topic posts are often well meaning and not as individually corrosive as other abuses, cumulatively the distraction damages the effectiveness of discussion.

    +
    +
    +
    +
    +
    +

    Culture

    +
    +
    +

    In addition to technical skills, Boost members value collaboration, acknowledgment of the help of others, and a certain level of politeness. Boost membership is very international, and ranges widely in age and other characteristics. Think of discussion as occurring among colleagues in a widely read forum, rather than among a few close friends.

    +
    +
    +

    Always remember that the cumulative effort spent by people reading your contribution scales with the (already large) number of Boost members. Thus, do invest time and effort to make your message as readable as possible. Adhere to English syntax and grammar rules such as proper capitalization. Avoid copious informalism, colloquial language, or abbreviations, they may not be understood by all readers. Re-read your message before submitting it.

    +
    +
    +
    +
    +

    Guidelines for Effective Discussions

    +
    +
    +

    Apply social engineering to prevent heated technical discussion from degenerating into a shouting match, and to actively encourage the cooperation upon which Boost depends.

    +
    +
    +
      +
    • +

      Questions help. If someone suggests something that you don’t think will work, then replying with a question like "will that compile?" or "won’t that fail to compile, or am I missing something?" is a lot smoother than "That’s stupid - it won’t compile." Saying "that fails to compile for me, and seems to violate section n.n.n of the standard" would be yet another way to be firm without being abrasive.

      +
    • +
    • +

      If most of the discussion has been code-free generalities, posting a bit of sample code can focus people on the practical issues.

      +
    • +
    • +

      If most of the discussion has been in terms of specific code, try to talk a bit about hidden assumptions and generalities that may be preventing discussion closure.

      +
    • +
    • +

      Taking a time-out is often effective. Just say: "Let me think about that for a day or two. Let’s take a time-out to digest the discussion so far."

      +
    • +
    • +

      Avoid Parkinson’s Bicycle Shed. Parkinson described a committee formed to oversee design of an early nuclear power plant. There were three agenda items - when to have tea, where to put the bicycle shed, and how to ensure nuclear safety. Tea was disposed of quickly as trivial. Nuclear safety was discussed for only an hour - it was so complex, scary, and technical that even among experts few felt comfortable with the issues. Endless days were then spent discussing construction of the bicycle shed (the parking lot would be the modern equivalent) because everyone thought they understood the issues and felt comfortable discussing them.

      +
    • +
    +
    +
    +
    +
    +

    Library Names

    +
    +
    +

    In order to ensure a uniform presentation in books and articles, we have adopted a convention for referring to Boost libraries. Library names can either be written in a compact form with a dot, as *Boost.Name", or in a long form as "the Boost Name library." For example:

    +
    +
    +
    +
    Boost.Python serves a very different purpose from the Boost Graph library.
    +
    +
    +
    +
    +
    Note
    +
    +

    The word "library" is not part of the name, and as such isn’t capitalized and may not be necessary.

    +
    +
    +
    +
    +

    Take care to avoid confusion in discussions between libraries that have been accepted into Boost and those that have not. Acceptance as a Boost library indicates that the code and design have passed through our peer-review process; failing to make the distinction devalues the hard work of library authors who’ve gone through that process. Here are some suggested ways to describe potential Boost libraries:

    +
    +
    +
      +
    1. +

      "the Name library" (probably the best choice where applicable)

      +
    2. +
    3. +

      "the proposed Boost Name library"

      +
    4. +
    5. +

      "the Boost.Name candidate"

      +
      +
      +
      Note
      +
      +

      This policy only applies to discussions, not to the documentation, directory structure, or even identifiers in the code of potential Boost libraries.

      +
      +
      +
      +
    6. +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/exception-safety.html b/preview/user-guide/exception-safety.html new file mode 100644 index 0000000..7605e5d --- /dev/null +++ b/preview/user-guide/exception-safety.html @@ -0,0 +1,810 @@ + + + + + + + + + + + + + + Exception-Safety in Generic Components :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Exception-Safety in Generic Components

    +
    +
    +
    +

    Exception-safety in a component means that it exhibits reasonable behavior when an exception is thrown during its execution. For most people, the term “reasonable” includes all the usual expectations for error-handling: that resources should not be leaked, and that the program should remain in a well-defined state so that execution can continue. For most components, it also includes the expectation that when an error is encountered, it is reported to the caller.

    +
    +
    +

    More formally, we can describe a component as minimally exception-safe if, when exceptions are thrown from within that component, its invariants are intact. Later on, we’ll see that at least three different levels of exception-safety can be usefully distinguished. These distinctions can help us to describe and reason about the behavior of large systems.

    +
    +
    +

    In a generic component, we usually have an additional expectation of exception-neutrality, which means that exceptions thrown by a component’s type parameters should be propagated, unchanged, to the component’s caller.

    +
    +
    +
    +
    +

    Myths and Superstitions

    +
    +
    +

    Exception-safety seems straightforward so far: it doesn’t constitute anything more than we’d expect from code using more traditional error-handling techniques. It might be worthwhile, however, to examine the term from a psychological viewpoint. Nobody ever spoke of “error-safety” before C++ had exceptions.

    +
    +
    +

    It’s almost as though exceptions are viewed as a mysterious attack on otherwise correct code, from which we must protect ourselves. Needless to say, this doesn’t lead to a healthy relationship with error handling! During standardization, a democratic process that requires broad support for changes, I encountered many widely-held superstitions. To even begin the discussion of exception-safety in generic components, it may be worthwhile confronting a few of them.

    +
    +
    +

    “Interactions between templates and exceptions are not well-understood.”

    +
    +

    This myth, often heard from those who consider these both new language features, is easily disposed of: there simply are no interactions. A template, once instantiated, works in all respects like an ordinary class or function. A simple way to reason about the behavior of a template with exceptions is to think of how a specific instantiation of that template works. Finally, the genericity of templates should not cause special concern. Although the component’s client supplies part of the operation (which may, unless otherwise specified, throw arbitrary exceptions), the same is true of operations using familiar virtual functions or simple function pointers.

    +
    +
    +
    +

    “It is well known to be impossible to write an exception-safe generic container.”

    +
    +

    This claim is often heard concerning an article by Tom Cargill in which he explores the problem of exception-safety for a generic stack template. In his article, Cargill raises many useful questions, but unfortunately fails to present a solution to his problem. He concludes by suggesting that a solution may not be possible. Unfortunately, his article was read by many as “proof” of that speculation. Since it was published there have been many examples of exception-safe generic components, among them the C++ standard library containers.

    +
    +
    +
    +
    Note
    +
    +

    Probably the greatest impediment to a solution in Cargill’s case was an unfortunate combination of choices on his part: the interface he chose for his container was incompatible with his particular demands for safety. By changing either one he might have solved the problem.

    +
    +
    +
    +
    +
    +

    “Dealing with exceptions will slow code down, and templates are used specifically to get the best possible performance.”

    +
    +

    A good implementation of C++ will not devote a single instruction cycle to dealing with exceptions until one is thrown, and then it can be handled at a speed comparable with that of calling a function. That alone gives programs using exceptions performance equivalent to that of a program which ignores the possibility of errors. Using exceptions can result in faster programs than traditional error handling methods for other reasons. First, a catch block indicates to the compiler which code is devoted to error-handling; it can then be separated from the usual execution path, improving locality of reference. Second, code using traditional error handling must typically test a return value for errors after every single function call; using exceptions completely eliminates that overhead.

    +
    +
    +
    +

    “Exceptions make it more difficult to reason about a program’s behavior.”

    +
    +

    Usually cited in support of this myth is the way hidden execution paths are followed during stack-unwinding. Hidden execution paths are nothing new to any C++ programmer who expects local variables to be destroyed upon returning from a function:

    +
    +
    +
    +
    ErrorCode f( int& result )         // 1
    +{                                  // 2
    +    X x;                           // 3
    +    ErrorCode err = x.g( result ); // 4
    +    if ( err != kNoError )         // 5
    +        return err;                // 6
    +    // ...More code here...
    +    return kNoError;               // 7
    +}
    +
    +
    +
    +

    In the example above, there is a hidden call to X::~X() in lines 6 and 7. Granted, using exceptions, there is no code devoted to error handling visible:

    +
    +
    +
    +
    int f()                 // 1
    +{                       // 2
    +    X x;                // 3
    +    int result = x.g(); // 4
    +    // ...More code here...
    +    return result;      // 5
    +}
    +
    +
    +
    +

    For many programmers more familiar with exceptions, the second example is actually more readable and understandable than the first. The hidden code paths include the same calls to destructors of local variables. Also, they follow a simple pattern which acts exactly as though there was a potential return statement after each function call in case of an exception. Readability is enhanced because the normal path of execution is unobscured by error-handling, and return values are freed up to be used naturally.

    +
    +
    +

    There is an even more important way in which exceptions can enhance correctness: by allowing simple class invariants. In the first example, if x’s constructor should need to allocate resources, it has no way to report a failure: in C++, constructors have no return values. The usual result when exceptions are avoided is that classes requiring resources must include a separate initializer function which finishes the job of construction. The programmer can therefore never be sure, when an object of class X is used, whether he is handling a full-fledged X or some abortive attempt to construct one (or worse: someone simply forgot to call the initializer!).

    +
    +
    +
    +
    +
    +

    A Contractual Basis for Exception-Safety

    +
    +
    +

    A non-generic component can be described as exception-safe in isolation, but because of its configurability by client code, exception-safety in a generic component usually depends on a contract between the component and its clients. For example, the designer of a generic component might require that an operation that is used in the component’s destructor not throw any exceptions. The generic component might, in return, provide one of the following guarantees:

    +
    +
    +
      +
    • +

      The basic guarantee: that the invariants of the component are preserved, and no resources are leaked.

      +
    • +
    • +

      The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.

      +
    • +
    • +

      The no-throw guarantee: that the operation will not throw an exception.

      +
      +
      +
      Notes
      +
      +

      It is usually inadvisable to throw an exception from a destructor in C++, since the destructor may itself be called during the stack-unwinding caused by another exception. If the second exception is allowed to propagate beyond the destructor, the program is immediately terminated.

      +
      +

      Mutating algorithms usually cannot provide the strong guarantee: to roll back a modified element of a range, it must be set back to its previous value using operator=, which itself might throw. In the C++ standard library, there are a few exceptions to this rule, whose rollback behavior consists only of destruction: uninitialized_copy, uninitialized_fill, and uninitialized_fill_n.

      +
      +
      +
      +
      +
    • +
    +
    +
    +

    The basic guarantee is a simple minimum standard for exception-safety to which we can hold all components. It says simply that after an exception, the component can still be used as before. Importantly, the preservation of invariants allows the component to be destroyed, potentially as part of stack-unwinding. This guarantee is actually less useful than it might at first appear. If a component has many valid states, after an exception we have no idea what state the component is in; only that the state is valid. The options for recovery, in this case, are limited: either destruction or resetting the component to some known state before further use. Consider the following example:

    +
    +
    +
    +
    template <class X>
    +void print_random_sequence()
    +{
    +    std::vector<X> v(10); // A vector of 10 items
    +    try {
    +        // Provides only the basic guarantee
    +        v.insert( v.begin(), X() );
    +    }
    +    catch(...) {} // ignore any exceptions above
    +    // print the vector's contents
    +    std::cout "(" << v.size() << ") ";
    +    std::copy( v.begin(), v.end(),
    +    std::ostream_iterator<X>( std::cout, " " ) );
    +}
    +
    +
    +
    +

    Since all we know about v after an exception is that it is valid, the function is allowed to print any random sequence of Xs. It is safe in the sense that it is not allowed to crash, but its output may be unpredictable.

    +
    +
    +
    +
    Note
    +
    +

    In practice of course, this function would make an extremely poor random sequence generator!

    +
    +
    +
    +
    +

    The strong guarantee provides full commit-or-rollback semantics. In the case of C++ standard containers, this means, for example, that if an exception is thrown all iterators remain valid. We also know that the container has the same elements as before the exception was thrown. A transaction that has no effects if it fails has obvious benefits: the program state is simple and predictable in case of an exception. In the C++ standard library, nearly all of the operations on the node-based containers list, set, multiset, map, and multimap provide the strong guarantee.

    +
    +
    +
    +
    Note
    +
    +

    Associative containers whose Compare object might throw an exception when copied cannot use this technique, since the swap function might fail.

    +
    +
    +
    +
    +

    The no-throw guarantee is the strongest of all, and it says that an operation is guaranteed not to throw an exception: it always completes successfully. This guarantee is necessary for most destructors, and indeed the destructors of C++ standard library components are all guaranteed not to throw exceptions. The no-throw guarantee turns out to be important for other reasons, as we shall see.

    +
    +
    +
    +
    Note
    +
    +

    All type parameters supplied by clients of the C++ standard library are required not to throw from their destructors. In return, all components of the C++ standard library provide at least the basic guarantee.

    +
    +
    +
    +
    +
    +
    + +
    +
    +

    Inevitably, the contract can get more complicated: a quid pro quo arrangement is possible. Some components in the C++ Standard Library give one guarantee for arbitrary type parameters, but give a stronger guarantee in exchange for additional promises from the client type that no exceptions will be thrown. For example, the standard container operation vector<T>::erase gives the basic guarantee for any T, but for types whose copy constructor and copy assignment operator does not throw, it gives the no-throw guarantee.

    +
    +
    +
    +
    Note
    +
    +

    Similar arrangements might have been made in the C++ standard for many of the mutating algorithms, but were never considered due to time constraints on the standardization process.

    +
    +
    +
    +
    +
    +
    +

    What Level of Exception-Safety should a Component Specify?

    +
    +
    +

    From a client’s point-of-view, the strongest possible level of safety would be ideal. Of course, the no-throw guarantee is simply impossible for many operations, but what about the strong guarantee? For example, suppose we wanted atomic behavior for vector<T>::insert. Insertion into the middle of a vector requires copying elements after the insertion point into later positions, to make room for the new element. If copying an element can fail, rolling back the operation would require undoing the previous copies…​which depends on copying again. If copying back should fail (as it likely would), we have failed to meet our guarantee.

    +
    +
    +

    One possible alternative would be to redefine insert to build the new array contents in a fresh piece of memory each time, and only destroy the old contents when that has succeeded. Unfortunately, there is a non-trivial cost if this approach is followed: insertions near the end of a vector which might have previously caused only a few copies would now cause every element to be copied. The basic guarantee is a natural level of safety for this operation, which it can provide without violating its performance guarantees. In fact all of the operations in the library appears to have such a natural level of safety.

    +
    +
    +

    Because performance requirements were already a well-established part of the draft standard and because performance is a primary goal of the STL, there was no attempt to specify more safety than could be provided within those requirements. Although not all of the library gives the strong guarantee, almost any operation on a standard container which gives the basic guarantee can be made strong using the make-a-new-copy strategy described above:

    +
    +
    +
    +
    template <class Container, class BasicOp>
    +void MakeOperationStrong( Container& c, const BasicOp& op )
    +{
    +    Container tmp(c); // Copy c
    +    op(tmp); // Work on the copy
    +    c.swap(tmp); // Cannot fail7
    +}
    +
    +
    +
    +

    This technique can be folded into a wrapper class to make a similar container which provides stronger guarantees (and different performance characteristics).

    +
    +
    +
    +
    Note
    +
    +

    This suggests another potential use for the oft-wished-for but as yet unseen container_traits<> template: automated container selection to meet exception-safety constraints.

    +
    +
    +
    +
    +
    +
    +

    Should We Take Everything We Can Get?

    +
    +
    +

    By considering a particular implementation, we can hope to discern a natural level of safety. The danger in using this to establish requirements for a component is that the implementation might be restricted. If someone should come up with a more-efficient implementation which we’d like to use, we may find that it’s incompatible with our exception-safety requirements. One might expect this to be of no concern in the well-explored domains of data structures and algorithms covered by the STL, but even there, advances are being made. A good example is the recent introsort algorithm, which represents a substantial improvement in worst-case complexity over the well-established quicksort.

    +
    +
    +

    To determine exactly how much to demand of the standard components, I looked at a typical real-world scenario. The chosen test case was a composite container. Such a container, built of two or more standard container components, is not only commonly needed, but serves as a simple representative case for maintaining invariants in larger systems:

    +
    +
    +
    +
    // SearchableStack - A stack which can be efficiently searched
    +// for any value.
    +template <class T>
    +class SearchableStack
    +{
    + public:
    +    void push(const T& t); // O(log n)
    +    void pop(); // O(log n)
    +    bool contains(const T& t) const; // O(log n)
    +    const T& top() const; // O(1)
    + private:
    +    std::set<T> set_impl;
    +    std::list<std::set<T>::iterator> list_impl;
    +};
    +
    +
    +
    +

    The idea is that the list acts as a stack of set iterators: every element goes into the set first, and the resulting position is pushed onto the list. The invariant is straightforward: the set and the list should always have the same number of elements, and every element of the set should be referenced by an element of the list. The following implementation of the push function is designed to give the strong guarantee within the natural levels of safety provided by set and list:

    +
    +
    +
    +
    template <class T>                                      // 1
    +void SearchableStack<T>::push(const T& t)               // 2
    +{                                                       // 3
    +    set<T>::iterator i = set_impl.insert(t);            // 4
    +    try                                                 // 5
    +    {                                                   // 6
    +        list_impl.push_back(i);                         // 7
    +    }                                                   // 8
    +    catch(...)                                          // 9
    +    {                                                   // 10
    +        set_impl.erase(i);                              // 11
    +        throw;                                          // 12
    +    }                                                   // 13
    +}                                                       // 14
    +
    +
    +
    +

    What does our code require of the library? We need to examine the lines where non-const operations occur:

    +
    +
    +
      +
    • +

      Line 4: if the insertion fails but set_impl is modified in the process, our invariant is violated. We need to be able to rely on the strong guarantee from set<T>::insert.

      +
    • +
    • +

      Line 7: likewise, if push_back fails, but list_impl is modified in the process, our invariant is violated, so we need to be able to rely on the strong guarantee from list<T>::insert.

      +
    • +
    • +

      Line 11: here we are rolling back the insertion on line 4. If this operation should fail, we will be unable to restore our invariant. We absolutely depend on the no-throw guarantee from set<T>::erase.

      +
    • +
    • +

      Line 11: for the same reasons, we also depend on being able to pass the i to the erase function: we need the no-throw guarantee from the copy constructor of set<T>::iterator.

      +
      +
      +
      Note
      +
      +

      One might be tempted to surround the erase operation with a try/catch block to reduce the requirements on set<T> and the problems that arise in case of an exception, but in the end that just begs the question. First, erase just failed and in this case there are no viable alternative ways to produce the necessary result. Second and more generally, because of the variability of its type parameters a generic component can seldom be assured that any alternatives will succeed.

      +
      +
      +
      +
    • +
    +
    +
    +

    I learned a great deal by approaching the question this way during standardization. First, the guarantee specified for the composite container depends on stronger guarantees from its components (the no-throw guarantees in line 11). Also, I took advantage of all of the natural levels of safety to implement this simple example. Finally, the analysis revealed a requirement on iterators which I had previously overlooked when operations were considered on their own. The conclusion was that we should provide as much of the natural level of safety as possible. Faster but less-safe implementations could always be provided as extensions to the standard components.

    +
    +
    +
    +
    Note
    +
    +

    The prevalent philosophy in the design of STL was that functionality that wasn’t essential to all uses should be left out in favor of efficiency, as long as that functionality could be obtained when needed by adapting the base components. This departs from that philosophy, but it would be difficult or impossible to obtain even the basic guarantee by adapting a base component that doesn’t already have it.

    +
    +
    +
    +
    +
    +
    +

    Automated Testing for Exception-Safety

    +
    +
    +

    As part of the standardization process, I produced an exception-safe reference implementation of the STL. Error-handling code is seldom rigorously tested in real life, in part because it is difficult to cause error conditions to occur. It is very common to see error-handling code that crashes the first time it is executed …​in a shipping product! To bolster confidence that the implementation worked as advertised, I designed an automated test suite, based on an exhaustive technique due to my colleague Matt Arnold.

    +
    +
    +

    The test program started with the basics: reinforcement and instrumentation, especially of the global operators new and delete. Instances of the components (containers and algorithms) were created, with type parameters chosen to reveal as many potential problems as possible. For example, all type parameters were given a pointer to heap-allocated memory, so that leaking a contained object would be detected as a memory leak.

    +
    +
    +
    +
    Note
    +
    +

    An excellent discussion on how to fortify memory subsystems can be found in: Steve Maguire, Writing Solid Code, Microsoft Press, Redmond, WA, 1993, ISBN 1-55615- 551-4.

    +
    +
    +
    +
    +

    Finally, a scheme was designed that could cause an operation to throw an exception at each possible point of failure. At the beginning of every client-supplied operation which is allowed to throw an exception, a call to ThisCanThrow was added. A call to ThisCanThrow also had to be added everywhere that the generic operation being tested might throw an exception, for example in the global operator new, for which an instrumented replacement was supplied.

    +
    +
    +
    +
    // Use this as a type parameter, e.g. vector<TestClass>
    +struct TestClass
    +{
    +    TestClass( int v = 0 )
    +        : p( ThisCanThrow(), new int( v ) ) {}
    +    TestClass( const TestClass& rhs )
    +        : p( ThisCanThrow(), new int( *rhs.p ) ) {}
    +    const TestClass& operator=( const TestClass& rhs )
    +        { ThisCanThrow(); *p = *rhs.p; }
    +    bool operator==( const TestClass& rhs ) const
    +        { ThisCanThrow(); return *p == *rhs.p; }
    +    ...etc...
    +    ~TestClass() { delete p; }
    +};
    +
    +
    +
    +

    ThisCanThrow simply decrements a throw counter and, if it has reached zero, throws an exception. Each test takes a form which begins the counter at successively higher values in an outer loop and repeatedly attempts to complete the operation being tested. The result is that the operation throws an exception at each successive step along its execution path that can possibly fail. For example, here is a simplified version of the function used to test the strong guarantee:

    +
    +
    +
    +
    extern int gThrowCounter; // The throw counter
    +void ThisCanThrow()
    +{
    +    if (gThrowCounter-- == 0)
    +        throw 0;
    +}
    +
    +template <class Value, class Operation>
    +void StrongCheck(const Value& v, const Operation& op)
    +{
    +    bool succeeded = false;
    +    for (long nextThrowCount = 0; !succeeded; ++nextThrowCount)
    +    {
    +        Value duplicate = v;
    +        try
    +        {
    +            gThrowCounter = nextThrowCount;
    +            op( duplicate ); // Try the operation
    +            succeeded = true;
    +        }
    +        catch(...) // Catch all exceptions
    +        {
    +            bool unchanged = duplicate == v; // Test strong guarantee
    +            assert( unchanged );
    +        }
    +        // Specialize as desired for each container type, to check
    +        // integrity. For example, size() == distance(begin(),end())
    +        CheckInvariant(v); // Check any invariant
    +    }
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    This technique requires that the operation being tested be exception-neutral. If the operation ever tries to recover from an exception and proceed, the throw counter will be negative, and subsequent operations that might fail will not be tested for exception-safety.

    +
    +
    +
    +
    +

    Notably, this kind of testing is much easier and less intrusive with a generic component than with non-generics, because testing-specific type parameters can be used without modifying the source code of the component being tested. Also, generic functions like StrongCheck above were instrumental in performing the tests on a wide range of values and operations.

    +
    +
    +
    +
    +

    Further Reading

    +
    +
    +

    To my knowledge, there are currently only two descriptions of STL exception-safety available. The original specification for the reference exception-safe implementation of the STL is an informal specification, simple and self-explanatory (also verbose), and uses the basic- and strong-guarantee distinctions outlined in this article. It explicitly forbids leaks, and differs substantively from the final C++ standard in the guarantees it makes, though they are largely identical. I hope to produce an updated version of this document soon.

    +
    +
    +

    The description of exception-safety in the C++ Standard is only slightly more formal, but relies on hard-to-read standardese and an occasionally subtle web of implication. In particular, leaks are not treated directly at all. It does have the advantage that it is the standard.

    +
    +
    +
    +
    Note
    +
    +

    The changes to the draft standard which introduced exception-safety were made late in the process, when amendments were likely to be rejected solely based on the number of altered words. Unfortunately, the result compromises clarity somewhat in favor of brevity. Greg Colvin was responsible for the clever language-lawyering needed to minimize the extent of these changes.

    +
    +
    +
    +
    +

    The original reference implementation of the exception-safe STL is an adaptation of an old version of the SGI STL, designed for C++ compilers with limited features. Although it is not a complete STL implementation, the code may be easier to read, and it illustrates a useful base-class technique for eliminating exception-handling code in constructors. The full test suite used to validate the reference implementation has been used successfully to validate all recent versions of the SGI STL, and has been adapted to test one other vendor’s implementation (which failed). As noted on the documentation page, it also seems to have the power to reveal hidden compiler bugs, particularly where optimizers interact with exception-handling code.

    +
    +
    +

    References

    +
    +
      +
    • +

      International Standard ISO/IEC 14882, Information Technology-Programming Languages-C++, Document Number ISO/IEC 14882-1998, available from http://webstore.ansi.org/ansidocstore/default.asp.

      +
    • +
    • +

      D. Abrahams, Exception Safety in STLport, available at http://www.stlport.org/doc/exception_safety.html.

      +
    • +
    • +

      D. Abrahams and B. Fomitchev, Exception Handling Test Suite, available at http://www.stlport.org/doc/eh_testsuite.html.

      +
    • +
    • +

      Tom Cargill, Exception Handling: A False Sense of Security, C++ Report, Nov-Dec 1994.

      +
    • +
    • +

      B. Fomitchev, Adapted SGI STL Version 1.0, with exception handling code by D. Abrahams, available at http://www.stlport.org.

      +
    • +
    • +

      D. R. Musser, Introspective Sorting and Selection Algorithms,” Software-Practice and Experience 27(8):983-993, 1997.

      +
    • +
    • +

      Bjarne Stroustrup, The Design And Evolution of C++. Addison Wesley, Reading, MA, 1995, ISBN 0-201-54330-3, Section 16.9.1.

      +
    • +
    +
    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    This topic was originally written by David Abrahams (dave@boostpro.com) as a paper entitled "Lessons Learned from Specifying Exception-Safety for the C++ Standard Library".

    +
    +
    +

    Abstract: "This paper represents the knowledge accumulated in response to a real-world need: that the C++ Standard Template Library exhibit useful and well-defined interactions with exceptions, the error-handling mechanism built-in to the core C++ language. It explores the meaning of exception-safety, reveals surprising myths about exceptions and genericity describes valuable tools for reasoning about program correctness, and outlines an automated testing procedure for verifying exception-safety."

    +
    +
    +

    Keywords: "exception-safety, exceptions, STL, C++"

    +
    +
    +
    +
    +

    See Also

    +
    +
    +
      +
    • +

      Boost.Exception : provides utilities for working with C++ exceptions, including exception types, error handling policies, and exception propagation mechanisms.

      +
    • +
    • +

      Boost.System : provides a set of portable error code and error category classes for representing and handling error conditions.

      +
    • +
    • +

      Boost.Test : provides a unit testing framework, including support for testing exception handling and error conditions.

      +
    • +
    • +

      Testing and Debugging

      +
    • +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/explore-the-content.html b/preview/user-guide/explore-the-content.html new file mode 100644 index 0000000..c91f74f --- /dev/null +++ b/preview/user-guide/explore-the-content.html @@ -0,0 +1,518 @@ + + + + + + + + + + + + + + Explore the Content :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Explore the Content

    +
    +
    +
    +

    There are a number of ways you can approach exploring Boost. Clearly, examining the documentation for any of the Boost libraries is a great way to start. However, with 180 or so libraries to choose from, you might want to consider a range of options to get going. This section covers a number of approaches you have to focus your exploration of the libraries, and get deeper into Boost content.

    +
    +
    +

    If knowing what others have done before you helps, refer to High-Profile users of Boost.

    +
    +
    +

    If you are already using, or considering, the Standard Template Library then refer to Boost vs the Standard Library to get some idea of which to use when similar ones are available in both sets of libraries.

    +
    +
    +

    If any of the libraries does pique your interest, consider examining and running working Examples.

    +
    +
    +

    There are mailing lists you might want to join too, to ask questions and join in the discussion, such as the Boost Users mailing list, or project-specific lists accessible from the Boost Mailing Lists site.

    +
    +
    +

    To delve into content for a specific scenario, refer to the Common Scenarios topics, such as:

    +
    + +
    +

    And, to the Advanced Scenarios topics such as:

    +
    + +
    +
    +
    +

    High-Profile users of Boost

    +
    +
    +

    Some well known libraries and applications have used the building blocks that Boost provides. These include:

    +
    +
    +
      +
    • +

      Folly, the Facebook Open Source Library, is an open-source library developed by Facebook that is intended to augment the Standard Library and Boost by providing additional features and optimizations, often with a focus on high-performance systems. It is a collection of relatively small and standalone libraries, and its features can be used on an as-needed basis.

      +
      +

      Some of these features include string formatting libraries, hash maps, dynamic types, and concurrency utilities. Folly makes extensive use of:

      +
      +
      +
        +
      • +

        Boost.Context for creating and manipulating execution contexts, which are used in Folly’s implementation of coroutines

        +
      • +
      • +

        Boost.Intrusive which provides containers that allow for the insertion and removal of elements in constant time

        +
      • +
      • +

        Boost.Optional which provides a way to represent optional, or nullable, objects of a given type

        +
        +

        Additionally, many parts of Folly are designed to interact seamlessly with Boost and the Standard Library, making it easy to integrate Folly into existing codebases that use these libraries. Folly serves as an example of how Boost libraries can be used in the development of large-scale, high-performance systems.

        +
        +
      • +
      +
      +
    • +
    • +

      The Bitcoin Core client, which is the reference implementation of the Bitcoin protocol, makes extensive use of the Boost libraries. For example, it uses Boost.Asio for network programming, Boost.Thread for multithreading, and Boost.Test for unit tests.

      +
    • +
    • +

      MongoDB, a popular open-source document database, leverages libraries such as Boost.Filesystem for filesystem interactions, Boost.Thread for threading, and Boost.SmartPtr for smart pointers.

      +
    • +
    • +

      The Low Level Virtual Machine (LLVM) project, which is a collection of modular and reusable compiler and toolchain technologies, utilizes Boost in parts of its code base. For instance, it uses Boost.Mpl for its metaprogramming functionality.

      +
    • +
    +
    +
    + + + + + +
    + + +Boost.Mpl has now been superseded by Boost.Mp11. +
    +
    +
    +
      +
    • +

      Microsoft has integrated Boost.Test into Visual Studio, in particular to enable unit testing.

      +
    • +
    • +

      Adobe also uses Boost in several of their software products. For instance, Adobe Source Libraries (ASL) includes and builds upon Boost.SmartPtr, Boost.Mpl, Boost.Lambda.

      +
    • +
    • +

      The Robot Operating System (ROS), a flexible framework for robotics software development, uses Boost in several areas, for instance, Boost.Python to provide Python bindings, and Boost.Signals2 for inter-process communication.

      +
    • +
    • +

      React Native is a popular JavaScript framework for building mobile application. Boost libraries are used extensively within JavaScriptCore (used to execute JavaScript within the app), and are a key part of the infrastructure that allows React Native to bridge between JavaScript and native code. The libraries used include Boost.Optional, Boost.Intrusive, and Boost.MultiIndex.

      +
    • +
    • +

      MySQL one of the most popular open-source relational database management systems, uses Boost libraries in its build process. It mainly uses the Boost header files, particularly those required for geometry processing operations, such as Boost.Geometry.

      +
    • +
    +
    +
    +
    +
    +

    Boost vs the Standard Library

    +
    +
    +

    There are several Boost libraries that have a Standard Template Library (STL) equivalent but offer more features, better performance, or additional functionality that can make them more compelling in certain situations. When comparing libraries which have similar features, also consider compilation time, binary size, code readability, and the portability of your code.

    +
    +
    +
      +
    • +

      Boost.Any is similar to std::any, introduced in C++17. However, if you’re working with a codebase that needs to be compatible with pre-C++17 standards, then Boost.Any can be a lifesaver.

      +
    • +
    • +

      Similar to the situation with Boost.Any, Boost.Optional provides functionality similar to std::optional, introduced in C++17, but works with earlier standards.

      +
    • +
    • +

      While C++11 introduced smart pointers into the standard library (with std::unique_ptr and std::shared_ptr), Boost.SmartPtr offers some additional features. These features include the use of intrusive_ptr which allows for the customization of the reference-counting mechanism.

      +
    • +
    • +

      Boost.Container offers some advanced containers like flat_map, small_vector, static_vector, and stable_vector that are not available in STL std::containers.

      +
    • +
    • +

      Boost.Random has more extensive features than std::random.

      +
    • +
    • +

      Boost.Algorithm provides some algorithms that are not available in STL std::algorithms, such as boost::algorithm::all_of_equal.

      +
    • +
    +
    +
    +
    +
    +

    Examples

    +
    +
    +

    Many Boost libraries, but not all, have an example folder that contains runnable source code projects for the library. To locate the examples, first navigate to the Super-project containing all the libraries, then select the library that interests you, then its' example folder, if one exists.

    +
    +
    +

    For example:

    +
    + +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/faq.html b/preview/user-guide/faq.html new file mode 100644 index 0000000..29a6300 --- /dev/null +++ b/preview/user-guide/faq.html @@ -0,0 +1,3385 @@ + + + + + + + + + + + + + + Frequently Asked Questions :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Frequently Asked Questions

    +
    +
    +
    +

    This section contains answers to the common questions that new developers to Boost often have.

    +
    +
    +
    +
    +

    Topics

    +
    +
    + +
    +
    +
    +
    +

    C++ Library Programming

    +
    +
    +
      +
    1. +

      What is involved in using a Boost header-only library?

      +
      +

      After installing the Boost libraries, not much, just include the libraries you want. Here is an example (example1.cpp) using Boost.Multiprecision:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +#include <iostream>
      +
      +// Alias for a high-precision floating-point type
      +using namespace boost::multiprecision;
      +using BigFloat = cpp_dec_float_50;
      +
      +int main() {
      +    BigFloat a = 1.0 / 3.0;
      +    BigFloat b = sqrt(BigFloat(2));
      +
      +    // Note that setprecision has been specified as slightly longer than the floating point numbers
      +    std::cout << "1/3 with high precision: " << std::setprecision(51) << a << std::endl;
      +    std::cout << "Square root of 2: " << std::setprecision(51) << b << std::endl;
      +
      +    return 0;
      +}
      +
      +
      +
      +

      Compile with:

      +
      +
      +
      +
      g++ -std=c++17 example1.cpp -o example1
      +
      +
      +
      +

      No linking is required, just run the program!

      +
      +
    2. +
    3. +

      What is involved in using a Boost compiled-binary library?

      +
      +

      Using a compiled-binary library involves linking to the library, and any dependent libraries that are also compiled. Here is an example (example2.cpp) using Boost.Filesystem.

      +
      +
      +
      +
      #include <boost/filesystem.hpp>
      +#include <iostream>
      +#include <fstream>
      +
      +namespace fs = boost::filesystem;
      +
      +int main() {
      +    fs::path filePath("example.txt");
      +
      +    if (fs::exists(filePath)) {
      +        std::cout << "File exists: " << filePath.string() << std::endl;
      +    } else {
      +        std::cout << "File does not exist, creating it..." << std::endl;
      +        std::ofstream file(filePath.string());
      +        file << "Hello, Boost.Filesystem!";
      +        file.close();
      +    }
      +
      +    return 0;
      +}
      +
      +
      +
      +

      This requires an extra step before running, linking to both Boost.Filesystem and Boost.System. We need to link to Boost.System because Boost.Filesystem calls boost::system::generic_category() - for error handling - and this call is only defined in the compiled version of Boost.System:

      +
      +
      +
      +
      g++ -std=c++17 example2.cpp -o example2 -lboost_filesystem -lboost_system
      +
      +
      +
      +

      Now you can run your program.

      +
      +
      +
      +
      Notes
      +
      +

      The example compiler used here is GNU C++. If you are using the Clang compiler, simply replace g++ with clang++. On macOS, if Boost is installed via Homebrew, you might need to specify the paths further:

      +
      +

      clang++ -std=c++17 example2.cpp -o example2 -I/usr/local/include -L/usr/local/lib -lboost_filesystem -lboost_system

      +
      +
      +

      If you are using MSVC, and the libraries are in the default path, then the command would be:

      +
      +
      +

      cl /std:c++17 example2.cpp /Fe:example2.exe /link boost_filesystem.lib boost_system.lib

      +
      +
      +
      +
      +
    4. +
    5. +

      Given a choice, when should I use header-only or compiled-binary libraries?

      +
      +

      Depends on your priorities:

      +
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      PriorityHeader-OnlyCompiled-Binary

      Ease of Use

      Yes - Easier (just include)

      No - Requires linking

      Compilation Time

      No - Slower

      Yes - Faster

      Binary Size

      No - Larger (possible code duplication)

      Yes - Smaller

      Performance

      Yes - Optimized via inlining

      Yes - Optimized via specialized builds

      Portability

      Yes - Highly portable

      No - Requires platform-specific builds

      Debugging

      No - Harder (complex errors with templated code)

      Yes - Easier

      ABI Stability

      No - Less stable

      Yes - More stable

      +
      +

      Also, with a header-only library the compiler has full visibility of the code, allowing inlining and optimizations that might not be possible with separately compiled binaries. This can reduce function call overhead when optimizations are applied. Since no precompiled binaries are needed, projects using header-only libraries are easier to distribute and deploy.

      +
      +
      +

      However, header-only libraries are compiled within each project, so any minor changes (even updates) can lead to unexpected behavior due to template changes. Shared libraries with well-defined Application Binary Interfaces (ABIs) offer better versioning control.

      +
      +
      +

      Header-only libraries are certainly easier to get going with. To optimize for better stability and debugging, and reducing binary size, refer to the next few questions on how to create binaries for header-only code - typically, when your project is becoming stable.

      +
      +
    6. +
    7. +

      Can I use C++20 Modules to precompile header-only libraries and import them when needed?

      +
      +

      Not reliably or consistently. Boost libraries are not currently written as C++20 modules. They use traditional headers, macros, and complex template structures that don’t cooperate well with the C++20 export module syntax.

      +
      +
      +

      As a workaround, consider using old-fashioned header files. For example, for boost_module.hpp:

      +
      +
      +
      +
      #pragma once
      +#include <boost/multiprecision/cpp_dec_float.hpp>
      +
      +using BigFloat = boost::multiprecision::cpp_dec_float_50;
      +
      +
      +
      +

      Then for the main code:

      +
      +
      +
      +
      #include "boost_module.hpp"
      +#include <iostream>
      +
      +int main() {
      +    BigFloat x = 1.0 / 3.0;
      +    std::cout << "1/3 with high precision: " << std::setprecision(51) << x << std::endl;
      +    return 0;
      +}
      +
      +
      +
      +

      Even if Boost were module-friendly, cpp_dec_float_50 is a template instantiated from a header, and exporting it in a module interface would require exposing a lot of detail that header-only libraries don’t support out of the box.

      +
      +
    8. +
    9. +

      Can I create a Static Library from header-only libraries and link when needed?

      +
      +

      Yes, even if the library is header-only, you can wrap it in a .cpp file, compile it into a static .a or .lib file, and link it. Start by creating a wrapper source file (boost_wrapper.cpp) that includes the header-only Boost libraries:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +
      +boost::multiprecision::cpp_dec_float_50 dummy_function() {
      +    return 1.0 / 3.0; // Forces compilation of template instantiation
      +}
      +
      +
      +
      +

      Now, compile it into a static library:

      +
      +
      +
      +
      g++ -c boost_wrapper.cpp -o boost_wrapper.o
      +ar rcs libboost_wrapper.a boost_wrapper.o
      +
      +
      +
      +

      Use it in your code:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +#include <iostream>
      +
      +int main() {
      +    boost::multiprecision::cpp_dec_float_50 x = 1.0 / 3.0;
      +    std::cout << "1/3: " << x << std::endl;
      +    return 0;
      +}
      +
      +
      +
      +

      Compile and link:

      +
      +
      +
      +
      g++ main.cpp -L. -lboost_wrapper -o main
      +
      +
      +
      +
      +
      Note
      +
      +

      One advantage of this approach is it avoids re-parsing and re-instantiating templates in every translation unit.

      +
      +
      +
      +
    10. +
    11. +

      Can I create a precompiled header (PCH) that imports Boost libraries?

      +
      +

      Yes, a precompiled header should enable faster recompilation when only the main code changes. And, unlike modules, it works in older C++ versions.

      +
      +
      +

      For example, create an hpp file (boost_pch.hpp) containing the required libraries:

      +
      +
      +
      +
      // boost_pch.hpp
      +#include <boost/multiprecision/cpp_dec_float.hpp>
      +
      +
      +
      +

      Precompile it into a .gch file:

      +
      +
      +
      +
      g++ -std=c++17 -x c++-header boost_pch.hpp -o boost_pch.hpp.gch
      +
      +
      +
      +

      Use it in your code:

      +
      +
      +
      +
      #include "boost_pch.hpp" // Uses precompiled header
      +
      +int main() {
      +    boost::multiprecision::cpp_dec_float_50 x = 1.0 / 3.0;
      +    std::cout << "1/3: " << x << std::endl;
      +    return 0;
      +}
      +
      +
      +
      +

      Typically, when your project starts becoming "large" use of compiled libraries becomes more relevant.

      +
      +
    12. +
    13. +

      In the programming world, what qualifies as a small, medium, or large project?

      +
      +

      While not perfect, lines of code is a quick way to classify project sizes:

      +
      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      Project SizeLines of Code Estimate

      Small

      less than 10,000

      Medium

      10,000 to 100,000

      Large

      100,000 to 1,000,000

      Enterprise/Monolithic

      more than 1,000,000

      +
      +

      Or possibly classify a project by the number of developers:

      +
      + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
      Project SizeDevelopers

      Small

      less than 5

      Medium

      6 to 50

      Large

      51+

      Enterprise/Monolithic

      Hundreds, across multiple time-zones

      +
      +

      There are other metrics too - if your incremental build takes minutes, it’s getting large. If a full rebuild takes hours, it’s definitely a large project. If the dependency tree is deep, requiring fine-grained modularization, it’s large.

      +
      +
      +
      +
      Note
      +
      +

      Size alone is not a perfect measure of complexity. A templated metaprogramming-heavy project might be "large" in complexity but only a few thousand lines. Or a UI-heavy application might have tons of boilerplate but be relatively simple. Boost Libraries are available to help prevent a "large" project becoming a "beast"!

      +
      +
      +
      +
    14. +
    15. +

      When does a coding project become a "beast"?

      +
      +

      A coding project becomes a beast when two or more of the following conditions are met:

      +
      +
      +
        +
      • +

        Build times are measured in coffee breaks - if compiling takes longer than making (and drinking) a cup of coffee, it’s a beast!

        +
      • +
      • +

        When you start considering distributed builds or caching everything, it’s serious.

        +
      • +
      • +

        No one developer knows how everything works anymore.

        +
      • +
      • +

        The project is in "dependency hell" - adding one more library requires resolving a cascade of conflicts. Or, you start saying, "Do we really need this feature?" just to avoid the dependency headache.

        +
      • +
      • +

        Debugging feels like archaeology - code from years ago still exists, but no one remembers why. Or, comments like // DO NOT TOUCH - IT JUST WORKS litter the source code.

        +
      • +
      • +

        Refactoring is a nightmare - a simple rename breaks hundreds of files, or "Let’s rewrite it from scratch" starts sounding reasonable.

        +
      • +
      • +

        Multi-minute CI/CD pipelines - your test suite takes longer to run than a lunch break.

        +
      • +
      • +

        Contributors live in fear of merge conflicts.

        +
      • +
      +
      +
    16. +
    +
    +
    +
    +
    +

    Combining Libraries

    +
    +
    +
      +
    1. +

      Can you give me some examples of Boost libraries that developers have found work well together?

      +
      +

      Many Boost libraries are designed to be modular, yet complementary, and over the years, developers have discovered powerful combinations of libraries that work well together. Here are some groups:

      +
      +
      +
        +
      • +

        If you are building an Asynchronous Networking Stack, then the following libraries mesh naturally: Boost.Asio for core asynchronous I/O and networking, Boost.System for error codes that are used in Asio error handling, Boost.Thread or Boost.Fiber for managing threads or fibers in concurrent code, Boost.Chrono for working with timeouts and deadlines, and Boost.Bind or Boost.Function for callbacks and handler binding in Asio.

        +
        +

        If the network supports financial systems, in particular high-frequency trading, then add Boost.Lockfree to support low-latency data structures, and Boost.Multiprecision for high-precision arithmetic.

        +
        +
      • +
      • +

        Say you are working on Compile-Time Metaprogramming and Reflection, then the following libraries enable expressive and powerful template code, with strong introspection and static analysis at compile time, reducing run-time cost: Boost.Hana or Boost.Mp11 for high-level metaprogramming, Boost.Fusion provides sequence manipulation for structs and tuples at compile time, Boost.TypeTraits for query and transform types, and Boost.StaticAssert or Boost.Assert to validate assumptions during compile-time logic.

        +
      • +
      • +

        A quite different field is Simulation, Geographic Information Systems (GIS), Robotics, and CAD. For this you need accurate, type-safe modeling of space, motion, and physical quantities, all interoperable in simulations or mathematical domains. The following provide this: Boost.Geometry for the algorithms in 2D/3D spatial operations, Boost.Units for strongly-typed physical units to prevent dimensional errors, Boost.Qvm for lightweight vector and matrix algebra, Boost.Math adds special functions, statistical distributions, numerical accuracy, and Boost.Numeric/interval can represent ranges of values that may contain uncertainty. In robotics in particular, you might need Boost.Thread to support parallel sensor processing. Also, Boost.Serialization might also help with state persistence.

        +
      • +
      • +

        If you are building a Test Suite, say with unit testing and regression tests, consider adding to Boost.Test the following: Boost.TypeTraits to inspect and verify types in test cases, Boost.Optional or Boost.Variant or Boost.Outcome to represent and test optional or alternative outcomes, Boost.Preprocessor to generate test cases or datasets at compile time, and finally Boost.Format or Boost.Locale for diagnostics, error reporting, and internationalized tests.

        +
      • +
      • +

        On a similar vein to testing is Logging. Logging infrastructure is well supported by Boost.Log. Boost.PropertyTree might help with configuration and data trees, Boost.CircularBuffer for bounded memory logging, and Boost.ProgramOptions for a command-line interface (perhaps for embedded systems).

        +
      • +
      • +

        As a final example consider Saving/Restoring State, Remote Procedure Calls (RPC), Configuration Files, Distributed Systems. The following collection covers all aspects of data flow - loading, storing, transforming, and parsing—all in a type-safe, extensible style: Boost.Serialization for the core for serializing C++ objects to/from streams, Boost.Variant or Boost.Optional to serialize complex, dynamic types, Boost.PropertyTree for easy access to config files (JSON, XML, or INI) and Boost.Spirit for parsing domain-specific formats into structured data.

        +
        +

        For deeper examples of multiple libraries, including working source code, refer to Common Scenarios and Advanced Scenarios.

        +
        +
      • +
      +
      +
    2. +
    3. +

      I want to build a cross-platform system, right from the start. What libraries should I use as core to that system?

      +
      +

      Desktop applications like text editors, project managers and utilities often need cross-platform compatibility, user input processing, and dynamic plugins via signal-slot mechanisms. Consider Boost.Filesystem to provide the file management, Boost.Locale for use in multiple regions, Boost.Signals2 to support an event system, and Boost.Regex for structured text parsing.

      +
      +
    4. +
    5. +

      Are there any combinations of Boost libraries that experience has shown do not play well together?

      +
      +

      Not in a broad sense, Boost C++ libraries are designed with a high degree of interoperability. However, there are always nuances when multiple libraries have overlapping functionality, conflicting macros, or different assumptions about thread safety, memory management, or initialization. Issues can usually be avoided with careful design, for example:

      +
      +
      +
        +
      • +

        Boost.Signals2 internally uses Boost.Thread for managing asynchronous signal connections. However, there have been instances where thread safety issues arise when these two libraries are used in parallel. If not handled properly, it can lead to deadlocks or race conditions, especially in multithreaded environments. Always ensure that signals are disconnected properly and thread-safe operations are applied where needed.

        +
      • +
      • +

        Both Boost.Filesystem and Boost.Regex perform some filesystem operations and string manipulation that can lead to conflicts when used in combination, especially if Regex is processing filenames or paths that contain special characters (for example, slashes or backslashes in Windows paths). When working with filenames and regular expressions, it’s best to sanitize the inputs carefully before passing them on.

        +
      • +
      • +

        Boost.Mp11 and Boost.Hana both work with metaprogramming, often with overlapping functionality, but their usage patterns can conflict. MP11 uses a more classic, compile-time only, and more explicit metaprogramming model, while Hana includes both compile-time and run-time metaprogramming functions, which introduce ambiguity when mixing the two libraries. Best to choose one of these libraries, unless you can ensure clean separation between the two.

        +
      • +
      • +

        The interaction between Boost.Serialization (for serializing and deserializing objects) and Boost.Python (for integrating C++ code with Python) can be tricky when serializing Python objects. Issues like memory management conflicts or incorrect serialization of Python objects can occur, especially with Python’s dynamic typing system. Wrapping Python objects in C++ classes with explicit serialization mechanisms may be necessary.

        +
      • +
      • +

        When using asynchronous I/O with Boost.Asio and regular expressions with Boost.Regex, conflicts can arise, particularly with blocking operations in boost::asio::io_service or boost::asio::strand. Regex can be CPU-intensive and might block the main event loop of Asio, leading to performance issues or deadlocks. Use non-blocking or asynchronous alternatives (separate threads) for Regex operations in the context of Asio.

        +
      • +
      • +

        Boost.Pool is a custom memory pool allocator that can cause issues when used with Boost.SmartPtr (such as boost::shared_ptr or boost::scoped_ptr) since these smart pointers manage memory differently. The interaction between custom memory pools and reference-counted pointers can lead to memory leaks or double-free errors if not handled correctly. When using Pool with smart pointers, ensure that custom allocators are compatible with the reference-counting behavior of smart pointers. Consider using boost::shared_ptr with boost::pool_allocator if you’re using custom memory pools.

        +
      • +
      • +

        Both Boost.Spirit (a parsing library) and Boost.Serialization involve significant template metaprogramming, which can result in large compile times and potential conflicts in template instantiations. The combination of these libraries in the same project can exacerbate compilation times and, in rare cases, cause conflicts in template instantiation or symbol resolution. Use these libraries in different parts of your project and limit cross-dependencies.

        +
      • +
      • +

        Boost.Test is a robust testing framework, while Boost.Thread is used for threading. Problems can occur if your tests are not properly isolated from thread contexts, or if tests involving multiple threads cause race conditions or deadlocks that aren’t immediately visible. Use proper synchronization techniques in multi-threaded tests to avoid race conditions. When testing threaded code, use the correct testing tools provided by Test, such as BOOST_THREAD_TEST, to ensure proper isolation of tests and reduce flaky test results.

        +
        +

        In general, to avoid problems, always test combinations of libraries early, to ensure proper synchronization and error handling.

        +
        +
      • +
      +
      +
    6. +
    7. +

      Is there a checklist to work through to ensure I have covered my bases when combining libraries?

      +
      +

      The following checklist should be a good start:

      +
      +
      +

      Boost C++ Library Integration Checklist

      +
      +
      +
        +
      • +

        Build and Linking

        +
      • +
      • +

        Confirm which Boost components are header-only vs require linking.

        +
      • +
      • +

        Use a consistent Boost version across the codebase.

        +
      • +
      • +

        Link required Boost libraries explicitly (for example, -lboost_filesystem, -lboost_thread).

        +
      • +
      • +

        Use CMake’s find_package(Boost REQUIRED COMPONENTS …​) correctly if applicable.

        +
        +

        Dependencies and Size

        +
        +
      • +
      • +

        Audit transitive dependencies with tools like the Boost Copy Tool (bcp) and Boost Dependency Report.

        +
      • +
      • +

        Include only the headers you need to keep compile times fast and code lean.

        +
        +

        Preprocessor Macros

        +
        +
      • +
      • +

        Check for key macros like BOOST_NO_EXCEPTIONS, BOOST_ASSERT, BOOST_DISABLE_ASSERTS.

        +
      • +
      • +

        Avoid macro name collisions (for example, bind, min, max) by careful header ordering or #undef.

        +
        +

        Thread Safety

        +
        +
      • +
      • +

        Ensure Boost libraries used are thread-safe in your usage context.

        +
      • +
      • +

        Use thread-safe variants (Boost.Signals2, Boost.Log with thread-safe sinks) as needed.

        +
        +

        Clean Code Practices

        +
        +
      • +
      • +

        Encapsulate low-level Boost operations behind clean APIs.

        +
      • +
      • +

        Apply RAII for all resource management (files, sockets, locks).

        +
      • +
      • +

        Handle exceptions and error codes consistently across Boost modules.

        +
        +

        Debugging and Tooling

        +
        +
      • +
      • +

        Prepare for template error verbosity (for example, with Boost.Spirit, Boost.Mp11, Boost.Hana).

        +
      • +
      • +

        Verify debug symbol generation and stack traces involving Boost types.

        +
        +

        Documentation and Discoverability

        +
        +
      • +
      • +

        Document Boost macros and configuration choices in the build setup or source files.

        +
      • +
      • +

        Link to official Boost documentation: https://www.boost.org/doc/libs/.

        +
        +

        Testing and CI

        +
        +
      • +
      • +

        Add unit tests for modules using Boost.

        +
      • +
      • +

        Test both success and failure paths (for example, file-not-found, timeout, parsing errors).

        +
      • +
      • +

        Test across multiple Boost versions/platforms if possible in CI pipelines.

        +
        +

        Integration with Other Libraries

        +
        +
      • +
      • +

        Watch for macro conflicts or settings when combining Boost with libraries like Qt, Poco, OpenCV.

        +
      • +
      • +

        Guard against duplicate symbols or conflicting linkage when using static/shared Boost libs.

        + +
      • +
      +
      +
    8. +
    +
    +
    +
    +
    +

    Compatibility

    +
    +
    +
      +
    1. +

      Can I use Boost with my existing C++ project?

      +
      +

      Yes, Boost is designed to work with your existing C++ code. You can add Boost libraries to any project that uses a compatible C++ compiler.

      +
      +
    2. +
    3. +

      Can I use Boost libraries with the new C++ standards?

      +
      +

      Yes, Boost libraries are designed to work with modern C++ standards including C++11, C++14, C++17, C++20, and C++23.

      +
      +
    4. +
    5. +

      What flavors of Linux are supported by the Boost libraries?

      +
      +

      Boost libraries are generally compatible with most Linux distributions, provided that the distribution has an up-to-date C++ compiler. This includes:

      +
      +
      +
        +
      • +

        Ubuntu

        +
      • +
      • +

        Fedora

        +
      • +
      • +

        Debian

        +
      • +
      • +

        CentOS

        +
      • +
      • +

        Red Hat Enterprise Linux

        +
      • +
      • +

        Arch Linux

        +
      • +
      • +

        openSUSE

        +
      • +
      • +

        Slackware

        +
      • +
      • +

        Gentoo

        +
      • +
      • +

        macOS

        +
      • +
      +
      +
    6. +
    7. +

      How can I be sure that a library I want to use is compatible with my OS?

      +
      +

      While Boost strives to ensure compatibility with a wide range of compilers and systems, not every library may work perfectly with every system or compiler due to the inherent complexities of software. The most reliable source of information is the specific Boost library’s documentation.

      +
      +
    8. +
    +
    +
    +
    +
    +

    Debugging

    +
    +
    +
      +
    1. +

      What support does Boost provide for debugging and testing?

      +
      +

      Boost provides Boost.Test for unit testing, which can be an integral part of the debugging process. It also provides the Boost.Stacktrace library that can be used to produce useful debug information during a crash or from a running application. Refer also to Category: Correctness and testing.

      +
      +
    2. +
    3. +

      How do I enable assertions in Boost?

      +
      +

      Boost uses its own set of assertion macros. By default, BOOST_ASSERT is enabled, but if it fails, it only calls abort(). If you define BOOST_ENABLE_ASSERT_HANDLER before including any Boost header, then you need to supply boost::assertion_failed(msg, code, file, line) and boost::assertion_failed_msg(msg, code, file, line) functions to handle failed assertions.

      +
      +
    4. +
    5. +

      How can I get a stack trace when my program crashes?

      +
      +

      You can use the Boost.Stacktrace library to obtain a stack trace in your application. You can capture and print stack traces in your catch blocks, in signal handlers, or anywhere in your program where you need to trace the execution path.

      +
      +
    6. +
    7. +

      Can I use Boost with a debugger like GDB or Visual Studio?

      +
      +

      Yes, Boost libraries can be used with common debuggers like GDB or Visual Studio. You can set breakpoints in your code, inspect variables, and execute code step by step. Boost doesn’t interfere with these debugging tools.

      +
      +
    8. +
    9. +

      Are there any debugging tools specifically provided by Boost?

      +
      +

      Boost doesn’t provide a debugger itself. The libraries tend to make heavy use of assertions to catch programming errors, and they often provide clear and detailed error messages when something goes wrong.

      +
      +
    10. +
    11. +

      What are best practices when using Boost Asserts?

      +
      +

      Boost provides the assertion boost::assert. Best practices when using this are:

      +
      +
      +
        +
      • +

        Use Assertions for Debugging and Development: Boost assertions should primarily be used during the debugging and development phase of your application. Assertions are designed to catch programming errors, not user errors.

        +
      • +
      • +

        Assert Conditions That Should Never Occur: You should only assert conditions that you believe can never occur during normal operation of your application. If there’s a chance that a condition may occur, handle it as an exception or error rather than asserting.

        +
      • +
      • +

        Provide Meaningful Assert Messages: Boost assertions allow you to provide a message alongside your assertion. Use this feature to provide meaningful context about why an assertion failed.

        +
      • +
      • +

        Consider Performance Impact: Boost assertions can slow down your application. In performance-critical code, consider disabling them in the production version of your application.

        +
      • +
      +
      +
    12. +
    13. +

      What is the recommended approach to logging, using boost::log?

      +
      +
        +
      • +

        Use Severity Levels: Boost.Log supports severity levels, which you can use to categorize and filter your log messages. This can help you control the amount of log output and focus on what’s important.

        +
      • +
      • +

        Provide Context: Boost.Log allows you to attach arbitrary data to your log messages, such as thread IDs, timestamps, or file and line information. Use this feature to provide context that can help you understand the state of your application when the log message was generated.

        +
      • +
      • +

        Use Asynchronous Logging: If logging performance is a concern, consider using the asynchronous logging feature. This allows your application to continue executing while log messages are processed in a separate thread.

        +
      • +
      • +

        Format Your Log Output: Boost.Log supports customizable log formatting. Use this feature to ensure that your log output is easy to read and contains all the information you need.

        +
      • +
      • +

        Handle Log Rotation: If your application produces a lot of log output, consider setting up log rotation, which is supported. This ensures that your log files don’t grow indefinitely.

        +
      • +
      +
      +
    14. +
    +
    +
    +
    +
    +

    Dependencies

    +
    +
    +
      +
    1. +

      What is meant by a "dependency" and the phrase "dependency chain"?

      +
      +

      In the context of this FAQ, a dependency is any other library, Boost or Standard or third-party, that a Boost library requires. A primary dependency is a library the top-level library explicitly includes, a secondary dependency is a library that one of the primary, or other secondary dependency, includes.

      +
      +
      +

      Boost libraries are modular, but they can depend on each other for various functionalities - for example, Boost.Asio relies on Boost.System for error codes.

      +
      +
      +

      In general, taking dependencies can add a lot of value and reduce development time considerably. Boost libraries are carefully reviewed and tested to minimize dependency issues.

      +
      +
      +

      As often with powerful concepts, there are pitfalls. Dependencies can lead to "dependency chains," where including one library pulls in others that may not be needed by your project.

      +
      +
    2. +
    3. +

      What issues do library developers have to address when managing dependencies?

      +
      +

      This includes handling several awkward situations: Version Conflicts - when different dependencies require incompatible versions of the same library, Transitive Dependencies - when a library pulls in additional, indirect dependencies that you may not even realize are part of your project, Bloat - when the sheer number of dependencies makes the build or runtime environment large, slow, or error-prone, and Security Risks - when outdated or unnecessary dependencies introduce vulnerabilities.

      +
      +
      +

      In forum posts you might come across the following phrases, each describing a frustration with dependencies:

      +
      +
      +
        +
      • +

        "Dependency creep" - the gradual accumulation of dependencies over time, often unnecessarily.

        +
      • +
      • +

        "Library fatigue" - the exhaustion or frustration of constantly managing and keeping track of too many libraries.

        +
      • +
      • +

        "Transitive dependency nightmare" - specifically refers to the frustration caused by indirect dependencies that you don’t directly control.

        +
      • +
      • +

        "Package spaghetti" or "Dependency spaghetti" - a messy tangle of interconnected dependencies.

        +
      • +
      • +

        "Build chain chaos" - can refer to the difficulties in managing the build process when dependencies are involved.

        +
      • +
      +
      +
    4. +
    5. +

      What is meant by a "standalone" library?

      +
      +

      A standalone library is one where there are no dependencies (or, in reality, few), or the library depends only on the C++ Standard Library. Sometimes separate standalone versions of specific libraries are available, though they might be lightweight versions and not have parity of functionality with the non-standalone version.

      +
      +
    6. +
    7. +

      What can I do to minimize the number and impact of dependencies?

      +
      +

      A simple question but with a non-trivial answer. Consider working through this list of strategies and carefully applying when you can:

      +
      +
      +
        +
      1. +

        Avoid including headers that aren’t directly needed. When building Boost with B2, you can exclude certain parts of Boost to minimize dependencies. For example, use the --with-[library] flag to build only the libraries you need. Say you only want Boost.System and Boost.Filesystem, then enter: ./b2 --with-system --with-filesystem. This will install only these two libraries, and their essential dependencies. Refer to Building with CMake if you are using CMake as your build tool.

        +
      2. +
      3. +

        Read the library documentation to find macros that are available to remove unneeded functionality. For example, when using Boost.Asio, if support for timers or SSL are unneeded, then enter the statement: #define BOOST_ASIO_DISABLE_SSL. Refer to Customize Builds to Reduce Dependencies for many more examples.

        +
      4. +
      5. +

        For powerful libraries like Boost.Asio, you can include only the headers you need, such as <boost/asio/io_context.hpp> rather than its parent <boost/asio.hpp>.

        +
      6. +
      7. +

        Use forward declarations where possible instead of including full headers.

        +
      8. +
      9. +

        Use a C++ Standard Library alternative if one exists, and has equivalent functionality and performance. For example, Boost.Variant could be replaced with std::variant.

        +
      10. +
      11. +

        Use the Header-Only Mode (where possible). Many Boost libraries are header-only, meaning they don’t require linking against precompiled binaries or additional dependencies. Examples include Boost.Optional, Boost.Variant, and Boost.TypeTraits. For details of the binary requirements of Boost libraries refer to Required Compiled Binaries and Optional Compiled Binaries. For example, Boost.Asio has both header-only and compiled modes and you can configure it to work as header-only by defining the macro: #define BOOST_ASIO_SEPARATE_COMPILATION.

        +
      12. +
      13. +

        For experienced developers only, consider commenting out unused code. This approach is possible but risky because it modifies library source code (Boost libraries are open-source), making updates and maintenance more challenging. It involves first identifying the parts of the library that introduce unnecessary dependencies and then commenting out the sections of source code or headers that you don’t need (such as unused features, optional functionality, error handling code). Finally, rebuild the library and check it compiles and links and runs without unwanted side-effects.

        +
      14. +
      +
      +
    8. +
    9. +

      Are there any tools specific to Boost that help manage dependencies?

      +
      +

      Yes, the Boost Copy Tool (bcp) is designed to help with dependency management. It allows you to extract a subset of the libraries and their dependencies into a separate directory, minimizing what gets pulled into your project. Install the tool and run bcp [library-name] [output-dir]. Review the output directory to ensure that only the necessary dependencies are included. For example, if you’re using Boost.Regex, enter bcp regex ./boost_subset and review the contents of your ./boost_subset directory.

      +
      +
      +

      There is also the Boost Dependency Report, which goes into detail on the primary and secondary dependencies of all the libraries.

      +
      +
    10. +
    11. +

      Are there generally available tools that help with dependency issues?

      +
      +

      You can use static analysis tools, like Clang-Tidy or Cppcheck, to analyze your application and see which parts of any dependency are actually being used. Once identified, you can both remove unnecessary headers or dependencies, and perhaps rewrite portions of your code to avoid unnecessary functionality.

      +
      +
    12. +
    +
    +
    +
    +
    +

    Documentation

    +
    +
    +
      +
    1. +

      Who writes the documentation for a Boost library?

      +
      +

      The library authors are responsible for all the documentation specific to their library. The authors are clearly the most knowledgeable on the design decisions, architecture, API calls, inner workings, and potential limitations of their library. Contributor guidelines on documentation help maintain consistency in styling and content across the library collection. Refer to Documentation Guidelines.

      +
      +
    2. +
    3. +

      If I find an issue with the documentation, or would like to suggest an improvement, can I make a formal request?

      +
      +

      Yes you can, file an issue on the library. Typically library authors welcome feedback that enhances the useability of their work - refer to Reporting Issues.

      +
      +
    4. +
    5. +

      Has any Boost library documentation been translated into languages other than English?

      +
      +

      There is no formal localization of library documentation. However, translation efforts have existed at various times for Japanese, Chinese and Russian. Most current effort is into Japanese - refer to boostjp.

      +
      +
    6. +
    7. +

      If I wanted to translate my favorite library documentation into my native language, who do contact to get started?

      +
      +

      The copyright ownership of library documentation remains with the documentation authors. Contact the authors via the Boost Developers Mailing List if you are inspired to take on this task.

      +
      +
    8. +
    9. +

      Have there ever been efforts to localize not just the documentation but the API calls themselves?

      +
      +

      Not for the Boost libraries. Microsoft did experiment with localized API calls many years ago, though the project was abandoned as way too complicated, unmaintainable, and not particularly useful.

      +
      +
    10. +
    +
    +
    +
    +
    +

    Graphics and Games

    +
    +
    +
      +
    1. +

      If I wanted to use the Boost libraries in conjunction with a graphics library, to write a 3D game, what graphics library would be most compatible with Boost?

      +
      +

      The following libraries work well with Boost because they don’t impose custom build systems or incompatible runtime dependencies — they’re just C++ libraries, and that’s exactly Boost’s domain.

      +
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Graphics LibraryWhy It’s Compatible with BoostIdeal Boost Libraries to Pair

      Ogre3D

      Modular, C++03/11 compatible, uses STL-style containers and patterns similar to Boost

      Boost.Filesystem, Boost.SmartPtr, Boost.Signals2, Boost.Asio

      bgfx

      Minimal dependencies, works well with Boost threading and filesystem

      Boost.Thread, Boost.Lockfree, Boost.System

      Magnum

      Modern, header-only components, great for C+17 and fits Boost idioms

      Boost.Geometry, Boost.Math, Boost.Uuid

      IrrlichtBAW

      Easy to integrate with Boost for physics, networking, or file I/O

      Boost.Filesystem, Boost.Serialization, Boost.ProgramOptions

      Vulkan

      Boost helps manage complexity: asynchronous loading, configuration, math, logging

      Boost.Asio, Boost.Log, Boost.MultiArray, Boost.Gil

      +
    2. +
    3. +

      What would be the simplest solution to 3D graphics and Boost working in harmony?

      +
      +

      Probably the Ogre3D graphics library, working with Boost.Filesystem for asset control and Boost.Asio for networking.

      +
      +
    4. +
    5. +

      What games systems are well matched with Boost libraries?

      +
      +

      Here’s how Boost might slot into a 3D game engine:

      +
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      SystemBoost LibraryPurpose

      Asset Loading

      Boost.Filesystem, Boost.Iostreams

      Cross-platform file handling

      Entity Updates

      Boost.Signals2, Boost.Variant2

      Event-driven game logic

      Network Multiplayer

      Boost.Asio

      Async client/server or peer/peer communication

      Configuration

      Boost.ProgramOptions, Boost.PropertyTree

      Game settings, config files

      Logging

      Boost.Log, Boost.Stacktrace

      Diagnostics and crash reporting

      Physics or AI Math

      Boost.Numeric/ublas , Boost.Geometry, Boost.Random

      Physics, spatial logic

      Texture/Image Manipulation

      Boost.Gil

      Procedural textures, screenshots

      Multithreading

      Boost.Thread, Boost.Lockfree, Boost.Fiber

      Game loop or rendering pipeline parallelism

      +
    6. +
    7. +

      Are there any graphics libraries that are problematic when combined with Boost libraries?

      +
      +

      Both Qt and Unreal Engine are heavy frameworks that conflict with Boost’s philosophy - they replace parts of the STL and introduce their own type systems, both of which can cause serious compatibility issues. Also, DirectX libraries might limit your portability and don’t align well with Boost’s cross-platform goals.

      +
      +
    8. +
    +
    +
    +
    +
    +

    ISO C++ Committee Meetings

    +
    +
    +
      +
    1. +

      Who can attend ISO C++ Committee meetings?

      +
      +

      Members of PL22.16 (the INCITS/ANSI committee) or of JTC1/SC22/WG21 - The C++ Standards Committee - ISOCPP member country committee (the "national body" in ISO-speak), can attend the meetings. You can also attend as a guest, or join in remotely through email. For details and contact information refer to Meetings and Participation.

      +
      +
      +

      INCITS has broadened PL22.16 membership requirements so anyone can join, regardless of nationality or employer, though there is a fee. Refer to Apply for Membership.

      +
      +
      +

      It is recommended that any non-member who would like to attend should check in with the PL22.16 chair or head of their national delegation. Boosters who are active on the committee can help smooth the way, so consider contacting the Boost developers' mailing list providing details of your interests.

      +
      +
    2. +
    3. +

      When and where are the next meetings?

      +
      +

      There are three meetings a year. Two are usually in North America, and one is usually outside North America. See Upcoming Meetings. Detailed information about a particular meeting, including hotel information, is usually provided in a paper appearing in one of mailings for the prior meeting. If there isn’t a link to it on the Meetings web page, you will have to go to the committee’s C++ Standards Committee Papers page and search a bit.

      +
      +
    4. +
    5. +

      Is there a fee for attending meetings?

      +
      +

      No, but there can be a lot of incidental expenses like travel, lodging, and meals.

      +
      +
    6. +
    7. +

      What is the schedule?

      +
      +

      The meetings typically start at 9:00AM on Monday, and 8:30AM other days. It is best to arrive a half-hour early to grab a good seat, some coffee, tea, or donuts, and to say hello to people.

      +
      +
      +

      Until the next standard ships most meetings are running through Saturday, although some end on Friday. The last day, the meeting is generally over much earlier than on other days. Because the last day’s formal meeting is for formal votes only, it is primarily of interest only to actual committee members.

      +
      +
      +

      Sometimes there are evening technical sessions; the details aren’t usually available until the Monday morning meeting. There may be a reception one evening, and, yes, significant others are invited. Again, details usually become available Monday morning.

      +
      +
    8. +
    9. +

      What actually happens at the meetings?

      +
      +

      Monday morning an hour or two is spent in full committee on admin trivia, and then the committee breaks up into working groups (Core, Library, and Enhancements). The full committee also gets together later in the week to hear working group progress reports.

      +
      +
      +

      The working groups are where most technical activities take place. Each active issue that appears on an issues list is discussed, as are papers from the mailing. Most issues are non-controversial and disposed of in a few minutes. Technical discussions are often led by long-term committee members, often referring to past decisions or longstanding working group practice. Sometimes a controversy erupts. It takes first-time attendees awhile to understand the discussions and how decisions are actually made. The working group chairperson moderates.

      +
      +
      +

      Sometimes straw polls are taken. In a straw poll anyone attending can vote, in contrast to the formal votes taken by the full committee, where only voting members can vote.

      +
      +
      +

      Lunch break is an hour and a half. Informal subgroups often lunch together; a lot of technical problems are discussed or actually solved at lunch, or later at dinner. In many ways these discussions involving only a few people are the most interesting. Sometimes during the regular meetings, a working group chair will break off a sub-group to tackle a difficult problem.

      +
      +
    10. +
    11. +

      Do I have to stay at the venue hotel?

      +
      +

      No, and committee members on tight budgets often stay at other, cheaper, hotels. The venue hotels are usually chosen because they have large meeting rooms available, and thus tend to be pricey. The advantage of staying at the venue hotel is that it is then easier to participate in the off-line discussions, which can be at least as interesting as what actually happens in the scheduled meetings.

      +
      +
    12. +
    13. +

      What do people wear at meetings?

      +
      +

      Programmer casual. No neckties to be seen.

      +
      +
    14. +
    15. +

      What should I bring to a meeting?

      +
      +

      It is almost essential to have a laptop computer. There is a meeting wiki and there is internet connectivity. Wireless connectivity has become the norm.

      +
      +
    16. +
    17. +

      What should I do to prepare for a meeting?

      +
      +

      It is helpful to have downloaded the mailing or individual papers for the meeting, and to have read any papers you are interested in. Familiarize yourself with the issues lists. Decide which of the working groups you want to attend.

      +
      +
    18. +
    19. +

      What is a "Paper"?

      +
      +

      An electronic document containing issues, proposals, or anything else the committee is interested in. Very little gets discussed at a meeting, much less acted upon, unless it is presented in a paper. Papers are available to anyone. Papers don’t just appear randomly; they become available four (lately six) times a year, before and after each meeting. Committee members often refer to a paper by saying what mailing it was in, for example: "See the pre-Redmond mailing."

      +
      +
    20. +
    21. +

      What is a "Mailing"?

      +
      +

      A mailing is the set of papers prepared before and after each meeting, or between meetings. It is physically just a .zip or .gz archive of all the papers for a meeting. Although the mailing’s archive file itself is only available to committee members and technical experts, the contents (except copies of the standard) are available to all as individual papers. The ways of ISO are inscrutable.

      +
      +
    22. +
    23. +

      What is a "Reflector"?

      +
      +

      The committee’s mailing lists are called "reflectors". There are a number of them; "all", "core", "lib", and "ext" are the main ones. As a courtesy, Boost technical experts can be added to committee reflectors at the request of a committee member.

      +
      +
    24. +
    +
    +
    +
    +
    +

    Libraries

    +
    +
    +
      +
    1. +

      What are smart pointers in Boost?

      +
      +

      Smart pointers are a feature of C++ that Boost provides in its Boost.SmartPtr library. They are objects that manage the lifetime of other objects, automatically deleting the managed object when it is no longer needed. See the Smart Pointers section.

      +
      +
    2. +
    3. +

      Does Boost provide a testing framework?

      +
      +

      Yes, Boost.Test is the unit testing framework provided by Boost. It includes tools for creating test cases, test suites, and for handling expected and unexpected exceptions. Refer to Testing and Debugging.

      +
      +
    4. +
    5. +

      What is Boost.Asio?

      +
      +

      Boost.Asio is a library that provides support for asynchronous input/output (I/O), a programming concept that allows operations to be executed without blocking the execution of the rest of the program.

      +
      +
    6. +
    7. +

      What is Boost.MP11?

      +
      +

      Boost.Mp11 (MetaProgramming Library for C++11) is a Boost library designed to bring powerful metaprogramming capabilities to C++ programs. It includes a variety of templates that can be used to perform compile-time computations and manipulations. Refer to Metaprogramming.

      +
      +
    8. +
    9. +

      Does Boost provide a library for threading?

      +
      +

      Yes, Boost.Thread provides a C++ interface for creating and managing threads, as well as primitives for synchronization and inter-thread communication. In addition, Boost.Atomic provides atomic operations and memory ordering primitives for working with shared data in multi-threaded environments. Boost.Lockfree provides lock-free data structures and algorithms for concurrent programming, allowing multiple threads to access shared data concurrently without explicit synchronization using locks or mutexes. For a lighter approach to multi-threading, consider Boost.Fiber. Fibers offer a high-level threading abstraction that allows developers to write asynchronous, non-blocking code with minimal overhead compared to traditional kernel threads.

      +
      +
    10. +
    11. +

      What is the Boost Spirit library?

      +
      +

      Boost.Spirit is a library for building recursive-descent parsers directly in C++. It uses template metaprogramming techniques to generate parsing code at compile time. Refer to Metaprogramming.

      +
      +
    12. +
    13. +

      I like algorithms, can you pique my interest with some Boost libraries that support complex algorithms?

      +
      +

      Boost libraries offer a wide range of algorithmic and data structure support. Here are five libraries that you might find interesting:

      +
      +
      +
        +
      • +

        Boost.Graph: This library provides a way to represent and manipulate graphs. It includes algorithms for breadth-first search, depth-first search, Dijkstra’s shortest paths, Kruskal’s minimum spanning tree, and much more.

        +
      • +
      • +

        Boost.Geometry: This library includes algorithms and data structures for working with geometric objects. It includes support for spatial indexing, geometric algorithms (like area calculation, distance calculation, intersections, etc.), and data structures to represent points, polygons, and other geometric objects.

        +
      • +
      • +

        Boost.Multiprecision: If you need to perform computations with large or precise numbers, this library can help. It provides classes for arbitrary precision arithmetic, which can be much larger or more precise than the built-in types.

        +
      • +
      • +

        Boost.Compute: This library provides a C++ interface to multi-core CPU and GPGPU (General Purpose GPU) computing platforms based on OpenCL. It includes algorithms for sorting, searching, and other operations, as well as containers like vectors and deques.

        +
      • +
      • +

        Boost.Spirit: If you’re interested in parsing or generating text, this library includes powerful tools based on formal grammar rules. It’s great for building compilers, interpreters, or other tools that need to understand complex text formats.

        +
      • +
      +
      +
    14. +
    15. +

      I am tasked with building a real-time simulation of vehicles in C++. What Boost libraries might give me the performance I need for real-time work, and support a simulation?

      +
      +

      Refer to Real-Time Simulation.

      +
      +
    16. +
    +
    +
    +
    +
    +

    Licensing

    +
    +
    +
      +
    1. +

      What is the license for Boost libraries?

      +
      +

      Most Boost libraries are licensed under the The Boost Software License (BSL), a permissive free software license that allows you to use, modify, and distribute the software under minimal restrictions. It is not a requirement for a library to be licensed under the BSL, but its license must meet the License Requirements. Refer to the documentation or source code of any specific library to determine which license applies.

      +
      +
    2. +
    3. +

      Can I use the Boost Logo, after I have built software using the Boost libraries, to help promote my product?

      +
      +

      Only with written permission from The Fiscal Sponsorship Committee. For full details refer to Logo Policy and Media Guide.

      +
      +
    4. +
    +
    +
    +
    +
    +

    Metaprogramming

    +
    +
    +
      +
    1. +

      What is metaprogramming in the context of Boost C++?

      +
      +

      Metaprogramming is a technique of programming that involves generating and manipulating programs. In the context of Boost and C++, metaprogramming often refers to template metaprogramming, which uses templates to perform computations at compile-time.

      +
      +
    2. +
    3. +

      What is Boost.MP11?

      +
      +

      Boost.Mp11 is a Boost library designed for metaprogramming using C++11. It provides a set of templates and types for compile-time computations and manipulations, effectively extending the C++ template mechanism.

      +
      +
    4. +
    5. +

      What can I achieve with Boost.MP11?

      +
      +

      With Boost.Mp11, you can perform computations and logic at compile-time, thus reducing runtime overhead. For example, you can manipulate types, perform iterations, make decisions, and do other computations during the compilation phase.

      +
      +
    6. +
    7. +

      What is a typelist and how can I use it with Boost.MP11?

      +
      +

      A typelist is a compile-time container of types. It’s a fundamental concept in C++ template metaprogramming where operations are done at compile time rather than runtime, and types are manipulated in the same way that values are manipulated in regular programming.

      +
      +
      +

      In the context of the Boost.Mp11 library, a typelist is a template class that takes a variadic list of type parameters. Here’s an example:

      +
      +
      +
      +
      #include <boost/mp11/list.hpp>
      +
      +using my_typelist = boost::mp11::mp_list<int, float, double>;
      +
      +
      +
      +

      In this example, my_typelist is a typelist containing the types int, float, and double. Once you have a typelist, you can manipulate it using the metaprogramming functions provided by the library. For example:

      +
      +
      +
      +
      #include <boost/mp11/list.hpp>
      +#include <boost/mp11/algorithm.hpp>
      +
      +using my_typelist = boost::mp11::mp_list<int, float, double>;
      +
      +// Get the number of types in the list
      +constexpr std::size_t size = boost::mp11::mp_size<my_typelist>::value;
      +
      +// Check if a type is in the list
      +constexpr bool contains_double = boost::mp11::mp_contains<my_typelist, double>::value;
      +
      +// Add a type to the list
      +using extended_typelist = boost::mp11::mp_push_back<my_typelist, char>;
      +
      +// Get the second type in the list
      +using second_type = boost::mp11::mp_at_c<my_typelist, 1>;
      +
      +
      +
      +

      In these examples, mp_size is used to get the number of types in the list, mp_contains checks if a type is in the list, mp_push_back adds a type to the list, and mp_at_c retrieves a type at a specific index in the list. All these operations are done at compile time.

      +
      +
    8. +
    9. +

      What are some limitations or challenges of metaprogramming with Boost.MP11?

      +
      +

      Metaprogramming with Boost.Mp11 can lead to complex and difficult-to-understand code, especially for programmers unfamiliar with the technique. Compile errors can be particularly cryptic due to the way templates are processed. Additionally, heavy use of templates can lead to longer compile times.

      +
      +
      +

      Other challenges include lack of runtime flexibility, as decisions are made at compile time. And perhaps issues with portability can occur (say, between compilers) as metaprogramming pushes the boundaries of a computer language to its limits.

      +
      +
    10. +
    +
    +
    + + + + + +
    + + +Boost.Mp11 supersedes the earlier Boost.Mpl and Boost.Preprocessor libraries. +
    +
    +
    +
    +
    +

    Modular Boost

    +
    +
    +
      +
    1. +

      What is meant by "Modular Boost"?

      +
      +

      Technically, Modular Boost consists of the Boost super-project and separate projects for each individual library in Boost. In terms of Git, the Boost super-project treats the individual libraries as submodules. Currently (early 2024) when the Boost libraries are downloaded and installed, the build organization does not match the modular arrangement of the Git super-project. This is largely a legacy issue, and there are advantages to the build layout matching the super-project layout. This concept, and the effort behind it, is known as "Modular Boost".

      +
      +
      +

      Refer to the Super-Project Layout topic (in the Contributor Guide) for a full description of the super-project.

      +
      +
    2. +
    3. +

      Will a Modular Boost affect the thrice-yearly Boost Release?

      +
      +

      No. The collection of libraries is still a single release, and there are no plans to change the release cadence.

      +
      +
    4. +
    5. +

      Will this require that the current Boost source structure is changed?

      +
      +

      Yes. Unfortunately there is one restriction that adhering to a modular Boost requires - there can be no sub-libraries. That is, we can’t support having libraries in the root/libs/<group name>/<library> format. All libraries must be single libraries under the root/libs directory. There’s only a handful of libraries that currently do not conform to this already (notably the root/libs/numeric/<name> group of libraries).

      +
      +
    6. +
    7. +

      Why do we want a Modular Boost?

      +
      +

      It’s easier on everyone if we adopt a flat hierarchy. The user will experience a consistent process no matter which libraries they want to use. Similarly for contributors, the creation process will be consistent. Also, tools can be written that can parse and analyze libraries without an awkward range of exceptions. This includes tools written by Boost contributors. For example, the tools that are used to determine library dependencies. And any tool that a user might want to write for their own, or shared, use.

      +
      +
      +

      Other advantages of a modular format include:

      +
      +
      +
        +
      • +

        Users of Boost can now choose to include only the specific modules they need for their project, rather than downloading and building the entire Boost framework. This can significantly reduce the size of the codebase and dependencies in a project, leading to faster compilation times and reduced resource usage.

        +
      • +
      • +

        Individual modules can be updated and released on their own schedule, independent of the rest of the libraries. This allows for quicker updates and bug fixes to individual libraries without waiting for a full release.

        +
      • +
      • +

        The structure aligns well with package managers like Conan, vcpkg, or Bazel, making it easier to manage Boost libraries within larger projects. Users can specify exactly which Boost libraries they need, and the package manager handles the inclusion and versioning.

        +
      • +
      +
      +
    8. +
    9. +

      Will the proposed changes be backwards-compatible from the user’s perspective. In particular, the public header inclusion paths will still be <boost/numeric/<name>.hpp> rather than, say, <boost/numeric-conversion/<name>.hpp>, correct?

      +
      +

      Correct - backwards-compatibility should be maintained.

      +
      +
    10. +
    11. +

      When will Modular Boost be available to users?

      +
      +

      An exact timeline requires issues to be resolved, though later in 2024 is the current plan-of-record.

      +
      +
    12. +
    +
    +
    +
    +
    +

    Numbers

    +
    +
    +
      +
    1. +

      Are there any Boost libraries that extend floating point precision, and at what cost?

      +
      +

      In C++, the precision of float and double types is determined by the IEEE 754 standard for floating-point arithmetic, which is used by nearly all modern compilers and hardware. A float (with 24 significant bits) is accurate to about 6 or 7 decimal places, a double (53 significant bits) to 15 to 17 decimal digits. A long double (80+ significant bits) extends this to 18 to 21 decimal digits.

      +
      +
      +

      Boost does not replace these types, but extends your range of options using Boost.Multiprecision. There are the predefined types cpp_dec_float_50 and cpp_dec_float_100, and the unlimited type cpp_dec_float_<N>, where you decide the value of N. cpp_dec_float_50 would obviously give 50 digits, and cpp_dec_float_201 gives 201 digits. For example:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +#include <iostream>
      +
      +using namespace boost::multiprecision;
      +
      +int main() {
      +    cpp_dec_float_50 pi("3.14159265358979323846264338327950288419716939937510");
      +    auto result = pi * pi;
      +
      +    // Set the precision slightly higher than the number of digits
      +    std::cout << std::setprecision(51) << result << std::endl;
      +}
      +
      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +#include <iostream>
      +
      +// Let's define a type to take pi to 200 decimal places, 201 including the initial "3"
      +using cpp_dec_float_201 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<201> >;
      +
      +int main() {
      +
      +    cpp_dec_float_201 pi("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
      +        "8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196");
      +
      +    std::cout << std::setprecision(201) << pi << std::endl;
      +}
      +
      +
      +
      +

      Boost.Math adds high-quality special functions that integrate well with these types from Boost.Multiprecision. For example, boost::math::gamma, boost::math::exp, and boost::math::lgamma are available. Also, Boost.Qvm (quaternions, vectors, matrices) supports these custom precision types.

      +
      +
      +

      The cost as you can imagine is performance, the benefit is extreme accuracy. Under the hood, cpp_dec_float<N> stores N decimal digits of precision, using a base-10 representation, and uses an array of limbs to manage arbitrary-length mantissas.

      +
      +
    2. +
    3. +

      Is there a Boost library that can help me with numbers like infinity, or the imaginary number that is the square root of -1?

      +
      +

      Yes, there is support for infinity, NaN (Not a Number), and imaginary numbers through different libraries. Boost.Math includes constants and utilities for working with infinity and NaN, which are part of IEEE 754 floating-point standards.

      +
      +
      +
      +
      #include <boost/math/constants/constants.hpp>
      +#include <limits>
      +#include <iostream>
      +#include <cmath>
      +
      +int main() {
      +    double inf = std::numeric_limits<double>::infinity();
      +    double nan = std::numeric_limits<double>::quiet_NaN();
      +
      +    std::cout << "Infinity: " << inf << "\n";
      +    std::cout << "NaN: " << nan << "\n";
      +
      +    // Or to test for them:
      +    if (std::isinf(inf)) std::cout << "This is infinity!\n";
      +    if (std::isnan(nan)) std::cout << "This is NaN!\n";
      +
      +}
      +
      +
      +
      +

      The complex functions of Boost.Math support imaginary numbers, such as the square root of -1.

      +
      +
      +
      +
      #include <boost/math/complex.hpp>
      +#include <iostream>
      +
      +int main() {
      +    std::complex<double> i(0.0, 1.0);
      +    std::complex<double> result = std::sqrt(std::complex<double>(-1.0, 0.0));
      +
      +    std::cout << "sqrt(-1) = " << result << "\n"; // outputs (0,1)
      +}
      +
      +
      +
      +

      Boost.Multiprecision supports high-precision complex types, for example:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_dec_float.hpp>
      +#include <boost/multiprecision/cpp_complex.hpp>
      +
      +using namespace boost::multiprecision;
      +using complex50 = cpp_complex_50;
      +
      +int main() {
      +    complex50 c(0, 1);
      +    auto r = sqrt(complex50(-1, 0));
      +    std::cout << r << "\n";  // (0,1)
      +}
      +
      +
      +
    4. +
    5. +

      Can Boost.Multiprecision help calcuate a huge number of prime numbers?

      +
      +

      Use the type boost::multiprecision::cpp_int to safely store large prime numbers beyond the capacity of the standard int64_t, and the core algorithm known as the Sieve of Eratosthenes:

      +
      +
      +
      +
      #include <boost/multiprecision/cpp_int.hpp>
      +#include <iostream>
      +#include <vector>
      +#include <cmath>
      +#include <chrono>
      +
      +using boost::multiprecision::cpp_int;
      +
      +std::vector<cpp_int> generate_primes(size_t count) {
      +    // Rough upper bound for nth prime using approximation: n * log(n) * 1.2
      +    size_t estimate = static_cast<size_t>(count * std::log(count) * 1.2);
      +    std::vector<bool> is_prime(estimate + 1, true);
      +    std::vector<cpp_int> primes;
      +
      +    is_prime[0] = is_prime[1] = false;
      +
      +    for (size_t i = 2; i <= estimate && primes.size() < count; ++i) {
      +        if (is_prime[i]) {
      +            primes.emplace_back(i); // Store as cpp_int
      +            for (size_t j = i * 2; j <= estimate; j += i) {
      +                is_prime[j] = false;
      +            }
      +        }
      +    }
      +
      +    return primes;
      +}
      +
      +int main() {
      +    size_t prime_count = 100000; // adjust this to your needs (10 million may need 6+ GB of RAM)
      +
      +    auto start = std::chrono::high_resolution_clock::now();
      +    std::vector<cpp_int> primes = generate_primes(prime_count);
      +    auto end = std::chrono::high_resolution_clock::now();
      +
      +    std::chrono::duration<double> elapsed = end - start;
      +    std::cout << "Generated " << primes.size() << " primes.\n";
      +    std::cout << "Largest prime found: " << primes.back() << "\n";
      +    std::cout << "Time elapsed: " << elapsed.count() << " seconds.\n";
      +
      +    return 0;
      +}
      +
      +
      +
      +

      Running this code:

      +
      +
      +
      +
      Generated 100000 primes.
      +Largest prime found: 1299709
      +Time elapsed: 1.86556 seconds.
      +
      +
      +
      +
      +
      Note
      +
      +

      cpp_int is overkill for small primes, but essential if you’re working with large ones, such as 512-bit cryptographic primes.

      +
      +
      +
      +
    6. +
    7. +

      Am I right that Boost libraries do not improve on the performance of the standard floating point double?

      +
      +

      Correct. Use double if you can, and only use higher precision types when you’re accumulating billions of values and errors grow unbounded, or you need more than 17 digits of accuracy, or you’re solving numerically unstable equations, or you’re doing astronomy, cryptography, quantum physics, symbolic algebra, or working with scientific constants.

      +
      +
      +
      +
      Note
      +
      +

      A numerically unstable equation is one in which small changes or errors in input, or intermediate calculations, can lead to large errors in the final result due to the amplification of rounding or truncation errors in floating-point arithmetic. Numerical instability often arises when subtracting two nearly equal numbers (called catastrophic cancellation), dividing by very small numbers, performing many iterations where small errors accumulate, and poor choice of algorithm. A catastrophic cancellation might occur when subtracting 1.0000001 from 1.0000002 - precision and rounding errors might distort the result. Stable algorithms preserve significant digits and give reliable results even with floating-point limits.

      +
      +
      +
      +
    8. +
    9. +

      What scientific numbers, similar to pi, require precision beyond that provided by the standard double?

      +
      +

      Here is a table of the usual suspects:

      +
      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      ConstantTypical Digits NeededWhy double Isn’t Enough

      π (pi)

      50-100+

      Needed with extreme accuracy in orbital mechanics, quantum computing, etc.

      e (Euler’s number)

      30-100+

      Used in high-precision financial models, calculus, and exponential growth systems.

      γ (Euler-Mascheroni constant)

      50-100+

      Arises in analytic number theory and integrals.

      φ (Golden ratio)

      30+

      Used in precise design and algorithmic ratios.

      Planck’s constant (h)

      25-100

      Central to quantum mechanics; precise modeling demands high precision.

      Fine-structure constant (α)

      30-80

      Key in atomic physics and fundamental interactions.

      Avogadro’s number

      23+

      Often stored as a float, but high-accuracy simulations may demand higher precision.

      Speed of light (c)

      17+

      For ultra-precise relativistic calculations.

      Gravitational constant (G)

      20-100

      Known only to limited digits experimentally, but simulations may push precision.

      Riemann zeta constants

      30-200+

      Arise in number theory and string theory.

      Catalan’s constant

      50+

      Appears in combinatorics and integrals.

      Apéry’s constant

      50-200

      Arises in irrationality proofs and advanced analysis.

      +
      +
      +
      Note
      +
      +

      Precision can become an obsession. Pi has been computed to over 100 trillion digits, but NASA’s orbital calculations use only around the first 15 digits of pi (so a double would work!).

      +
      +
      +
      +
    10. +
    11. +

      To avoid floating point numbers altogether, I could use fractions. For example, storing a third as 1 over 3 avoids using 0.33333 ad infinitum. Is there a Boost library that would make sense of numbers stored only as integer fractions?

      +
      +

      Yes. Boost.Rational is a library designed specifically to represent and manipulate rational numbers — that is, numbers stored as fractions of two integers (such as, 1/3, 355/113).

      +
      +
      +

      It avoids floating-point approximation entirely, preserving mathematical exactness throughout arithmetic operations. The library automatically normalizes (reduces) fractions - so 3/6 would be reduced to 1/2. And it can interoperate with int, long, or even boost::multiprecision::cpp_int. For example:

      +
      +
      +
      +
      #include <boost/rational.hpp>
      +#include <iostream>
      +
      +int main() {
      +    boost::rational<int> a(1, 3);  // 1/3
      +    boost::rational<int> b(2, 5);  // 2/5
      +
      +    auto sum = a + b;              // 1/3 + 2/5 = 11/15
      +    auto product = a * b;          // 1/3 * 2/5 = 2/15
      +
      +    std::cout << "Sum: " << sum.numerator() << "/" << sum.denominator() << "\n";
      +    std::cout << "Product: " << product << "\n";  // prints as 2/15
      +
      +    // Comparison
      +    if (a < b)
      +        std::cout << "a is less than b\n";
      +}
      +
      +
      +
      +
      +
      Note
      +
      +

      Using rational numbers there is a risk of integer overflow, so consider using large integers for inputs (boost::multiprecision::cpp_int or similar), and this approach is not ideal for numbers known to be irrational (square root of 2, and the scientific constants listed above).

      +
      +
      +
      +
    12. +
    13. +

      Can I use Boost.Multiprecision or Boost.Math to help with my project on RSA public-key encryption?

      +
      +

      Yes. Starting with the basic algorithm for RSA (Rivest-Shamir-Adleman - the authors of the algorithm) which follows these steps:

      +
      +
      +
        +
      1. +

        Choose two large prime numbers p and q

        +
      2. +
      3. +

        Compute n = p * q

        +
      4. +
      5. +

        Compute Euler’s totient ϕ(n) = (p-1)(q-1)

        +
      6. +
      7. +

        Choose public exponent e such that 1 < e < ϕ(n) and gcd(e,ϕ(n)) = 1

        +
      8. +
      9. +

        Compute private exponent d such that e⋅d ≡ 1 mod ϕ(n)

        +
      10. +
      11. +

        Now you have: public-key = (e,n) and private-key = (d,n)

        +
        +

        We can now use cpp_int from Boost.Multiprecision to handle arbitrary-precision integers. And, if need be, you can use is_prime from Boost.Math for primality checks on larger randomly generated values (which you may want to add at a later date, using Boost.Random).

        +
        +
        +
        +
        #include <boost/multiprecision/cpp_int.hpp>
        +#include <boost/integer/common_factor_rt.hpp>
        +#include <iostream>
        +
        +using namespace boost::multiprecision;
        +
        +// Compute modular inverse of a modulo m using Extended Euclidean Algorithm
        +cpp_int modinv(cpp_int a, cpp_int m) {
        +    cpp_int m0 = m, t, q;
        +    cpp_int x0 = 0, x1 = 1;
        +
        +    while (a > 1) {
        +        q = a / m;
        +        t = m;
        +        m = a % m;
        +        a = t;
        +        t = x0;
        +        x0 = x1 - q * x0;
        +        x1 = t;
        +    }
        +
        +    return (x1 < 0) ? x1 + m0 : x1;
        +}
        +
        +int main() {
        +    // Small primes for demo
        +    cpp_int p = 61;
        +    cpp_int q = 53;
        +
        +    cpp_int n = p * q;                     // n = 3233
        +    cpp_int phi = (p - 1) * (q - 1);       // φ(n) = 3120
        +
        +    cpp_int e = 17; // Common public exponent
        +    cpp_int d = modinv(e, phi);            // Compute private key
        +
        +    // Display keys
        +    std::cout << "Public Key (e, n): (" << e << ", " << n << ")\n";
        +    std::cout << "Private Key (d, n): (" << d << ", " << n << ")\n";
        +
        +    // Create message
        +    cpp_int message = 65;
        +    std::cout << "Initial message: " << message << "\n";
        +
        +    // Encrypt message
        +    cpp_int encrypted = powm(message, e, n); // m^e mod n
        +    std::cout << "Encrypted message: " << encrypted << "\n";
        +
        +    // Decrypt message
        +    cpp_int decrypted = powm(encrypted, d, n); // c^d mod n
        +    std::cout << "Decrypted message: " << decrypted << "\n";
        +
        +    return 0;
        +}
        +
        +
        +
        +
        +
        Note
        +
        +

        Consider using independent_bits_engine from Boost.Random for a clean way to get large random integers of fixed bit-width, and then consider very large prime numbers of perhaps 1024 bits.

        +
        +
        +
        +
      12. +
      +
      +
    14. +
    15. +

      What does a 1024-bit prime number look like?

      +
      +

      Here is one:

      +
      +
      +
      +
      cpp_int prime = 165918700393058288029118516503856682928352034064210292320510526037152431960844672521054555721941412725769027652540094762345484278576411078143188748708281181119556988860248537167684663864334811189453410905241474311369868568296877192226227785240656833746573473244854528133231976802973699288063056142727481235873
      +
      +
      +
    16. +
    17. +

      I need efficient memory storage for a real-time simulation. The use case is small counts, for example the number of carrier task forces operating in one ocean at any one time - a number which will never exceed 10 let alone 256?

      +
      +

      A full sized int or even a byte is comically oversized for this use case. You could use the standard: std::uint8_t num_groups;, however you might like to add some range-safety. Consider the following code as it’s memory footprint is exacty 3 bytes:

      +
      +
      +
      +
      #include <cstdint>
      +#include <boost/endian/arithmetic.hpp>
      +#include <boost/numeric/conversion/cast.hpp>
      +
      +struct OceanStatus {
      +    boost::endian::little_uint8_t carrier_groups; // 1 byte on disk
      +    boost::endian::little_uint8_t submarine_groups;
      +    boost::endian::little_uint8_t air_wings;
      +
      +    void set_carrier_groups(int x) {
      +
      +        // Guarantee 0–10 range at runtime
      +        if (x < 0 || x > 10)
      +            throw std::out_of_range("carrier group count must be 0-10");
      +
      +        // Safe cast to uint8_t
      +        carrier_groups = boost::numeric_cast<std::uint8_t>(x);
      +    }
      +};
      +
      +
      +
    18. +
    19. +

      What library should I look at to help pack really small integers (say 2 to 4 bits each) into the minimum number of bytes possible?

      +
      +

      The libary to evaluate is Boost.DynamicBitset, it gives you stable bit indexing, easy clearing/writing slices, guaranteed predictable ordering, and portability across CPU architectures. In particular, check out the function to_block_range for exporting packed blocks. This should be easier - and safer - than hand-rolling your own masks and shifts.

      +
      +
    20. +
    +
    +
    +
    +
    +

    Other Languages

    +
    +
    +
      +
    1. +

      Have developers written applications in languages such as Python that have successfully used the Boost libraries?

      +
      +

      Yes, developers have successfully used Boost libraries in applications written in languages other than C++ by leveraging language interoperability features and creating bindings or wrappers.

      +
      +
      +

      The most notable example is the use of Boost.Python, a library specifically designed to enable seamless interoperability between C++ and Python. Boost.Python allows developers to expose C++ classes, functions, and objects to Python, enabling the use of the libraries from Python code. This has been used extensively in scientific computing, game development, and other fields where the performance of C++ is combined with the ease of Python.

      +
      +
    2. +
    3. +

      What real world applications have combined Python with the Boost libraries?

      +
      +

      Here are some examples:

      +
      +
      +
        +
      • +

        Blender is a widely-used open-source 3D creation suite. It supports the entirety of the 3D pipeline, including modeling, rigging, animation, simulation, rendering, compositing, and motion tracking. Blender uses Boost libraries for various purposes, including memory management, string manipulation, and other utility functions. Blender’s Python API, which allows users to script and automate tasks, integrates with C++ code using Boost.Python.

        +
      • +
      • +

        PyTorch is an open-source machine learning library based on the Torch library. It is used for applications such as natural language processing and computer vision. PyTorch uses several Boost libraries to handle low-level operations efficiently. Boost.Python is used to create bindings between C++ and Python, allowing PyTorch to provide a seamless interface for Python developers.

        +
      • +
      • +

        OpenCV (Open Source Computer Vision Library) is an open-source computer vision and machine learning software library. OpenCV’s Python bindings use Boost.Python to interface between the C++ core and Python. This allows Python developers to use OpenCV’s powerful C++ functions with Python syntax.

        +
      • +
      • +

        Enthought Canopy is a comprehensive Python analysis environment and distribution for scientific and analytic computing. It includes a Python distribution, an integrated development environment (IDE), and many additional tools and libraries.

        +
      • +
      +
      +
    4. +
    5. +

      Are there some solid examples of real world applications that have combined C# with the Boost libraries?

      +
      +

      Here are some great examples:

      +
      +
      +
        +
      • +

        In the world of game development, several projects use C++ for performance-critical components and C# for scripting and higher-level logic. The Boost libraries are often used in the C++ components, in particular to leverage their algorithms, and data structures. Unity allows the use of native plugins written in pass[C++]. These plugins can use Boost libraries for various functionalities, such as pathfinding algorithms or custom data structures, and then be called from C# scripts within Unity.

        +
      • +
      • +

        Financial applications often require high performance and reliability. They may use C++ for core processing and Boost libraries for tasks like date-time calculations, serialization, and multithreading. C# is used for GUI and integration with other enterprise systems. Trading platforms and risk management systems sometimes use Boost libraries for backend processing and interoperate with C# components for the user interface and data reporting.

        +
      • +
      • +

        Scientific computing applications that need high-performance computation often use C++ for core algorithms. C# is great for visualization, user interaction, and orchestration. Computational chemistry and physics applications sometimes use Boost for numerical computations and data handling, while C# provides the tools for managing simulations and visualizing results.

        +
      • +
      +
      +
    6. +
    7. +

      Can I see some sample code of how to wrap Boost functions to be available for use in a C# app?

      +
      +

      The following code shows how to create a wrapper for a C++ class that uses Boost, and then calls this class from a C# application. The handling of return values and exceptions are shown too. All the class does is convert a string to upper case.

      +
      +
      +

      The following code was written and tested using Visual Studio 2022, with Boost version 1.88. Visual Studio has been installed with tools to create both native C++ and .NET C# apps.

      +
      +
      +

      In Visual Studio, create a C++ Dynamic Link Library (DLL) project, MyDLL, and in the project properties make sure the Additional Include Directories has the path to your Boost include files, and Additional Library Directories has the path to your Boost lib files. Most importantly in the Configuration Properties/Advanced section, make sure the Common Language Runtime Support setting is .NET Framework Runtime Support (/clr). Delete the default dllmain.cpp file.

      +
      +
      +

      Create a header file, MyClass.h, and copy in the following code:

      +
      +
      +
      +
      #pragma once
      +#include <string>
      +
      +class MyClass {
      +public:
      +    std::string to_upper(const std::string& input);
      +};
      +
      +
      +
      +

      Create a second header file, MyClassWrapper.h, and copy in:

      +
      +
      +
      +
      #pragma once
      +
      +#include "MyClass.h"
      +
      +using namespace System;
      +
      +public ref class MyClassWrapper {
      +private:
      +    MyClass* instance;
      +
      +public:
      +    MyClassWrapper();
      +    ~MyClassWrapper();
      +    !MyClassWrapper();
      +
      +    String^ ToUpper(String^ input);
      +};
      +
      +
      +
      +

      Create a new source file, MyClass.cpp, and copy in:

      +
      +
      +
      +
      #include "pch.h"
      +#include "MyClass.h"
      +#include <boost/algorithm/string.hpp>
      +#include <stdexcept>
      +
      +std::string MyClass::to_upper(const std::string& input) {
      +    if (input.empty()) {
      +        throw std::runtime_error("Input string is empty");
      +    }
      +    return boost::to_upper_copy(input);
      +}
      +
      +
      +
      +

      We use Boost.Algorithm here, to show how to engage our libraries.

      +
      +
      +

      Next, create a second source file, MyClassWrapper.cpp, to expose the class to .NET:

      +
      +
      +
      +
      #include "pch.h"
      +#include "MyClassWrapper.h"
      +#include <msclr/marshal_cppstd.h>
      +#include <stdexcept>
      +
      +using namespace msclr::interop;
      +using namespace System::Runtime::InteropServices;
      +
      +MyClassWrapper::MyClassWrapper() {
      +    instance = new MyClass();
      +}
      +
      +MyClassWrapper::~MyClassWrapper() {
      +    this->!MyClassWrapper();
      +}
      +
      +MyClassWrapper::!MyClassWrapper() {
      +    delete instance;
      +}
      +
      +String^ MyClassWrapper::ToUpper(String^ input) {
      +    try {
      +        std::string nativeInput = marshal_as<std::string>(input);
      +        std::string result = instance->to_upper(nativeInput);
      +        return gcnew String(result.c_str());
      +    }
      +    catch (const std::exception& e) {
      +        throw gcnew ExternalException(gcnew String(e.what()));
      +    }
      +}
      +
      +
      +
      +

      Now, build your DLL, and hopefully it will build correctly. If it does, close that solution. Errors are usually because of missing components, rather than faulty code.

      +
      +
      +

      Now create the C# application that uses the wrapper. In Visual Studio, create a C# Console app, CppCsharp, noting that a .NET framework is part of the project, and overwrite the default with the following code.

      +
      +
      +
      +
      using System;
      +
      +class Program
      +{
      +    static void Main()
      +    {
      +        MyClassWrapper myClass = new MyClassWrapper();
      +
      +        try
      +        {
      +            string result = myClass.ToUpper("hello world");
      +            Console.WriteLine("Result: " + result);
      +
      +            // Test with an empty string to trigger the exception
      +            result = myClass.ToUpper("");
      +            Console.WriteLine("Result: " + result);
      +
      +        }
      +        catch (System.Runtime.InteropServices.ExternalException e)
      +        {
      +            Console.WriteLine("Caught an exception: " + e.Message);
      +        }
      +    }
      +}
      +
      +
      +
      +

      You will notice that the MyClassWrapper declaration is marked as erroneous.

      +
      +
      +

      In Visual Studio, in the Project menu, select Add Project Reference, and then use the Browse option to locate your MyDLL.dll. You should notice the error marks disappear.

      +
      +
      +

      Run the program, noting the initial string is converted to upper case, and the second call correctly returns the exception:

      +
      +
      +
      +
      Result: HELLO WORLD
      +Caught an exception: Input string is empty
      +
      +
      +
    8. +
    9. +

      Does the Java Native Interface (JNI) work with the Boost libraries?

      +
      +

      Through the use of the Java Native Interface (JNI) or Java Native Access (JNA), developers can call Boost libraries from Java applications. It involves creating native methods in Java that are implemented in C++ and using Boost libraries as part of those implementations.

      +
      +
      +
      +
      Note
      +
      +

      Similar techniques can be applied to other languages, such as R, Ruby, Perl, and Lua, using their respective foreign function interfaces (FFI) or binding libraries.

      +
      +
      +
      +
    10. +
    11. +

      What is the industry consensus for the expected remaining lifespan for C++, and does any other language look like it might become the replacement for it?

      +
      +

      The expected remaining lifespan of the C++ programming language is generally considered to be long, probably spanning several decades. While it’s difficult to assign a precise number of years, here’s an overview of the factors contributing to this consensus:

      +
      +
      +
        +
      • +

        C++ is deeply embedded in many critical systems, including operating systems, game engines, real-time systems, financial systems, and large-scale infrastructure projects. The massive amount of existing code ensures that the language will be relevant for a long time as maintaining, updating, and interacting with this codebase will remain necessary.

        +
      • +
      • +

        The Boost libraries and the C++ Standard place a strong emphasis on backward compatibility, which helps ensure that older code continues to work with new versions of the language.

        +
      • +
      • +

        The C++ language continues to evolve, with regular updates to the standard (for example, C++11, C++14, C++17, C++20, and C++23). These updates introduce new features and improvements that keep the language modern and competitive.

        +
      • +
      • +

        The C++ community, including the ISO C++ committee and Boost users, are highly active, ensuring that the language adapts to new programming paradigms, hardware architectures, and developer needs.

        +
      • +
      • +

        High Performance - C++ remains one of the go-to languages for applications where performance is critical, such as gaming, high-frequency trading, and embedded systems. Its ability to provide low-level memory and hardware control while still supporting high-level abstractions makes it difficult to replace.

        +
      • +
      • +

        For system-level programming and scenarios where fine-grained control over system resources is necessary, C++ is still unmatched.

        +
      • +
      • +

        C++ is still widely taught in universities, especially in courses related to systems programming, algorithms, and data structures. As a teaching language, it instills principles of memory management, performance optimization, and object-oriented programming, which are valuable across many programming domains.

        +
      • +
      • +

        C++ has a strong presence in specialized domains such as aerospace, robotics, telecommunications, and automotive software, where reliability, real-time performance, and low-level hardware access are critical. For example, some current EV manufacturers are using C++ and Unreal Engine to develop their in-car infotainment and control systems.

        +
      • +
      • +

        While newer languages may rise in popularity for certain use cases, no other language currently offers the same combination of performance, control, and ecosystem that C++ provides, making it unlikely to be replaced any time soon.

        +
        +

        Future technological shifts, such as advances in quantum computing or entirely new programming paradigms, could influence (increase or decrease) the lifespan of C++. However, given its adaptability and entrenched role in many industries, C++ is expected to evolve alongside these changes rather than be replaced by them.

        +
        +
      • +
      +
      +
    12. +
    13. +

      If I was to learn one other language, in addition to C++, what should it be to best prepare myself for an uncertain future?

      +
      +

      Python is often the top recommendation due to its versatility, simplicity, and wide application in growing fields like artificial intelligence (AI), machine learning (ML), rapid prototyping, and data science. And Boost.Python is there to help you integrate with the Boost libraries. Rust is another strong contender, especially if you are interested in systems programming and are looking for reliability and security. If you see the future as more cloud computing, then Go makes a strong case for itself. And let’s not forget that so much computing is now web based, so JavaScript deserves a mention here too. All of these languages offer valuable resources that complement C++ and prepare you for an uncertain future.

      +
      +
    14. +
    +
    +
    +
    +
    +

    Production and Debug Builds

    +
    +
    +
      +
    1. +

      What is the value of using BOOST_ASSERT or BOOST_STATIC_ASSERT over the Standard Library assert macros?

      +
      +

      There are a few advantages of using the Boost asserts, available in <boost/assert.hpp>, including that BOOST_ASSERT is fully customizable using BOOST_ENABLE_ASSERT_HANDLER, which can be used to log extra data or stack traces, and there is better integration with Boost.Test. BOOST_STATIC_ASSERT is best utilized when using older C++ standards (pre-C++17), or you are using deeply templated code. You might also prefer the Boost macros if you are engaging the features of other Boost libraries and are looking for consistent tooling. For a fuller discussion, refer to Boost Macros.

      +
      +
    2. +
    3. +

      For maximum performance, is it good practice to remove, or comment out, the `BOOST_ASSERT`s for the final production code, or do they simply not get compiled into anything so there is no performance cost for leaving them as is?

      +
      +

      By default, BOOST_ASSERT macros are completely removed from the compiled binary when NDEBUG is defined, just like the standard assert macro. If NDEBUG is not defined a BOOST_ASSERT(x) will expand, usually to an assertion_failed() if the assert condition fails. If NDEBUG is defined it expands to ((void)0) so nothing is generated. Boost does provide the BOOST_DISABLE_ASSERTS macro, which has the same effect on Boost asserts as NDEBUG - but will leave other asserts alone.

      +
      +
    4. +
    5. +

      What is usually considered to be best practices in handling assertions that fire with a production build?

      +
      +

      Instead of throwing an exception when an assert fails, it is often the best practice to log the failure. For example, here is a custom assert handler using the features of Boost.Log to record the event:

      +
      +
      +
      +
      #include <boost/assert.hpp>
      +#include <boost/log/trivial.hpp>
      +#include <boost/log/utility/setup/file.hpp>
      +#include <boost/log/utility/setup/console.hpp>
      +#include <boost/log/utility/setup/common_attributes.hpp>
      +#include <boost/log/expressions.hpp>
      +#include <sstream>
      +#include <cstdlib>
      +
      +namespace logging = boost::log;
      +
      +// Configure Boost.Log (call once at startup)
      +void init_logging() {
      +    logging::add_common_attributes();
      +
      +    // Console output
      +    logging::add_console_log(
      +        std::clog,
      +        logging::keywords::format = "[%TimeStamp%] [%Severity%] %Message%"
      +    );
      +
      +    // File output
      +    logging::add_file_log(
      +        logging::keywords::file_name = "assert_failures_%N.log",
      +        logging::keywords::rotation_size = 10 * 1024 * 1024, // 10 MB
      +        logging::keywords::format = "[%TimeStamp%] [%Severity%] %Message%"
      +    );
      +}
      +
      +// Custom handler for BOOST_ASSERT
      +namespace boost {
      +    void assertion_failed(char const* expr, char const* function, char const* file, long line) {
      +        std::ostringstream oss;
      +        oss << "BOOST_ASSERT failed!\n"
      +            << "  Expression: " << expr << "\n"
      +            << "  Function:   " << function << "\n"
      +            << "  File:       " << file << "\n"
      +            << "  Line:       " << line;
      +
      +        BOOST_LOG_TRIVIAL(error) << oss.str();
      +
      +        std::abort(); // Optional: comment out if soft fail is desired
      +    }
      +}
      +
      +
      +
      +

      An example use of this handler would be:

      +
      +
      +
      +
      #include <boost/assert.hpp>
      +#include <iostream>
      +
      +// Declare logging initializer
      +void init_logging();
      +
      +void test_logic(int value) {
      +    BOOST_ASSERT(value >= 0);
      +    std::cout << "Value is: " << value << std::endl;
      +}
      +
      +int main() {
      +    init_logging();
      +
      +    std::cout << "Testing BOOST_ASSERT with value = 42..." << std::endl;
      +    test_logic(42);
      +
      +    std::cout << "Testing BOOST_ASSERT with value = -1..." << std::endl;
      +    test_logic(-1); // Logs to file and console, then aborts
      +
      +    return 0;
      +}
      +
      +
      +
    6. +
    7. +

      What should I be aware of when moving from a Debug to a Production release?

      +
      +

      Use this checklist to ensure your application correctly integrates Boost libraries across Debug and Release configurations.

      +
      +
      +
        +
      • +

        Linking and Compatibility

        +
      • +
      • +

        Link with the correct Boost library variant (-gd for Debug, none for Release).

        +
      • +
      • +

        Ensure runtime settings (Debug CRT or Release CRT) match Boost binaries.

        +
      • +
      • +

        Avoid mixing Debug-built Boost libraries with Release-built applications.

        +
      • +
      • +

        Macro Definitions and Configuration

        +
      • +
      • +

        Define BOOST_DEBUG in Debug builds to enable extra runtime checks (if applicable).

        +
      • +
      • +

        Define BOOST_DISABLE_ASSERTS in Release builds to remove BOOST_ASSERT checks.

        +
      • +
      • +

        Optionally define BOOST_ENABLE_ASSERT_HANDLER to install custom assertion handlers.

        +
      • +
      • +

        Review conditional macros like BOOST_NO_EXCEPTIONS, BOOST_NO_RTTI, etc.

        +
      • +
      • +

        Assertions and Diagnostics

        +
      • +
      • +

        Use BOOST_ASSERT for critical development-time checks.

        +
      • +
      • +

        Consider diagnostic logging using BOOST_LOG_TRIVIAL.

        +
      • +
      • +

        Ensure failing assertions are tested and logged in Debug builds.

        +
      • +
      • +

        Debugging and Tooling

        +
      • +
      • +

        Run AddressSanitizer, Valgrind, or Visual Leak Detector in Debug builds. Refer to Contributor Guide: Sanitizers.

        +
      • +
      • +

        Confirm Boost.Pool, Boost.Container, and alloc-heavy libraries don’t leak memory.

        +
      • +
      • +

        Validate Boost.Thread, Boost.Asio, and Boost.Fiber components using thread sanitizers.

        +
      • +
      • +

        Performance Awareness

        +
      • +
      • +

        Avoid benchmarking with Debug builds — optimization is disabled.

        +
      • +
      • +

        Use Release builds to test compile times for Boost.Mp11, Boost.Spirit, and any heavy use of templates.

        +
      • +
      • +

        Validate any BOOST_FORCEINLINE or BOOST_NOINLINE effects in both builds.

        +
      • +
      • +

        Unit Testing

        +
      • +
      • +

        Run the full suite of unit tests in both Debug and Release.

        +
      • +
      • +

        Ensure no logic is only covered by Debug-only paths or assertions.

        +
      • +
      • +

        Use Boost.Test to validate results across optimization levels.

        +
      • +
      +
      +
    8. +
    9. +

      Typically, how should I set up a CMake file to handle Debug and Release builds?

      +
      +

      Here’s an example of how to set up your CMakeLists.txt to handle BOOST_ASSERT correctly by toggling behavior based on the build type (Debug or Release). The example includes linking with some sample libraries (Boost.Log, Boost.System and Boost.Thread):

      +
      +
      +
      +
      cmake_minimum_required(VERSION 3.10)
      +project(MyBoostApp)
      +
      +# Set your C++ standard
      +set(CMAKE_CXX_STANDARD 17)
      +set(CMAKE_CXX_STANDARD_REQUIRED ON)
      +
      +# Enable debug symbols for Debug mode
      +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
      +
      +# Link Boost (adjust components as needed)
      +find_package(Boost REQUIRED COMPONENTS log log_setup system thread)
      +
      +target_link_libraries(MyBoostApp PRIVATE
      +    Boost::log
      +    Boost::log_setup
      +    Boost::system
      +    Boost::thread
      +)
      +
      +add_executable(MyBoostApp main.cpp)
      +
      +target_include_directories(MyBoostApp PRIVATE ${Boost_INCLUDE_DIRS})
      +target_link_libraries(MyBoostApp PRIVATE ${Boost_LIBRARIES})
      +
      +# Enable BOOST_ASSERT in Debug, disable in Release
      +target_compile_definitions(MyBoostApp PRIVATE
      +    $<$<CONFIG:Debug>:BOOST_ENABLE_ASSERT_HANDLER>
      +    $<$<CONFIG:Release>:NDEBUG>
      +)
      +
      +# Optional: You can define a custom assert handler in debug builds
      +# by linking a file like the assert handler shown above that defines `boost::assertion_failed`
      +
      +
      +
    10. +
    +
    +
    +
    +
    +

    Reflection

    +
    +
    +
      +
    1. +

      Is there a native library or system that approximates the capabilities of .NET System.Reflection?

      +
      +

      Reflection in .NET is the ability of a program to inspect and manipulate its own structure and metadata at runtime. Think of reflection as a runtime mirror — it lets a program look at itself and act accordingly. Boost does not have a full runtime reflection system like .NET’s System.Reflection, but it does include several libraries and utilities that provide partial or compile-time reflection capabilities — the kind that are most practical and efficient in C++. The closest Boost comes to real reflection is encapsualted in Boost.Describe. This library allows you to describe the structure of a class — its members, base classes, and enums — at compile time, so you can iterate over them generically. Internally, Boost.Describe uses the features of Boost.Mp11.

      +
      +
      +

      Other libraries that you might find value in include Boost.Pfr (Precise Function Reflection), which lets you reflect on structure fields without macros or metadata, using clever template magic. For richer type information there is Boost.TypeIndex and Boost.CallableTraits, and for metaprogramming there is Boost.Mp11, Boost.Fusion, and Boost.Hana.

      +
      +
    2. +
    3. +

      Are there plans to extend Reflection further into Boost or the Standard C++ Library?

      +
      +

      The short answer is yes, into the Standard, but not yet. There are some niggling downsides to enabling full reflection, including slower than normal code, more difficult code maintenance and debugging, and string related issues (as string names are relied on). The standard work is known as the Reflection TS (Technical Specification).

      +
      +
    4. +
    5. +

      Can you show me example code demonstrating how to use Boost.Describe for Reflection?

      +
      +

      The following example shows how Boost.Describe and Boost.Mp11 work together to achieve something close to automatic runtime reflection:

      +
      +
      +
      +
      #include <boost/describe.hpp>
      +#include <boost/mp11.hpp>
      +#include <iostream>
      +
      +
      +// Describe a simple struct
      +struct User {
      +    int id;
      +    std::string name;
      +};
      +
      +// Generate reflection metadata
      +BOOST_DESCRIBE_STRUCT(User, (), (id, name))
      +
      +// Print fields using Boost.MP11 iteration
      +template <typename T>
      +void print_fields(const T& obj) {
      +    boost::mp11::mp_for_each<boost::describe::describe_members<T, boost::describe::mod_public>>(
      +        [&](auto D) {
      +            std::cout << D.name << " = " << obj.*D.pointer << "\n";
      +        });
      +}
      +
      +int main() {
      +    User u{ 42, "Ada" };
      +    print_fields(u);
      +}
      +
      +
      +
    6. +
    7. +

      Can you show me example code demonstrating how to use Boost.PFR for Reflection?

      +
      +

      Boost.Pfr provides the io function for automatic input/output stream operators (<< and >>) for aggregate types — meaning you can print or read structs directly without manually defining stream operators. It reflects all public fields of a type at compile time (without macros or boilerplate), producing readable output like {field1, field2, field3} automatically, for example:

      +
      +
      +
      +
      #include <boost/pfr.hpp>
      +#include <iostream>
      +
      +struct User {
      +    int id;
      +    std::string name;
      +    double balance;
      +};
      +
      +int main() {
      +    User u{ 42, "Alice", 100.5 };
      +
      +    std::cout << "As tuple: " << boost::pfr::io(u) << "\n";
      +}
      +
      +
      +
    8. +
    +
    +
    +
    +
    +

    Releases

    +
    +
    +
      +
    1. +

      How do I download the latest libraries?

      +
      +

      Go to Boost Downloads.

      +
      +
    2. +
    3. +

      What do the Boost version numbers mean?

      +
      +

      The scheme is x.y.z, where x is incremented only for massive changes, such as a reorganization of many libraries, y is incremented whenever a new library is added, and z is incremented for maintenance releases. y and z are reset to 0 if the value to the left changes

      +
      +
    4. +
    5. +

      Is there a formal relationship between Boost.org and the C++ Standards Committee?

      +
      +

      No, although there is a strong informal relationship in that many members of the committee participate in Boost, and the people who started Boost were all committee members.

      +
      +
    6. +
    7. +

      Will the Boost.org libraries become part of the next C++ Standard?

      +
      +

      Some might, but that is up to the standards committee. Committee members who also participate in Boost will definitely be proposing at least some Boost libraries for standardization. Libraries which are "existing practice" are most likely to be accepted by the C++ committee for future standardization. Having a library accepted by Boost is one way to establish existing practice.

      +
      +
    8. +
    9. +

      Is the Boost web site a commercial business?

      +
      +

      No. It is a non-profit.

      +
      +
    10. +
    11. +

      Why do Boost headers have a .hpp suffix rather than .h or none at all?

      +
      +

      File extensions communicate the "type" of the file, both to humans and to computer programs. The '.h' extension is used for C header files, and therefore communicates the wrong thing about C++ header files. Using no extension communicates nothing and forces inspection of file contents to determine type. Using .hpp unambiguously identifies it as C++ header file, and works well in practice.

      +
      +
    12. +
    13. +

      How do I contribute a library?

      +
      +

      Refer to the Contributor Guide. Note that shareware libraries, commercial libraries, or libraries requiring restrictive licensing are all not acceptable. Your library must be provided free, with full source code, and have an acceptable license. There are other ways of contributing too, providing feedback, testing, submitting suggestions for new features and bug fixes, for example. There are no fees for submitting a library.

      +
      +
    14. +
    +
    +
    +
    +
    +

    Safe C++

    +
    +
    +
      +
    1. +

      I use Boost Libraries in my current projects. What do I need to know about Safe C++?

      +
      +

      Retrofitting the C++ language with memory-safe constructs has proven to be daunting. The Safe C++ proposal for a memory-safe set of operations is currently in a state of indefinite hiatus. For more information, including current safe coding practices, refer to Contributors FAQ: Safe C++. For terminology - refer to Glossary: S.

      +
      +
    2. +
    +
    +
    +
    +
    +

    Smart Pointers

    +
    +
    +
      +
    1. +

      What different types of smart pointers are there?

      +
      +

      The Boost.SmartPtr library provides a set of smart pointers that helps in automatic and appropriate resource management. They are particularly useful for managing memory and provide a safer and more efficient way of handling dynamically allocated memory. The library provides the following types of smart pointers:

      +
      +
      +
        +
      • +

        boost::scoped_ptr: A simple smart pointer for sole ownership of single objects that must be deleted. It’s neither copyable nor movable. Deletion occurs automatically when the scoped_ptr goes out of scope.

        +
      • +
      • +

        boost::scoped_array: Similar to scoped_ptr, but for arrays instead of single objects. Deletion occurs automatically when the scoped_array goes out of scope.

        +
      • +
      • +

        boost::shared_ptr: A reference-counted smart pointer for single objects or arrays, which automatically deletes the object when the reference count reaches zero. Multiple shared_ptr can point to the same object, and the object is deleted when the last shared_ptr referencing it is destroyed.

        +
      • +
      • +

        boost::shared_array: Similar to shared_ptr, but for arrays instead of single objects.

        +
      • +
      • +

        boost::weak_ptr: A companion to shared_ptr that holds a non-owning ("weak") reference to an object that is managed by shared_ptr. It must be converted to shared_ptr in order to access the referenced object.

        +
      • +
      • +

        boost::intrusive_ptr: A smart pointer that uses intrusive reference counting. Intrusive reference counting relies on the object to maintain the reference count, rather than the smart pointer. This can provide performance benefits in certain situations, but it requires additional support from the referenced objects.

        +
      • +
      • +

        boost::enable_shared_from_this: Provides member function shared_from_this, which enables an object that’s already managed by a shared_ptr to safely generate more shared_ptr instances that all share ownership of the same object.

        +
      • +
      • +

        boost::unique_ptr: A smart pointer that retains exclusive ownership of an object through a pointer. It’s similar to std::unique_ptr in the C++ Standard Library.

        +
      • +
      +
      +
    2. +
    3. +

      Can you give me a brief coding overview of how to use smart pointers efficiently?

      +
      +

      There are several types of smart pointers with different characteristics and use cases, so use them appropriately according to your program’s requirements. Here are some common examples:

      +
      +
      +

      A shared_ptr is a reference-counting smart pointer, meaning it retains shared ownership of an object through a pointer. When the last shared_ptr to an object is destroyed, the pointed-to object is automatically deleted. For example:

      +
      +
      +
      +
      #include <boost/shared_ptr.hpp>
      +
      +void foo() {
      +    boost::shared_ptr<int> sp(new int(10));
      +    // Now 'sp' owns the 'int'.
      +    // When 'sp' is destroyed, the 'int' will be deleted.
      +}
      +
      +
      +
      +

      Note that shared_ptr objects can be copied, meaning ownership of the memory can be shared among multiple pointers. The memory will be freed when the last remaining shared_ptr is destroyed. For example:

      +
      +
      +
      +
      #include <boost/shared_ptr.hpp>
      +
      +void foo() {
      +    boost::shared_ptr<int> sp1(new int(10));
      +    // Now 'sp1' owns the 'int'.
      +    boost::shared_ptr<int> sp2 = sp1;
      +    // Now 'sp1' and 'sp2' both own the same 'int'.
      +    // The 'int' will not be deleted until both 'sp1' and 'sp2' are destroyed.
      +}
      +
      +
      +
      +

      A weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object managed by a shared_ptr. It must be converted to shared_ptr in order to access the object. For example:

      +
      +
      +
      +
      #include <boost/shared_ptr.hpp>
      +#include <boost/weak_ptr.hpp>
      +
      +void foo() {
      +    boost::shared_ptr<int> sp(new int(10));
      +    boost::weak_ptr<int> wp = sp;
      +    // 'wp' is a weak pointer to the 'int'.
      +    // If 'sp' is destroyed, 'wp' will be able to detect it.
      +}
      +
      +
      +
      +

      A unique_ptr is a smart pointer that retains exclusive ownership of an object through a pointer. It’s similar to std::unique_ptr in the C++ Standard Library. For example:

      +
      +
      +
      +
      #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
      +
      +void foo() {
      +    boost::movelib::unique_ptr<int> up(new int(10));
      +    // Now 'up' owns the 'int'.
      +    // When 'up' is destroyed, the 'int' will be deleted.
      +}
      +
      +
      +
    4. +
    +
    +
    +
    +
    +

    Standard Library

    +
    +
    +
      +
    1. +

      Where can I find the most complete documentation on the C++ Standard Library?

      +
      +

      Here, the C++ Standard Library. The Search feature is useful for locating individual components.

      +
      +
    2. +
    3. +

      How can I be sure when I should use a Boost library or a component of the Standard Library?

      +
      +

      Most Boost libraries provide useful and advanced functionality unavailable in the Standard Library. A few Boost libraries have indeed been superseded by the Standard Library, but remain in Boost for backwards compatibility. To determine which you should use, given the choice, consider working through the following process.

      +
      +
      +
      +
      Note
      +
      +

      When a Boost library is included in the Standard Library, not all of the functionality provided is necessarily standardized. For example, Boost.System has been standardized but still contains additional functionality not available in the standard. Although standardization might include all of the functionality of a Boost library, performance is not always identical and it can be of value to use the Boost version for higher performance (for example, Boost.Regex). In a few cases, the whole of the Boost library is standardized and the Boost version does not improve on performance (for example, Boost.Thread).

      +
      +
        +
      1. +

        Check the Boost library documentation, as their relationship to the Standard Library is sometimes documented. Both the Overview and the Release Notes are good sources of information for mentions of standardization.

        +
      2. +
      3. +

        The C++ Standard Library is also well documented. Check to see if the functionality you are looking for is now part of the standard. If you have specific features in mind, comparing the Boost and Standard library functions and classes should provide you with a definitive answer on which to use.

        +
      4. +
      5. +

        If you are less certain of the specific features you need, developers often discuss the status and relevance of Boost libraries in comparison to the standard. Browse, or ask a question in, Stack Overflow, Reddit, or the Boost Developers Mailing List.

        +
      6. +
      7. +

        If you want to dig into the source code, check the activity in the Boost library’s GitHub repository. Libraries that have been largely superseded have less recent activity compared to those still actively developed and extended. Also check Release Notes for mentions of deprecations or recommendations.

        +
      8. +
      9. +

        Current examples of libraries where you should now use the Standard Library include Boost.SmartPtr (use std::shared_ptr, std::unique_ptr etc.), Boost.Thread (use std::thread), Boost.Chrono (use std::chrono), and Boost.Random (use std::rand). Referring to the documentation for these might help show the language used when discussing the relationship with the Standard Library.

        +
      10. +
      +
      +
      +
      +
      +
    4. +
    5. +

      Are there any Boost libraries currently being considered for inclusion in the Standard Library?

      +
      +

      Yes, currently the functionality of two Boost libraries are being considered:

      +
      + +
    6. +
    7. +

      What is the current status of the Standard Library and when is the next release?

      +
      +

      C++ 2026 is slated as the next full release, for details refer to Current Status.

      +
      +
    8. +
    +
    +
    +
    +
    +

    Templates

    +
    +
    +
      +
    1. +

      What are C++ templates?

      +
      +

      C++ templates are a powerful feature of the language that allows for generic programming. They enable the creation of functions or classes that can operate on different data types without having to duplicate code.

      +
      +
    2. +
    3. +

      What are function templates in C++?

      +
      +

      Function templates are functions that can be used with any data type. You define them using the keyword template followed by the template parameters. Function templates allow you to create a single function that can operate on different data types.

      +
      +
    4. +
    5. +

      What is template specialization in C++?

      +
      +

      Template specialization is a feature of C++ templates that allows you to define a different implementation of a template for a specific type or set of types. It can be used with both class and function templates.

      +
      +
    6. +
    7. +

      What are the benefits and drawbacks of using templates in C++?

      +
      +

      The benefits of using templates include code reusability, type safety, and the ability to use generic programming paradigms. The drawbacks include potentially increased compile times, difficult-to-understand error messages, and complexities associated with template metaprogramming.

      +
      +
    8. +
    9. +

      How can I use templates to implement a generic sort function in C++?

      +
      +

      Here’s an example of how you might use a function template to implement a generic sort function, working with Boost.Range, so any type that is supported by this library can be sorted using the following function:

      +
      +
      +
      +
      #include <boost/range/iterator_range.hpp>
      +
      +// Bubble sort using Boost.Range-compatible interface
      +template<typename Range>
      +void bubble_sort_range(Range& r) {
      +    using std::begin;
      +    using std::end;
      +
      +    using Iterator = typename boost::range_iterator<Range>::type;
      +    using Category = typename std::iterator_traits<Iterator>::iterator_category;
      +
      +    // Enforce random access iterators at compile time
      +    BOOST_STATIC_ASSERT((std::is_base_of<std::random_access_iterator_tag, Category>::value));
      +
      +    Iterator first = boost::begin(r);
      +    Iterator last = boost::end(r);
      +
      +    if (first == last) return;
      +
      +    bool swapped = true;
      +    while (swapped) {
      +        swapped = false;
      +        for (Iterator it = first; it + 1 != last; ++it) {
      +            if (*(it + 1) < *it) {
      +                std::iter_swap(it, it + 1);
      +                swapped = true;
      +            }
      +        }
      +        --last;
      +    }
      +}
      +
      +// Usage example:
      +
      +#include <iostream>
      +#include <vector>
      +
      +int main() {
      +    std::vector<int> nums = { 9, 3, 7, 1, 4, 6, 12, 21, 14, 13, 11, 9, -1, -4 };
      +    bubble_sort_range(nums);
      +
      +    for (int n : nums)
      +        std::cout << n << " ";
      +    std::cout << "\n";
      +
      +    std::vector<std::string> names = { "charlie", "alice", "bob", "pete", "vanessa", "dave", "alexi"};
      +    bubble_sort_range(names);
      +
      +    for (const auto& name : names)
      +        std::cout << name << " ";
      +    std::cout << "\n";
      +}
      +
      +
      +
      +

      Running the example you should get the output:

      +
      +
      +
      +
      -4 -1 1 3 4 6 7 9 9 11 12 13 14 21
      +alexi alice bob charlie dave pete vanessa
      +
      +
      +
      +
      +
      Note
      +
      +

      This use of templates is given as an example only, the std::sort, std::stable_sort, and std::spreadsort are super efficient and should be used whenever possible. However, if you have a special process you would like to apply to different types of ranges, this templated approach may work well for you. For specialized sorts, refer to Boost.Sort.

      +
      +
      +
      +
    10. +
    +
    +
    +
    +
    +

    Types

    +
    +
    +
      +
    1. +

      The Boost Libraries have been criticized for using Boost-specific types, do all the libraries use Boost types or do some use standard integers, floats, and strings to name a few of the most-used types?

      +
      +

      This question comes up often when people start using Boost seriously. The short answer is "no", not all Boost libraries use Boost-specific types. In fact, many Boost libraries rely primarily on standard types such as int, double, std::string, and std::vector. Boost types generally appear only where they add functionality the standard library didn’t have at the time — or still doesn’t.

      +
      + +
      +

      A few libraries use minimal specific types, such as Boost.System, Boost.ProgramOptions.

      +
      +
      +

      The following libraries were introducted before Standard C++ introduced equivalents: Boost.Optional, Boost.Variant, Boost.Function, Boost.Any, Boost.Filesystem, Boost.SmartPtr.

      +
      +
      +

      In some libraries Boost-specfic types are needed for some issues like portability, allocator support, or async control. Such libraries inlude the popular Boost.Asio, and others including Boost.Coroutine2, Boost.Context, Boost.Lockfree.

      +
      +
      +

      For the libraries that require meta-types at compile time, these do require mostly Boost-specific types: Boost.Mp11, Boost.Hana, Boost.TypeIndex, Boost.StaticAssert.

      +
      +
    2. +
    3. +

      Can you give me some examples of types added to Boost libraries?

      +
      +

      In Boost.Asio the type boost::asio::context was added to support a low-level async framework, though does use standard-compatible I/O buffers. In Boost.System, boost::system::error_code was added to support location metadata not available in the standard. In Boost.Optional there is the type boost::optional<T>, which is now available in the standard library as std::optional - but was not available at the time Boost.Optional was released.

      +
      +
    4. +
    5. +

      If I am updating an older version of a codebase, but am not updating the C++ Standard used for that codebase, does it make sense to use Boost libraries?

      +
      +

      Boost libraries will provide you with some version independance. For example std::shared_ptr and std::optional are not available before the C++ 11 Standard, using Boost.SharedPtr and Boost.Optional should provide a robust approach to an update of older code.

      +
      +
    6. +
    7. +

      What are the issues with std::string that are addressed by Boost libraries such as Static-String, String-Algo, or String-View?

      +
      +

      The std::string is great for general-purpose English or programming string handling, but has limitations in several key areas: performance (it requires frequent heap allocations and copies), immutability/safety (it can be unintentionally modified or shared), internationization (foreign languages), and feature gaps (it lacks certain high-level string algorithms or fixed-capacity behavior).

      +
      +
      +

      For embedded systems, real-time applications, and performance-critical loops consider using Boost.StaticString as it provides a compile-time fixed-capacity string (boost::static_string<N>) that eliminates heap allocations.

      +
      +
      +

      For multi-language software and UTF-8 processing, consider using Boost.Locale for locale-aware comparisons, formatting, and conversions.

      +
      +
      +

      When working with configuration files, command-line tools, log or protocol parsing - or more advanced tasks such as data validation and pattern recognition - consider the Boost.StringAlgo, Boost.Regex, Boost.Xpressive, or Boost.LexicalCast libraries. These libraries offer hundreds of algorithms, views, conversions that will avoid the tedious task of reimplementing string utilities.

      +
      +
      +

      The Boost.StringView library has now been superceded by std::string_view, available from C++ 17.

      +
      +
    8. +
    9. +

      Can you show me example code where standard integers and Boost.Multiprecision code work well together?

      +
      +

      The following code shows automatic promotion (big_int += small_int), arbitrary precision (cpp_int grows as large as is needed), high-precision floating point (area = high_precision_pi * radius * radius), and interoperability (approx_area conversion):

      +
      +
      +
      +
      #include <iostream>
      +#include <boost/multiprecision/cpp_int.hpp>
      +#include <boost/multiprecision/cpp_dec_float.hpp>
      +
      +namespace mp = boost::multiprecision;
      +
      +int main() {
      +
      +    // --- 1. Standard integer and multiprecision integer ---
      +    std::int64_t small_int = 42;
      +    mp::cpp_int big_int = 1;
      +
      +    // Multiply big_int by a large factor
      +    for (int i = 0; i < 50; ++i)
      +        big_int *= 10; // No overflow — arbitrary precision!
      +
      +    // Add standard integer directly — implicit promotion works
      +    big_int += small_int;
      +
      +    std::cout << "Big integer (with 42 added): " << big_int << "\n\n";
      +
      +    // --- 2. Using multiprecision floats with standard numeric types ---
      +    mp::cpp_dec_float_50 high_precision_pi = 3.14159265358979323846264338327950288419716939937510;
      +    double radius = 2.5;
      +
      +    // You can mix standard and multiprecision floats seamlessly
      +    mp::cpp_dec_float_50 area = high_precision_pi * radius * radius;
      +
      +    std::cout << std::setprecision(40);
      +    std::cout << "Area of circle (high precision): " << area << "\n\n";
      +
      +    // --- 3. Conversion back to standard types ---
      +    // Note: Narrowing conversions can lose precision
      +    double approx_area = static_cast<double>(area);
      +    std::cout << "Area (as double): " << std::setprecision(16) << approx_area << "\n";
      +
      +    // --- 4. Interoperation example: sum of large values ---
      +    mp::cpp_int total = 0;
      +    for (std::int64_t i = 1; i <= 1'000'000; ++i)
      +        total += i; // summing using high-precision integer
      +
      +    std::cout << "\nSum of first 1,000,000 integers: " << total << "\n";
      +}
      +
      +
      +
      +

      Running this code should give you:

      +
      +
      +
      +
      Big integer (with 42 added): 100000000000000000000000000000000000000000000000042
      +
      +Area of circle (high precision): 19.63495408493620697498727167840115725994
      +
      +Area (as double): 19.63495408493621
      +
      +Sum of first 1,000,000 integers: 500000500000
      +
      +
      +
      +

      Boost.Multiprecision is designed to seamlessly extend the built-in numeric types, so you can mix std::int, std::uint64_t, double, and multiprecision types freely — the library’s operator overloads handle promotion automatically. Typically, in scientific computing (very large floating point numbers) cpp_dec_float_50 is combined with double, and for working with very large integers (say boundary values), combine cpp_int with std::int64_t or std::size_t.

      +
      +
    10. +
    11. +

      I am having trouble with a multi-platfrom project that requires strings in UTF-8 format, but with Windows APIs requiring UTF-16?

      +
      +

      You should conside using Boost.Nowide, a library that makes Windows Unicode handling sane! This library provides UTF-8 versions of fopen, std::cout, as well as file I/O and environmental variables. It also provides the crucial automatic conversion to UTF-16 when calling Windows APIs. You might also find Boost.Locale useful if internationalization is required, Boost.StaticString, and the small_vector type of Boost.Container for efficient short-string handling.

      +
      +
    12. +
    13. +

      Storage space is of the essence in the real-time app I am building, are there Boost libraries that can provide small integers, specifying 8 or 16 bits and no more storage than that is allocated?

      +
      +

      For byte level efficiency look at Boost.Endian, this library gives you precise control over both integer size and alignment. It also provides cross-platfrom compatibility, if that is important. For example, boost::endian::little_int8_t smallCount; will always be 8 bit. Boost.Multiprecision does provide for declaring small integers as low as 8 bits, but is not so memory efficient. If your goal is to save overall memory, not just per-number bytes, check out Boost.Container, as it supports small-vector optimization and no heap allocations.

      +
      +
    14. +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/generic-programming.html b/preview/user-guide/generic-programming.html new file mode 100644 index 0000000..dc382f0 --- /dev/null +++ b/preview/user-guide/generic-programming.html @@ -0,0 +1,662 @@ + + + + + + + + + + + + + + Generic Programming Techniques :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Generic Programming Techniques

    +
    +
    +
    +

    Generic programming is about generalizing software components so that they can be reused in a wide variety of situations. In C++, class and function templates are particularly effective mechanisms for generic programming because they make the generalization possible without sacrificing efficiency.

    +
    +
    +

    As a simple example of generic programming, we will look at how to generalize the memcpy() function of the C standard library. An implementation of memcpy() might look like the following:

    +
    +
    +
    +
    void* memcpy(void* region1, const void* region2, size_t n)
    +{
    +  const char* first = (const char*)region2;
    +  const char* last = ((const char*)region2) + n;
    +  char* result = (char*)region1;
    +  while (first != last)
    +    *result++ = *first++;
    +  return result;
    +}
    +
    +
    +
    +

    The memcpy() function is already generalized to some extent by the use of void* so that the function can be used to copy arrays of different kinds of data. But what if the data we would like to copy is not in an array? Perhaps it is in a linked list. Can we generalize the notion of copy to any sequence of elements? Looking at the body of memcpy(), the function’s minimal requirements are that it needs to traverse through the sequence using some sort of pointer, access elements pointed to, write the elements to the destination, and compare pointers to know when to stop. The C++ standard library groups requirements such as these into concepts, in this case the Input Iterator concept (for region2) and the Output Iterator concept (for region1).

    +
    +
    +

    If we rewrite memcpy() as a function template, and use the Input Iterator and Output Iterator concepts to describe the requirements on the template parameters, we can implement a highly reusable copy() function in the following way:

    +
    +
    +
    +
    template <typename InputIterator, typename OutputIterator>
    +OutputIterator
    +copy(InputIterator first, InputIterator last, OutputIterator result)
    +{
    +  while (first != last)
    +    *result++ = *first++;
    +  return result;
    +}
    +
    +
    +
    +

    Using the generic copy() function, we can now copy elements from any kind of sequence, including a linked list that exports iterators such as std::list.

    +
    +
    +
    +
    #include <list>
    +#include <vector>
    +#include <iostream>
    +
    +int main()
    +{
    +  const int N = 3;
    +  std::vector<int> region1(N);
    +  std::list<int> region2;
    +
    +  region2.push_back(1);
    +  region2.push_back(0);
    +  region2.push_back(3);
    +
    +  std::copy(region2.begin(), region2.end(), region1.begin());
    +
    +  for (int i = 0; i < N; ++i)
    +    std::cout << region1[i] << " ";
    +  std::cout << std::endl;
    +}
    +
    +
    +
    +
    +
    +

    Anatomy of a Concept

    +
    +
    +

    A concept is a set of requirements consisting of valid expressions, associated types, invariants, and complexity guarantees. A type that satisfies the requirements is said to model the concept. A concept can extend the requirements of another concept, which is called refinement.

    +
    +
    +
      +
    • +

      Valid Expressions are C++ expressions which must compile successfully for the objects involved in the expression to be considered models of the concept.

      +
    • +
    • +

      Associated Types are types that are related to the modeling type in that they participate in one or more of the valid expressions. Typically associated types can be accessed either through typedefs nested within a class definition for the modeling type, or they are accessed through a Traits class.

      +
    • +
    • +

      Invariants are run-time characteristics of the objects that must always be true, that is, the functions involving the objects must preserve these characteristics. The invariants often take the form of pre-conditions and post-conditions.

      +
    • +
    • +

      Complexity Guarantees are maximum limits on how long the execution of one of the valid expressions will take, or how much of various resources its computation will use.

      +
    • +
    +
    +
    +

    The concepts used in the C++ Standard Library are documented in the C++ reference Concepts library.

    +
    +
    +
    +
    +

    Traits

    +
    +
    +

    A traits class provides a way of associating information with a compile-time entity (a type, integral constant, or address). For example, the class template std::iterator_traits<T> looks something like this:

    +
    +
    +
    +
    template <class Iterator>
    +struct iterator_traits {
    +  typedef ... iterator_category;
    +  typedef ... value_type;
    +  typedef ... difference_type;
    +  typedef ... pointer;
    +  typedef ... reference;
    +};
    +
    +
    +
    +

    The value_type of the traits specifies the type of data that the iterator points to, in generic code, while the iterator_category can be used to select more efficient algorithms depending on the iterator’s capabilities.

    +
    +
    +

    A key feature of traits templates is that they’re non-intrusive: they allow us to associate information with arbitrary types, including built-in types and types defined in third-party libraries, Normally, traits are specified for a particular type by (partially) specializing the traits template.

    +
    +
    +

    For more details, refer to std::iterator_traits. Another very different expression of the traits idiom in the standard is std::numeric_limits<T> which provides constants describing the range and capabilities of numeric types.

    +
    +
    +
    +
    +

    Tag Dispatching

    +
    +
    +

    Tag dispatching is a way of using function overloading to dispatch based on properties of a type, and is often used hand in hand with traits classes. A good example of this synergy is the implementation of the std::advance function in the C++ Standard Library, which increments an iterator n times. Depending on the kind of iterator, there are different optimizations that can be applied in the implementation. If the iterator is random access (can jump forward and backward arbitrary distances), then the advance() function can simply be implemented with i += n, and is very efficient: constant time. Other iterators must be advanced in steps, making the operation linear in n. If the iterator is bidirectional, then it makes sense for n to be negative, so we must decide whether to increment or decrement the iterator.

    +
    +
    +

    The relation between tag dispatching and traits classes is that the property used for dispatching (in this case the iterator_category) is often accessed through a traits class. The main advance() function uses the iterator_traits class to get the iterator_category. It then makes a call to the overloaded advance_dispatch() function. The appropriate advance_dispatch() is selected by the compiler, based on whatever type the iterator_category resolves to, either input_iterator_tag, bidirectional_iterator_tag, or random_access_iterator_tag. A tag is simply a class whose only purpose is to convey some property for use in tag dispatching and similar techniques. Refer to cppreference: iterator_tags for more information.

    +
    +
    +
    +
    namespace std {
    +  struct input_iterator_tag { };
    +  struct bidirectional_iterator_tag { };
    +  struct random_access_iterator_tag { };
    +
    +  namespace detail {
    +    template <class InputIterator, class Distance>
    +    void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) {
    +      while (n--) ++i;
    +    }
    +
    +    template <class BidirectionalIterator, class Distance>
    +    void advance_dispatch(BidirectionalIterator& i, Distance n,
    +       bidirectional_iterator_tag) {
    +      if (n >= 0)
    +        while (n--) ++i;
    +      else
    +        while (n++) --i;
    +    }
    +
    +    template <class RandomAccessIterator, class Distance>
    +    void advance_dispatch(RandomAccessIterator& i, Distance n,
    +       random_access_iterator_tag) {
    +      i += n;
    +    }
    +  }
    +
    +  template <class InputIterator, class Distance>
    +  void advance(InputIterator& i, Distance n) {
    +    typename iterator_traits<InputIterator>::iterator_category category;
    +    detail::advance_dispatch(i, n, category);
    +  }
    +}
    +
    +
    +
    +
    +
    +

    Adaptors

    +
    +
    +

    An adaptor is a class template which builds on another type or types to provide a new interface or behavioral variant. Examples of standard adaptors are std::reverse_iterator, which adapts an iterator type by reversing its motion upon increment/decrement, and std::stack, which adapts a container to provide a simple stack interface.

    +
    +
    +

    A comprehensive review of the adaptors in the standard can be found in An overview of the standard template library.

    +
    +
    +
    +
    +

    Type Generators

    +
    +
    +
    +
    Note
    +
    +

    The type generator concept has largely been superseded by the more refined notion of a metafunction. Refer to Templates and the documentation for Boost.Mp11.

    +
    +
    +
    +
    +

    A type generator is a template whose only purpose is to synthesize a new type or types based on its template arguments. The generated type is usually expressed as a nested typedef named, appropriately type. A type generator is usually used to consolidate a complicated type expression into a simple one.

    +
    +
    +

    This example uses an old version of iterator_adaptor whose design didn’t allow derived iterator types. As a result, every adapted iterator had to be a specialization of iterator_adaptor itself and generators were a convenient way to produce those types.

    +
    +
    +
    +
    template <class Predicate, class Iterator,
    +    class Value = complicated default,
    +    class Reference = complicated default,
    +    class Pointer = complicated default,
    +    class Category = complicated default,
    +    class Distance = complicated default
    +         >
    +struct filter_iterator_generator {
    +    typedef iterator_adaptor<
    +
    +        Iterator,filter_iterator_policies<Predicate,Iterator>,
    +        Value,Reference,Pointer,Category,Distance> type;
    +};
    +
    +
    +
    +

    Now, that’s complicated, but producing an adapted filter iterator using the generator is much easier. You can usually just write:

    +
    +
    +
    +
    boost::filter_iterator_generator<my_predicate,my_base_iterator>::type
    +
    +
    +
    +
    +
    Note
    +
    +

    Type generators are sometimes viewed as a workaround for the lack of “templated typedefs” in C++.

    +
    +
    +
    +
    +
    +
    +

    Object Generators

    +
    +
    +

    An object generator is a function template whose only purpose is to construct a new object out of its arguments. Think of it as a kind of generic constructor. An object generator may be more useful than a plain constructor when the exact type to be generated is difficult or impossible to express and the result of the generator can be passed directly to a function rather than stored in a variable. Most Boost object generators are named with the prefix make_, after std::make_pair(const T&, const U&).

    +
    +
    +

    For example, given:

    +
    +
    +
    +
    struct widget {
    +  void tweak(int);
    +};
    +std::vector<widget *> widget_ptrs;
    +
    +
    +
    +

    By chaining two standard object generators, std::bind2nd and std::mem_fun, we can easily tweak all widgets:

    +
    +
    +
    +
    void tweak_all_widgets1(int arg)
    +{
    +   for_each(widget_ptrs.begin(), widget_ptrs.end(),
    +      bind2nd(std::mem_fun(&widget::tweak), arg));
    +}
    +
    +
    +
    +

    Without using object generators the example above would look like this:

    +
    +
    +
    +
    void tweak_all_widgets2(int arg)
    +{
    +   for_each(struct_ptrs.begin(), struct_ptrs.end(),
    +      std::binder2nd<std::mem_fun1_t<void, widget, int> >(
    +          std::mem_fun1_t<void, widget, int>(&widget::tweak), arg));
    +}
    +
    +
    +
    +

    As expressions get more complicated the need to reduce the verbosity of type specification gets more compelling.

    +
    +
    +
    +
    +

    Policy Classes

    +
    +
    +

    A policy class is a template parameter used to transmit behavior. An example from the standard library is std::allocator, which supplies memory management behaviors to standard containers.

    +
    +
    +

    Policy classes have been explored in detail by Andrei Alexandrescu in one chapter of his book, Modern C++ Design. He writes:

    +
    +
    +

    "In brief, policy-based class design fosters assembling a class with complex behavior out of many little classes (called policies), each of which takes care of only one behavioral or structural aspect. As the name suggests, a policy establishes an interface pertaining to a specific issue. You can implement policies in various ways as long as you respect the policy interface.

    +
    +
    +

    Because you can mix and match policies, you can achieve a combinatorial set of behaviors by using a small core of elementary components."

    +
    +
    +

    Andrei’s description of policy classes suggests that their power is derived from granularity and orthogonality. Less-granular policy interfaces have been shown to work well in practice, though. There is also precedent in the standard library: std::char_traits, despite its name, acts as a policies class that determines the behaviors of std::basic_string.

    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    This topic was originally written by David Abrahams, in 2001.

    +
    +
    +
    +
    +

    See Also

    +
    +
    +
      +
    • +

      Boost.Any : provides a type-safe container for storing values of any type and retrieved dynamically at runtime.

      +
    • +
    • +

      Boost.Variant : provides a type-safe container for representing a fixed set of alternative types, and accessed using type-safe visitor patterns.

      +
    • +
    • +

      Boost.Iterator : provides utilities for working with iterators and iterator ranges and includes iterator adaptors, iterator categories, and iterator concepts.

      +
    • +
    • +

      Boost.Fusion : provides a set of data structures and algorithms for working with heterogeneous sequences of elements in a generic and type-safe manner.

      +
    • +
    • +

      Boost.Mp11 : provides a modern metaprogramming framework.

      +
    • +
    • +

      Boost.TypeTraits : provides support for fundamental properties of types.

      +
    • +
    • +

      Frequently Asked Questions

      +
    • +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/getting-started.html b/preview/user-guide/getting-started.html new file mode 100644 index 0000000..d1d3766 --- /dev/null +++ b/preview/user-guide/getting-started.html @@ -0,0 +1,1747 @@ + + + + + + + + + + + + + + Getting Started :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Getting Started

    +
    +
    +
    +

    This section explains how to get your first Boost app running. +Here’s a step-by-step guide for installing from source.

    +
    +
    +
    +
    +

    Prerequisites

    +
    +
    +

    The only prerequisite for installing boost is a C++ compiler. +If you already have that set-up, please skip to the Binaries or From Source section.

    +
    +
    +

    If you don’t have access to a C++ compiler yet, here are a few ways to get started:

    +
    +
    +
    +
    +
      +
    • +

      Windows

      +
    • +
    • +

      Linux

      +
    • +
    • +

      macOS

      +
    • +
    +
    +
    +
    +

    Users on Windows usually get started with the Visual Studio compiler. +You can download the Microsoft Visual Studio 2022 (Community Edition) as the IDE and C++ compiler in these examples.

    +
    +
    +
    +
    +

    Users on Linux usually get started with GCC. +You can check if GCC is already installed with:

    +
    +
    +
    +
    g++ --version
    +
    +
    +
    +

    Otherwise, you need to install the necessary build tools and libraries. +For Ubuntu or Debian-based distributions, use the following commands:

    +
    +
    +
    +
    sudo apt update
    +sudo apt install build-essential python3 libbz2-dev libz-dev libicu-dev
    +
    +
    +
    +

    For Fedora systems, use the following commands:

    +
    +
    +
    +
    sudo dnf update
    +sudo dnf install gcc-c++ python3 bzip2-devel zlib-devel libicu-devel
    +
    +
    +
    +

    For Redhat-based systems (RHEL, CentOS Stream, etc.), use the following commands:

    +
    +
    +
    +
    sudo yum update
    +sudo yum install gcc-c++ python3 bzip2-devel zlib-devel libicu-devel
    +
    +
    +
    +

    For Arch-based systems (Arch Linux, Manjaro, etc.), use the following commands:

    +
    +
    +
    +
    sudo pacman -Syu
    +sudo pacman -S base-devel python3 bzip2 zlib icu
    +
    +
    +
    +
    +
    +

    Users on macOS usually get started with Clang. +You can check if Clang is already installed with:

    +
    +
    +
    +
    clang++ --version
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Binaries

    +
    +
    +

    Installing Boost with a package manager might simplify the process and ensure that all dependencies are installed correctly. +In this guide, we will discuss two types of package managers: C++ Package Managers package managers such as Conan and Vcpkg, and System Package Managers, such as APT and Homebrew.

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

    While using a package manager can simplify the installation process, there are some potential downsides to consider, such as a lack of control over the installation process and potential version conflicts with other installed software. +We will discuss these in more detail in the sections below.

    +
    +
    +

    If you want to ensure you have the latest version Boost, see the instructions to build and install Boost from source.

    +
    +
    +
    +
    +

    C++ Package Managers

    +
    +

    C++ package managers are a popular choice for managing dependencies in C++ projects. +They provide a simple and consistent way to download, configure, and install libraries as a process that is replicable on various platforms.

    +
    +
    +
    +
    +
      +
    • +

      Vcpkg

      +
    • +
    • +

      Conan

      +
    • +
    +
    +
    +
    +

    To install Boost with Vcpkg, you can run a command like:

    +
    +
    +
    +
    vcpkg install boost
    +
    +
    +
    +

    or adding boost to your vcpkg.json manifest file:

    +
    +
    +
    +
    {
    +    "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
    +    "name": "my-application",
    +    "version": "0.15.2",
    +    "dependencies": [
    +        "boost"
    +    ]
    +}
    +
    +
    +
    +

    You can also install individual boost modules by providing their names as a suffix:

    +
    +
    +
    +
    vcpkg install boost-variant2 boost-describe
    +
    +
    +
    +

    or adding the modules to your vcpkg.json manifest file.

    +
    +
    +
    +
    {
    +    "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
    +    "name": "my-application",
    +    "version": "0.15.2",
    +    "dependencies": [
    +        "boost-variant2",
    +        "boost-describe"
    +    ]
    +}
    +
    +
    +
    +

    For most users, Vcpkg recommends Manifest mode. +Follow the instructions in the introduction guide to manifest files.

    +
    +
    +

    To consume the libraries transparently from CMake, one can use the Vcpkg toolchain with the CMAKE_TOOLCHAIN_FILE configuration option.

    +
    +
    +
    +
    +

    You can install Boost with Conan through the boost package.

    +
    +
    +
    +
    +
    +

    However, these installation methods are not officially supported, which means the packages are not regularly tested by Boost authors.

    +
    +
    +
    +

    System-Level Installation

    +
    +

    Depending on your operating system, you may have different package managers available. +For instance, on Debian-based Linux distributions, APT is a popular choice, while macOS users often use Homebrew, and Windows users may prefer Chocolatey. +Depending on your variant of Unix, you can use a package manager such as apt, dnf, yum, or pacman.

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

    While using a system package manager has its advantages, there are also some drawbacks to consider. +These include lack of control over the installation process, and the high likelihood of using outdated or unsupported versions of the Boost libraries, which may be several years old.

    +
    +
    +
    +
    +
    +
    +
      +
    • +

      Ubuntu

      +
    • +
    • +

      Fedora

      +
    • +
    • +

      CentOS

      +
    • +
    • +

      Arch

      +
    • +
    • +

      Homebrew

      +
    • +
    +
    +
    +
    +

    To install the Boost C++ libraries onto Debian-based systems (such as Debian, Ubuntu), you can use the package manager apt.

    +
    +
    +
    +
    # Update your package list
    +sudo apt update
    +# Install the Boost development libraries
    +sudo apt install libboost-all-dev
    +
    +
    +
    +
    +
    +

    To install the Boost C++ libraries on Fedora, you can use the package manager dnf.

    +
    +
    +
    +
    # Update your package list
    +sudo dnf update
    +# Install the Boost development libraries
    +sudo dnf install boost-devel
    +
    +
    +
    +

    The Boost libraries are usually available as pre-compiled packages in the official Fedora repositories.

    +
    +
    +
    +
    +

    To install the Boost C++ libraries on CentOS, you can use the package manager yum.

    +
    +
    +
    +
    Note
    +
    +

    If you are using CentOS 8 or later, you might need to enable the PowerTools repository to get the Boost development libraries:

    +
    +
    +
    +
    +
    +
    sudo yum config-manager --set-enabled powertools
    +
    +
    +
    +
    +
    # Update your package list
    +sudo yum update
    +# Install the Boost development libraries
    +sudo yum install boost-devel
    +
    +
    +
    +

    The Boost libraries are usually available as pre-compiled packages in the official CentOS repositories.

    +
    +
    +
    +
    +

    To install the Boost C++ libraries onto Arch-based systems (such as Arch Linux, Manjaro), you can use the package manager pacman.

    +
    +
    +
    +
    # Update your package list
    +sudo yum update
    +# Install the Boost development libraries
    +sudo pacman -S boost
    +
    +
    +
    +
    +
    +

    Homebrew is a package manager for macOS that allows users to easily install, manage, and update a wide range of software packages and libraries from the command line.

    +
    +
    +
    +
    # Update your package list
    +brew update
    +brew upgrade
    +# Install the Boost development libraries
    +brew install boost
    +
    +
    +
    +

    Homebrew will download and install the Boost libraries and their dependencies. +To verify that the Boost libraries are installed correctly, you can run the following command:

    +
    +
    +
    +
    brew list boost
    +
    +
    +
    +
    +
    +
    +

    Once the installation is complete, the Boost libraries will be installed on your system, typically in /usr. +To verify that the Boost libraries have been installed correctly, you can check the version number:

    +
    +
    +
    +
    cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION"
    +
    +
    +
    +

    This command should output the Boost version installed on your system.

    +
    +
    +
    +
    +
    +

    From Source

    +
    +
    +

    Download Boost

    +
    +
    +
    +
      + +
    • +

      CMake

      +
    • +
    +
    + +
    +
    +
      +
    1. +

      Navigate to https://github.com/boostorg/boost/releases and under Releases, download the Boost distribution. +For instance:

      +
      +
        +
      1. +

        Windows: boost-1_89_0.zip

        +
      2. +
      3. +

        Unix variants: boost-1_89_0.tar.bz2

        +
      4. +
      +
      +
    2. +
    3. +

      After the download has completed in your Downloads folder, right-click on the compressed file and extract it to a folder.

      +
    4. +
    +
    +
    + + + + + +
    + + +You don’t need to build Boost with CMake to be able to use Boost with CMake. +CMake integration will work fine even if you install Boost with B2. +
    +
    +
    +
    +
    +
    +

    Or you can streamline the whole process directly from the command line:

    +
    +
    +
    +
    +
      +
    • +

      Windows

      +
    • +
    • +

      Linux

      +
    • +
    • +

      macOS

      +
    • +
    • +

      Git

      +
    • +
    +
    +
    +
    +
    +
    curl https://archives.boost.io/release/1.89.0/source/boost_1_89_0.zip (1)
    +tar -xf boost_1_89_0.zip (2)
    +cd boost_1_89_0 (3)
    +
    +
    +
    + + + + + + + + + + + + + +
    1Download the boost distribution boost_1_89_0.zip
    2Extract the files into boost_1_89_0
    3Change the current working directory to boost_1_89_0 +
    +
    +
    Note
    +
    +

    These instructions assume you have Curl and Tar installed on your system, and your OS is Windows 10 or later.

    +
    +
    +
    +
    +
    +
    +
    +
    +
    wget https://archives.boost.io/release/1.89.0/source/boost_1_89_0.tar.bz2 (1)
    +tar xf boost_1_89_0.tar.bz2 (2)
    +cd boost_1_89_0 (3)
    +
    +
    +
    + + + + + + + + + + + + + +
    1Download the boost distribution boost_1_89_0.tar.bz2
    2Extract the files into boost_1_89_0
    3Change the current working directory to boost_1_89_0
    +
    +
    +
    +
    +
    +
    curl https://archives.boost.io/release/1.89.0/source/boost_1_89_0.tar.bz2 (1)
    +tar xf boost_1_89_0.tar.bz2 (2)
    +cd boost_1_89_0 (3)
    +
    +
    +
    + + + + + + + + + + + + + +
    1Download the boost distribution boost_1_89_0.tar.bz2
    2Extract the files into boost_1_89_0
    3Change the current working directory to boost_1_89_0
    +
    +
    +
    +
    +

    You can clone and initialize the complete Boost super-project directly from GitHub with:

    +
    +
    +
    +
    git clone https://github.com/boostorg/boost.git -b boost-1.89.0 boost_1_89_0 --depth 1 (1)
    +cd boost_1_89_0
    +git submodule update --depth 1 --init --recursive (2)
    +
    +
    +
    + + + + + + + + + +
    1Clone the Boost super-project
    2Initialize all boost modules
    +
    +
    +
    +
    +
    +
    +

    Individual Modules

    +
    +

    The process above downloads all boost libraries, which is the usual process in a local installation. +In projects where only a subset of the Boost libraries is required, which is usually desired in Continuous Integration Systems, the following procedure can be used:

    +
    +
    +
    Downloading Boost.Unordered and internal dependencies
    +
    +
    git clone https://github.com/boostorg/boost.git -b boost-1.89.0 boost_1_89_0 --depth 1 (1)
    +git submodule update --depth 1 -q --init tools/boostdep (2)
    +git submodule update --depth 1 -q --init libs/unordered (3)
    +python tools/boostdep/depinst/depinst.py -X test -g "--depth 1" unordered (4)
    +
    +
    +
    + + + + + + + + + + + + + + + + + +
    1Download the Boost super-project, which contains references to all Boost libraries
    2Initialize Boost.Boostdep used to determine internal boost dependencies
    3Initialize Boost.Unordered. +Repeat this step for any other modules you need.
    4Initialize any dependencies of Boost.Unordered. +Repeat this step for any other modules you need.
    +
    +
    +

    This procedure requires git and python. +The following steps in this document apply to both methods of installing Boost. +The only difference is what libraries will be available.

    +
    +
    +
    +

    Bootstrap

    +
    +

    If you followed the steps above, your current working directory should be boost_1_89_0. +Otherwise, open up a command line terminal, and navigate to the boost folder you extracted.

    +
    +
    +
    +
    +
      + +
    • +

      CMake

      +
    • +
    +
    + +
    +
    +

    You can also build the Boost libraries with CMake. +This is the usual procedure to build and install Boost with CMake:

    +
    +
    +
    +
    mkdir __build
    +cd __build
    +cmake ..
    +cmake --build .
    +cmake --build . --target install
    +
    +
    +
    +

    If you are using a multi-config generator, such as Visual Studio, you can install the Debug and Release variants of the library separately with:

    +
    +
    +
    +
    cmake --build . --target install --config Debug
    +cmake --build . --target install --config Release
    +
    +
    +
    +

    Although both the B2 and the CMake scripts work fine, the final installed libraries will have different layouts for historical reasons. +Both the CMake integration scripts and the libraries will be installed under different paths and this can create incompatibilities between Boost installations.

    +
    +
    + + + + + +
    + + +You don’t need to build Boost with CMake to be able to use Boost with CMake. +CMake integration will work fine even if you install Boost with B2. +
    +
    +
    +

    You can find more information about the limitations of a CMake infrastructure on boostorg/cmake

    +
    +
    +
    +
    +
    +
    +

    Environment variables

    +
    +

    We recommend you update your environment variables after installing Boost. +When you update your environment variables, you are telling your operating system and other tools where to look for the Boost libraries and headers.

    +
    +
    +
    +
    +
      +
    • +

      Windows

      +
    • +
    • +

      Linux

      +
    • +
    • +

      macOS

      +
    • +
    +
    +
    +
    +
    +
    set BOOST_ROOT=C:\boost (1)
    +
    +
    +
    + + + + + +
    1Specify the root directory of the Boost C++ libraries so other tools can find it
    +
    +
    + + + + + +
    + + +Replace C:\boost with the prefix directory you specified during the installation, if different. +
    +
    +
    +
    +
    +
    +
    export BOOST_ROOT=/usr/local (1)
    +export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH (2)
    +export CPLUS_INCLUDE_PATH=/usr/local/include:$CPLUS_INCLUDE_PATH (3)
    +
    +
    +
    + + + + + + + + + + + + + +
    1Specify the root directory of the Boost C++ libraries so other tools can find it
    2Specify additional directories to search for shared libraries when executing a program
    3Specify additional directories to search for C++ header files
    +
    +
    + + + + + +
    + + +Replace /usr/local with the prefix directory you specified during the installation, if different. +
    +
    +
    +

    You can add these export commands to your ~/.bashrc or ~/.profile file to make the changes permanent.

    +
    +
    +
    +
    +
    +
    export BOOST_ROOT=/usr/local (1)
    +
    +
    +
    + + + + + +
    1Specify the root directory of the Boost C++ libraries so other tools can find it
    +
    +
    + + + + + +
    + + +Replace /usr/local with the prefix directory you specified during the installation, if different. +
    +
    +
    +

    You can add these export commands to your ~/.bashrc or ~/.profile file to make the changes permanent.

    +
    +
    +
    +
    +
    +
    +
    +
    +

    Your First App

    +
    +
    +

    Header-only libraries

    +
    +

    Let’s start by using a header-only library. +Copy the following program into a file called example.cpp.

    +
    +
    +
    example.cpp
    +
    +
    // Include a header from the Boost.Lambda library
    +#include <boost/lambda/lambda.hpp>
    +#include <iostream>
    +#include <algorithm>
    +
    +int main()
    +{
    +    using namespace boost::lambda;
    +    typedef std::istream_iterator<int> in;
    +
    +    std::cout << "Enter numbers: ";
    +
    +    // Read a sequence of integers from standard input, use Boost.Lambda to multiply each number by three, then write it to the standard output
    +    std::for_each(
    +        in(std::cin), in(), std::cout << (_1 * 3) << " ");
    +}
    +
    +
    +
    +

    We can now compile this program:

    +
    +
    +
    +
    +
      +
    • +

      CMake

      +
    • +
    • +

      Visual Studio

      +
    • +
    • +

      By Hand

      +
    • +
    +
    +
    +
    +

    You can use CMake to configure a project to use Boost and your example.cpp. +Here’s an example CMakeLists.txt file that uses Boost:

    +
    +
    +
    CMakeLists.txt
    +
    +
    cmake_minimum_required(VERSION 3.8...3.31)
    +project(MyProject)
    +
    +find_package(Boost REQUIRED)
    +add_executable(MyProject example.cpp)
    +target_link_libraries(MyProject Boost::headers)
    +
    +
    +
    +

    Store this file next to your example.cpp and run the basic CMake workflow:

    +
    +
    +
    +
    mkdir build (1)
    +cd build (2)
    +cmake .. -D BOOST_ROOT=path/to/boost_1_89_0 (3)
    +cmake --build . (4)
    +
    +
    +
    + + + + + + + + + + + + + + + + + +
    1Create a build directory which should store the results
    2Change the current working directory to build
    3Run the CMake configure step, providing it with the Boost directory
    4Build the project
    +
    +
    +

    If using CMake >=3.13, this can be simplified to:

    +
    +
    +
    +
    cmake -S . -B build -D BOOST_ROOT=path/to/boost_1_89_0
    +cmake --build build
    +
    +
    +
    +

    In either case, the resulting executable should be available in the build directory.

    +
    +
    +
    +
    +
      +
    • +

      Open Visual Studio and select Create a new project

      +
    • +
    • +

      Choose Console App from the range of project templates.

      +
    • +
    • +

      Change the names in the Configure your new project dialog, or leave the defaults, and click Create.

      +
    • +
    • +

      Replace all the boilerplate content of the .cpp file with the contents of the example.cpp file, noting the inclusion of the header from Boost: lambda.hpp.

      +
    • +
    • +

      Right-click on the name of the project in the Solution Explorer pane, and select Properties.

      +
    • +
    • +

      Under C/C++ select General, then click on Additional Include Directories

      +
    • +
    • +

      Add the path to your Boost include folder, that will have been built in the previous section.

      +
    • +
    +
    +
    +
    +additional include directories +
    +
    +
    +
      +
    • +

      Next, still in the project properties, select Linker, then General, and locate the Additional Library Directories

      +
    • +
    • +

      Add the path to the Boost lib folder.

      +
    • +
    +
    +
    +
    +additional library directories +
    +
    +
    +
      +
    • +

      Click OK to accept your input.

      +
    • +
    +
    +
    +

    You can already run your example from Visual Studio:

    +
    +
    +
      +
    • +

      In the Debug menu, select Start Without Debugging, or press the F5 key.

      +
    • +
    • +

      A Command Prompt should open up, so enter a list of numbers separated by spaces, and then Enter.

      +
    • +
    • +

      You should get a line of numbers, your originals multiplied by 3.

      +
    • +
    +
    +
    +

    first app running

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

    Visual Studio provides support for CMake since Visual Studio 2017. CMake is a cross-platform build system that can generate build files for a variety of build tools, including Visual Studio solutions, makefiles, and ninja files. +By supporting CMake, Visual Studio is able to provide a consistent development experience across multiple platforms and build tools. +Additionally, the ability to generate CMake projects from Visual Studio allows developers to take advantage of Visual Studio’s debugging and profiling tools while still using their preferred build system.

    +
    +
    +

    While Visual Studio provides a user friendly environment for building software, it may not always be the best choice for managing complex projects with multiple dependencies. +In such cases, it is recommended to consider using CMake, a popular and flexible build system that can generate build files for a variety of build tools. +You can have the option of using CMake to manage your complex projects, while still using Visual Studio’s robust development and debugging features.

    +
    +
    +
    +
    +
    +
    +

    In the directory where you saved example.cpp, issue the following command:

    +
    +
    +

    Visual Studio Compiler:

    +
    +
    +
    +
    cl /I C:\boost\include example.cpp
    +
    +
    +
    +

    GCC:

    +
    +
    +
    +
    g++ -I /usr/local/include example.cpp -o example
    +
    +
    +
    +

    Clang:

    +
    +
    +
    +
    clang++ -I /usr/local/include example.cpp -o example
    +
    +
    +
    + + + + + +
    + + +Replace C:\boost or /usr/local with your Boost installation prefix if necessary. +
    +
    +
    + + + + + +
    + + +
    +

    It is generally not recommended to use these commands by hand for complex projects, as managing all the compile and link options can quickly become unwieldy. +Using a build system like CMake or Make can greatly simplify the process of building and managing a project, particularly when dealing with large codebases or dependencies.

    +
    +
    +

    Using a build system also has other advantages, such as easier dependency management, the ability to easily configure the build for different platforms or compilers, and the ability to easily integrate with other tools such as version control systems and automated testing frameworks.

    +
    +
    +
    +
    +
    +
    +
    +

    To test the result, run the executable from the path where it was built:

    +
    +
    +
    +
    +
      +
    • +

      Windows

      +
    • +
    • +

      Linux

      +
    • +
    • +

      macOS

      +
    • +
    +
    +
    +
    +
    +
    echo 1 2 3 | example
    +
    +
    +
    +
    +
    +
    +
    echo 1 2 3 | ./example
    +
    +
    +
    +
    +
    +
    +
    echo 1 2 3 | ./example
    +
    +
    +
    +
    +
    +
    +

    Did you get the expected result?

    +
    +
    +
    +

    Compiled Libraries

    +
    +

    In this section, we will locate an example from GitHub, and then build and run a project based on the example.

    +
    +
    +

    For most Boost libraries, there is an example sub-folder containing a range of examples. +For this guide, we will locate an example that reads a JSON file, and pretty-prints its contents.

    +
    +
    +

    Copy all the code from json/example/pretty.cpp into your example.cpp. +Let’s compile it:

    +
    +
    +
    +
    +
      +
    • +

      CMake

      +
    • +
    • +

      Visual Studio

      +
    • +
    • +

      By Hand

      +
    • +
    +
    +
    +
    +

    Edit the contents of CMakeLists.txt:

    +
    +
    +
    CMakeLists.txt
    +
    +
    cmake_minimum_required(VERSION 3.8...3.31)
    +project(MyProject)
    +
    +find_package(Boost REQUIRED COMPONENTS json)
    +add_executable(MyProject main.cpp)
    +target_link_libraries(MyProject Boost::json)
    +
    +
    +
    +

    In this example, we explicitly require json as Boost.Json is a compiled library. +Compiled libraries need to be explicitly required and linked separately.

    +
    +
    +

    Run the commands for the usual CMake workflow once more to build the executable.

    +
    +
    + + + + + +
    + + +Note how the difference between header-only and compiled libraries is transparent when using a build system. +
    +
    +
    +
    +
    +
      +
    1. +

      Create a new Visual Studio C++ Console App. +Name it JsonPrint.

      +
    2. +
    3. +

      Update both the additional include directories, and additional library directories, as you did for the previous section.

      +
    4. +
    5. +

      Copy all the code from https://github.com/boostorg/json/blob/develop/example/pretty.cpp, and use it to replace all the default content of the project’s cpp file.

      +
    6. +
    +
    +
    +

    You can already run your example from Visual Studio:

    +
    +
    +
      +
    1. +

      Search your computer for any JSON file, unless you have one you would like to use already. +Record the full path to that file.

      +
    2. +
    3. +

      In Visual Studio, locate and select Build Solution.

      +
    4. +
    +
    +
    +

    You should get neatly formatted output:

    +
    +
    +

    json example running

    +
    +
    +
      +
    • +

      If your JSON included symbols such as the umlaut, these will not be rendered correctly unless you change the format of your Command Prompt to UTF-8. By default, a Command Prompt supports a code page numbered 437. To change the code page to UTF-8, type chcp 65001.

      +
    • +
    • +

      If you get compile errors such as cannot open file 'libboost_json-vc143-mt-gd-x64-1_81.lib' you have probably not entered the Additional Library Directories correctly.

      +
    • +
    +
    +
    +
    +
    +

    Repeat the instructions to read the compile the executable:

    +
    +
    +

    In the directory where you saved example.cpp, issue the following command:

    +
    +
    +

    Visual Studio Compiler:

    +
    +
    +
    +
    cl /I C:\boost\include /link C:\boost\lib\libboost_json-vc71-mt-d-x86-1_34.lib example.cpp
    +
    +
    +
    +

    GCC:

    +
    +
    +
    +
    g++ -I /usr/local/include example.cpp -L /usr/local/libboost_json.a -o example
    +
    +
    +
    +

    Clang:

    +
    +
    +
    +
    clang++ -I /usr/local/include example.cpp -L /usr/local/lib -l boost_json -o example
    +
    +
    +
    + + + + + +
    + + +Replace C:\boost or /usr/local with your Boost installation prefix if necessary. +
    +
    +
    +

    As Boost.Json is a compiled library, we need the linker option in our example. +The name of the library file might vary according to your architecture and the options provided to b2 while installing boost. +Check the lib in your installation prefix.

    +
    +
    +
    +
    +
    +

    Search your computer for any JSON file, unless you have one you would like to use already. +Record the full path to that file and run the example with:

    +
    +
    +
    +
    +
      +
    • +

      Windows

      +
    • +
    • +

      Linux

      +
    • +
    • +

      macOS

      +
    • +
    +
    +
    +
    +
    +
    example "path/to/json/file.json"
    +
    +
    +
    +
    +
    +
    +
    ./example "path/to/json/file.json"
    +
    +
    +
    +
    +
    +
    +
    ./example "path/to/json/file.json"
    +
    +
    +
    +
    +
    +
    +

    Did you get the expected result?

    +
    +
    +
    +

    Summary

    +
    +

    Although the samples you have now built and run are quite simple, if you have got this far successfully, it means your build, installation and project linking are all working correctly. +Great job!

    +
    +
    +
    +

    Next Steps

    +
    +

    You might like to scan the examples folders of some of the other libraries that you are interested in, and create and run projects to get them running.

    +
    +
    +

    Once you are more experienced with Boost, you might like to build and install only those libraries you require. To this end, it can be helpful to know the dependencies that your target libraries have. This includes both primary dependencies (the libraries directly referenced by your target library) and secondary dependencies (the libraries not referenced by your target library, but referenced by the primary or other secondary libraries). To aid you in determining this information, refer to the Boost Dependency Report. This report is updated with each public release of Boost.

    +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/glossary.html b/preview/user-guide/glossary.html new file mode 100644 index 0000000..4fa311f --- /dev/null +++ b/preview/user-guide/glossary.html @@ -0,0 +1,1611 @@ + + + + + + + + + + + + + + Glossary :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Glossary

    +
    +
    +
    +

    You will find a myriad of jargon, acronyms and product or tool names used both in technical documentation and social media discussion of the Boost C++Libraries and C++ development in general. This section contains descriptions of the most common.

    +
    +
    +

    You will find well known acronyms such as DLL, URL and UUID in this list, because they also refer to Boost libraries of the same name.

    +
    +
    +

    Where terms apply specifically to one technology, such as Quantum Computing or Safe C++, many of the specific terms are only listed under the entry for that technology.

    +
    +
    +
    +
    +

    Contents

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

    A

    B

    C

    D

    E

    F

    G

    H

    I

    J

    K

    L

    M

    N

    O

    P

    Q

    R

    S

    T

    U

    V

    W

    X

    Y

    Z

    +
    +
    +
    +

    A

    +
    +
    +

    ABI : Application Binary Interface

    +
    +
    +

    Abseil : Abseil is a collection of C++ libraries, developed by Google (drawn from it’s codebase), and designed to be compatible with the C++ Standards.

    +
    +
    +

    ADL : Argument-Dependent Lookup

    +
    +
    +

    AFAICT : As Far As I Can Tell

    +
    +
    +

    AFAIK : As Far As I Know

    +
    +
    +

    Antora : An open-source documentation site generator built around AsciiDoc, designed for managing and publishing large, multi-repository documentation collections. It produces modular, versioned, and navigation-rich websites, making it especially popular for technical docs and developer portals.

    +
    +
    +

    AppVeyor : A cloud-based Continuous Integration (CI) and Continuous Delivery (CD) service. It’s similar to GitHub Actions, Travis CI, or CircleCI, but with some unique strengths, such as it is a hosted service so you don’t need to set up your own build servers, it has a Windows-first focus (originally designed to fill a gap when most CI services were Linux-only), and is great for testing MSVC builds, PowerShell scripts, and Windows installers. It does now also support Linux and macOS. It integrates well with GitHub and uses YAML configuration files.

    +
    +
    +

    ASIO : Asynchronous Input/Output - refer to Boost.Asio

    +
    +
    +

    AST : Abstract Syntax Tree - a data structure used in compilers to represent the structure of code in a hierarchical, tree-like form. It’s a crucial intermediate step in parsing code for tasks like analysis, compilation, and optimizations. See also, Multiple Dispatch.

    +
    +
    +

    ATM : At The Moment

    +
    +
    +
    +
    +

    B

    +
    +
    +

    BBK : Badly Broken Keyboard - describing terrible code or debugging issues

    +
    +
    +

    BFS : Breadth-First Search

    +
    +
    +

    Bikeshedding or BS : Focusing on trivial issues

    +
    +
    +

    Binding : The process of associating identifiers (like variables or functions) with values, types, or memory locations — can be static or dynamic. Static binding occurs at compile time (the compiler knows exactly which function to call). Dynamic binding happens at runtime — the decision about which function to call is deferred until the program runs (often using virtual tables ).

    +
    +
    +

    Bloom Filter : A space-efficient, fast, and probabilistic structure that can tell you if an item is definitely not in a database or is possibly in the database. For example, say you have a database of bad actors that is used to help prevent fraudulent access to a financial web app. A bloom filter can be used to tell if a new transaction definitely does not come from this set, so proceed normally, or possibly comes from this set in which case a deeper investigation into its validity (a full search of the bad actors) should be carried out. The following diagram shows the flow of control:

    +
    +
    +
    +Bloom filter +
    +
    +
    +

    Bloom filters are stealthy players in many performance-critical applications. They’re used in areas where fast lookups, limited memory, and tolerable false positive rates are acceptable. Blacklisted entity checks (fraud detection, compliance with sensitive data) is a top contender - other uses include:

    +
    +
    +
      +
    • +

      High-frequency trading, to track recent orders or trades to avoid duplicate processing.

      +
    • +
    • +

      In URL, File or Query caches, to reduce IO and memory overhead by quickly testing if a URL/File/Query has been visited (cached) already.

      +
    • +
    • +

      Database engines, to avoid unnecessary disk reads during key lookup - anything to avoid a full-text search.

      +
    • +
    • +

      Bioinformatics, to reduce the number of comparisons between huge DNA sequences.

      +
    • +
    +
    +
    +

    Databases used with bloom filters have the entries hashed (see Hash Functions ) before they are stored.

    +
    +
    +

    The Boost.Bloom library was released with Boost 1.89.0.

    +
    +
    +
    +
    Note
    +
    +

    The Bloom filter is named after its inventor, Burton Howard Bloom, who described its purpose in a 1970 paper - Space/Time Trade-offs in Hash Coding with Allowable Errors.

    +
    +
    +
    +
    +

    BOFH : B’d Operator From Hell - referring to a grumpy system admin

    +
    +
    +

    BOGOSITY : A measure of how bogus something is - typically bogus code or bogus logic

    +
    +
    +

    Brave : An open-source, Chromium-based browser. Brave is a fork of Chromium, which itself is mostly written in C++. The Blink rendering engine, V8 JavaScript engine, and much of the browser’s core (networking, storage, DOM, etc.) are implemented in C++.

    +
    +
    +

    BSOD : Black Screen of Doubt (usually slang, tongue-in-cheek) - developer hesitation to trust AI-generated code because of uncertainty about hidden bugs or security risks.

    +
    +
    +

    BTW : By The Way

    +
    +
    +

    BUGS : Bots Unleashing Garbage Software - used to describe the natural by-product of copy-pasting AI snippets.

    +
    +
    +
    +
    +

    C

    +
    +
    +

    CICD (CI/CD) : Continuous Integration and Continuous Deployment (or Delivery). CI refers to the practice of automatically integrating code changes into a shared repository, where each change is verified by automated builds and tests. CD extends this process to automatically deploy or deliver new code to production environments. Refer to Contributor Guide: Continuous Integration.

    +
    +
    +

    CHAOS : Code Helped Along, Obviously Shaky - AI suggestions that compile but crash spectacularly.

    +
    +
    +

    CML : Can mean CMake Language, Conversion Markup Language, Configuration Menu Language, Concurrent ML (a high-level language for concurrent programming) - depending on context.

    +
    +
    +

    CoT : Chain of Thought - a reasoning technique where an AI “thinks out loud,” useful for debugging or explaining coding decisions.

    +
    +
    +

    CppFront : a project created by Herb Sutter, which is a syntax experiment for C++. It’s designed as a front-end tool to make C++ more modern and easier to use by offering a simpler syntax that translates into standard C++ code. Essentially, it’s a transpiler for a modernized dialect of C++.

    +
    +
    +

    CRC : Cyclic Redundancy Code - refer to Boost.Crc

    +
    +
    +

    CRTP : Curiously Recurring Template Pattern

    +
    +
    +

    CSS : Cascading Style Sheet - defines the styles used in HTML web pages.

    +
    +
    +

    CUDA : CUDA originally stood for Compute Unified Device Architecture though is now generally used as a name for a parallel computing platform, language and API. For more information, refer to CUDA Toolkit.

    +
    +
    +

    CYA : Cover Your Automation (semi-sarcastic acronym) - a reminder that AI outputs must be validated, tests must run, and responsibility still falls on the human developer.

    +
    +
    +
    +
    +

    D

    +
    +
    +

    DDS : Data Distribution Service

    +
    +
    +

    DFL : Do not Fix Later - used sarcastically pointing out procrastination on fixing bugs

    +
    +
    +

    DFS : Depth-First Search

    +
    +
    +

    DLL : Dynamic Link Library - also refer to Boost.Dll

    +
    +
    +

    DOA : Deploy On Arrival when management insists the first draft goes live

    +
    +
    +

    DOCCA : A set of XSLT transformations that convert Doxygen XML extracted from Javadoc comments in C++ source code, into Boost.Quickbook output.

    +
    +
    +

    Drone : A continuous integration (CI) and delivery platform that automates the build, test, and deploy stages of a software pipeline. It is container-based and integrates with various version control systems, supporting multiple languages and environments - refer to Contributor Guide: Continuous Integration.

    +
    +
    +

    DRY : Don’t Repeat Yourself

    +
    +
    +
    +
    +

    E

    +
    +
    +

    ELF binary : refers to a file that follows the Executable and Linkable Format (ELF), which is a common standard file format for executables, object code, shared libraries, and core dumps on Unix-like operating systems such as Linux. ELF supports advanced features like dynamic linking, which is useful for shared libraries. Tools like gdb (the GNU Debugger) can use the debug symbols and information stored in ELF binaries to provide insights during debugging sessions.

    +
    +
    +

    EVP :

    +
    +
    +
      +
    • +

      Used in cryptography, particularly in OpenSSL, where EVP stands for Envelope. It is used to refer to high-level cryptographic functions in the OpenSSL library, such as encryption, hashing, and signing. C++ programs using OpenSSL for cryptographic operations might use the EVP APIs.

      +
    • +
    • +

      Enhanced Vector Processing : in high-performance computing contexts, EVP might refer to techniques that leverage vectorization or SIMD (Single Instruction, Multiple Data) for improving computational performance. It relates to libraries or frameworks that optimize algorithms using vectorized processing.

      +
    • +
    +
    +
    +

    EVP_MD_CTX : Envelope Message Digest Context - part of OpenSSL’s high-level cryptographic library and is used to manage the context for performing message digest (hashing) operations. The EVP API provides a high-level and flexible interface, allowing developers to use a consistent set of functions for various cryptographic algorithms without being tied to a specific implementation.

    +
    +
    +
    +
    +

    F

    +
    +
    +

    FAKE : Fabricated Algorithms, Knowledge, and Examples - when a developer or AI “cites” StackOverflow answers it made up.

    +
    +
    +

    FarmHash : Google developed FarmHash as a family of non-cryptographic hash functions, designed to be fast on modern CPUs (both 32-bit and 64-bit), deterministic (same input results in the same output), well-distributed (low collision rate for typical data), but non-cryptographic (not secure against intentional collisions, so it should not be used for passwords, signatures, or security tokens). Good for hash tables, checksums, data partitioning, bloom filters, or fingerprinting content where cryptographic security isn’t required. See Hash Functions.

    +
    +
    +

    FIFO : First In, First Out

    +
    +
    +

    FIM : Fill-in-the-Middle - a coding-specific AI technique where the model predicts the missing part of code between known “prefix” and “suffix.”

    +
    +
    +

    FOMO : Fear Of Missing Out

    +
    +
    +

    FOOBAR or FUBAR : Fed Up Beyond All Recognition

    +
    +
    +

    FPU : Floating Point Unit

    +
    +
    +

    FSM : Finite State Machine

    +
    +
    +

    FUD : Fear, Uncertainty, and Doubt

    +
    +
    +

    FWIW : For What It’s Worth

    +
    +
    +
    +
    +

    G

    +
    +
    +

    GCC : GNU Compiler Collection - a popular open-source compiler that supports C++, and it is frequently mentioned in discussions about toolchains, performance optimizations, and cross-platform development.

    +
    +
    +

    GDB : Often used as short for GNU Debugger, though can mean Graph Database.

    +
    +
    +

    Generative AI : A field of Artificial Intelligence (AI) that works by first breaking down known constructs (for example, text or images) into small reusable components. This might be tokens, subwords, or characters for textual input, or pixels, patches, or semantic elements (sky, tree, car, etc.) for an image. Then, using statistical models, patterns, or learned rules, generative AI assembles these atomic components into something new, ideally in novel and interesting ways, based on user input. Generative AI has borrowed many terms from everyday English, but repurposed them with specific technical meanings, for example:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermAI Meaning

    Attention

    A mechanism that lets models weigh the importance of different input parts dynamically.

    Beam Search

    A decoding algorithm that keeps top candidate sequences during generation.

    Bias

    Model parameters or training data patterns that skew outputs in certain directions.

    Gradient Clipping

    A technique used during training neural networks to prevent exploding gradients by limiting their size.

    Hallucination

    When a model confidently outputs false or fabricated information. For example, with the question "What is the capital of Mars" the model confidently responds "Obviously, Olympus Mons"!

    Latent Space

    A compressed, abstract representation of data in machine learning models, where relationships between data points can be more easily explored.

    Loss

    A numerical measure of how wrong a model’s predictions are during training.

    Overfitting

    When a model learns the training data too well, including the noise, and fails to generalize to new data.

    Prompt

    The input text given to a generative model to guide its response.

    Prompt Injection

    A security vulnerability where a user sneaks malicious or unintended instructions into an AI’s prompt, causing it to misbehave.

    Sampling

    Selecting outputs probabilistically from a distribution of next-token predictions.

    Temperature

    A parameter controlling randomness in output sampling: low = deterministic/boring, high = random/chaotic.

    Token

    A unit of text, like a word or subword, that a model processes.

    Token Embedding

    A numeric representation of words or subwords that captures their meaning and context, used as input to AI models.

    +
    +

    GH : Usually means GitHub.

    +
    +
    +

    GHA : Short for GitHub Actions.

    +
    +
    +

    GIL : Generic Image Library - Boost.Gil is a library designed for image processing, offering a flexible way to manipulate and process images.

    +
    +
    +

    Grapheme Cluster : The smallest unit of text that a user perceives as a single character, even though it may actually consist of multiple Unicode code points. This is important to represent languages like Hindi, Thai, Korean, Japanese, and others.

    +
    +
    +

    gRPC : A high-performance, open-source RPC (Remote Procedure Call) framework developed by Google that uses Protocol Buffers (protobuf) for defining service interfaces and message types. It enables efficient, strongly-typed communication between distributed systems over HTTP/2, supporting features like streaming, authentication, and load balancing. It is a competitor to a point of REST and OpenAPI.

    +
    +
    +
    +
    +

    H

    +
    +
    +

    Handlebars : Handlebars is a templating language used to generate text (HTML, JSON, config files, source code, etc.) by combining a template with data. +You write placeholders like {{name}} or conditionals like {{#if active}}, and the engine replaces them with values at runtime. The original Handlebars was a JavaScript project, though developers have found the C++ port useful for code generation, report and config file creation, embedding HTML or JSON templates, and web server frameworks that render dynamic pages.

    +
    +
    +

    The Handlebars concept works well with Boost.Json as it integrates easily with data-driven templates, Boost.PropertyTree to represent hierarchical data, Boost.Spirit to parse templates into an internal format, Boost.Filesystem to load and organize templates from disk, among many other use-cases. More advanced work might involve Boost.Beast to render dynamic web pages, Boost.Process to generate config files for subprocesses, and Boost.ProgramOptions to feed runtime configuration into templates.

    +
    +
    +

    Mustache is the lightweight, portable ancestor of Handlebars.

    +
    +
    +

    Hash Functions : A hash function takes a string and converts it into a number. Often used in fraud detection to store details such as: email addresses (normalized/lowered), credit card fingerprints (not full PANs as this might expose sensitive data, usually the last four digits or a tokenized version of the numbers), device IDs, IP and user-agent strings, phone numbers (E.164 format), and usernames / login handles. Once hashed, these numbers can be stored in a database and searched for patterns to create Bloom Filters (to detect fake accounts) as well as searched on a per-item basis. Commonly used hash algorithms include:

    +
    +
    +
      +
    • +

      MurmurHash3 / MurmurHash2, which is fast, multithreaded, but non-cryptographic. It has excellent avalanche properties (small input changes can lead to big output changes) and is used in many real-time systems due to speed and low collision rate. Redis Bloom, Apache Hadoop, and Apache Hive use it for sketch-based analytics.

      +
    • +
    • +

      CityHash / FarmHash, developed by Google and optimized for short strings and performance on modern CPUs. Useful for hashing things like IP addresses, usernames, or device IDs. FarmHash is a successor to CityHash with better SIMD support.

      +
    • +
    • +

      FNV-1a / Fowler-Noll-Vo, is super simple and fast, and often used when a lightweight, deterministic hash is needed. It is low-quality for cryptographic purposes, but fine for many Bloom Filters.

      +
    • +
    • +

      xxHash is an extremely fast, modern non-crypto hash function that is gaining popularity in streaming analytics and fraud pipelines. Great choice when you’re hashing millions of records per second.

      +
    • +
    • +

      SHA-512 / SHA-256 / SHA-3 are cryptographic hashes, developed by the NSA and published by NIST in 2001. SHA simply stands for Secure Hash Algorithm. They are slower than non-cryptographic hashes, but resilient to collisions and attacks. Often used in fraud systems when storing user personal information (emails, phone numbers) in a filter, and you need to protect against reverse-engineering the filter contents.

      +
    • +
    +
    +
    +

    The following shows an example of a string hashed with the SHA-256 algorithm:

    +
    +
    +
    +
    Email: fraudster@example.com
    +SHA-256 Hash: 0a89310b6c5fc95e6fcb53a19ad4d80d65cf63d1870076859ec79dc21d1c47f2
    +
    +
    +
    +

    Terms related to hashing include:

    +
    +
    +
      +
    • +

      Fingerprint - a combination of strings that are hashed as one - for example: +SHA-256(email + deviceID + timestamp).

      +
    • +
    • +

      PCI DSS Compliance - the Payment Card Industry Data Security Standard (PCI DSS) which strictly regulates the handling of credit card PANs.

      +
    • +
    • +

      Rainbow Tables - precomputed databases of common inputs and their hash values, used by attackers to quickly reverse hashes by looking up matches instead of computing them.

      +
    • +
    • +

      Salting - the process of adding a unique, random value to input data before hashing it, to prevent attackers from using precomputed hash tables (like rainbow tables) to reverse-engineer the original input.

      +
      +
      +
      Note
      +
      +

      For uses of hash functions in Boost libraries, refer to Boost.Hash2, and Boost.Bloom.

      +
      +
      +
      +
    • +
    +
    +
    +

    HCF : Halt and Catch Fire - a bug that crashes everything, usually exaggerated

    +
    +
    +

    HITL, HITR : Human in the loop or Human in the Review - referring to human engagement in an AI process

    +
    +
    +

    HOF : High-Order Functions - refer to Boost.Hof

    +
    +
    +

    HRT : High-Resolution Timer - a high-resolution timing mechanisms used in C++ for precise measurements of time, especially in performance profiling and real-time systems.

    +
    +
    +

    HSM : Hierarchical State Machine - used in designing state machines in software development, often in real-time systems or simulations.

    +
    +
    +
    +
    +

    I

    +
    +
    +

    ICE : In-Context Examples - supplying code snippets or project context so that an AI produces relevant suggestions instead of generic ones.

    +
    +
    +

    ICL : Interval Container Library - refer to Boost.Icl

    +
    +
    +

    ID10T : Idiot - pronounced "ID-ten-T" (user errors)

    +
    +
    +

    IDEs : Integrated Development Environments

    +
    +
    +

    IIUC : If I understand correctly

    +
    +
    +

    IIRC : If I remember correctly

    +
    +
    +

    IMO or IMHO : In My (Honest or Humble) Opinion

    +
    +
    +

    INCITS : The InterNational Committee for Information Technology Standards is the central U.S. forum dedicated to creating technology standards for the next generation of innovation.

    +
    +
    +

    IO : Input/Output - refer to Boost.Io

    +
    +
    +

    IOW : In Other Words

    +
    +
    +

    IR : Intermediate Representation - an internal representation of code or data.

    +
    +
    +

    IWBNI : It Would Be Nice If - a feature request is a dream

    +
    +
    +

    IWYU : include-what-you-use - a tool for use with Clang to analyze #includes in C and C++ source files.

    +
    +
    +
    +
    +

    J

    +
    +
    +

    Jamfile : A plain text configuration file that describes how to build a project using Boost.Build (B2). The file defines targets (executables, libraries, tests), specifies sources, include paths, compiler/linker options, and dependencies, and uses a high-level declarative syntax (not low-level Makefiles). The file is typically named Jamfile or Jamfile.v2.

    +
    +
    +

    Jinja or Jinga2 : Jinga is a popular Python text template engine. Jinga2C++ is a modern C++ implementation of Jinga.

    +
    +
    +

    JNI : Java Native Interface - a framework that allows C++ code to interact with Java code. JNI is relevant when integrating C++ components into Java applications, especially in cross-language development.

    +
    +
    +

    JIT : Just-In-Time (Compilation) - while JIT compilation is more commonly associated with languages like JavaScript or Java, it is occasionally discussed in the context of C++ when talking about optimization techniques, runtime compilation, or performance-critical applications. Some C++ libraries (e.g., LLVM) support JIT compilation features.

    +
    +
    +
    +
    +

    K

    +
    +
    +

    K8s : The Kubernetes container orchestration system

    +
    +
    +

    KDE : The K Desktop Environment (a Linux graphical environment)

    +
    +
    +

    KISS : Keep It Simple, Stupid

    +
    +
    +

    KPI : Key Performance Indicator

    +
    +
    +

    KVM : Kernel-based Virtual Machine

    +
    +
    +
    +
    +

    L

    +
    +
    +

    LEAF : Lightweight Error Augmentation Framework - refer to Boost.Leaf

    +
    +
    +

    LGTM : Looks Good To Me - often used in code reviews to signal approval

    +
    +
    +

    LIFO : Last In, First Out

    +
    +
    +

    LLVM : Initially this stood for Low Level Virtual Machine but is now no longer considered an acronym. LLVM is now the name for a set of compiler and toolchain technologies that support the development of a frontend for any programming language and a backend for any processor architecture. It is written in C++.

    +
    +
    +

    LOL : Laughing Out Loud or Lots of Logs

    +
    +
    +

    LOPS Lack Of Programmer Skill - used humorously when a problem is tricky to debug

    +
    +
    +

    LSP :

    +
    +
    +
      +
    • +

      Liskov Substitution Principle - states that objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program, ensuring that a subclass can stand in for its superclass without altering expected behavior.

      +
    • +
    • +

      Language Server Protocol - a standard protocol used for communication between code editors/IDEs (like VS Code) and programming language tools (like compilers or linters). It’s designed to enable features like autocomplete, go-to-definition, and refactoring.

      +
    • +
    +
    +
    +
    +
    +

    M

    +
    +
    +

    MDS :

    +
    +
    +
      +
    • +

      Meltdown Data Sampling : in the context of system security and CPU vulnerabilities, MDS refers to a family of side-channel attacks that target weaknesses in modern CPU architectures. These attacks can potentially leak sensitive data through speculative execution flaws, similar to vulnerabilities like Meltdown and Spectre.

      +
    • +
    • +

      Modular Design Structure : sometimes used to describe a software design methodology in which systems are broken down into modules, allowing for separation of concerns and better maintainability.

      +
    • +
    • +

      Multiple Data Streams : a more abstract term, refers to scenarios where an application handles multiple data streams simultaneously, possibly in a parallel or distributed environment.

      +
    • +
    +
    +
    +

    MFW : My Face When - used humorously or sarcastically depending heavily on the accompanying context or image.

    +
    +
    +

    MIR, MLIR : Mid-level Intermediate Representation - an intermediate form of code that is generated by the compiler during the compilation process, designed to be easier for the compiler to analyze and optimize. In particular, this mid-level code aids with Borrow Checking, incremental compilation and ensuring safety (type, memory, etc.) issue.

    +
    +
    +

    MOC : In the context of Qt and C++, this refers to the Meta-Object Compiler - a tool that processes Qt’s extensions to C++, such as signals and slots (a mechanism for event-driven programming) and other meta-object features (like introspection and dynamic properties). The MOC generates additional C++ code that enables these features to work seamlessly.

    +
    +
    +

    Molecular Modeling : the process of simulating the behavior of atoms and molecules. This domain is packed with terms that sound totally ordinary (or even friendly) but mean something extremely technical, counter-intuitive, or unintentionally hilarious once you know the truth:

    +
    +
    +
      +
    • +

      Coarse Graining : Replacing groups of atoms with fake blobs to survive computationally, or "Physics was too expensive so we squinted".

      +
    • +
    • +

      Docking : Guessing how two molecules might awkwardly stick together. Cynically, "We tried 10 million wrong poses and picked the least bad one".

      +
    • +
    • +

      Energy Minimization : Nudging atoms until the molecule stops screaming numerically.

      +
    • +
    • +

      Force Field : A big pile of equations pretending to be physics.

      +
    • +
    • +

      Free Energy : A brutally hard quantity requiring weeks of simulation and graduate student suffering.

      +
    • +
    • +

      MD : Molecular Dynamics, or running Newton’s laws on millions of atoms for weeks to watch them jiggle.

      +
    • +
    • +

      RMSD : Root Mean Square Deviation, or how different is this molecule from that molecule, really, or "Your protein folded wrong again".

      +
    • +
    • +

      Sampling : Exploring a near-infinite configuration space and praying you didn’t miss the important parts, or perhaps "We simulated 2 microseconds and still learned nothing".

      +
    • +
    • +

      Solvation : Dumping your sim molecule into pretend water.

      +
    • +
    • +

      Wet Lab, Dry Lab : A Wet lab is pipettes, cells, chemicals, spills, whereas a Dry lab is probably a supercomputer melting GPUs.

      +
    • +
    +
    +
    +

    MPI : Message Parsing Interface - refer to Boost.Mpi

    +
    +
    +

    MPL or MP11 : Metaprogramming Libraries - refer to Boost.Mpl and the later Boost.Mp11

    +
    +
    +

    Multiple Dispatch : Refers to the ability of a function or method to dynamically select its implementation based on the runtime types of multiple arguments, rather than just the type of the receiver (this) or a single argument. While C++ natively supports single dispatch (via virtual functions), it does not have built-in multiple dispatch like some languages (for example, Julia or Common Lisp). However, it can be emulated in C++ using design patterns like the visitor pattern, double dispatch, or external libraries. This technique is useful when the behavior of a function genuinely depends on the combination of several objects' dynamic types - for example, a complex collision between multiple object types. See Open Methods.

    +
    +
    +
      +
    • +

      Single Dispatch is the most common form of dispatch in C++ and many languages — it means that the method or function to call is determined only by the type of the first (usually the calling) object at runtime, typically using virtual functions. For example, when you call shape→draw(), the draw() method selected depends only on the runtime type of shape, not on the types of any other arguments.

      +
    • +
    • +

      Visitor Pattern : a design pattern that lets you separate an algorithm from the objects it operates on — by letting you “visit” objects and perform operations on them without modifying their classes. It allows you to add new operations to a group of existing object types without changing those types, by defining a Visitor class that implements the operation for each type. It’s commonly used to achieve double dispatch and to apply operations across complex object structures like trees or ASTs.

      +
    • +
    +
    +
    +

    Mustache : Mustache is a logic-less templating language, originally designed for generating text files (like HTML, JSON, config files). It’s called "logic-less" because it avoids embedded control structures or code. That makes it ideal for clean separation between code and output, template portability across languages (same Mustache template can work in C++, Python, or JavaScript), and easy embedding in low-level applications.

    +
    +
    +

    Mustache is a similar but simpler alternative to Handlebars.

    +
    +
    +

    Mutation : Modifying the state of an object or variable in place (for example, altering a list rather than creating a new one). The opposite of mutation is immutable - once created, the object’s value cannot be changed — any modification produces a new object instead.

    +
    +
    +

    MVP : Model-View-Presenter

    +
    +
    +
    +
    +

    N

    +
    +
    +

    NDA : Non-Disclosure Agreement

    +
    +
    +

    NIMBY : Not In My Back Yard - when a programmer doesn’t want to deal with a particular issue

    +
    +
    +

    NLL : Non-Lexical Lifetimes - an NLL borrow checker in the Rust language that uses a more precise, dataflow-based analysis to determine when a borrow starts and ends, based on the actual usage of the variables. This allows for more flexible and intuitive borrowing rules.

    +
    +
    +

    Normalize :

    +
    +
    +
      +
    • +

      When working with strings, transforming strings into a canonical form so comparisons work as expected. Used heavily in Unicode and filesystem paths, for example: "é" can be stored as one code point or two; normalization makes them match. There are several normalization strategies:

      +
      +
        +
      • +

        NFC : Normalized Form C (Canonical Composition) - characters are converted to canonical equivalents and then composed into pre-combined forms when possible. For example: e + ◌́ → é +(U+0065 U+0301 → U+00E9).

        +
      • +
      • +

        NFD : Normalized Form D (Canonical Decomposition) - characters are decomposed into base characters and combining marks. For example: é → e + ◌́ (U+00E9 → U+0065 U+0301)

        +
      • +
      • +

        NFKC : Normalization Form KC (Compatibility Composition) - converts characters to their compatibility equivalents, then composes them. For example, “①” → “1”.

        +
      • +
      • +

        NFKD : Normalization Form KD (Compatibility Decomposition) - converts compatibility characters to their equivalents and decomposes them. For example: “㍿” (Japanese corporate sign) → “株式会社”.

        +
      • +
      +
      +
    • +
    +
    +
    +

    Use NFC for most applications. Consider NFKC or NFKD for search engines, security checks, deduplication. Consider NFD for low-level linguistic processing.

    +
    +
    +
      +
    • +

      In mathematics, adjusting values in a dataset to a common scale. Vectors are often normalized so that they represent a single unit in any direction.

      +
    • +
    +
    +
    +

    NTTP : Non-Type Template Parameter

    +
    +
    +
    +
    +

    O

    +
    +
    +

    Odeint : Ordinary Differential Equations (Initial) - a library for solving initial value problems of ordinary differential equations, refer to Boost.Numeric/odeint

    +
    +
    +

    OOB : Out of Bounds or Out of Band - meaning irrelevant

    +
    +
    +

    OOP : Object-Ori

    +
    +
    +

    Open-Methods : Refers to a language mechanism that allows you to define new behaviors (essentially, methods) for existing types without modifying those types. C++ doesn’t natively support open methods in the way that some dynamic languages (like Common Lisp) do. Keys to the purpose of open methods are the Open/Closed Principle (OCP) - where a software entity (class, module, function, etc.) should be open for extension but closed for modification - and multiple dispatch. In single dispatch method resolution is based on the runtime type of a single object, usually the one the method is called on. With multiple dispatch method resolution is based on the runtime types of two or more arguments. C++ supports single dispatch via virtual functions, Multiple Dispatch has to be simulated and typically coded into a library.

    +
    +
    +

    The main advantage of open methods is that they help prevent bugs when modifying stable code. For example, when a new file format becomes popular, code can be extended to support it without modifying the existing code. In simple terms, they allow for safer scaling of software. Another specific use is you can add behavior involving multiple types, for example adding collision handling between type A and type B that is to date unsupported in your code.

    +
    +
    +

    An open-method library is currently in the Boost formal review process.

    +
    +
    +

    OTOH : On the other hand

    +
    +
    +
    +
    +

    P

    +
    +
    +

    PEBKAC : Problem Exists Between Keyboard And Chair - user error

    +
    +
    +

    PFR : A library to perform basic reflection - refer to Boost.Pfr

    +
    +
    +

    Phi Function : a construct used in Static Single Assignment (see SSA) form to resolve multiple possible values for a variable when control flow converges in a program. It selects a value based on the control flow path taken to reach the convergence point. Phi functions are not visible to developers — they exist in the intermediate representation (IR) of compilers working with low-level code optimizations.

    +
    +
    +

    PICNIC : Problem In Chair, Not In Computer

    +
    +
    +

    PIMPL :

    +
    +
    +
      +
    • +

      Pointer to IMPLementation

      +
    • +
    • +

      Perception Is My Lasting Principle - the "Cheshire Cat" idiom where someone’s perception of reality is subjective

      +
    • +
    +
    +
    +

    Pinyin Order : A common system of sorting written Chinese based on the romanized pronunciation of the characters. Sorts characters like English words A through Z based on the Pinyin spelling and tone. This compares with Stroke Order - which sorts based on the number of strokes in the written character - and Radical Order - a sorting system based on the traditional Kangxi radicals. Pinyin ordering is common in dictionaries aimed at learners, phone books, and computer input systems.

    +
    +
    +

    PITA : Pain In The Application or Programmer In Trouble Again - difficult or frustrating code issue, such as when debugging AI-hallucinated functions.

    +
    +
    +

    POD : Plain Old Data

    +
    +
    +

    Polymorphism : In object-orientated programming, refers to having one common interface to an arbitrary set of specific types.

    +
    +
    +

    POSIX : Portable Operating System Interface

    +
    +
    +

    PPA : Personal Package Archive - a repository on Launchpad (a platform for Ubuntu software collaboration) that allows developers and maintainers to distribute software or updates that are not yet included in the official Ubuntu repositories.

    +
    +
    +

    PR : Pull Request - a request to include specified content into a GitHub repository. An administrator can accept or reject the PR.

    +
    +
    +

    Promotion : A compiler promotes a smaller type to a larger type so an operation can be done safely. For example:

    +
    +
    +
    +
    int a = 42;
    +long long b = a; // promotion: int -> long long
    +
    +
    +
    +

    The reverse ( a = b; ) is not a promotion, it would be an unsafe conversion. The key point is there is no danger of data loss in a promotion.

    +
    +
    +
    +
    +

    Q

    +
    +
    +

    QBK : Quickbook - a Boost tool for automated documentation, not to be confused with Intuit Quickbooks accounting software.

    +
    +
    +

    QED : "Quod erat demonstrandum" in Latin, which translates to "that which was to be demonstrated".

    +
    +
    +

    QML : Qt Meta Language - a declarative language used in conjunction with Qt for designing user interfaces. QML is commonly referenced in C++ discussions related to UI development in Qt.

    +
    +
    +

    QOI : Quite OK Image format - a relatively new image file format that aims to provide lossless image compression with a focus on simplicity and speed, sometimes used in performance-critical applications dealing with image processing.

    +
    +
    +

    QoS : Quality of Service - a concept that often appears in networking discussions, especially when C++ programs deal with real-time communications, distributed systems, or systems requiring specific performance guarantees.

    +
    +
    +

    Qt : This is a widely-used C++ framework for cross-platform GUI applications. While not an acronym, it’s often capitalized as Qt in discussions. Qt is known for its rich set of libraries and tools to develop not only graphical applications but also applications that require network handling, file I/O, and more.

    +
    +
    +

    Quantum Computing : Unlike classical computing based on bits which must have a value of 0 or 1, quantum computing is based on qubits that can exist in multiple states at the same time. Still in the research phase, this technology can dramatically improve the performance of certain algorithms - especially those we currently call "brute-force" computing - in fields such as cryptography, chemistry simulation, graph traversing, and no doubt many others as new algorithms are discovered. We can currently simulate quantum algorithms in C++ - refer to Quantum Computing. There is a mass of new terminology to grasp - many of which have completely different meanings outside of quantum computing - including:

    +
    +
    +
      +
    • +

      Bloch Sphere : a geometric representation of a single qubit’s state as a point on the surface of a unit sphere, useful for visualizing superposition and phase.

      +
      +
      +Bloch Sphere +
      +
      +
      +

      The Bloch sphere is a 3D representation of a single qubit’s state. Any point on the sphere’s surface corresponds to a valid qubit state, with poles representing |0⟩ and |1⟩, and equatorial points representing equal superpositions. This tool helps visualize qubit transformations, such as rotations from quantum gates or decoherence effects over time.

      +
      +
    • +
    • +

      Clifford+T Gate Set : a universal set of quantum gates that includes Clifford gates and the T gate, used to construct fault-tolerant quantum circuits. The Clifford gate is a type of quantum gate that forms a foundational set of operations used in quantum error correction and stabilizer circuits. The T gate is a single-qubit quantum gate that applies a π/4 phase shift to the |1⟩ state, making it essential for achieving universal quantum computation when combined with Clifford gates.

      +
    • +
    • +

      Decoherence : the process by which a quantum system loses its quantum properties (like superposition or entanglement) due to environmental interaction.

      +
    • +
    • +

      Entanglement : a quantum phenomenon where two or more qubits become linked, such that measuring one affects the state of the others, regardless of distance.

      +
      +
      +Entanglement +
      +
      +
      +

      This shows a classic quantum circuit diagram demonstrating how to create an entangled pair of qubits (often called a Bell State). Qubit 0 (q₀) — starts in state |0⟩. Qubit 1 (q₁) — also starts in state |0⟩. A Hadamard Gate (H) is applied to q₀, which puts q₀ into a superposition: (|0⟩ + |1⟩) / √2. A CNOT gate is applied with q₀ as the control qubit, and q₁ as the target qubit. This entangles the qubits — their states become correlated. This means measuring q₀ as 0 forces q₁ to be 0, and measuring q₀ as 1 forces q₁ to be 1. Even if far apart, their outcomes are perfectly correlated — the hallmark of entanglement.

      +
      +
    • +
    • +

      Hamiltonian : an operator representing the total energy of a quantum system, governing how its state evolves over time via Schrödinger’s equation.

      +
    • +
    • +

      Interference : arises from the wave-like nature of quantum states, allowing quantum algorithms to amplify correct answers while canceling out incorrect ones, enhancing computational efficiency.

      +
    • +
    • +

      Measurement : the act of observing a qubit’s state, which causes its wavefunction to collapse into a definite classical outcome (0 or 1).

      +
    • +
    • +

      Noisy Intermediate-Scale Quantum (NISQ) : +A classification of current quantum devices with dozens to hundreds of qubits that are not yet error-corrected or scalable but still useful for experimentation.

      +
    • +
    • +

      QASM (Quantum Assembly Language) : a low-level language for describing quantum circuits and operations, often used to interface with quantum simulators and hardware.

      +
    • +
    +
    +
    +
      +
    • +

      Qubit : the basic unit of quantum information, capable of existing in a superposition of 0 and 1, unlike a classical bit which is strictly one or the other.

      +
    • +
    • +

      Qubit Connectivity (Topology) : the layout that defines which qubits in a quantum computer can directly interact, affecting how efficiently quantum circuits can be executed.

      +
    • +
    • +

      Qubit Decoherence Time (T1, T2) : T1 refers to how long a qubit holds its energy state (relaxation), and T2 refers to how long it maintains its phase (coherence) — both affect quantum stability.

      +
    • +
    • +

      Quantum Annealing : an optimization technique that finds the lowest-energy configuration of a system by slowly evolving its quantum state.

      +
    • +
    • +

      Quantum Circuit : a structured sequence of quantum gates applied to qubits to implement a quantum algorithm.

      +
      +
      +Quantum Circuit +
      +
      +
      +

      This diagram shows a basic quantum circuit composed of qubit wires (horizontal lines) and quantum gates. The gates — such as Hadamard (H), CNOT, and Measurement (M) — manipulate the quantum state of the qubits. The circuit structure visually represents the flow of operations over time from left to right, forming the basis of all quantum algorithms.

      +
      +
    • +
    • +

      Quantum Error Correction (QEC) : techniques used to detect and correct quantum errors by encoding logical qubits across multiple physical qubits.

      +
    • +
    • +

      Quantum Fourier Transform (QFT) : a quantum algorithm for transforming a quantum state into its frequency domain - used in Shor’s algorithm and other applications.

      +
    • +
    • +

      Quantum Gate : a basic operation applied to qubits that changes their state, analogous to logic gates in classical circuits but with quantum behavior.

      +
    • +
    • +

      Quantum Phase Estimation (QPE) : an algorithm used to estimate the eigenvalue (phase) associated with an eigenvector of a unitary operator—central to many quantum applications.

      +
    • +
    • +

      Quantum Teleportation : a process where the state of a qubit is transferred from one location to another, without moving the physical particle itself, by using entanglement and classical communication. It doesn’t transmit matter or energy like in science fiction — instead, it “teleports” quantum information perfectly, but always requires destroying the original state.

      +
      +
      +Quantum Teleportation +
      +
      +
      +

      This diagram shows the basic process of quantum teleportation, where the unknown state of qubit |ψ⟩ (held by Alice) is transferred to Bob using entanglement and classical communication. The circuit begins with an entangled pair of qubits shared between Alice (qubit A) and Bob (qubit B). Alice performs a set of quantum operations — a CNOT gate followed by a Hadamard gate — on her qubits, then measures them. She sends the two classical measurement results (bits) to Bob over a classical channel. Bob then applies specific quantum gates (Pauli X and/or Z) depending on Alice’s results, reconstructing the original state |ψ⟩ on his qubit — effectively completing the teleportation without physically moving the qubit itself.

      +
      +
    • +
    • +

      Quantum Volume : a benchmark that evaluates a quantum computer’s ability to run complex circuits by factoring in gate fidelity, connectivity, and qubit count.

      +
    • +
    • +

      Superposition : a principle in quantum mechanics where a qubit can exist in multiple states simultaneously, enabling parallelism in computation.

      +
    • +
    • +

      Trotterization : a technique for approximating quantum evolution by breaking time-dependent Hamiltonians into discrete, manageable steps.

      +
    • +
    +
    +
    +

    QVM : Quaternions Vectors and Matrices - refer to Boost.Qvm

    +
    +
    +
    +
    +

    R

    +
    +
    +

    RAII : Resource Acquisition Is Initialization

    +
    +
    +

    Red Teaming : The process of setting up an adversarial review team to catch errors, weak claims, and omissions from a proposal or presentation.

    +
    +
    +

    RLHF : Reinforcement Learning from Human Feedback - a method used to train coding AIs with human reviewers guiding the model’s output quality.

    +
    +
    +

    RPC : Remote Procedure Call

    +
    +
    +

    RTFM : Read The Fine (or Friendly) Manual or Robots Tell Fabricated Methods - the latter is used when an AI confidently explains APIs that don’t exist.

    +
    +
    +

    RTTI : Run-Time Type Information

    +
    +
    +

    RUST : Rust is a relatively new programming language incorporating memory-safety, thread-safety and type-safety constructs. This language provides many of the concepts proposed for Safe C++.

    +
    +
    +

    Rustaceans : Aficionados of the Rust programming language

    +
    +
    +
    +
    +

    S

    +
    +
    +

    Safe C++ : There are memory-safe discussions and initiatives going on in the wider C++ development world, though it seems like it’s a tough nut to crack. The Safe C++ proposal is currently in a state of indefinite hiatus. Key concepts of memory-safety, and it’s partners type-safety and thread-safety, include:

    +
    +
    +
      +
    • +

      Borrowing : this refers to a feature of an ownership system that allows a variable to grant temporary access to its data without giving up ownership. Immutable borrowing allows others to read but not modify data. Multiple immutable borrows are allowed at the same time. With mutable borrowing others can modify the data, but only one mutable borrow is allowed at any one time (to prevent data races), and the owner cannot modify the value until the borrow ends. Borrowing enforces lifetimes - so borrowed references do not outlive the original data.

      +
    • +
    +
    +
    +
      +
    • +

      Borrow Checking : a kind of compile-time analysis that prevents using a reference after an object has gone out of scope.

      +
    • +
    • +

      Choice types : a choice type is similar to an enum, but contains a type-safe selection of alternative types.

      +
    • +
    • +

      Explicit mutation : all mutations are explicit, so there are no uncertain side-effects.

      +
    • +
    • +

      Interior mutability : types with interior mutability implement deconfliction strategies to support shared mutation, without the risk of data races or violating exclusivity.

      +
    • +
    • +

      Pattern matching : the only way to access alternatives of Choice types to ensure type-safety.

      +
    • +
    • +

      Relocation object model : a memory model that supports relocation/destruction of local objects, in order to satisfy type-safety.

      +
    • +
    • +

      Send and sync : these are type traits that ensure memory-safety between threads. The send is enabled for a variable if it is safe to transfer ownership of its value to another thread. A sync trait is enabled if it is safe to share a reference to a value with other threads.

      +
    • +
    • +

      The safe context : operations in the safe context are guaranteed not to cause undefined behavior.

      +
    • +
    +
    +
    +

    SFINAE or SFINAED : Substitution Failure Is Not An Error

    +
    +
    +

    SHA : Secure Hash Algorithm, a function that will reliably give different hash values for different inputs.

    +
    +
    +

    Shadowing : When a local variable or parameter hides another variable with the same name, where that second variable lives in an outer scope.

    +
    +
    +

    SIGILS : refers to symbols or characters that precede a variable, literal, or keyword to indicate its type or purpose. For example, in "%hash" the "%" is a sigil. It is occasionally used with a tongue-in-cheek tone because of its mystical connotations, referring to how these symbols can seem "magical" in making the code work!

    +
    +
    +

    SipHash : A cryptographic hash for short messages (designed in 2012 by Jean-Philippe Aumasson and Daniel J. Bernstein). Specifically a pseudorandom function (PRF) keyed with a secret key to SipHash(k, message) to 64-bit hash. +It is fast enough for hash table lookups, but unlike MurmurHash/FarmHash, it resists hash-flooding attacks.

    +
    +
    +

    Slice : Extracting a contiguous subsequence of a string, for example "ring" is a slice of "string".

    +
    +
    +

    SMOP : Small Matter of Programming - sarcastically downplaying complex problems

    +
    +
    +

    SOLID : Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion (Design principles)

    +
    +
    +

    SSA : Static Single Assignment - a property of intermediate representations (IRs) used in compilers. SSA is a popular technique in modern compilers to make optimizations and analysis simpler and more efficient. Each variable is assigned exactly once and is immutable after assignment. If a variable is updated, a new variable is created instead. Refer also to Phi Functions.

    +
    +
    +

    Stitching : Joining strings end-to-end.

    +
    +
    +

    STL : Standard Template Library

    +
    +
    +

    Swifties : In the programming context, aficionados of the Swift language.

    +
    +
    +
    +
    +

    T

    +
    +
    +

    TCO : Tail Call Optimization

    +
    +
    +

    TCP : Transmission Control Protocol

    +
    +
    +

    TDD : Test-Driven Development - sometimes reframed as AI-TDD, where developers rely on AI to generate tests first, then code.

    +
    +
    +

    Test Matrix : A test matrix is a table used to define and track test cases, inputs, and environments, such as various operating systems, compilers, and hardware platforms. Each row represents a test scenario or feature, while the columns represent variations like software versions or hardware setups - refer to Contributor Guide: Test Matrix.

    +
    +
    +

    TLS : Thread-Local Storage

    +
    +
    +

    TL;DR : Too Long; Didn’t Read

    +
    +
    +

    TL;DW : Too Long; Didn’t Watch - used when someone posts an overly long video or demo

    +
    +
    +

    Tokenize : Breaking a string into meaningful syntactic units (words, symbols, numbers), often used by a compiler working with source code.

    +
    +
    +

    Top Posting : The process of replying to an email, or other message, by adding your comments entirely to the top of the discussion, as opposed to inline posting where responses are written to the individual points made in the thread.

    +
    +
    +

    Trim : Removing whitespace, or other specified characters, at the beginning or end of a string.

    +
    +
    +

    TTI : Type Traits Introspection - refer to Boost.Tti

    +
    +
    +

    TTOU : Time To Opt Out - used humorously to express wanting to quit a project that is heading south

    +
    +
    +

    TTW : Time To Whine - used sarcastically used when someone starts complaining about their code or environment

    +
    +
    +
    +
    +

    U

    +
    +
    +

    UB : Undefined Behavior

    +
    +
    +

    UBlas : Basic Linear Algebra - refer to Boost.Numeric/ublas

    +
    +
    +

    UBSan Targets : Refers to builds or test configurations that are compiled and run with Undefined Behavior Sanitizer (UBSan) enabled. UBSan is a runtime checker built into Clang and GCC that detects undefined behavior such as signed integer overflow, misaligned memory access, null pointer dereference in some contexts, out-of-bounds array access, and type punning violations (bad casts).

    +
    +
    +

    URL : Universal Resource Locator - refer to Boost.URL

    +
    +
    +

    UDP : User Datagram Protocol

    +
    +
    +

    UTC : Coordinated Universal Time

    +
    +
    +

    UUID : Universal Unique Identifier - refer to Boost.Uuid

    +
    +
    +
    +
    +

    V

    +
    +
    +

    VALA : Vector Arithmetic Logic Array - a specialized hardware design or computation technique, but in some performance-critical C++ applications, vector arithmetic and optimization may be discussed in a similar context.

    +
    +
    +

    VCPKG : Microsoft’s open source package manager for acquiring and managing libraries

    +
    +
    +

    VFS : Virtual File System - abstract file system operations across multiple platforms might implement or make use of a VFS layer. This allows consistent file I/O behavior regardless of the underlying file system.

    +
    +
    +

    VLA : Variable Length Array - although C++ does not officially support VLAs in the standard, some compilers provide support as an extension. VLAs allow the length of an array to be determined at runtime.

    +
    +
    +

    VMD : Variadic Macro Data - refer to Boost.Vmd

    +
    +
    +

    VoIP : Voice over Internet Protocol - in networking libraries or real-time communication systems, VoIP is often discussed when implementing features for voice transmission over IP networks.

    +
    +
    +

    Vptr : A hidden pointer within an object, pointing to the class’s virtual table.

    +
    +
    +

    VR : Virtual Reality - in game programming, simulations, or graphics-intensive applications, VR is often mentioned in discussions. C++ is commonly used for developing VR engines and related tools.

    +
    +
    +

    VTable : Virtual Table - a mechanism used in C++ to support dynamic (runtime) polymorphism through virtual functions. Discussions involving inheritance and object-oriented programming often reference vtables. Virtual tables are used in Dynamic Binding. Typically, if a class contains at least one virtual function, a compiler secretly creates a vtable for that class. The vtable stores addresses (pointers) to the actual implementations of that class’s virtual functions. When you call a virtual function (for example, ptr→speak()), the program uses the vptr → vtable → function pointer chain to find and invoke the correct version.

    +
    +
    +
    +
    +

    W

    +
    +
    +

    WAD : Works As Designed - usually sarcastic

    +
    +
    +

    WG21 : Working Group 2021 - a C++ Standards working group

    +
    +
    +

    WIP : Work In Progress

    +
    +
    +

    WITIWF : Well I Thought It Was Funny

    +
    +
    +

    WowBagger : The name of the web server where boost.org and lists.boost.org are running. It’s a Redhat Linux machine and soon to be replaced.

    +
    +
    +

    WRT : With Respect To

    +
    +
    +

    WTB : Where’s The Bug? - used sarcastically when trying to find a difficult-to-locate issue

    +
    +
    +

    WTF : What The …​. or Wrong Type Found - the latter when an AI autocompletes everything except the right type.

    +
    +
    +
    +
    +

    X

    +
    +
    +

    XFS : Extended File System - a high-performance file system in Linux

    +
    +
    +

    XSS : Cross-Site Scripting - a security vulnerability where malicious scripts are injected into websites

    +
    +
    +

    XUL : XML User Interface Language - used to define user interfaces in Mozilla applications

    +
    +
    +
    +
    +

    Y

    +
    +
    +

    YAGNI : You Aren’t Gonna Need It

    +
    +
    +

    YAP : An expression template library - refer to Boost.Yap

    +
    +
    +

    YOLO : You Only Live Once or You Only Launch Once - used when someone takes a risky or questionable coding decision, such as when shipping AI-generated code directly to prod without review.

    +
    +
    +
    +
    +

    Z

    +
    +
    +

    ZALGO : refers to a form of distorted or "corrupted" text, and while this is more of a meme in the programming community, it comes up when discussing character encoding or text rendering in C++.

    +
    +
    +

    ZF : Zero-Fill - zero-filling memory, often done for security reasons or to initialize data in C++ programs.

    +
    +
    +

    ZFP : Compressed Floating-Point Arrays - ZFP is a C++ library for compressed floating-point arrays, often used in scientific computing or simulations requiring efficient memory usage.

    +
    +
    +

    Zlib : Zlib Compression Library - a widely-used compression library in C++ for data compression and decompression.

    +
    +
    +

    ZMQ : ZeroMQ - a high-performance asynchronous messaging library that can be used in C++ for concurrent programming and networking applications.

    +
    +
    +

    Z-order or Z-ordering : Refers to the drawing order of objects in 2D or 3D space. This is relevant in C++ game development or graphical applications when managing layers of objects.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/header-organization-compilation.html b/preview/user-guide/header-organization-compilation.html new file mode 100644 index 0000000..d369279 --- /dev/null +++ b/preview/user-guide/header-organization-compilation.html @@ -0,0 +1,611 @@ + + + + + + + + + + + + + + Header Organization and Compiled Binaries :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Header Organization and Compiled Binaries

    +
    +
    +
    +

    This section covers the basics of the organization of Boost libraries in the folder structure, a list of libraries requiring compilation into binaries, or optionally using compilation, and the tools which you might use to compile the headers.

    +
    +
    +
    +
    +

    Header Organization

    +
    +
    +

    The organization of Boost library headers isn’t entirely uniform, but most libraries follow a few patterns:

    +
    +
    +
      +
    • +

      Some older libraries and most very small libraries place all public headers directly into Boost.

      +
    • +
    • +

      Most libraries' public headers live in a subdirectory of boost, named after the library. +For example, you’ll find the Python library’s +def.hpp header in boost/python/def.hpp.

      +
    • +
    • +

      Some libraries have an “aggregate header” in boost that includes all of the library’s other headers. +For example, +Boost.Python's aggregate header is boost/python.hpp.

      +
    • +
    • +

      Most libraries place private headers in a subdirectory called +detail, or aux. +Don’t expect to find anything you can use in these directories.

      +
    • +
    +
    +
    +

    It’s important to note the following:

    +
    +
    +
      +
    1. +

      The path to the boost root directory (often +/usr/local/boost_1_82_0) is sometimes referred to as $BOOST_ROOT +in documentation and mailing lists.

      +
    2. +
    3. +

      To compile anything in Boost, you need a directory containing the +boost subdirectory in your #include path.

      +
    4. +
    5. +

      Since all of Boost’s header files have the .hpp extension, and live in the boost subdirectory of the boost root, your Boost #include +directives will look like: #include <boost/whatever.hpp> or #include "boost/whatever.hpp", depending on your preference regarding the use of angle bracket includes.

      +
    6. +
    7. +

      Don’t be distracted by the doc subdirectory; it only contains a subset of the Boost documentation. +Start with libs/index.html if you’re looking for the whole enchilada.

      +
    8. +
    +
    +
    +
    +
    +

    Required Compiled Binaries

    +
    +
    +

    Most Boost libraries are header-only: they consist entirely of header files containing templates and inline functions, and require no separately-compiled library binaries or special treatment when linking.

    +
    +
    +

    The only Boost libraries that must be built separately are:

    +
    + +
    +
    +
    +

    Optional Compiled Binaries

    +
    +
    +

    A few libraries have optional separately-compiled binaries:

    +
    +
    +
      +
    • +

      Boost.Exception provides non-intrusive implementation of exception_ptr for 32-bit _MSC_VER==1310 +and _MSC_VER==1400 which requires a separately-compiled binary. +This is enabled by #define BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR.

      +
    • +
    • +

      Boost.Graph also has a binary component that is only needed if you intend to parse GraphViz files.

      +
    • +
    • +

      Boost.Math has binary components for the TR1 and C99 cmath functions.

      +
    • +
    • +

      Boost.Random has a binary component which is only needed if you’re using random_device.

      +
    • +
    • +

      Boost.System is header-only since Boost 1.69. A stub library is still built for compatibility, but linking to it is no longer necessary.

      +
    • +
    • +

      Boost.Test can be used in “header-only” or “separately compiled” mode, although separate compilation is recommended for serious use.

      +
    • +
    +
    +
    +
    +
    +

    Identify Your Toolset

    +
    +
    +

    In order to build binaries from source, find the toolset corresponding to your compiler in the following table (an up-to-date list is also available in Builtin tools).

    +
    +
    +
    +
    Note
    +
    +

    If you previously chose a toolset for the purposes of building b2, you should assume it won’t work and instead choose newly from the table below.

    +
    +
    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Toolset NameVendorNotes

    acc

    Hewlett Packard

    Only very recent versions are known to work +well with Boost

    borland

    Borland

    como

    Comeau Computing

    Using this toolset may require configuring another toolset to act as its backend.

    darwin

    Apple Computer

    Apple’s version of the GCC toolchain with support for Darwin and MacOS X features such as frameworks.

    gcc

    The Gnu Project

    Includes support for Cygwin and MinGW compilers.

    hp_cxx

    Hewlett Packard

    Targeted at the Tru64 operating system.

    intel

    Intel

    msvc

    Microsoft

    sun

    Oracle

    Only very recent versions are known to work well with +Boost. Note that the Oracle/Sun compiler has a large number of options +which effect binary compatibility. It is vital that the libraries are +built with the same options that your application will use. In particular +be aware that the default standard library may not work well with Boost, +unless you are building for Cpp11.

    +

    The particular compiler options you need can be injected with the b2 command line options cxxflags= and linkflags=. For example to build with the Apache standard library in Cpp03 mode use:

    +

    b2 cxxflags=-library=stdcxx4 linkflags=-library=stdcxx4.

    vacpp

    IBM

    The VisualAge C++ compiler.

    +
    +

    If you have multiple versions of a particular compiler installed, you can append the version number to the toolset name, preceded by a hyphen, e.g. intel-9.0 or borland-5.4.3.

    +
    +
    +

    On Windows, append a version number even if you only have one version installed (unless you are using the msvc or gcc toolsets, which have special version detection code) or auto-linking will fail.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/implementation-variations.html b/preview/user-guide/implementation-variations.html new file mode 100644 index 0000000..0552882 --- /dev/null +++ b/preview/user-guide/implementation-variations.html @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + Implementation Variation Techniques :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Implementation Variation Techniques

    +
    +
    +
    +

    This topic discusses the separation of interface and implementation.

    +
    +
    +

    The interface specifications for boost.org library components (as well as for quality software in general) are conceptually separate from implementations of those interfaces. This may not be obvious, particularly when a component is implemented entirely within a header, but this separation of interface and implementation is always assumed. From the perspective of those concerned with software design, portability, and standardization, the interface is what is important, while the implementation is just a detail.

    +
    +
    +

    Dietmar Kühl, one of the original Boost contributors, comments "The main contribution is the interface, which is augmented with an implementation, proving that it is possible to implement the corresponding class and providing a free implementation."

    +
    +
    +
    +
    +

    Implementation Variations

    +
    +
    +

    There may be a need for multiple implementations of an interface, to accommodate either platform dependencies or performance tradeoffs. Examples of platform dependencies include compiler shortcomings, file systems, thread mechanisms, and graphical user interfaces. The classic example of a performance tradeoff is a fast implementation that uses a lot of memory versus a slower implementation which uses less memory.

    +
    +
    +

    Boost libraries generally use a configuration header, boost/config.hpp, to capture compiler and platform dependencies. Although the use of boost/config.hpp is not required, it is the preferred approach for simple configuration problems.

    +
    +
    +
    +
    +

    Boost Policy

    +
    +
    +

    The Boost policy is to avoid platform dependent variations in interface specifications, but supply implementations which are usable over a wide range of platforms and applications. That means Boost libraries will use the techniques below described as appropriate for dealing with platform dependencies.

    +
    +
    +

    The Boost policy toward implementation variations designed to enhance performance is to avoid them unless the benefits greatly exceed the full costs. The term full costs is intended to include both tangible costs like extra maintenance, and intangible cost like increased difficulty in user understanding.

    +
    +
    +
    +
    +

    Techniques for Providing Implementation Variations

    +
    +
    +

    Several techniques may be used to provide implementation variations. Each is appropriate in some situations, and not appropriate in others.

    +
    +
    +

    Single General Purpose Implementation

    +
    +

    The first technique is to simply not provide implementation variation at all. Instead, provide a single general-purpose implementation, and forgo the increased complexity implied by all other techniques.

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

    Appropriate

    When it is possible to write a single portable implementation which has reasonable performance across a wide range of platforms. Particularly appropriate when alternative implementations differ only in esoteric ways.

    Not appropriate

    When implementation requires platform specific features, or when there are multiple implementations possible with widely differing performance characteristics.

    +
    +

    In design discussions, some implementation is often alleged to be much faster than another, yet a timing test discovers no significant difference. The lesson is that while algorithmic differences may affect speed dramatically, coding differences such as changing a class from virtual to non-virtual members or removing a level of indirection are unlikely to make any measurable difference unless deep in an inner loop. And even in an inner loop, modern CPUs often execute such competing code sequences in the same number of clock cycles! A single general purpose implementation is often just fine.

    +
    +
    +

    Or as Donald Knuth said in Computing Surveys, vol 6, #4, p 268, "Premature optimization is the root of all evil.".

    +
    +
    +
    +

    Macros

    +
    +

    While the evils of macros are well known, there remain a few cases where macros are the preferred solution:

    +
    +
    +
      +
    • +

      Preventing multiple inclusion of headers via #include guards.

      +
    • +
    • +

      Passing minor configuration information from a configuration header to other files.

      +
    • +
    +
    + ++++ + + + + + + + + + + +

    Appropriate

    For small compile-time variations that would otherwise be costly or confusing to install, use, or maintain. More appropriate to communicate within and between library components than to communicate with library users.

    Not appropriate

    If other techniques will do.

    +
    +

    To minimize the negative aspects of macros:

    +
    +
    +
      +
    • +

      Only use macros when they are clearly superior to other techniques. Otherwise they should be viewed as a last resort.

      +
    • +
    • +

      Names should be all uppercase and begin with the namespace name. This will minimize the chance of name collisions. For example, the #include guard for a boost header called foobar.h might be named BOOST_FOOBAR_H.

      +
    • +
    +
    +
    +
    +

    Separate Files

    +
    +

    A library component can have multiple variations, each contained in its own separate file or files. The files for the most appropriate variation are copied to the appropriate include or implementation directories at installation time.

    +
    +
    +

    The way to provide this approach in Boost libraries is to include specialized implementations as separate files in separate sub-directories in the .ZIP distribution file. For example, the structure within the .ZIP distribution file for a library named foobar which has both default and specialized variations might look something like:

    +
    +
    +
    +
    foobar.h                // The default header file
    +foobar.cpp              // The default implementation file
    +readme.txt              // Readme explains when to use which files
    +self_contained/foobar.h // A variation with everything in the header
    +linux/foobar.cpp        // Implementation file to replace the default
    +win32/foobar.h          // Header file to replace the default
    +win32/foobar.cpp        // Implementation file to replace the default
    +
    +
    + ++++ + + + + + + + + + + +

    Appropriate

    When different platforms require different implementations, or when there are major performance differences between possible implementations.

    Not appropriate

    When it makes sense to use more that one of the variations in the same installation.

    +
    +
    +

    Separate Components

    +
    +

    Rather than have several implementation variations of a single component, supply several separate components. For example, the Boost library currently supplies scoped_ptr and shared_ptr classes rather than a single smart_ptr class parameterized to distinguish between the two cases. There are several ways to make the component choice:

    +
    +
    +
      +
    • +

      Hardwired by the programmer during coding.

      +
    • +
    • +

      Chosen by programmer written runtime logic (trading off some extra space, time, and program complexity for the ability to select the implementation at run-time.)

      +
    • +
    +
    + ++++ + + + + + + + + + + +

    Appropriate

    When the interfaces for the variations diverge, and when it is reasonable to use more than one of the variations. When run-time selection of implementation is called for.

    Not appropriate

    When the variations are data type, traits, or specialization variations which can be better handled by making the component a template. Also not appropriate when choice of variation is best done by some setup or installation mechanism outside of the program itself. Thus usually not appropriate to cope with platform differences.

    +
    +
    +
    Note
    +
    +

    There is a related technique where the interface is specified as an abstract (pure virtual) base class (or an interface definition language), and the implementation choice is passed off to some third-party, such as a dynamic-link library or object-request broker. While that is a powerful technique, it is way beyond the scope of this discussion.

    +
    +
    +
    +
    +
    +

    Template-Based Approaches

    +
    +

    Turning a class or function into a template is often an elegant way to cope with variations. Template-based approaches provide optimal space and time efficiency in return for constraining the implementation selection to compile time.

    +
    +
    +

    Important template techniques include:

    +
    +
    +
      +
    • +

      Data type parameterization: this allows a single component to operate on a variety of data types and is why templates were originally invented.

      +
    • +
    • +

      Traits parameterization; if parameterization is complex, bundling up aspects into a single traits helper class can allow great variation while hiding messy details. The C++ Standard Library provides several examples of this idiom, such as iterator_traits<> (24.3.1 lib.iterator.traits) and char_traits<> (21.2 lib.char.traits).

      +
    • +
    • +

      Specialization: a template parameter can be used purely for the purpose of selecting a specialization. For example:

      +
    • +
    +
    +
    +
    +
    SomeClass<fast>  my_fast_object;  // fast and small are empty classes
    +SomeClass<small> my_small_object; // used just to select specialization
    +
    +
    + ++++ + + + + + + + + + + +

    Appropriate

    When the need for variation is due to data type or traits or is performance-related like selecting among several algorithms, and when a program might reasonably use more than one of the variations.

    Not appropriate

    When the interfaces for variations are different, or when choice of variation is best done by some mechanism outside of the program itself. Thus usually not appropriate to cope with platform differences.

    +
    +
    +
    +
    +

    Acknowledgements

    +
    +
    +

    This topic was originally written by Beman Dawes, in 2001.

    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    The following libraries demonstrate the importance of separating interfaces from implementations:

    +
    +
    +
      +
    • +

      Boost.Any : the implementation internally uses type erasure techniques to hide the actual type of the stored value, decoupling the interface from the concrete implementation details.

      +
    • +
    • +

      Boost.Function : the implementation internally uses type erasure techniques to store and invoke callable objects polymorphically, decoupling the interface from the specific callable object type.

      +
    • +
    • +

      Boost.Optional : the implementation internally uses tag dispatching techniques to handle the presence or absence of the optional value, decoupling the interface from the concrete implementation details.

      +
      +
      +
      Note
      +
      +

      Tag dispatching is a technique used to select different implementations of a function, or algorithm, based on the types or properties of its arguments.

      +
      +
      +
      +
    • +
    • +

      Boost.Iterator : the implementation internally uses iterator traits and type traits to provide a generic interface for working with iterators, decoupling the interface from the specific iterator type and implementation.

      +
    • +
    • +

      Boost.Mp11 : the implementation internally uses template metaprogramming techniques to perform type-level computations, decoupling the interface from the specific type and template instantiation.

      +
    • +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/in-memoriam-beman-dawes.html b/preview/user-guide/in-memoriam-beman-dawes.html new file mode 100644 index 0000000..3bec3c9 --- /dev/null +++ b/preview/user-guide/in-memoriam-beman-dawes.html @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + In Memoriam: Beman Dawes :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    In Memoriam: Beman Dawes

    +
    +
    +
    +
    +Beman Dawes +
    +
    +
    +

    Beman Dawes passed on December first, 2020 at the age of 81 years. He was survived by his wife Sonda.

    +
    +
    +

    Dave Abrahams: "Beman Dawes was my friend, inspiration, and collaborator. He was a living demonstration that collegial respect and kindness are fundamental to getting great results. His idea for Boost blossomed into a unique community, inventing the art of library design. RIP."

    +
    +
    +

    Emil Dotchevski: "I talked with Beman many times. He was always kind, and through my experience with him I am honored to have had a chance to work with this brilliant member of our community. He should be celebrated as one of those little-known figures who nonetheless has had an enormous positive impact on the world through his work."

    +
    +
    +

    Niall Douglas: "Beman had an unusually large impact on C++ over his long and very productive life. My personal opinion of his most monumental achievement was getting Filesystem into standard C++, which was probably the most tortuous, lengthy, and difficult library to have ever been standardized (to date), and that followed a preceding tortuous, lengthy and difficult Boost peer review involving multiple redesigns of the proposed library. Beman was on WG21 from nearly the beginning, served as the Library Working Group chair for some time, and was one of the original co-founders of the Boost C++ Libraries. He also had a long history of continuous contributions to open source, starting from when many on r/cpp were still children."

    +
    +
    +

    Stefanus Du Toit: "Just learned about the passing of Beman Dawes. Beman was a truly positive and inspirational influence on the C++ community. A rare example of someone putting contribution to the greater good above all else. You’ll be missed, Beman."

    +
    +
    +

    Howard Hinnant: "He was a friend. He was a giant. He will be missed."

    +
    +
    +

    Jon Kalb: "Beman Dawes' legacy in the C++ community is matched by few. As a leader in the process of defining the C++ standard, he recognized a need for high quality, non-proprietary libraries. He saw not only that these were few, but that there was no environment to create new ones. He created the Boost Libraries with the goal of making high quality, peer-reviewed, open source libraries available for every C++ programmer and as an environment to develop candidate libraries for standardization. He then helped launch BoostCon (now C++Now), as a way of nurturing the community that made Boost possible and appreciates high quality C++ libraries. He did all of this with such humor, humility, generosity, and grace that he will be much missed."

    +
    +
    +

    Christopher Kormanyos: "When the evolution from Fortran to C to C++ was on, progress seemed to hit a snag around the turn of the century. Beman’s innovative, comprehensive and reliable work on C++ and Boost helped get C++ back on track. I feel that he enlightened the era and inspired other pioneers of that time and beyond, transforming C++ into the powerful, expressive language it is today."

    +
    +
    +

    Robert Ramey: "I do not think C++ would be where it is today without the extraordinary accomplishments of two particular people. Beman Dawes and David Abrahams. Before their efforts in the late nineties C++ was suffering from a lack of libraries which made it noncompetitive with alternatives being promoted at the time - most notably Java and C#. These alternatives were funded by the biggest of the big. The future must have looked bleak to C++ fans at the time. I was looking for an alternative to C++ when I came upon Boost with a number of portable and indispensable libraries. Boost was founded by these two gentleman (of complimentary personalities). That changed everything for me - and I’m sure I’m not the only one. And I suspect that it was responsible for changing the future of C++. To those who believe that one man can’t make a big difference - I offer this counter example."

    +
    +
    +

    David Sankel: "I had the opportunity to interact with Beman at both BoostCon and the Standardization committee. He was an incredibly reasonable, and nurturing person. Boost and the greater C++ community is indebted to his tremendous legacy."

    +
    +
    +

    Andrey Semashev: "Although I haven’t known Beman in person, I feel in debt to him for his role in Boost and C++ in general. The Boost Project and the community around it were most educational and inspiring, which allowed me to grow as a developer over the years. His libraries, such as Boost.Filesystem and Boost.System, have helped countless users and made it into the C++ standard as fundamental library components. He has been a long member of the C++ Standards Committee and chaired the Library Working Group. One of the most influential people in the C++ world, he will be missed."

    +
    +
    +

    Herb Sutter: "Beman was one of the most important and influential C++ experts in the world, and made his many contributions mostly behind the scenes, so that many C++ developers have likely never heard of him. I and everyone else who have ever benefited from any of the standardized STL, Boost, C++Now, std::filesystem, C++98/11/14/17, and more - so, really, most people who have ever used C++ - all owe Beman a debt of gratitude. We miss him greatly."

    +
    +
    +

    If you’ve thoughts about Beman that you’d like to share, please send them to memorial@boost.org.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/index.html b/preview/user-guide/index.html new file mode 100644 index 0000000..85aaa82 --- /dev/null +++ b/preview/user-guide/index.html @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + User Guide :: Boost Site Docs + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    User Guide

    +
    +
    +
    +

    This User Guide is for all C++ developers using or evaluating Boost libraries.

    +
    +
    +

    Each individual library has its' own specific user documentation. +This User Guide covers all aspects of the libraries that are generic to the entire set.

    +
    +
    +
    +
    +

    Feedback

    +
    +
    +

    Feedback on any aspect of the documentation is encouraged, and is available by creating a New Issue. +Also, if you have feedback on any particular library, create an issue in the repo for that library.

    +
    +
    +
    +
    +

    First Steps

    +
    +
    +

    Start by reading the Introduction to Boost.

    +
    +
    +
    +
    +

    See Also

    +
    +
    + +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/intro.html b/preview/user-guide/intro.html new file mode 100644 index 0000000..84cb96d --- /dev/null +++ b/preview/user-guide/intro.html @@ -0,0 +1,573 @@ + + + + + + + + + + + + + + Introduction :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Introduction

    +
    +
    +
    +

    Boost is a collection of high-quality and peer-reviewed libraries that aims to make C++ development highly productive.

    +
    +
    +

    Boost is publicly released three times per year (April, August, and December). Each release has updates to existing libraries, and any new libraries that have passed the rigorous acceptance process. Currently, there are over 180 libraries covering a myriad of programming tasks.

    +
    +
    +
    +
    +

    Advantages of using Boost

    +
    +
    +

    There are many advantages to using Boost in your C++ projects, the main one being using Boost avoids reinventing the wheel if there is a library that implements functions that you would otherwise have to write yourself. In addition:

    +
    +
    +
      +
    • +

      Boost libraries are peer reviewed, well designed, and extensively tested prior to release.

      +
    • +
    • +

      Boost does not compete with the C++ Standard Library. Rather it complements the Standard with exciting additional functionality. Many components of the Standard started as components of Boost libraries.

      +
    • +
    • +

      Boost is open-source, and available for you to use in any of your projects. It is free, including for commercial projects. Refer to The Boost Software License.

      +
    • +
    • +

      Boost allows for cross-platform development, with single source code. Boost supports Windows, Linux variants, Apple OS X, IOS, Android, and Xbox.

      +
    • +
    • +

      The Boost Libraries are designed to be as independent as possible so that users can pick and choose the libraries they need without being forced to include unnecessary code. If a library has dependencies these other libraries are loaded automatically if just a subset of the full collection of libraries is being installed.

      +
    • +
    • +

      Particular strengths of the libraries include extensive documentation, ease of installing and updating, many libraries are header-only, and that less-common use cases are often covered.

      +
    • +
    • +

      Through template metaprogramming Boost libraries are a good platform for building other libraries.

      +
    • +
    • +

      Boost can be used in conjunction with graphics and games SDKs, such as OpenGL, Vulkan, and DirectX, and with game development engines such as the Unreal Engine.

      +
    • +
    • +

      It is easy to ask questions and share your Boost experiences with other programmers, via the User Community.

      +
    • +
    • +

      A developer can gain knowledge of what is available. A library may be of no current use, but knowledge of its existence can help in future awareness and planning.

      +
    • +
    • +

      Bugs, though rare, and other issues can be filed on the library authors, refer to Reporting Issues.

      +
    • +
    +
    +
    +
    +
    +

    Considerations when using Boost

    +
    +
    +

    The libraries implement a modern approach to C++ programming, generally prioritizing performance, correctness, cross-platform portability, efficiency and reusability. Boost offers building blocks, rather than a high-level app framework.

    +
    +
    +

    Boost is template-heavy, in order to provide maximum portability and reusability, which can make for dense syntax, which takes some getting used to.

    +
    +
    +

    Boost libraries are written by one, or a small team, of independent developers. There will be minor differences in portability, standards, documentation, error reporting, and other aspects, between the libraries. The stringent review process does help minimize these differences.

    +
    +
    +
    +
    +

    Library Categories

    +
    +
    +

    The current Boost libraries are categorized as follows - the count shows the number of current libraries in the category.

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CategoryCountDescription

    Algorithms

    13

    A range of libraries including several for 2D geometry, graphs, performance when iterating, sorting, string efficiency, and miscellaneous utility algorithms.

    Broken compiler workarounds

    1

    Addresses compiler idiosyncrasies, and help for non-conforming standard libraries.

    Concurrent Programming

    16

    Libraries that address concurrency, threads, networking, sockets, context switching, memory, and other multi-threading functions.

    Containers

    24

    Includes coverage of arrays, buffers, graphs, JSON, heaps, properties, stacks, and other storage constructs and issues.

    Correctness and testing

    7

    Includes coverage of asserts, contracting, integer correctness, tracing, and unit testing.

    Data structures

    22

    Supports a wide range of data structures, including maps, containers, heaps, JSON, optional objects, pointers, polygons, properties, and stacks.

    Domain Specific

    5

    Covers date and time utilities, cyclic redundancy code (CRC), unit analysis, and unique identifiers.

    Error handling and recovery

    5

    Covers asserts, error reporting and handling, and an infrastructure for throwing exceptions.

    Function objects and higher-order programming

    17

    Covers binding, function wrapping, function overloading, lambda functions, generic functions, and callback functions.

    Generic Programming

    15

    A range of generalized libraries, including for passing parameters, function template overloads, handling operators and iterators, generic types and templates, and parallel extensions.

    Image processing

    1

    A single library for generic image processing.

    Input/Output

    14

    Features include portable networking, conversions for correct byte-ordering, formatting, streams, JSON, serialization, and URL parsing.

    Inter-language support

    1

    A single library providing a framework for interfacing Python with C++.

    Iterators

    6

    Covers iterations in images, graphs, arithmetic classes, and tokens.

    Language Features Emulation

    13

    Covers language features such as reflection, exceptions, semantics, deterministic failure, parameters, scope, types, and typeof.

    Math and numerics

    19

    Covers many math issues, such as statistics, types and conversions, geometry, histograms, trigonometry, common factors, Quaternions, n-dimensional arrays, equations, operators, polygons, vectors, matrices, random numbers, ratios, rational numbers, safe integers, and linear algebra.

    Memory

    3

    Memory functions including for alignment, allocators, traits, pool management, smart pointers, and non-copyable classes.

    Parsing

    4

    Libraries providing a parsing framework, covering grammars, primitives, directives, and other language features.

    Patterns and Idioms

    6

    Covers design patterns, empty member optimization, deterministic failure, callbacks, and non-copyable classes.

    Preprocessor Metaprogramming

    3

    Covers macro parameters, repetition, recursion, and macro data.

    Programming Interfaces

    6

    Covers object wrappers for deferred calls or callbacks, deterministic failure, parameters, Python bindings, and error reporting.

    State Machines

    2

    Covers high-performance, and arbitrarily complex finite state machines.

    String and text processing

    16

    Covers type conversion, string formatting, streams, localization, regular expressions, parsing, tokens, and string algorithms.

    System

    11

    Time utilities, context switching, handling libraries, threads, a smart file system, processes, backtraces, and errors.

    Template Metaprogramming

    15

    Libraries to support the development of higher-level libraries, with features such as callable traits, reflection, function types, tuples, higher-order functions, parsing, sequences, metafunctions, static assertions, introspection, properties, and expressions.

    Miscellaneous

    15

    Libraries for numerical type and text conversion, byte-ordering, logging, swapping, timing, initialization, and many other utilities.

    +
    +
    +
    Note
    +
    +

    One library may appear in more than one category.

    +
    +
    +
    +
    +
    +
    +

    Summary

    +
    +
    +

    The purpose of the Boost libraries is to evangelize and support C++ development. You can take advantage of thousands of lines of high performance code.

    +
    +
    +

    Next Steps

    +
    +

    If you are new to Boost, the recommended next step is to download the entire library for your selected OS, and build a few sample programs.

    +
    +
    + +
    +
    +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/library-naming.html b/preview/user-guide/library-naming.html new file mode 100644 index 0000000..5023d2d --- /dev/null +++ b/preview/user-guide/library-naming.html @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + Library Names and Organization :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Library Names and Organization

    + +
    +

    Introduction

    +
    +
    +

    If your compiler supports auto-linking, such as Visual C++, then there is no need to understand the details of library binary naming.

    +
    +
    +

    However, if auto-linking is not supported by your compiler, then, in order to choose the right binary for your build configuration you +need to know how Boost binaries are named.

    +
    +
    +
    +
    +

    Library Name Elements

    +
    +
    +

    Each library filename is composed of a common sequence of elements that describe how it was built. For example, libboost_regex-vc71-mt-d-x86-1_34.lib can be broken down into the following elements:

    +
    +
    +
      +
    • +

      lib: Prefix: except on Microsoft Windows, every Boost library name begins with this string. On Windows, only ordinary static libraries use the lib prefix; import libraries and DLLs do not. (1)

      +
    • +
    • +

      boost_regex: Library name: all boost library filenames begin with boost_.

      +
    • +
    • +

      -vc71: Toolset tag: identifies the toolset and version used to build the binary.

      +
    • +
    • +

      -mt: Threading tag: indicates that the library was built with multithreading support enabled. Libraries built without multithreading support can be identified by the absence of -mt .

      +
    • +
    +
    +
    +
      +
    • +

      -d: ABI tag: encodes details that affect the library’s interoperability with other compiled code. For each such feature, a single letter is added to the tag:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      KeyUse CaseB2 Option

      s

      Linking statically to the C++ standard library and compiler +runtime support libraries.

      runtime-link=static

      g

      Using debug versions of the standard and runtime support +libraries.

      runtime-debugging=on

      y

      Using a special debug build of Python.

      python-debugging=on

      d

      Building a debug version of your code. (2)

      variant=debug

      p

      Using the STLPort standard library rather than the default one +supplied with your compiler.

      stdlib=stlport

      +
      +

      For example, if you build a debug version of your code for use with debug versions of the static runtime library and the STLPort standard library, the tag would be: -sgdp . If none of the above apply, the ABI tag is omitted.

      +
      +
    • +
    • +

      -x86: Architecture and address model tag: in the first letter, encodes the architecture as follows:

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      KeyArchitectureB2 Option

      x

      x86-32, x86-64

      architecture=x86

      a

      ARM

      architecture=arm

      i

      IA-64

      architecture=ia64

      s

      Sparc

      architecture=sparc

      m

      MIPS/SGI

      architecture=mips*

      p

      RS/6000 & PowerPC

      architecture=power

      +
      +

      The two digits following the letter encode the address model as follows:

      +
      + +++++ + + + + + + + + + + + + + + + + + + + +
      KeyAddress ModelB2 Option

      32

      32 bit

      address-model=32

      64

      64 bit

      address-model=64

      +
    • +
    • +

      -1_34: Version tag: the full Boost release number, with periods replaced by underscores. For example, version 1.31.1 would be tagged as -1_31_1.

      +
    • +
    • +

      .lib: Extension: determined according to the operating system’s usual convention. On most unix-style platforms the extensions are .a and .so for static libraries (archives) and shared libraries, respectively. On Windows, .dll indicates a shared library and .lib indicates a static or import library. Where supported by toolsets on unix variants, a full version extension is added (e.g. ".so.1.34") and a symbolic link to the library file, named without the trailing version number, will also be created.

      +
    • +
    +
    +
    +
    +
    +

    Installed Library Names

    +
    +
    +

    When libraries are installed using the B2 app, the actual name can vary from the full name described above.

    +
    +
    +

    The --layout=<layout> option determines how the library name is handled, and the appropriate header locations so that multiple versions of Boost, or multiple compilers, can be used on the same system.

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    LayoutDescriptionDefault On

    versioned

    The names of Boost binaries include the Boost version number, name and version of the compiler, and encoded build properties. Boost headers are installed in a subdirectory of <HDRDIR> whose name contains the Boost version number.

    Windows

    tagged

    Names of boost binaries include the encoded build properties such as variant and threading, but do not including compiler name and version, or Boost version. This option is useful if you build several variants of Boost, using the same compiler.

    none

    system

    Binaries names do not include the Boost version number or the name and version number of the compiler. Boost headers are installed directly into <HDRDIR>. This option is intended for system integrators building distribution packages.

    Unix

    +
    +
    +
    +

    The Boost Distribution

    +
    +
    +

    After installing Boost, this is the resulting directory structure, in the boost_1_82_0 root:

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Root LevelLower LevelDescription

    bin.v2

    libs

    Mainly contains the compiled binaries for those libraries that require compilation.

    boost

    library folders

    All Boost header files

    doc

    A subset of all Boost library docs

    libs

    library folders

    Tests, .cpps, docs, etc., by library

    more

    getting_started writingdoc

    Policy, getting started, and Contributor Guide documentation

    stage

    lib

    CMake files for each library

    status

    Boost-wide test suite

    tools

    tool folders

    Utilities: B2, quickbook, bcp, etc.

    b2.exe

    Boost install app, and supporting files

    index.htm

    A copy of www.boost.org starts here

    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) This convention distinguishes the static version of a Boost library from the import library for an identically-configured Boost DLL, which would otherwise have the same name.

    +
    +
    +

    (2) These libraries were compiled without optimization or inlining, with full debug symbols enabled, and without #define NDEBUG. Although it’s true that sometimes these choices don’t affect binary compatibility with other compiled code, you can’t count on that with Boost libraries.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/reduce-dependencies.html b/preview/user-guide/reduce-dependencies.html new file mode 100644 index 0000000..4c88495 --- /dev/null +++ b/preview/user-guide/reduce-dependencies.html @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + Customize Builds to Reduce Dependencies :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Customize Builds to Reduce Dependencies

    +
    +
    +
    +

    There are many libraries that provide macros or configuration options to remove optional components and so reduce dependencies. Refer to the documentation, in particular the macros, for the individual libraries you intend to use. Here are some specific examples:

    +
    +
    +
    +
    +

    Boost.Asio

    +
    +
    +

    Boost.Asio defines macros to remove certain functionality and control behavior:

    +
    +
    +
      +
    • +

      BOOST_ASIO_SEPARATE_COMPILATION use the header-only features of the library.

      +
    • +
    • +

      BOOST_ASIO_DISABLE_SSL disables timers and SSL components.

      +
    • +
    +
    +
    +
    +
    +

    Boost.Filesystem

    +
    +
    +

    Boost.Filesystem includes macros to control its behavior and reduce dependencies. For example:

    +
    +
    +
      +
    • +

      BOOST_FILESYSTEM_NO_DEPRECATED disables deprecated features.

      +
    • +
    • +

      BOOST_FILESYSTEM_NO_LIB prevents automatic linking of the library.

      +
    • +
    +
    +
    +
    +
    +

    Boost.Locale

    +
    +
    +

    Boost.Locale allows customization through macros:

    +
    +
    +
      +
    • +

      BOOST_LOCALE_WITH_ICU enables or disables ICU support.

      +
    • +
    • +

      BOOST_LOCALE_WITH_ICONV enables or disables Iconv support.

      +
    • +
    • +

      BOOST_LOCALE_WITH_STD enables or disables support for the standard library’s localization facilities.

      +
    • +
    +
    +
    +
    +
    +

    Boost.Log

    +
    +
    +

    Boost.Log has optional features that can be disabled using macros, such as:

    +
    +
    +
      +
    • +

      BOOST_LOG_NO_THREADS disables multi-threading support if not required.

      +
    • +
    • +

      BOOST_LOG_WITHOUT_DEBUG_OUTPUT removes debug output support.

      +
    • +
    • +

      BOOST_LOG_WITHOUT_EVENT_LOG excludes Windows Event Log support.

      +
    • +
    • +

      BOOST_LOG_WITHOUT_SYSLOG disables support for Syslog (on Unix systems).

      +
    • +
    +
    +
    +
    +
    +

    Boost.ProgramOptions

    +
    +
    +

    Boost.ProgramOptions provides macros to remove certain components:

    +
    +
    +
      +
    • +

      BOOST_PROGRAM_OPTIONS_NO_LIB disables automatic linking.

      +
    • +
    +
    +
    +

    It also allows customization to minimize dependencies when certain features aren’t needed, such as avoiding wide-character support. Refer to its documentation.

    +
    +
    +
    +
    +

    Boost.Python

    +
    +
    +

    Boost.Python has options to exclude optional components, such as disabling support for certain Python features or optimizations:

    +
    +
    +

    BOOST_PYTHON_NO_LIB disables automatic linking.

    +
    +
    +
    +
    +

    Boost.Regex

    +
    +
    +

    Boost.Regex offers macros to customize its functionality, such as:

    +
    +
    +
      +
    • +

      BOOST_REGEX_NO_LIB disables automatic linking.

      +
    • +
    • +

      BOOST_REGEX_NO_EXTERNAL_TEMPLATES prevents the use of external templates to reduce dependencies.

      +
    • +
    • +

      BOOST_REGEX_MATCH_EXTRA can be undefined to exclude certain match-related features.

      +
    • +
    +
    +
    +
    +
    +

    Boost.Serialization

    +
    +
    +

    Boost.Serialization allows disabling certain features to reduce dependencies:

    +
    +
    +
      +
    • +

      BOOST_SERIALIZATION_NO_LIB disables automatic linking.

      +
    • +
    • +

      BOOST_SERIALIZATION_NO_XML_ARCHIVE excludes XML archive support.

      +
    • +
    • +

      BOOST_SERIALIZATION_NO_TEXT_ARCHIVE excludes text archive support.

      +
    • +
    • +

      BOOST_SERIALIZATION_NO_EXCEPTION_SAFETY removes exception safety-related functionality.

      +
    • +
    +
    +
    +
    +
    +

    Boost.System

    +
    +
    +

    Boost.System has macros to control its behavior:

    +
    +
    +
      +
    • +

      BOOST_ERROR_CODE_HEADER_ONLY makes it header-only by eliminating the need for compiled binaries.

      +
    • +
    +
    +
    +
    +
    +

    Boost.Test

    +
    +
    +

    Boost.Test allows stripping optional components to make it more lightweight:

    +
    +
    +
      +
    • +

      BOOST_TEST_NO_LIB disables automatic linking.

      +
    • +
    • +

      BOOST_TEST_DYN_LINK forces dynamic linking.

      +
    • +
    • +

      BOOST_TEST_NO_MAIN prevents the inclusion of the main function, allowing integration into existing test frameworks.

      +
    • +
    +
    +
    +
    +
    +

    See Also

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/release-process.html b/preview/user-guide/release-process.html new file mode 100644 index 0000000..c2988a7 --- /dev/null +++ b/preview/user-guide/release-process.html @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + Release Process :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Release Process

    +
    +
    +
    +

    Boost libraries are released together and publicly three times per year:

    +
    +
    +
      +
    • +

      Second week of April

      +
    • +
    • +

      Second week of August

      +
    • +
    • +

      Second week of December

      +
    • +
    +
    +
    +

    Each release will contain updates to existing libraries, and some releases will contain new libraries. The release is built from the Boost GitHub site: https://github.com/boostorg/boost.

    +
    +
    +
    +
    +

    Preparing for a Boost Release

    +
    +
    +

    When a release approaches, there is a strict policy on how to merge additions or changes into the library repository. Library maintainers work to prepare their libraries for the release, which involves updating documentation, fixing bugs, and addressing any compatibility issues. Additionally, library maintainers ensure that their libraries pass the Boost regression tests, which help identify potential problems before the release.

    +
    +
    +

    As a release date approaches, there are increasing restrictions on what can be merged, to ensure stability.

    +
    +
    +

    Regression Testing

    +
    +

    Regression testing is an essential part of the release process, ensuring the quality and compatibility of the libraries. The Boost community maintains a set of regression tests, which are run on a diverse range of platforms and compilers. The tests are performed by volunteers who contribute their computing resources to the project.

    +
    +
    +

    The results of the regression tests are published on the Boost website, providing library maintainers and users with up-to-date information about the library’s compatibility and performance. Library maintainers use this information to identify and fix any issues before a release.

    +
    +
    +
    +
    +
    +

    Beta and Final Release

    +
    +
    +

    There is a strict countdown to a public release. Four weeks prior to the release date the Beta release is published to the Boost site.

    +
    +
    +

    If issues are found with a release that has gone public, and the issues are important enough to address quickly (that is, before the next full public release), then a point release will be built when fixes are available and tested.

    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    For details of the Release Process that are pertinent to contributors, refer to the Contributor Guide Release Process.

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/reporting-issues.html b/preview/user-guide/reporting-issues.html new file mode 100644 index 0000000..1fc34e6 --- /dev/null +++ b/preview/user-guide/reporting-issues.html @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + Reporting Issues :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Reporting Issues

    +
    +
    +
    +

    If you come across a bug, or other issue, with one of the libraries, go through the following process to report it:

    +
    +
    +
      +
    1. +

      If you know where to look in the source code, make sure the bug isn’t already fixed in the latest sources, refer to the Boost.org repositories.

      +
    2. +
    3. +

      Search the issues on GitHub to make sure we don’t already know about the bug. If we do, you can certainly add further information to an existing bug ticket.

      +
    4. +
    5. +

      If the bug has not been fixed already, and there is no relevant issue, then report it.

      +
    6. +
    +
    +
    +
    +
    +

    Bug and Issue Reporting

    +
    +
    +

    The repositories use the built-in GitHub issue tracker. With Boost, users are encouraged to use the issue tracker for discussions and feature requests, as well as to report bugs and other issues.

    +
    +
    +

    To report an issue, locate the New Issue button in the repo for the library. For example, https://github.com/boostorg/json/issues for the Boost.Json library.

    +
    +
    +

    When reporting a bug or issue, you might be offered a range of templates to choose from to guide your filing. If there is no template to follow, cut-and-paste the following into the text field for the issue, and replace the text in italics with appropriate details.

    +
    +
    +
    +
    ### Version of Boost
    +
    +_Enter the Boost version number, such as `1.82.0`._
    +
    +### Actual and Expected Behavior
    +
    +_Describe the result you got, and what you consider the result should be._
    +
    +_Attach a _minimal_ and _complete_ program that reproduces the problem._
    +
    +_Aside from helping the library maintainer fix the problem, you may find the bug in your own code, which can avoid a costly delay waiting for a response._
    +
    +### Steps necessary to reproduce the problem
    +
    +_Describe the problem carefully, including steps required to reproduce it by library maintainers._
    +
    +_A small compiling program is the best. If your code is public, you can provide a link to the repository._
    +
    +### All relevant compiler information
    +
    +_If you are unable to compile include the type and version of compiler you are using as well as all compiler output including the error message, file, and line numbers involved._
    +
    +
    +
    +

    The more information you provide the sooner your issue can get resolved.

    +
    +
    +
    +
    Note
    +
    +

    Currently, the Boost Super-project does not use the GitHub Discussion feature. If filing an issue does not seem appropriate, post on the Boost developers mailing list.

    +
    +
    +
    +
    +
    +
    +

    See Also

    +
    +
    +

    For information on issues from the library contributor’s perspective, refer to Version Control.

    +
    + +
    +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/resources.html b/preview/user-guide/resources.html new file mode 100644 index 0000000..45bfd18 --- /dev/null +++ b/preview/user-guide/resources.html @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + Resources :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Resources

    +
    +
    +
    +

    For additional resources when it comes to learning about and using Boost, there are some helpful external options. If you like hard-copy format, there is a range of published Books. If you prefer an online format, there are quite a few tutorials published on YouTube. These options are good at giving the overall picture, and getting you started.

    +
    +
    +

    If you have very specific technical questions Stack Overflow may well have the answer.

    +
    +
    +
    + +
    +

    YouTube

    +
    +
    +

    Consider searching YouTube for online tutorials. There are tutorials on installing Boost, a beginners guide to Boost, introductions to individual libraries (such as Boost.Variant and Boost.Python), and on contributing libraries to Boost.

    +
    +
    +
    +
    +

    Stack Overflow

    +
    +
    +

    For more specific technical questions, Stack Overflow has many questions and answers:

    +
    + +
    +
    +
    +

    Reddit

    +
    +
    +

    Questions and answers of varying technical depth:

    +
    +
    + +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/syntax-highlight-test.html b/preview/user-guide/syntax-highlight-test.html new file mode 100644 index 0000000..9958f3d --- /dev/null +++ b/preview/user-guide/syntax-highlight-test.html @@ -0,0 +1,704 @@ + + + + + + + + + + + + + + Syntax Highlighting: Dark Mode Before/After :: Boost Site Docs + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Syntax Highlighting: Dark Mode Before/After

    +
    +
    +
    +

    This page compares syntax highlighting in dark mode before and after the fixes. Toggle dark mode to see the difference. The "Before" column shows the old behavior (light-theme colors on dark background). The "After" column shows the corrected Atom One Dark colors.

    +
    +
    +
    +
    +

    Bash

    +
    +
    +
    +

    Before

    +
    #!/bin/bash
    +NAME="Boost"
    +BUILD_DIR="${HOME}/build/${NAME}"
    +
    +build_library() {
    +    local lib_name="$1"
    +    echo "Building ${lib_name}..."
    +    mkdir -p "$BUILD_DIR"
    +    if [ -f "CMakeLists.txt" ]; then
    +        cmake -DCMAKE_BUILD_TYPE=Release .
    +        make -j$(nproc)
    +    fi
    +}
    +
    +LIBRARIES=("filesystem" "system" "thread")
    +for lib in "${LIBRARIES[@]}"; do
    +    build_library "$lib"
    +done
    +
    +
    +

    After

    +
    #!/bin/bash
    +NAME="Boost"
    +BUILD_DIR="${HOME}/build/${NAME}"
    +
    +build_library() {
    +    local lib_name="$1"
    +    echo "Building ${lib_name}..."
    +    mkdir -p "$BUILD_DIR"
    +    if [ -f "CMakeLists.txt" ]; then
    +        cmake -DCMAKE_BUILD_TYPE=Release .
    +        make -j$(nproc)
    +    fi
    +}
    +
    +LIBRARIES=("filesystem" "system" "thread")
    +for lib in "${LIBRARIES[@]}"; do
    +    build_library "$lib"
    +done
    +
    +
    +
    +
    +
    +

    HTML

    +
    +
    +
    +

    Before

    +
    <!DOCTYPE html>
    +<html lang="en">
    +<head>
    +    <meta charset="UTF-8">
    +    <title>Boost C++ Libraries</title>
    +    <link rel="stylesheet" href="/css/styles.css">
    +</head>
    +<body>
    +    <header class="main-header" id="top">
    +        <nav>
    +            <a href="/">Boost</a>
    +        </nav>
    +    </header>
    +    <!-- Main content -->
    +    <h1>Welcome</h1>
    +</body>
    +</html>
    +
    +
    +

    After

    +
    <!DOCTYPE html>
    +<html lang="en">
    +<head>
    +    <meta charset="UTF-8">
    +    <title>Boost C++ Libraries</title>
    +    <link rel="stylesheet" href="/css/styles.css">
    +</head>
    +<body>
    +    <header class="main-header" id="top">
    +        <nav>
    +            <a href="/">Boost</a>
    +        </nav>
    +    </header>
    +    <!-- Main content -->
    +    <h1>Welcome</h1>
    +</body>
    +</html>
    +
    +
    +
    +
    +
    +

    YAML

    +
    +
    +
    +

    Before

    +
    # Antora playbook
    +site:
    +  title: Boost C++ Libraries
    +  url: https://www.boost.io
    +
    +content:
    +  sources:
    +    - url: https://github.com/boostorg/website-v2-docs.git
    +      branches: [develop, master]
    +
    +ui:
    +  bundle:
    +    url: ./antora-ui/build/ui-bundle.zip
    +
    +runtime:
    +  fetch: true
    +  log:
    +    level: warn
    +
    +
    +

    After

    +
    # Antora playbook
    +site:
    +  title: Boost C++ Libraries
    +  url: https://www.boost.io
    +
    +content:
    +  sources:
    +    - url: https://github.com/boostorg/website-v2-docs.git
    +      branches: [develop, master]
    +
    +ui:
    +  bundle:
    +    url: ./antora-ui/build/ui-bundle.zip
    +
    +runtime:
    +  fetch: true
    +  log:
    +    level: warn
    +
    +
    +
    +
    +
    +

    Python

    +
    +
    +
    +

    Before

    +
    #!/usr/bin/env python3
    +"""Build script for Boost documentation."""
    +
    +import os
    +import subprocess
    +from pathlib import Path
    +from typing import List, Optional
    +
    +BOOST_VERSION = "1.84.0"
    +
    +class DocBuilder:
    +    def __init__(self, version: str):
    +        self.version = version
    +        self._libraries: List[str] = []
    +
    +    def build(self) -> bool:
    +        for lib in self._libraries:
    +            print(f"Building {lib}...")
    +            result = subprocess.run(
    +                ["antora", "--fetch"],
    +                capture_output=True,
    +            )
    +            if result.returncode != 0:
    +                return False
    +        return True
    +
    +
    +

    After

    +
    #!/usr/bin/env python3
    +"""Build script for Boost documentation."""
    +
    +import os
    +import subprocess
    +from pathlib import Path
    +from typing import List, Optional
    +
    +BOOST_VERSION = "1.84.0"
    +
    +class DocBuilder:
    +    def __init__(self, version: str):
    +        self.version = version
    +        self._libraries: List[str] = []
    +
    +    def build(self) -> bool:
    +        for lib in self._libraries:
    +            print(f"Building {lib}...")
    +            result = subprocess.run(
    +                ["antora", "--fetch"],
    +                capture_output=True,
    +            )
    +            if result.returncode != 0:
    +                return False
    +        return True
    +
    +
    +
    +
    +
    +

    JSON

    +
    +
    +
    +

    Before

    +
    {
    +    "name": "@antora/ui-default",
    +    "version": "1.0.0",
    +    "dependencies": {
    +        "highlight.js": "^11.9.0"
    +    },
    +    "engines": {
    +        "node": ">= 16.0.0"
    +    },
    +    "private": true,
    +    "license": "BSL-1.0"
    +}
    +
    +
    +

    After

    +
    {
    +    "name": "@antora/ui-default",
    +    "version": "1.0.0",
    +    "dependencies": {
    +        "highlight.js": "^11.9.0"
    +    },
    +    "engines": {
    +        "node": ">= 16.0.0"
    +    },
    +    "private": true,
    +    "license": "BSL-1.0"
    +}
    +
    +
    +
    +
    +
    +

    CSS

    +
    +
    +
    +

    Before

    +
    /* Dark mode overrides */
    +:root {
    +    --bg-primary: #ffffff;
    +    --text-primary: #18191b;
    +}
    +
    +html.dark {
    +    --bg-primary: #282c34;
    +}
    +
    +.hljs-keyword {
    +    color: var(--code-keyword);
    +    font-weight: 600;
    +}
    +
    +pre code {
    +    display: block;
    +    padding: 1rem;
    +    font-size: 0.875rem;
    +}
    +
    +
    +

    After

    +
    /* Dark mode overrides */
    +:root {
    +    --bg-primary: #ffffff;
    +    --text-primary: #18191b;
    +}
    +
    +html.dark {
    +    --bg-primary: #282c34;
    +}
    +
    +.hljs-keyword {
    +    color: var(--code-keyword);
    +    font-weight: 600;
    +}
    +
    +pre code {
    +    display: block;
    +    padding: 1rem;
    +    font-size: 0.875rem;
    +}
    +
    +
    +
    +
    +
    +

    JavaScript

    +
    +
    +
    +

    Before

    +
    'use strict'
    +
    +const hljs = require('highlight.js/lib/common')
    +
    +/**
    + * Process code blocks after highlight.js runs.
    + * @param {string} selector - CSS selector
    + * @returns {number} count
    + */
    +function processBlocks(selector) {
    +    const elements = document.querySelectorAll(selector)
    +    let count = 0
    +
    +    elements.forEach((el) => {
    +        if (el.classList.contains('processed')) return
    +        el.classList.add('processed')
    +        count++
    +    })
    +    return count
    +}
    +
    +module.exports = { processBlocks }
    +
    +
    +

    After

    +
    'use strict'
    +
    +const hljs = require('highlight.js/lib/common')
    +
    +/**
    + * Process code blocks after highlight.js runs.
    + * @param {string} selector - CSS selector
    + * @returns {number} count
    + */
    +function processBlocks(selector) {
    +    const elements = document.querySelectorAll(selector)
    +    let count = 0
    +
    +    elements.forEach((el) => {
    +        if (el.classList.contains('processed')) return
    +        el.classList.add('processed')
    +        count++
    +    })
    +    return count
    +}
    +
    +module.exports = { processBlocks }
    +
    +
    +
    +
    +
    +

    Plain pre (no hljs — e.g. "Expected Output")

    +
    +
    +
    +

    Before

    +
    === uint128_t Construction ===
    +From builtin (42U): 42
    +From parts (1, 0) = 2^64: 18446744073709551616
    +From parts (max, max): 340282366920938463463374607431768211455
    +  Equals numeric_limits max? true
    +From literal "36893488147419103232"_U128: 36893488147419103232
    +
    +=== Default and Copy Construction ===
    +Default constructed: 0
    +Copy constructed: 36893488147419103232
    +
    +
    +

    After

    +
    === uint128_t Construction ===
    +From builtin (42U): 42
    +From parts (1, 0) = 2^64: 18446744073709551616
    +From parts (max, max): 340282366920938463463374607431768211455
    +  Equals numeric_limits max? true
    +From literal "36893488147419103232"_U128: 36893488147419103232
    +
    +=== Default and Copy Construction ===
    +Default constructed: 0
    +Copy constructed: 36893488147419103232
    +
    +
    +
    +
    + +
    +
    + +
    + + diff --git a/preview/user-guide/task-aeronautical-engineering.html b/preview/user-guide/task-aeronautical-engineering.html new file mode 100644 index 0000000..b34d35d --- /dev/null +++ b/preview/user-guide/task-aeronautical-engineering.html @@ -0,0 +1,944 @@ + + + + + + + + + + + + + + Aeronautical Engineering :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Aeronautical Engineering

    +
    +
    +
    +

    There are some specific challenges in the design and building of aircraft, that are less pronounced in other engineering disciples. These challenges include the size of the development teams, all working on one project, the strong presence of regulation and certification, and the unglamorous but mission-critical need for numerical correctness, stability, and traceability. Aerospace software lives for decades, must behave identically across platforms, and is scrutinized by certification authorities who care far more about bounded error than raw speed.

    +
    +
    +

    This topic examines the pressure on software engineers when working in the aeronautical design space: a space where sqrt(x*x + y*y) might not be acceptable, whereas boost::math::hypot(x, y); works.

    +
    + +
    +
    +
    +

    Aeronautical Design Fundamentals

    +
    +
    +

    Boost Libraries have a number of components that can play important roles in building a co-operative (distributed) design system. These libraries won’t give you a full “collaboration system” out of the box, but they provide powerful building blocks for networking, concurrency, data exchange, task distribution, serialization, and scripting integration — all foundational pieces of a distributed CAD/PDM/PLM system.

    +
    +
    +

    A cooperative aircraft design system must support:

    +
    +
    +
      +
    1. +

      Distributed teams (multiple time zones, intermittent connectivity)

      +
    2. +
    3. +

      Strong data integrity and traceability (certification pressure)

      +
    4. +
    5. +

      Concurrent edits on large models (geometry, constraints, metadata)

      +
    6. +
    7. +

      Heavy computation (FEA, CFD, optimization)

      +
    8. +
    9. +

      Modular extensibility (tools evolve over decades)

      +
    10. +
    +
    +
    +

    Aircraft design blueprint

    +
    +
    +

    The modelling service component owns the "truth" of geometry and constraints. Conflict resolution is a well known challenge - engineer A moves an aircraft rib, whilst engineer B instead, increases the rib thickness. Something like this may well need to be flagged for human resolution

    +
    +
    +

    When building a system for use anywhere in the aerospace industry, it is a good idea to stick to these core principles:

    +
    +
    +
      +
    1. +

      Command determinism - No hidden randomness and no time-based logic without injected clocks.

      +
    2. +
    3. +

      Immutable inputs - Commands are value objects and model state is derived, not mutated ad hoc.

      +
    4. +
    5. +

      Controlled time - Simulated time replaces wall-clock time.

      +
    6. +
    7. +

      Replay-first mindset - Tests are replays and live execution is just “replay at real-time speed”.

      +
    8. +
    9. +

      Time-Travel Debugging - Step forward and backward through events.

      +
    10. +
    11. +

      Section Cuts (an aerospace favorite) - Auto-generate spanwise cuts (1), diff cross-sections, and plot profiles.

      +
    12. +
    +
    +
    +

    A deterministic simulation of engineering intent is what exactly what certification bodies care about.

    +
    +
    +

    Design and simulation are a big part of the story. Then comes testing.

    +
    +
    +

    In aerospace terms: if you can’t replay it, you can’t certify it. An aircraft test harness must answer questions like:

    +
    +
    +
      +
    • +

      Can we replay every design change exactly?

      +
    • +
    • +

      Are distributed services deterministic?

      +
    • +
    • +

      Does concurrency produce identical results across runs?

      +
    • +
    • +

      Can we detect regressions in geometry, constraints, and analysis?

      +
    • +
    • +

      Can we reproduce a failure years later?

      +
    • +
    +
    +
    +

    This goes far beyond unit tests.

    +
    +
    +

    One of Boost’s quiet superpowers is numerical correctness without fanfare - the standard library often prioritizes simplicity whereas Boost prioritizes correctness. Numerical errors are design flaws, not rounding accidents!

    +
    +
    +
    +
    Note
    +
    +

    Acronyms are dense in aerospace. FEA is Finite Element Analysis (essentially breaking complex structures into small elements for testing and behavior). CFD is Computational Fluid Dynamics (for example, modelling turbulence). PLM is Product Lifecycle Management (tracking changes, metadata, milestones) but can also mean Part Load Management. PDM is Product Data Management, managing exactly what data exists and which version is authoritative, but it can also mean Power Distribution Module. Context is mandatory - the unofficial rule is "if someone doesn’t ask for clarification, they probably misunderstand"!

    +
    +
    +
    +
    +
    +
    +

    Libraries

    +
    +
    +
      +
    • +

      Boost.Math : Provides carefully implemented, well-documented algorithms for elementary and special functions with known accuracy characteristics, correct handling of edge cases, and predictable behavior across compilers and architectures. Functions like hypot, robust inverse trig, stable polynomial evaluation, and well-behaved probability distributions eliminate entire classes of silent numerical failures that are notoriously hard to reproduce and even harder to certify. Equally important, this library supports a verification-first engineering culture. Its scale-aware comparisons, error bounds, and compatibility with multi-precision backends allow engineers to create reference implementations and numerical “gold standards” alongside high-performance code. This is exactly what certification demands: the ability to demonstrate not only that results are fast, but that they are correct within defined tolerances, repeatable years later, and defensible under audit. The library quietly delivers numerical trust, and avoid such things as floating-point drift and order-dependent drift.

      +
    • +
    +
    +
    +

    Boost.Multiprecision : For when extremely large or small numbers need to be calculated, with great precision.

    +
    +
    +

    Aircraft gear blueprint

    +
    +
    +
      +
    • +

      Boost.Accumulators : This provides numerically stable statistics, preventing summation_drift and an answer to never sum large datasets naïvely.

      +
    • +
    • +

      Boost.Asio : A distributed design system must support robust, scalable communication — real-time updates, distributed computation requests, and client-server synchronization.

      +
    • +
    • +

      Boost.Serialization and Boost.Interprocess :Save/load complex design models, and useful if modules on the same machine need fast shared data access.

      +
    • +
    • +

      Boost.Geometry, Boost.Polygon, and Boost.Graph : These libs work well with design and CAD-related math, 2D polygon manipulation, and representing complex relationships (dependency graphs, design hierarchies).

      +
    • +
    • +

      Boost.Thread, Boost.Lockfree, and Boost.Fiber : All to provide UI responsiveness with background computations.

      +
    • +
    • +

      Boost.Signals2 : Useful for local publish/subscribe patterns within a module.

      +
    • +
    • +

      Boost.ProgramOptions and Boost.PropertyTree : Useful for server/service configuration and for storing structured metadata.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Demonstrating Range Failure

    +
    +
    +

    In order to show the effects of unmanaged numerical ranges, we’ll calculate the hypotenuse of a simple right-angled triangle. The two sides of the triangle are of equal length, so the result should be the square root of 2 (1.4142…​) times the length of one of the sides. This is true if the sides of the triangle are both 1, or both 1 zillion.

    +
    +
    +

    The naive version tries to calculate the hypotenuse using standard math.

    +
    +
    +
    +
    #include <cmath>
    +#include <iostream>
    +
    +double naive_hypot(double x, double y)
    +{
    +    return std::sqrt(x * x + y * y);
    +}
    +
    +int main()
    +{
    +    double x = 1e154;
    +    double y = 1e154;
    +
    +    double result = naive_hypot(x, y);
    +
    +    std::cout << "Naive hypot result: " << result << "\n";
    +
    +    if (std::isinf(result))
    +        std::cout << "Result overflowed to infinity\n";
    +}
    +
    +
    +
    +

    If you run this code, you will probably get:

    +
    +
    +
    +
    Naive hypot result: inf
    +Result overflowed to infinity
    +
    +
    +
    +

    You should also have noticed that you did not get an error, warning, or exception. So, what happened?

    +
    +
    +

    The answer is the square of the huge values overflowed.

    +
    +
    +

    Now try using Boost.:math.

    +
    +
    +
    +
    #include <boost/math/special_functions/hypot.hpp>
    +#include <iostream>
    +
    +int main()
    +{
    +    double x = 1e154;
    +    double y = 1e154;
    +
    +    double result = boost::math::hypot(x, y);
    +
    +    std::cout << "Boost hypot result: " << result << "\n";
    +}
    +
    +
    +
    +

    If you run this version, you should get the correct result:

    +
    +
    +
    +
    Boost hypot result: 1.41421e+154
    +
    +
    +
    +

    Boost.Math uses scaling algorithms so that errors are avoided in the edge cases of handling very large values, or for that matter very tiny values.

    +
    +
    +

    The difference between sqrt(x*x + y*y) and boost::math::hypot(x, y) is not performance or convenience — it is whether intermediate values are allowed to destroy correctness.

    +
    +
    +
    +
    +

    Demonstrating Underflow

    +
    +
    +

    Underflow is the quiet sibling of overflow and much closer in spirit to drift. Underflow occurs when a result is too small to be represented as a normal floating-point number and is rounded to zero.

    +
    +
    +

    The following code shows repeated division, eventually resulting in underflow:

    +
    +
    +
    +
    #include <iostream>
    +#include <iomanip>
    +
    +int main()
    +{
    +    double x = 1.0;
    +
    +    std::cout << std::setprecision(17);
    +
    +    for (int i = 0; i < 1100; ++i)
    +    {
    +        x /= 2.0;
    +
    +        if (x == 0.0)
    +        {
    +            std::cout << "Underflow to zero at iteration " << i << "\n";
    +            break;
    +        }
    +    }
    +
    +    std::cout << "Final value: " << x << "\n";
    +}
    +
    +
    +
    +

    Run this code:

    +
    +
    +
    +
    Underflow to zero at iteration 1074
    +Final value: 0
    +
    +
    +
    +

    The double does have around 308 bits of range (and 52 bits of mantissa), but eventually precision collapses. Boost.Math can improve numerical stability, but it cannot extend the representable range of a floating-point type. If the value is important, then we add Boost.Multiprecision to our toolset:

    +
    +
    +
    +
    #include <boost/multiprecision/cpp_bin_float.hpp>
    +#include <iostream>
    +#include <iomanip>
    +
    +using highp = boost::multiprecision::cpp_bin_float_100;
    +
    +int main()
    +{
    +    highp x = 1.0;
    +
    +    for (int i = 0; i < 1100; ++i)
    +        x /= 2;
    +
    +    std::cout << std::scientific << std::setprecision(50);
    +    std::cout << "Value after division: " << x << "\n";
    +}
    +
    +
    +
    +

    Run this:

    +
    +
    +
    +
    Value after division: 7.36215182902286267543686617714496511764913503250964e-332
    +
    +
    +
    +

    Aeronautical models need to cope with situations like long-duration decay processes, residual convergence (2), damping terms, energy dissipation, and very small forces accumulated over time. The key concept here is that zero is physically wrong!

    +
    +
    +

    For a second example, let’s examine where underflow destroys a physical invariant. In the following code the super small but non-zero velocity value is lost:

    +
    +
    +
    +
    #include <iostream>
    +#include <iomanip>
    +
    +int main()
    +{
    +    double velocity = 1e-300;   // Very small, but non-zero
    +    double dt = 1e-300;         // Time step
    +
    +    double displacement = velocity * dt;
    +
    +    std::cout << std::setprecision(17);
    +    std::cout << "Displacement: " << displacement << "\n";
    +
    +    if (displacement == 0.0)
    +        std::cout << "Underflow: motion lost\n";
    +}
    +
    +
    +
    +

    Run the code:

    +
    +
    +
    +
    Displacement: 0
    +Underflow: motion lost
    +
    +
    +
    +

    Again we look to Boost.Multiprecision to maintain the significance of a tiny value:

    +
    +
    +
    +
    #include <boost/multiprecision/cpp_dec_float.hpp>
    +#include <iostream>
    +
    +using highp = boost::multiprecision::cpp_dec_float_50;
    +
    +int main()
    +{
    +    highp velocity = highp("1e-300");
    +    highp dt       = highp("1e-300");
    +
    +    highp displacement = velocity * dt;
    +
    +    std::cout << displacement << "\n";
    +}
    +
    +
    +
    +

    Run this and you get the correct answer:

    +
    +
    +
    +
    1e-600
    +
    +
    +
    +

    In physical models, if motion exists, it should be represented.

    +
    +
    +

    For the aerospace engineer underflow is dangerous because it is so quiet that incorrect results can look plausible, zero is, after all, a valid number.

    +
    +
    +
    +
    +

    Demonstrating Order-Dependent Drift

    +
    +
    +

    Order-dependent drift is one of the most misunderstood floating-point hazards, and it shows up constantly in aerospace (summations of forces, energies, residuals, loads).

    +
    +
    +

    Order-dependent drift occurs because floating-point addition is not associative: (a + b) + c does not equal a + (b + c) when one, or more, value is very large and other values are very small. Physically, the small forces matter. Numerically, they may disappear.

    +
    +
    +

    In the following example, the small forces are silently discarded:

    +
    +
    +
    +
    #include <vector>
    +#include <iostream>
    +#include <iomanip>
    +
    +double naive_sum(const std::vector<double>& values)
    +{
    +    double sum = 0.0;
    +    for (double v : values)
    +        sum += v;
    +    return sum;
    +}
    +
    +int main()
    +{
    +    std::vector<double> forces;
    +
    +    forces.push_back(1e20);          // Large load
    +    for (int i = 0; i < 1'000'000; ++i)
    +        forces.push_back(1.0);       // Small loads
    +
    +    double result = naive_sum(forces);
    +
    +    std::cout << std::setprecision(17);
    +    std::cout << "Naive sum: " << result << "\n";
    +}
    +
    +
    +
    +

    Run this and you get the answer:

    +
    +
    +
    +
    Naive sum: 1e+20
    +
    +
    +
    +

    Boost provides numerically stable accumulation algorithms via Boost.Accumulators. In the following example, small values are preserved and order no longer matters.

    +
    +
    +

    Kahan summation (3) keeps a compensation term that tracks lost low-order bits:

    +
    +
    +
    +
    #include <boost/accumulators/accumulators.hpp>
    +#include <boost/accumulators/statistics/sum_kahan.hpp>
    +#include <iostream>
    +#include <iomanip>
    +
    +
    +using namespace boost::accumulators;
    +
    +int main()
    +{
    +    accumulator_set<double, features<tag::sum_kahan>> acc;
    +
    +    acc(1e20);
    +    for (int i = 0; i < 1'000'000; ++i)
    +        acc(1.0);
    +
    +    std::cout << std::setprecision(17);
    +    std::cout << "Boost Kahan sum: " << sum(acc) << "\n";
    +}
    +
    +
    +
    +

    Run this and you get the correct answer:

    +
    +
    +
    +
    Boost Kahan sum: 1.00000000000001e+20
    +
    +
    +
    +

    Order-dependent drift is not randomness — it is determinism you didn’t control.

    +
    +
    +
    +
    Note
    +
    +

    Boost.Accumulators and Boost.Math are known for compiling cleanly only once every required header is present and all parameters are present and correct. Otherwise these libs can generate a lot of errors.

    +
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    Wrap your mind around the high level architecture, think federated services, not a monolith:

    +
    +
    +
    +
    ┌────────────┐     ┌────────────┐
    +│ CAD Client │     │ Analysis   │
    +│            │     │ Client     │
    +└─────┬──────┘     └─────┬──────┘
    +      │                  │
    +      ├───────┬──────────┤
    +              ▼
    +     ┌───────────────────────┐
    +     │ Collaboration Gateway │
    +     │(Boost.Asio/Beast/Json)│
    +     └──────────┬────────────┘
    +                │
    + ┌──────────────┼──────────────────┐
    + │              │                  │
    + ▼              ▼                  ▼
    +Model Service  Compute Service   Metadata Service
    +(Geometry)     (FEA/CFD)         (PLM / audit)
    +
    +
    +
    +

    And consider your test harness/certification architecture right from the start:

    +
    +
    +
    +
    ┌──────────────────────────────┐
    +│ Test Runner (CLI)            │
    +│ (Boost.ProgramOptions)       │
    +└────────────┬─────────────────┘
    +             ▼
    +┌──────────────────────────────┐
    +│ Scenario Loader              │
    +│ (Boost.Filesystem)           │
    +└────────────┬─────────────────┘
    +             ▼
    +┌──────────────────────────────┐
    +│ Event Replayer               │
    +│ (Boost.Serialization)        │
    +└────────────┬─────────────────┘
    +             ▼
    +┌──────────────────────────────┐
    +│ Virtual Services             │
    +│ (Model / Compute / Metadata) │
    +└────────────┬─────────────────┘
    +             ▼
    +┌──────────────────────────────┐
    +│ Verifier                     │
    +│ (Boost.Test / Geometry)      │
    +└──────────────────────────────┘
    +
    +
    +
    +

    Start with correctness in mind, and continue along that path.

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +A spanwise cut is a cross-section taken along the span of a wing or lifting surface, from the wing root (near the fuselage) toward the wing tip. It is used to examine how properties vary across the width of the wingspan, rather than along the flight direction. Nothing is even across the span of a wing, and spanwise cuts are used to measure pressure coefficients, bending stress, fatigue hot spots, baseline verses modified wing geometry, and loads of various sorts.

    +
    +
    +

    (2) +Residual convergence is about measuring how wrong your current solution still is, rather than how much the solution (the result) itself is changing. Residuals are a measure of the errors, and if the residuals flatten out or oscillate, something is wrong. Even if your solver converges, a non-shrinking residual means you might be converging to the wrong answer.

    +
    +
    +

    (3) +Kahan summation is a technique for adding lots of floating-point numbers while losing far less precision than sum += x. This technique keeps a small “error accumulator” that tracks the bits lost to rounding — and feeds them back in on the next addition. In simple terms, you don’t get more precision than double allows, but you stop throwing it away. In aerospace, bio-tech, finance, and simulation code, it’s one of those “once you see it, you never un-see it” techniques.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-ai-client.html b/preview/user-guide/task-ai-client.html new file mode 100644 index 0000000..932e5f9 --- /dev/null +++ b/preview/user-guide/task-ai-client.html @@ -0,0 +1,1171 @@ + + + + + + + + + + + + + + AI Client :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    AI Client

    +
    +
    +
    +

    Many apps across all sorts of scenarios might significantly benefit from some artificial intelligence (AI). Writing your own AI system is a big task, an alternative is a subscription to an AI system, accessible through networked API calls. This section shows how to use some Boost libraries in a client app to send requests to ChatGPT, and receive and process responses.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are the libraries that are most directly applicable to writing a client app:

    +
    +
    +
      +
    • +

      Boost.Json: An efficient library for parsing, serializing, and manipulating JSON data. This is useful specifically in client-server communication and web services.

      +
    • +
    • +

      Boost.Beast: This is a library built on top of Boost.Asio that provides implementations of HTTP and WebSockets.

      +
    • +
    • +

      Boost.Asio: A cross-platform C++ library for network and low-level I/O programming. It provides a consistent asynchronous model using a modern C++ approach. Boost.Asio supports a variety of network protocols, including ICMP, TCP, and UDP.

      +
      +
      +
      Notes
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0. In order to get the example to run, you will need an Open AI API account in order to obtain an API key, Organization Id, and credits for API calls. There may be usage fees involved.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    AI Text Client

    +
    +
    +

    The following code enables the writing of queries to a command window prompt, and sends them to ChatGPT for processing. For debugging and educational purposes the HTTP request is displayed, but masking the API key and Organization Id.

    +
    +
    +

    Prerequisites

    +
    +
      +
    1. +

      You will need an Open AI API account, where you can obtain both the API key and Organization Id. You will also need to ensure you have credits for API calls.

      +
    2. +
    3. +

      Ensure your CA certificates are up to date, and you know the path to cacert.pem.

      +
    4. +
    +
    +
    +

    We use the features of Boost.Beast and Boost.Json to aid in the writing of the client:

    +
    +
    +
    +
    #include <boost/beast/core.hpp>
    +#include <boost/beast/ssl.hpp>
    +#include <boost/beast/http.hpp>
    +#include <boost/beast/version.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +
    +namespace beast = boost::beast;         // Common Boost.Beast types
    +namespace http = beast::http;           // HTTP-specific types
    +namespace net = boost::asio;            // Networking (Asio)
    +namespace ssl = boost::asio::ssl;       // SSL/TLS
    +namespace json = boost::json;           // JSON handling
    +using tcp = boost::asio::ip::tcp;       // TCP networking
    +
    +//------------------------------------------------------------------------------
    +// Function to query the OpenAI Chat API
    +//------------------------------------------------------------------------------
    +std::string query_chatgpt(
    +    const std::string& api_key,         // OpenAI API key (Bearer token)
    +    const std::string& org_id,          // OpenAI Organization ID
    +    const std::string& user_prompt)     // User's question/prompt
    +{
    +    const std::string host = "api.openai.com";
    +    const std::string port = "443";
    +    const std::string target = "/v1/chat/completions"; // Chat API endpoint
    +
    +    net::io_context ioc;                // Asio I/O context for event-driven networking
    +
    +    //-------------------------------
    +    // SSL/TLS setup
    +    //-------------------------------
    +    ssl::context ctx{ ssl::context::sslv23_client }; // Use TLS client
    +    ctx.set_default_verify_paths();                  // Use system's CA certs
    +    ctx.set_verify_mode(ssl::verify_peer);           // Verify server identity
    +
    +    // Create an SSL stream (TCP + TLS)
    +    beast::ssl_stream<beast::tcp_stream> stream{ ioc, ctx };
    +
    +    // Enable Server Name Indication (SNI) for TLS
    +    if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()))
    +        throw beast::system_error{
    +            beast::error_code(static_cast<int>(::ERR_get_error()),
    +                              net::error::get_ssl_category()) };
    +
    +    //-------------------------------
    +    // Connect to OpenAI server
    +    //-------------------------------
    +    tcp::resolver resolver{ ioc };
    +    auto const results = resolver.resolve(host, port); // DNS lookup
    +    beast::get_lowest_layer(stream).connect(results);  // TCP connect
    +    stream.handshake(ssl::stream_base::client);        // TLS handshake
    +
    +    //-------------------------------
    +    // Build the JSON request body
    +    //-------------------------------
    +    json::array messages;
    +    messages.push_back({ {"role", "user"}, {"content", user_prompt} });
    +
    +    json::object body;
    +    body["model"] = "gpt-4o-mini";                  // Choose the OpenAI model
    +    body["messages"] = messages;
    +
    +    std::string body_str = json::serialize(body);   // Convert JSON to string
    +
    +    //-------------------------------
    +    // Build HTTP POST request
    +    //-------------------------------
    +    http::request<http::string_body> req{ http::verb::post, target, 11 }; // HTTP/1.1
    +    req.set(http::field::host, host);
    +    req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
    +    req.set(http::field::authorization, "Bearer " + api_key);   // API key
    +    req.set("OpenAI-Organization", org_id);                     // Org ID
    +    req.set(http::field::content_type, "application/json");
    +    req.set(http::field::accept, "application/json");
    +    req.body() = body_str;
    +    req.prepare_payload();                                      // Set Content-Length header automatically
    +
    +    // ===== RAW HTTP REQUEST DUMP (with masked API key) =====
    +    {
    +        http::request<http::string_body> masked_req = req;
    +        masked_req.set(http::field::authorization, "Bearer ***********************");
    +        masked_req.set("OpenAI-Organization", "***********************");
    +        std::cout << "\n===== RAW HTTP REQUEST =====\n";
    +        std::cout << masked_req << "\n";
    +        std::cout << "===== END RAW HTTP REQUEST =====\n\n";
    +    }
    +
    +
    +    //-------------------------------
    +    // Send request & read response
    +    //-------------------------------
    +    http::write(stream, req);                   // Send request
    +
    +    beast::flat_buffer buffer;                  // Buffer for reading
    +    http::response<http::string_body> res;      // HTTP response container
    +    http::read(stream, buffer, res);            // Read full response
    +
    +    //-------------------------------
    +    // Shutdown TLS connection
    +    //-------------------------------
    +    beast::error_code ec;
    +    stream.shutdown(ec);
    +    if (ec == net::error::eof || ec == ssl::error::stream_truncated)
    +        ec.assign(0, ec.category());            // Ignore harmless shutdown errors
    +    if (ec)
    +        throw beast::system_error{ ec };
    +
    +    //-------------------------------
    +    // Parse JSON response
    +    //-------------------------------
    +    auto parsed = json::parse(res.body());
    +
    +    // Check for "choices" array in response
    +    if (parsed.as_object().if_contains("choices")) {
    +        auto& choices = parsed.at("choices").as_array();
    +        if (!choices.empty()) {
    +            auto& msg = choices[0].as_object().at("message").as_object();
    +            if (msg.if_contains("content")) {
    +                return std::string(msg.at("content").as_string().c_str());
    +            }
    +        }
    +        return "[No content found in choices]";
    +    }
    +
    +    // If "error" present, show error message
    +    else if (parsed.as_object().if_contains("error")) {
    +        auto& err = parsed.at("error").as_object();
    +        return "[API Error] " + std::string(err.at("message").as_string().c_str());
    +    }
    +    else {
    +        return "[Unexpected API response: " + res.body() + "]";
    +    }
    +}
    +
    +//------------------------------------------------------------------------------
    +// MAIN FUNCTION
    +//------------------------------------------------------------------------------
    +int main() {
    +
    +    // Your OpenAI API key & Organization ID
    +    const std::string api_key = "YOUR OPEN AI API KEY";
    +    const std::string org_id = "YOUR OPEN AI ORGANIZATION ID";
    +
    +    _putenv_s("SSL_CERT_FILE", "PATH TO YOUR CA CERTIFICATE\\cacert.pem");
    +
    +    try {
    +        while (true) {
    +
    +            // Ask user for input
    +            std::string prompt;
    +            std::cout << "\nEnter prompt (or type 'exit' to quit): ";
    +            std::getline(std::cin, prompt);
    +
    +            // Exit loop if user types "exit"
    +            if (prompt == "exit")
    +                break;
    +
    +            // Call OpenAI API
    +            std::string response = query_chatgpt(api_key, org_id, prompt);
    +
    +            // Show model's reply
    +            std::cout << "ChatGPT: " << response << "\n";
    +        }
    +    }
    +    catch (const std::exception& e) {
    +
    +        // Handle and display any errors
    +        std::cerr << "Error: " << e.what() << "\n";
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Run the program. If you get an error, most center around authorization issues (valid API key and Organization Id).

    +
    +
    +

    You should be able to write a series of text queries:

    +
    +
    +
    +
    Enter prompt (or type 'exit' to quit): Can you sort the following numbers into ascending order: 14 -8 0 3.5 99 3.14159 ?
    +
    +===== RAW HTTP REQUEST =====
    +POST /v1/chat/completions HTTP/1.1
    +Host: api.openai.com
    +User-Agent: Boost.Beast/357
    +Content-Type: application/json
    +Accept: application/json
    +Content-Length: 144
    +Authorization: Bearer ***********************
    +OpenAI-Organization: ***********************
    +
    +{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Can you sort the following numbers into ascending order: 14 -8 0 3.5 99 3.14159"}]}
    +===== END RAW HTTP REQUEST =====
    +
    +ChatGPT: Sure! Here are the numbers sorted in ascending order:
    +
    +-8, 0, 3.14159, 3.5, 14, 99
    +
    +Enter prompt (or type 'exit' to quit): What is the height of Vesuvius?
    +
    +===== RAW HTTP REQUEST =====
    +POST /v1/chat/completions HTTP/1.1
    +Host: api.openai.com
    +User-Agent: Boost.Beast/357
    +Content-Type: application/json
    +Accept: application/json
    +Content-Length: 96
    +Authorization: Bearer ***********************
    +OpenAI-Organization: ***********************
    +
    +{"model":"gpt-4o-mini","messages":[{"role":"user","content":"What is the height of Vesuvius?"}]}
    +===== END RAW HTTP REQUEST =====
    +
    +ChatGPT: Mount Vesuvius has an elevation of about 1,281 meters (4,203 feet) above sea level. It is known for its dramatic eruptions and is located near Naples, Italy.
    +
    +Enter prompt (or type 'exit' to quit): exit
    +
    +
    +
    +
    +
    +
    +

    Secure AI Text and ASCII Diagram Client

    +
    +
    +

    We can improve on the security of the requests by using HTTPS (via SSL), rather than HTTP. Also, we have added in the feature of requesting ASCII diagrams:

    +
    +
    +
    +
    #include <boost/beast/core.hpp>
    +#include <boost/beast/http.hpp>
    +#include <boost/beast/ssl.hpp>
    +#include <boost/beast/version.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +
    +namespace beast = boost::beast;
    +namespace http = beast::http;
    +namespace net = boost::asio;
    +namespace ssl = boost::asio::ssl;
    +namespace json = boost::json;
    +using tcp = boost::asio::ip::tcp;
    +
    +int main()
    +{
    +    try
    +    {
    +        //-----------------------------------------
    +        // USER CONFIGURATION
    +        //-----------------------------------------
    +        const std::string host = "api.openai.com";
    +        const std::string port = "443";
    +        const std::string target = "/v1/chat/completions";
    +        const int version = 11; // HTTP/1.1
    +
    +        const std::string api_key = "YOUR API KEY";
    +        const std::string org_id = "YOUR ORGANIZATION ID";
    +
    +        _putenv_s("SSL_CERT_FILE", "PATH TO YOUR CA CERTIFICATES\\cacert.pem");
    +
    +        // Optionally, enter your project Id, if you have one.
    +        const std::string project_id = "";
    +
    +        //-----------------------------------------
    +        // SSL/TLS Context
    +        //-----------------------------------------
    +        ssl::context ctx(ssl::context::tls_client);
    +        ctx.set_default_verify_paths();
    +        ctx.set_verify_mode(ssl::verify_peer);
    +
    +        //-----------------------------------------
    +        // I/O Context
    +        //-----------------------------------------
    +        net::io_context ioc;
    +
    +        //-----------------------------------------
    +        // Resolver: hostname → TCP endpoint
    +        //-----------------------------------------
    +        tcp::resolver resolver(ioc);
    +        auto const results = resolver.resolve(host, port);
    +
    +        //-----------------------------------------
    +        // SSL stream over TCP socket
    +        //-----------------------------------------
    +        beast::ssl_stream<tcp::socket> stream(ioc, ctx);
    +
    +        if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()))
    +            throw beast::system_error(
    +                beast::error_code(static_cast<int>(::ERR_get_error()), net::error::get_ssl_category()),
    +                "Failed to set SNI hostname");
    +
    +        //-----------------------------------------
    +        // Connect and handshake
    +        //-----------------------------------------
    +        net::connect(stream.next_layer(), results.begin(), results.end());
    +        stream.handshake(ssl::stream_base::client);
    +
    +        //-----------------------------------------
    +        // Loop for user input
    +        //-----------------------------------------
    +        std::string user_input;
    +        while (true)
    +        {
    +            std::cout << "\nEnter your request (ASCII diagram or text) or 'exit': ";
    +            std::getline(std::cin, user_input);
    +
    +            if (user_input == "exit")
    +                break;
    +
    +            //-----------------------------------------
    +            // JSON request body
    +            //-----------------------------------------
    +            std::string body =
    +                "{"
    +                "\"model\": \"gpt-4o-mini\","
    +                "\"messages\": ["
    +                "{\"role\": \"user\", \"content\": \"" + user_input + "\"}"
    +                "],"
    +                "\"temperature\": 0"
    +                "}";
    +
    +            //-----------------------------------------
    +            // HTTP POST
    +            //-----------------------------------------
    +            http::request<http::string_body> req{ http::verb::post, target, version };
    +            req.set(http::field::host, host);
    +            req.set(http::field::content_type, "application/json");
    +            req.set(http::field::authorization, "Bearer " + api_key);
    +            req.set("OpenAI-Organization", org_id);
    +            if (!project_id.empty()) {
    +                req.set("OpenAI-Project", project_id);
    +            }
    +            req.body() = body;
    +            req.prepare_payload();
    +
    +            //-----------------------------------------
    +            // Send request
    +            //-----------------------------------------
    +            http::write(stream, req);
    +
    +            //-----------------------------------------
    +            // Receive response
    +            //-----------------------------------------
    +            beast::flat_buffer buffer;
    +            http::response<http::string_body> res;
    +            http::read(stream, buffer, res);
    +
    +            //-----------------------------------------
    +            // Parse JSON and extract the assistant's text
    +            //-----------------------------------------
    +            try {
    +                json::value jv = json::parse(res.body());
    +                std::string output;
    +
    +                if (jv.is_object()) {
    +                    auto& obj = jv.as_object();
    +                    if (obj.contains("choices") && obj["choices"].is_array()) {
    +                        auto& choices = obj["choices"].as_array();
    +                        if (!choices.empty()) {
    +                            auto& msg = choices[0].as_object()["message"].as_object();
    +                            if (msg.contains("content")) {
    +                                output = msg["content"].as_string().c_str();
    +                            }
    +                        }
    +                    }
    +                }
    +
    +                // Print raw output so ASCII art formatting is preserved
    +                std::cout << "\nAssistant Response:\n" << output << "\n";
    +
    +            }
    +            catch (const std::exception& e) {
    +                std::cerr << "Failed to parse JSON: " << e.what() << "\n";
    +                std::cerr << "Raw response:\n" << res.body() << "\n";
    +            }
    +        }
    +
    +        //-----------------------------------------
    +        // Graceful SSL shutdown
    +        //-----------------------------------------
    +        beast::error_code ec;
    +        stream.shutdown(ec);
    +        if (ec == net::error::eof) ec = {};
    +        if (ec) throw beast::system_error{ ec };
    +
    +    }
    +    catch (std::exception const& e)
    +    {
    +        std::cerr << "Error: " << e.what() << "\n";
    +        return EXIT_FAILURE;
    +    }
    +
    +    return EXIT_SUCCESS;
    +}
    +
    +
    +
    +

    Run the program. Notice that the ASCII diagram requests have to be fairly simple to avoid an error, and that the diagrams can be clunky representations!

    +
    +
    +
    +
    Enter your request (ASCII diagram or text) or 'exit': Can you draw an ASCII diagram of a speedboat?
    +
    +Assistant Response:
    +Sure! Here's a simple ASCII representation of a speedboat:
    +
    +```
    +        __/__
    +  _____/_____|_____
    +  \              /
    +~~~~~~~~~~~~~~~~~~~~~
    +```
    +
    +Feel free to modify it or let me know if you need something different!
    +
    +Enter your request (ASCII diagram or text) or 'exit': Can you draw an ASCII diagram of an HTTPS request and response?
    +
    +Assistant Response:
    +Certainly! Below is a simple ASCII diagram representing an HTTPS request and response cycle.
    +
    +```
    +Client (Browser)                     Server
    +   |                                    |
    +   | ----------- HTTPS Request -------> |
    +   |                                    |
    +   |                                    |
    +   | <--------- HTTPS Response -------- |
    +   |                                    |
    +```
    +
    +### Breakdown of the Diagram:
    +
    +1. **Client (Browser)**: This is the user's web browser or application that initiates the request.
    +2. **Server**: This is the web server that hosts the website or service the client is trying to access.
    +3. **HTTPS Request**: This is the request sent from the client to the server. It typically includes:
    +   - HTTP method (GET, POST, etc.)
    +   - URL
    +   - Headers (e.g., User-Agent, Accept, etc.)
    +   - Body (for POST requests)
    +4. **HTTPS Response**: This is the response sent from the server back to the client. It typically includes:
    +   - Status code (e.g., 200 OK, 404 Not Found)
    +   - Headers (e.g., Content-Type, Content-Length, etc.)
    +   - Body (the requested resource, such as HTML, JSON, etc.)
    +
    +### Note:
    +- HTTPS (Hypertext Transfer Protocol Secure) ensures that the data exchanged between the client and server is encrypted for security.
    +- The arrows indicate the direction of data flow, with the request going from the client to the server and the response going back from the server to the client.
    +
    +Enter your request (ASCII diagram or text) or 'exit': What is the capital of France?
    +
    +Assistant Response:
    +The capital of France is Paris.
    +
    +Enter your request (ASCII diagram or text) or 'exit': Can you draw me an ASCII diagram of the Eiffel Tower?
    +
    +Assistant Response:
    +Sure! Here's a simple ASCII representation of the Eiffel Tower:
    +
    +```
    +       /\
    +      /  \
    +     /    \
    +    /      \
    +   /        \
    +  /          \
    + /            \
    +/______________\
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +      ||||
    +```
    +
    +This is a basic representation, but I hope you like it!
    +
    +Enter your request (ASCII diagram or text) or 'exit': exit
    +
    +
    +
    +

    Clearly AI produced ASCII diagrams have their limitations!

    +
    +
    +
    +
    +

    AI Generated Image Client

    +
    +
    +

    Let’s improve on those ASCII diagrams by calling the images generation endpoint (/v1/images/generations), taking a text description of the required image, and returning JSON containing a URL with the download link to the image.

    +
    +
    +
    +
    #include <boost/beast/core.hpp>      // Core Beast utilities
    +#include <boost/beast/ssl.hpp>       // SSL/TLS support for Beast
    +#include <boost/beast/http.hpp>      // HTTP request/response
    +#include <boost/beast/version.hpp>   // Version macros
    +#include <boost/json.hpp>            // Boost.JSON for parsing API responses
    +#include <iostream>
    +#include <fstream>
    +
    +namespace beast = boost::beast;          // From <boost/beast.hpp>
    +namespace http = beast::http;            // From <boost/beast/http.hpp>
    +namespace net = boost::asio;             // From <boost/asio.hpp>
    +namespace ssl = boost::asio::ssl;        // From <boost/asio/ssl.hpp>
    +namespace json = boost::json;            // From <boost/json.hpp>
    +using tcp = boost::asio::ip::tcp;        // TCP protocol abstraction
    +
    +int main()
    +{
    +    try
    +    {
    +        //-----------------------------------------
    +        // USER CONFIGURATION
    +        //-----------------------------------------
    +        const std::string host = "api.openai.com";   // OpenAI API host
    +        const std::string port = "443";              // HTTPS (TLS) port
    +        const std::string target = "/v1/images/generations"; // OpenAI endpoint for image generation
    +        const int version = 11; // HTTP/1.1 (11 = 1.1, 10 = 1.0)
    +
    +        // Replace these with your actual credentials
    +        const std::string api_key = "<YOUR_API_KEY>";
    +        const std::string org_id = "<YOUR_ORG_ID>";   // Optional: can be blank
    +
    +        // Path to a certificate bundle (needed so TLS can verify api.openai.com is trusted)
    +        _putenv_s("SSL_CERT_FILE", "<YOUR_CERT_PATH>\\cacert.pem");
    +
    +        //-----------------------------------------
    +        // SSL/TLS CONTEXT
    +        //-----------------------------------------
    +        ssl::context ctx(ssl::context::tls_client);  // Create a client-side TLS context
    +        ctx.set_default_verify_paths();              // Use system default trusted certificates
    +        ctx.set_verify_mode(ssl::verify_peer);       // Verify server certificate authenticity
    +
    +        //-----------------------------------------
    +        // I/O CONTEXT
    +        //-----------------------------------------
    +        net::io_context ioc;  // Asynchronous event loop (needed for networking)
    +
    +        //-----------------------------------------
    +        // RESOLVE HOSTNAME → TCP ENDPOINT
    +        //-----------------------------------------
    +        tcp::resolver resolver(ioc);
    +        auto const results = resolver.resolve(host, port);
    +
    +        //-----------------------------------------
    +        // CREATE SSL STREAM WRAPPED AROUND TCP SOCKET
    +        //-----------------------------------------
    +        beast::ssl_stream<tcp::socket> stream(ioc, ctx);
    +
    +        // Enable SNI (Server Name Indication), required by many servers including OpenAI
    +        if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()))
    +            throw beast::system_error(
    +                beast::error_code(static_cast<int>(::ERR_get_error()), net::error::get_ssl_category()),
    +                "Failed to set SNI hostname");
    +
    +        //-----------------------------------------
    +        // CONNECT TO SERVER AND HANDSHAKE TLS
    +        //-----------------------------------------
    +        net::connect(stream.next_layer(), results.begin(), results.end()); // TCP connect
    +        stream.handshake(ssl::stream_base::client);                        // TLS handshake
    +
    +        //-----------------------------------------
    +        // MAIN LOOP: ASK USER FOR PROMPT
    +        //-----------------------------------------
    +        std::string user_input;
    +        while (true)
    +        {
    +            std::cout << "\nEnter an image request (e.g. 'A sunset over the mountain') or 'exit': ";
    +            std::getline(std::cin, user_input);
    +
    +            if (user_input == "exit")
    +                break; // Exit program cleanly
    +
    +            //-----------------------------------------
    +            // BUILD JSON REQUEST BODY
    +            //-----------------------------------------
    +            json::object body;
    +            body["prompt"] = user_input;     // User's text description
    +            body["n"] = 1;                   // Number of images to generate
    +            body["size"] = "512x512";        // Image resolution
    +            body["response_format"] = "url"; // We want a downloadable URL back
    +            std::string body_str = json::serialize(body);
    +
    +            //-----------------------------------------
    +            // CREATE HTTP POST REQUEST
    +            //-----------------------------------------
    +            http::request<http::string_body> req{ http::verb::post, target, version };
    +            req.set(http::field::host, host);
    +            req.set(http::field::content_type, "application/json");  // JSON request body
    +            req.set(http::field::authorization, "Bearer " + api_key); // API key
    +            req.set("OpenAI-Organization", org_id);                 // Optional header
    +            req.body() = body_str;                                  // JSON as request body
    +            req.prepare_payload();                                  // Update headers (like Content-Length)
    +
    +            //-----------------------------------------
    +            // SEND REQUEST TO OPENAI
    +            //-----------------------------------------
    +            http::write(stream, req);
    +
    +            //-----------------------------------------
    +            // RECEIVE RESPONSE
    +            //-----------------------------------------
    +            beast::flat_buffer buffer;          // Temporary storage for network data
    +            http::response<http::string_body> res;
    +            http::read(stream, buffer, res);    // Read HTTP response into `res`
    +
    +            //-----------------------------------------
    +            // PARSE JSON RESPONSE
    +            //-----------------------------------------
    +            try {
    +                json::value jv = json::parse(res.body());
    +
    +                if (jv.is_object()) {
    +                    auto& obj = jv.as_object();
    +                    if (obj.contains("data")) {
    +                        auto& data = obj["data"].as_array();
    +                        if (!data.empty()) {
    +
    +                            // Extract URL of generated image
    +                            std::string url = data[0].as_object()["url"].as_string().c_str();
    +                            std::cout << "\nDownload your image here:\n" << url << "\n";
    +                        }
    +                    }
    +                }
    +            }
    +            catch (const std::exception& e) {
    +                std::cerr << "Failed to parse JSON: " << e.what() << "\n";
    +                std::cerr << "Raw response:\n" << res.body() << "\n";
    +            }
    +        }
    +
    +        //-----------------------------------------
    +        // CLEANLY SHUTDOWN TLS CONNECTION
    +        //-----------------------------------------
    +        beast::error_code ec;
    +        stream.shutdown(ec);
    +
    +        // Ignore common "truncated" shutdowns that happen when the peer closes first
    +        if (ec == net::error::eof || ec == ssl::error::stream_truncated) {
    +            ec = {};
    +        }
    +
    +        if (ec) {
    +            throw beast::system_error{ ec };
    +        }
    +
    +    }
    +    catch (std::exception const& e)
    +    {
    +        // If anything throws, report it
    +        std::cerr << "Error: " << e.what() << "\n";
    +        return EXIT_FAILURE;
    +    }
    +
    +    return EXIT_SUCCESS;
    +}
    +
    +
    +
    +

    Run the program:

    +
    +
    +
    +
    Enter an image request (e.g. 'A sunset over the mountains') or 'exit': A sunset over the mountain
    +
    +Download your image here:
    +https://oaidalleapiprodscus.blob.core.windows.net/private/org-DOWNLOAD-LINK-DETAILS
    +
    +
    +
    +
    +A sunset over the mountain +
    +
    +
    +

    Try a stylized image:

    +
    +
    +
    +
    Enter an image request (e.g. 'A sunset over the mountains') or 'exit': A cartoon image of a volcanic eruption
    +
    +Download your image here:
    +https://oaidalleapiprodscus.blob.core.windows.net/private/org-DOWNLOAD-LINK-DETAILS
    +
    +
    +
    +

    Cartoon volcanic eruption

    +
    +
    +

    Try a more complex subject:

    +
    +
    +
    +
    Enter an image request (e.g. 'A sunset over the mountains') or 'exit': A C++ computer programmer hard at work
    +
    +Download your image here:
    +https://oaidalleapiprodscus.blob.core.windows.net/private/org-DOWNLOAD-LINK-DETAILS
    +
    +
    +
    +

    Cpp programmer at work

    +
    +
    +

    Push the limits to reveal limitations:

    +
    +
    +
    +
    Enter an image request (e.g. 'A sunset over the mountains') or 'exit': A diagram with text showing how a jet engine works
    +
    +Download your image here:
    +https://oaidalleapiprodscus.blob.core.windows.net/private/org-DOWNLOAD-LINK-DETAILS
    +
    +
    +
    +

    Jet engine with text

    +
    +
    +

    Clearly, asking for text annotations in this case was asking too much!

    +
    +
    +
    +
    Enter an image request (e.g. 'A sunset over the mountains') or 'exit': exit
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    Making requests to an AI model is fun. However, to be useful a lot of experimentation and honing of requests may well be necessary.

    +
    +
    +

    Consider updating the examples to tailor the requests to a particular scenario you have in mind. There are also speech-to-text, text-to-speech, and translation endpoints you might give a try.

    +
    +
    +

    For more information and examples on the use of Boost libraries in client/server connections, refer to Networking.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-bio-tech-engineering.html b/preview/user-guide/task-bio-tech-engineering.html new file mode 100644 index 0000000..ac0c3c9 --- /dev/null +++ b/preview/user-guide/task-bio-tech-engineering.html @@ -0,0 +1,910 @@ + + + + + + + + + + + + + + Bio-Tech Engineering :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Bio-Tech Engineering

    +
    +
    +
    +

    Boost libraries provide low-level, auditable control over algorithms and numeric behavior, making them well-suited to computational biology, genomics pipelines, and regulated - verifiable, reproducible and stable - biomedical software.

    +
    +
    +

    This topic examines the libraries that should assist in building a bio-tech tool, focusing on evolving data structures.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +
      +
    • +

      Boost.Graph : Provides the features necessary for phylogenetic trees (explored further in this topic) as well as interaction networks, pathway graphs, and other structures well suited to bio-tech study. The library supports efficient graph traversal, shortest path and labeled graph algorithms.

      +
    • +
    • +

      Boost.Filesystem and Boost.Serialization : Provide the persistent storage needed for long runs and simulations.

      +
    • +
    • +

      Boost.Asio : Provides great support for distributed bio-tech platforms, which might be used in cloud-based analysis, multi-lab collaboration, and possibly working with streaming and experimental data.

      +
    • +
    • +

      Boost.MultiArray : Particularly useful for tasks in the medical/biological image and signal processing realms, where multi-dimensional image or sensor data is a key component.

      +
    • +
    • +

      Boost.Math, Boost.Multiprecision, Boost.Random : Provide the numerical and simulation support for such processes as energy accumulation, long simulations, validation, protein folding, molecular dynamics, docking simulations, energy minimalization, among so many others.

      +
    • +
    • +

      Boost.Container : Useful for memory-stable storage of works-in-progress, notable scenarios include particles/atoms, cache-friendly structures, deterministic memory layout.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Working with Phylogenetic Trees

    +
    +
    +

    In biotechnology and molecular biology, phylogenetic trees (1) have become go-to data structures - researchers compare the DNA, RNA, or protein sequences of multiple organisms to infer evolutionary relationships and similarities. This is particularly important in drug discovery, where understanding conserved sequences across species can indicate potential targets for antibiotics, antivirals, or cancer therapies. Similarly, phylogenetic analysis aids scientists track how viruses like influenza or SARS-CoV-2 mutate over time, and predict which strains are most likely to dominate.

    +
    +
    +

    Beyond genomics, phylogenetic trees are also widely used in synthetic biology and metagenomics (2). In synthetic biology, phylotrees guide the design of engineered organisms or genetic circuits.

    +
    +
    +

    Phylogenetic trees have also proven valuable in epidemiology and biotechnology safety monitoring. By mapping the evolutionary history of pathogens, scientists can trace the source of outbreaks, identify transmission patterns, and evaluate the emergence of drug resistance.

    +
    +
    +

    In medicine, metagenomic analyses of the human microbiome (3) help researchers understand the links between microbial communities and diseases such as obesity, diabetes, and autoimmune disorders. In environmental science, metagenomics can identify microorganisms capable of degrading pollutants or producing biofuels. In industrial biotech, it guides the optimization of microbial consortia for fermentation, waste treatment, or bioproduct synthesis.

    +
    +
    +

    A key challenge in metagenomics is handling the vast, complex datasets generated by high-throughput sequencing. Computational tools that efficiently model, manipulate, and analyze these data — including phylogenetic trees derived from metagenomic sequences — are essential to insightful observations and conclusions.

    +
    +
    +
    +
    +

    Create a Phylogenetic Tree

    +
    +
    +

    Phylogenetic trees provide a natural way to organize and visualize complex communities. Using a Boost-based framework - like the following example - each step of tree construction, from adding new sequences, refining branches, to removing erroneous data — can be captured, and animated:

    +
    +
    +
    +
    #include <boost/graph/adjacency_list.hpp>
    +#include <iostream>
    +
    +// ------------------------------
    +// Vertex data
    +// ------------------------------
    +struct Species
    +{
    +    std::string name;
    +};
    +
    +// ------------------------------
    +// Graph type
    +// ------------------------------
    +using PhyloTree = boost::adjacency_list<
    +    boost::vecS,
    +    boost::vecS,
    +    boost::directedS,
    +    Species
    +>;
    +
    +using Vertex = boost::graph_traits<PhyloTree>::vertex_descriptor;
    +
    +// ------------------------------
    +// Recursive ASCII tree printer
    +// ------------------------------
    +void print_tree(const PhyloTree& tree, Vertex v,
    +    const std::string& prefix = "",
    +    bool is_last = true)
    +{
    +    std::cout << prefix
    +        << (is_last ? "|__ " : "|_ ")
    +        << tree[v].name << "\n";
    +
    +    auto children = boost::make_iterator_range(out_edges(v, tree));
    +
    +    for (auto it = children.begin(); it != children.end(); ++it)
    +    {
    +        Vertex child = target(*it, tree);
    +        bool last = (std::next(it) == children.end());
    +
    +        print_tree(tree,
    +            child,
    +            prefix + (is_last ? "   " : "|  "),
    +            last);
    +    }
    +}
    +
    +// ------------------------------
    +// Print full tree from root
    +// ------------------------------
    +void show_tree(const PhyloTree& tree, Vertex root,
    +    const std::string& title)
    +{
    +    std::cout << "\n=== " << title << " ===\n";
    +    print_tree(tree, root);
    +}
    +
    +int main()
    +{
    +    PhyloTree tree;
    +
    +    // ------------------------------
    +    // Create root
    +    // ------------------------------
    +    auto luca = add_vertex({ "LUCA" }, tree);
    +    show_tree(tree, luca, "Initial tree");
    +
    +    // ------------------------------
    +    // Add primary domains
    +    // ------------------------------
    +    auto bacteria = add_vertex({ "Bacteria" }, tree);
    +    auto archaea = add_vertex({ "Archaea" }, tree);
    +    auto eukarya = add_vertex({ "Eukarya" }, tree);
    +
    +    add_edge(luca, bacteria, tree);
    +    add_edge(luca, archaea, tree);
    +    add_edge(luca, eukarya, tree);
    +
    +    show_tree(tree, luca, "After adding domains");
    +
    +    // ------------------------------
    +    // Add Eukarya branches
    +    // ------------------------------
    +    auto animals = add_vertex({ "Animals" }, tree);
    +    auto plants = add_vertex({ "Plants" }, tree);
    +    auto fungi = add_vertex({ "Fungi" }, tree);
    +
    +    add_edge(eukarya, animals, tree);
    +    add_edge(eukarya, plants, tree);
    +    add_edge(eukarya, fungi, tree);
    +
    +    show_tree(tree, luca, "After Eukarya speciation");
    +
    +    // ------------------------------
    +    // Add animal subclasses
    +    // ------------------------------
    +    auto mammals = add_vertex({ "Mammals" }, tree);
    +    auto reptiles = add_vertex({ "Reptiles" }, tree);
    +
    +    add_edge(animals, mammals, tree);
    +    add_edge(animals, reptiles, tree);
    +
    +    show_tree(tree, luca, "After animal diversification");
    +
    +    // ------------------------------
    +    // Scientific correction: prune plants
    +    // ------------------------------
    +    clear_vertex(plants, tree);
    +    remove_vertex(plants, tree);
    +
    +    show_tree(tree, luca, "After pruning Plants");
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    The methods such as add_edge, add_vertex, and many others are provided by the Boost.Graph library, so little additional code is needed to manipulate a tree.

    +
    +
    +
    +
    +

    Run the code:

    +
    +
    +
    +
    === Initial tree ===
    +|__ LUCA
    +
    +=== After adding domains ===
    +|__ LUCA
    +   |_ Bacteria
    +   |_ Archaea
    +   |__ Eukarya
    +
    +=== After Eukarya speciation ===
    +|__ LUCA
    +   |_ Bacteria
    +   |_ Archaea
    +   |__ Eukarya
    +      |_ Animals
    +      |_ Plants
    +      |__ Fungi
    +
    +=== After animal diversification ===
    +|__ LUCA
    +   |_ Bacteria
    +   |_ Archaea
    +   |__ Eukarya
    +      |_ Animals
    +      |  |_ Mammals
    +      |  |__ Reptiles
    +      |_ Plants
    +      |__ Fungi
    +
    +=== After pruning Plants ===
    +|__ LUCA
    +   |_ Bacteria
    +   |_ Archaea
    +   |__ Eukarya
    +      |_ Animals
    +      |  |_ Mammals
    +      |  |__ Reptiles
    +      |__ Fungi
    +
    +
    +
    +

    Consider adding your own calls to create and prune branches and leaves as appropriate.

    +
    +
    +
    +
    Note
    +
    +

    LUCA stands for "Last Universal Common Ancestors" - a key concept in evolutionary modeling (4).

    +
    +

    LUCA : Primordial ocean of glowing protocells :

    +
    +
    +

    LUCA

    +
    +
    +
    +
    +
    +
    +
    +

    Persist a Phylogenetic Tree

    +
    +
    +

    Let’s add efficient storing and retrieving of data to our program:

    +
    +
    +
    +
    #include <boost/graph/adjacency_list.hpp>
    +#include <boost/graph/adj_list_serialize.hpp>
    +
    +#include <boost/serialization/vector.hpp>
    +#include <boost/serialization/list.hpp>
    +#include <boost/serialization/string.hpp>
    +#include <boost/serialization/nvp.hpp>
    +
    +#include <boost/archive/text_oarchive.hpp>
    +#include <boost/archive/text_iarchive.hpp>
    +#include <boost/filesystem.hpp>
    +
    +#include <iostream>
    +#include <fstream>
    +
    +// ------------------------------
    +// Vertex data
    +// ------------------------------
    +struct Species
    +{
    +    std::string name;
    +
    +    template<class Archive>
    +    void serialize(Archive& ar, const unsigned int)
    +    {
    +        ar& BOOST_SERIALIZATION_NVP(name);
    +    }
    +};
    +
    +// ------------------------------
    +// Graph type
    +// ------------------------------
    +using PhyloTree = boost::adjacency_list<
    +    boost::vecS,
    +    boost::vecS,
    +    boost::directedS,
    +    Species
    +>;
    +
    +using Vertex = boost::graph_traits<PhyloTree>::vertex_descriptor;
    +
    +// ------------------------------
    +// ASCII tree printer
    +// ------------------------------
    +void print_tree(const PhyloTree& tree, Vertex v,
    +    const std::string& prefix = "",
    +    bool is_last = true)
    +{
    +    std::cout << prefix
    +        << (is_last ? "|_ " : "|__")
    +        << tree[v].name << "\n";
    +
    +    auto children = boost::make_iterator_range(out_edges(v, tree));
    +
    +    for (auto it = children.begin(); it != children.end(); ++it)
    +    {
    +        Vertex child = target(*it, tree);
    +        bool last = (std::next(it) == children.end());
    +
    +        print_tree(tree,
    +            child,
    +            prefix + (is_last ? "   " : "|  "),
    +            last);
    +    }
    +}
    +
    +// ------------------------------
    +// Animated display
    +// ------------------------------
    +void animate(const PhyloTree& tree, Vertex root,
    +    const std::string& title,
    +    int delay_ms = 800)
    +{
    +    std::cout << "\n=== " << title << " ===\n";
    +    print_tree(tree, root);
    +    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
    +}
    +
    +// ------------------------------
    +// Save / load helpers using Boost.Filesystem
    +// ------------------------------
    +void save_tree(const PhyloTree& tree,
    +    const boost::filesystem::path& file)
    +{
    +    boost::filesystem::create_directories(file.parent_path());
    +
    +    std::ofstream ofs(file.string());
    +    boost::archive::text_oarchive oa(ofs);
    +
    +    oa << BOOST_SERIALIZATION_NVP(tree);
    +}
    +
    +void load_tree(PhyloTree& tree,
    +    const boost::filesystem::path& file)
    +{
    +    if (!boost::filesystem::exists(file))
    +        throw std::runtime_error("Tree file does not exist");
    +
    +    std::ifstream ifs(file.string());
    +    boost::archive::text_iarchive ia(ifs);
    +
    +    ia >> BOOST_SERIALIZATION_NVP(tree);
    +}
    +
    +// ------------------------------
    +// Main demo
    +// ------------------------------
    +int main()
    +{
    +    PhyloTree tree;
    +
    +    auto luca = add_vertex({ "LUCA" }, tree);
    +    animate(tree, luca, "Initial tree");
    +
    +    auto bacteria = add_vertex({ "Bacteria" }, tree);
    +    auto archaea = add_vertex({ "Archaea" }, tree);
    +    auto eukarya = add_vertex({ "Eukarya" }, tree);
    +
    +    add_edge(luca, bacteria, tree);
    +    add_edge(luca, archaea, tree);
    +    add_edge(luca, eukarya, tree);
    +
    +    animate(tree, luca, "Domains of life");
    +
    +    auto animals = add_vertex({ "Animals" }, tree);
    +    auto plants = add_vertex({ "Plants" }, tree);
    +    auto fungi = add_vertex({ "Fungi" }, tree);
    +
    +    add_edge(eukarya, animals, tree);
    +    add_edge(eukarya, plants, tree);
    +    add_edge(eukarya, fungi, tree);
    +
    +    animate(tree, luca, "Eukaryotic diversification");
    +
    +    auto mammals = add_vertex({ "Mammals" }, tree);
    +    auto reptiles = add_vertex({ "Reptiles" }, tree);
    +
    +    add_edge(animals, mammals, tree);
    +    add_edge(animals, reptiles, tree);
    +
    +    animate(tree, luca, "Animal diversification");
    +
    +    // Scientific correction: prune plants
    +    clear_vertex(plants, tree);
    +    remove_vertex(plants, tree);
    +
    +    animate(tree, luca, "After pruning Plants");
    +
    +    // ------------------------------
    +    // Persist tree to disk
    +    // ------------------------------
    +    boost::filesystem::path data_dir = "data";
    +    boost::filesystem::path tree_file = data_dir / "phylo_tree.dat";
    +
    +    save_tree(tree, tree_file);
    +    std::cout << "\nTree saved to " << tree_file << "\n";
    +
    +    // ------------------------------
    +    // Reload and verify
    +    // ------------------------------
    +    PhyloTree loaded;
    +    load_tree(loaded, tree_file);
    +
    +    std::cout << "\n=== Reloaded tree ===\n";
    +    print_tree(loaded, luca);
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Run the code:

    +
    +
    +
    +
    === Initial tree ===
    +|_ LUCA
    +
    +=== Domains of life ===
    +|_ LUCA
    +   |__Bacteria
    +   |__Archaea
    +   |_ Eukarya
    +
    +=== Eukaryotic diversification ===
    +|_ LUCA
    +   |__Bacteria
    +   |__Archaea
    +   |_ Eukarya
    +      |__Animals
    +      |__Plants
    +      |_ Fungi
    +
    +=== Animal diversification ===
    +|_ LUCA
    +   |__Bacteria
    +   |__Archaea
    +   |_ Eukarya
    +      |__Animals
    +      |  |__Mammals
    +      |  |_ Reptiles
    +      |__Plants
    +      |_ Fungi
    +
    +=== After pruning Plants ===
    +|_ LUCA
    +   |__Bacteria
    +   |__Archaea
    +   |_ Eukarya
    +      |__Animals
    +      |  |__Mammals
    +      |  |_ Reptiles
    +      |_ Fungi
    +
    +Tree saved to "data\phylo_tree.dat"
    +
    +=== Reloaded tree ===
    +|_ LUCA
    +   |__Bacteria
    +   |__Archaea
    +   |_ Eukarya
    +      |__Animals
    +      |  |__Mammals
    +      |  |_ Reptiles
    +      |_ Fungi
    +
    +
    +
    +

    Locate the folder containing your program, then examine the contents of data\phylo_tree.dat:

    +
    +
    +
    +
    22 serialization::archive 20 0 0 8 7 0 0 4 LUCA 8 Bacteria 7 Archaea 7 Eukarya 7 Animals 5 Fungi 7 Mammals 8 Reptiles 0 1 0 0 0 2 0 3 3 4 3 5 4 6 4 7
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    If manipulating trees, which are a form of graph, is part of your bio-tech projects, consider examining the full range of structures and methods available in Boost.Graph.

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +A phylogenetic tree, often called a “phylotree”, is a diagrammatic representation of the evolutionary relationships among various biological species or entities, based on similarities and differences in their genetic, morphological, or biochemical characteristics. Each node represents a species (or other taxonomic unit), and the edges—or branches—denote evolutionary paths connecting them. The root of the tree represents the most recent common ancestor (often shortened to MRCA) of all the species in the diagram, while the leaves correspond to current-day organisms or sequences. Phylogenetic trees can be either rooted, showing directionality of evolution, or unrooted, highlighting relationships without assuming an ancestral origin.

    +
    +
    +

    (2) +Metagenomics is the study of genetic material recovered directly from environmental samples, rather than from individual, isolated organisms. It allows scientists to analyze entire microbial communities in their natural habitats — such as soil, water, the human gut, or industrial bioreactors — without the need to culture the organisms in a lab. By sequencing and analyzing the collective genomes of these communities, metagenomics provides insights into the diversity, function, and interactions of microorganisms that might otherwise remain hidden.

    +
    +
    +

    (3) +The human microbiome refers to the vast community of microorganisms that live in and on the human body, including bacteria, viruses, fungi, and archaea. These microbes inhabit diverse environments such as the gut, skin, mouth, respiratory tract, and urogenital system. Collectively, their genomes — known as the microbiome — contain far more genes than the human genome itself, forming a complex biological system that interacts continuously with its host.

    +
    +
    +

    Gut microbes, for example, help digest complex carbohydrates, synthesize vitamins, regulate the immune system, and protect against pathogenic organisms. Disruptions to the microbiome, often called dysbiosis, have been linked to a wide range of conditions including inflammatory bowel disease, obesity, diabetes, allergies, and even neurological disorders. As a result, microbiome research has become a major focus in areas such as precision medicine, probiotic development, and microbiome-targeted therapies.

    +
    +
    +

    From a computational perspective, studying the human microbiome relies heavily on metagenomics and phylogenetic analysis.

    +
    +
    +

    (4) +LUCA, or Last Universal Common Ancestors, refers to the most recent organism (or often population of organisms) from which all life on Earth descends. In phylogenetic trees, LUCA is often used as the root node, representing the point before life diversified into the major domains (such as Bacteria, Archaea, and Eukarya). Importantly, LUCA is not thought of as the very first living thing, but rather as the latest shared ancestor of all existing life — a complex organism that already possessed fundamental biological machinery like genetic coding, ribosomes, and basic metabolic pathways. That’s why using LUCA as the root in your demo is both scientifically meaningful and intuitive: it provides a natural starting point from which the evolutionary branches unfold.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-database.html b/preview/user-guide/task-database.html new file mode 100644 index 0000000..92e6e19 --- /dev/null +++ b/preview/user-guide/task-database.html @@ -0,0 +1,1279 @@ + + + + + + + + + + + + + + High-Performance Database Engine :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    High-Performance Database Engine

    +
    +
    +
    +

    Creating a high-performance database application in C++ involves a range of tasks, including efficient data structures, shared and optimized memory management, safe message and network communication, persistent storage, and so much more. This section examines how to get started.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are some Boost libraries that might be useful when planning and building your database app:

    +
    +
    +
      +
    • +

      Boost.Container : Provides STL-compatible containers, including stable vector, flat set/map and more. The containers provided by this library can offer performance benefits over their standard library equivalents, making them a good fit for a high-performance database application.

      +
    • +
    • +

      Boost.Pool : This library is used for simple, fast memory allocation and can improve efficiency in some scenarios by managing memory in chunks.

      +
    • +
    • +

      Boost.Interprocess : This library allows for shared memory communication and synchronization between processes. In a database context, this can be useful for inter-process communication (IPC) and shared memory databases.

      +
    • +
    • +

      Boost.Lockfree : Provides lock-free data structures which could be useful in multi-threaded database applications where you want to avoid locking overhead.

      +
    • +
    • +

      Boost.Serialization : If you need to serialize objects for storage, Boost.Serialization can be a useful tool. However, be aware that for many database applications, more specialized serialization formats (like Protocol Buffers, Thrift, etc.) might be more appropriate.

      +
    • +
    • +

      Boost.Asio : Provides a consistent asynchronous model using a modern C++ approach for network and low-level I/O programming. It supports a variety of network protocols, which could be helpful if your database needs to communicate over a network.

      +
    • +
    • +

      Boost.Thread : Provides a portable interface for multithreading, which can be crucial when creating a high-performance database that can handle multiple queries concurrently.

      +
    • +
    • +

      Boost.Fiber : Allows you to write code that works with fibers, which are user-space threads that can be used to write concurrent code. This can be useful in situations where you have many tasks that need to run concurrently but are I/O-bound rather than CPU-bound.

      +
    • +
    • +

      Boost.Polygon or Boost.Geometry : For storing and querying spatial data, these libraries can provide the necessary data types and algorithms.

      +
    • +
    • +

      Boost.Filesystem : Provides a portable way of querying and manipulating paths, files, and directories.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Sample Database Engine using Containers

    +
    +
    +

    A database engine requires efficient data structures for handling indexes, caches, and storage layouts. The Boost.Container library provides drop-in replacements for standard containers like std::vector, std::map, and std::unordered_map, but optimized for memory efficiency and performance.

    +
    +
    +

    In the following sample code, we will use in-memory indexing as the basis of a database engine. The Boost.Container flat_map feature is used to store a sorted index for quick lookups, and the stable_vector feature to store persistent records with stable pointers. The sample demonstrates inserting and retrieving records efficiently.

    +
    +
    +
    +
    #include <boost/container/flat_map.hpp>
    +#include <boost/container/stable_vector.hpp>
    +#include <iostream>
    +#include <string>
    +
    +// Define a Simple Database Table Structure
    +struct Record {
    +    int id;             // Primary Key
    +    std::string name;   // Represents record data
    +
    +    Record(int id, std::string name) : id(id), name(std::move(name)) {}
    +};
    +
    +// Implement a Database Table Class
    +class DatabaseTable {
    +public:
    +    using RecordStorage = boost::container::stable_vector<Record>;
    +    using IndexMap = boost::container::flat_map<int, size_t>; // Fast lookup
    +
    +    void insert(int id, const std::string& name) {
    +        size_t index = records.size();
    +        records.emplace_back(id, name);
    +        index_map[id] = index;
    +    }
    +
    +    const Record* find(int id) {
    +        auto it = index_map.find(id);
    +        if (it != index_map.end()) {
    +            return &records[it->second];
    +        }
    +        return nullptr;
    +    }
    +
    +    void print_all() const {
    +        for (const auto& record : records) {
    +            std::cout << "ID: " << record.id << ", Name: " << record.name << "\n";
    +        }
    +    }
    +
    +private:
    +    RecordStorage records;  // Stores records in a stable manner
    +    IndexMap index_map;     // Provides fast ID lookups
    +};
    +
    +// Demonstrate Database Operations
    +int main() {
    +    DatabaseTable db;
    +
    +    // Insert records
    +    db.insert(101, "Alice");
    +    db.insert(102, "Bob");
    +    db.insert(103, "Charlie");
    +
    +    // Retrieve a record
    +    const Record* record = db.find(102);
    +    if (record) {
    +        std::cout << "Found: ID = " << record->id << ", Name = " << record->name << "\n";
    +    } else {
    +        std::cout << "Record not found!\n";
    +    }
    +
    +    // Print all records
    +    std::cout << "All records:\n";
    +    db.print_all();
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Key features of this sample are that it is memory-efficient (reducing fragmentation and with good performance), stable_vector prevents invalid references when resizing, and flat_map is faster than std::map for heavy use.

    +
    +
    +
    +
    +

    Run the program, the output should be:

    +
    +
    +
    +
    Found: ID = 102, Name = Bob
    +All records:
    +ID: 101, Name: Alice
    +ID: 102, Name: Bob
    +ID: 103, Name: Charlie
    +
    +
    +
    +
    +
    +

    Optimize Memory Allocation

    +
    +
    +

    As we are dealing with frequent allocations of small objects (the database records) we’ll enhance our database engine by using Boost.Pool. This library avoids repeated calls to malloc, new and delete.

    +
    +
    +
    +
    #include <boost/container/flat_map.hpp>
    +#include <boost/pool/pool.hpp>
    +#include <iostream>
    +#include <string>
    +
    +struct Record {
    +    int id;
    +    std::string name;
    +
    +    Record(int id, std::string name) : id(id), name(std::move(name)) {}
    +};
    +
    +class DatabaseTable {
    +public:
    +    using IndexMap = boost::container::flat_map<int, Record*>;
    +
    +    DatabaseTable() : recordPool(sizeof(Record)) {}
    +
    +    Record* insert(int id, const std::string& name) {
    +        void* memory = recordPool.malloc(); // Allocate memory from the pool
    +        if (!memory) {
    +            throw std::bad_alloc();
    +        }
    +
    +        Record* newRecord = new (memory) Record(id, name); // Placement new
    +        index_map[id] = newRecord;
    +        return newRecord;
    +    }
    +
    +    void remove(int id) {
    +        auto it = index_map.find(id);
    +        if (it != index_map.end()) {
    +            it->second->~Record(); // Call destructor
    +            recordPool.free(it->second); // Free memory back to the pool
    +            index_map.erase(it);
    +        }
    +    }
    +
    +    Record* find(int id) {
    +        auto it = index_map.find(id);
    +        return (it != index_map.end()) ? it->second : nullptr;
    +    }
    +
    +    void print_all() {
    +        for (const auto& pair : index_map) {
    +            std::cout << "ID: " << pair.first << ", Name: " << pair.second->name << "\n";
    +        }
    +    }
    +
    +    ~DatabaseTable() {
    +        for (const auto& pair : index_map) {
    +            pair.second->~Record();
    +            recordPool.free(pair.second);
    +        }
    +    }
    +
    +private:
    +    boost::pool<> recordPool;
    +    IndexMap index_map;
    +};
    +
    +// Demonstrate Efficient Memory Use
    +int main() {
    +    DatabaseTable db;
    +
    +    // Insert records
    +    db.insert(101, "Alice");
    +    db.insert(102, "Bob");
    +    db.insert(103, "Charlie");
    +
    +    // Retrieve a record
    +    Record* record = db.find(102);
    +    if (record) {
    +        std::cout << "Found: ID = " << record->id << ", Name = " << record->name << "\n";
    +    }
    +
    +    // Remove a record
    +    db.remove(102);
    +    if (!db.find(102)) {
    +        std::cout << "Record 102 removed successfully.\n";
    +    }
    +
    +    // Print all records
    +    std::cout << "All records:\n";
    +    db.print_all();
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Custom Object Pools can be tuned for your specific object sizes.

    +
    +
    +
    +
    +

    The output should be:

    +
    +
    +
    +
    Found: ID = 102, Name = Bob
    +Record 102 removed successfully.
    +All records:
    +ID: 101, Name: Alice
    +ID: 103, Name: Charlie
    +
    +
    +
    +
    +
    +

    Use Persistent Shared Memory

    +
    +
    +

    In a realistic database environment, you would probably want to enable a shared-memory database table that multiple processes can access simultaneously. For this, we need the features of Boost.Interprocess. This library enables multiple processes to share the same data faster than inter-process communication (IPC) via files or sockets, and includes mutexes and condition variables.

    +
    +
    +
    +
    #include <boost/interprocess/managed_shared_memory.hpp>
    +#include <boost/interprocess/containers/vector.hpp>
    +#include <iostream>
    +
    +namespace bip = boost::interprocess;
    +
    +const char* SHM_NAME = "SharedDatabase";
    +const char* TABLE_NAME = "UserTable";
    +const std::size_t MAX_USERS = 10;
    +
    +struct UserRecord {
    +    int id;
    +    char name[32];
    +};
    +
    +using ShmemAllocator = bip::allocator<UserRecord, bip::managed_shared_memory::segment_manager>;
    +using UserTable = bip::vector<UserRecord, ShmemAllocator>;
    +
    +void create_table() {
    +    bip::shared_memory_object::remove(SHM_NAME);
    +
    +    bip::managed_shared_memory segment(bip::create_only, SHM_NAME, 65536);
    +    const ShmemAllocator alloc_inst(segment.get_segment_manager());
    +    UserTable* table = segment.construct<UserTable>(TABLE_NAME)(alloc_inst);
    +
    +    for (int i = 0; i < 3; ++i) {
    +        UserRecord user;
    +        user.id = 1 + table->size();
    +        std::snprintf(user.name, sizeof(user.name), "User%d", user.id);
    +        table->push_back(user);
    +    }
    +
    +    std::cout << "Shared memory table created with 3 initial users.\n";
    +}
    +
    +void show_table() {
    +
    +    try
    +    {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        UserTable* table = segment.find<UserTable>(TABLE_NAME).first;
    +
    +        if (!table) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        std::cout << "User Table:\n";
    +        for (const auto& user : *table) {
    +            std::cout << "  ID: " << user.id << ", Name: " << user.name << "\n";
    +        }
    +    }
    +    catch (...)
    +    {
    +        std::cerr << "Shared Memory error - create a table\n";
    +    }
    +}
    +
    +void add_user() {
    +
    +    try
    +    {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        UserTable* table = segment.find<UserTable>(TABLE_NAME).first;
    +
    +        if (!table) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        if (table->size() >= MAX_USERS) {
    +            std::cerr << "Table is full (max " << MAX_USERS << " users).\n";
    +            return;
    +        }
    +
    +        std::string name;
    +
    +        std::cout << "Enter user name: ";
    +        std::getline(std::cin, name);
    +
    +        UserRecord user;
    +        user.id = 1 + table->size();
    +        std::snprintf(user.name, sizeof(user.name) - 1, "%s", name.c_str());
    +        user.name[sizeof(user.name) - 1] = '\0';
    +
    +        table->push_back(user);
    +        std::cout << "User added.\n";
    +    }
    +    catch (...)
    +    {
    +        std::cerr << "Shared Memory error - create a table\n";
    +    }
    +}
    +
    +void print_menu() {
    +    std::cout << "\n=== Shared Memory User Table Menu ===\n";
    +    std::cout << "1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: ";
    +}
    +
    +int main() {
    +    while (true) {
    +        print_menu();
    +
    +        int choice = 0;
    +        std::cin >> choice;
    +        std::cin.ignore(); // discard newline
    +
    +        switch (choice) {
    +        case 1:
    +            create_table();
    +            show_table();
    +            break;
    +        case 2:
    +            show_table();
    +            break;
    +        case 3:
    +            add_user();
    +            break;
    +        case 4:
    +            bip::shared_memory_object::remove(SHM_NAME);
    +            break;
    +        case 5:
    +            std::cout << "Exiting...\n";
    +            return 0;
    +        default:
    +            std::cout << "Invalid option. Try again.\n";
    +        }
    +    }
    +}
    +
    +
    +
    +

    Boost shared memory is persistent. Run the program, add some user records, and exit without choosing option 4. Then run the program again and note the records you added have persisted.

    +
    +
    +

    First run:

    +
    +
    +
    +
    === Shared Memory User Table Menu ===
    +1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: 1
    +Shared memory table created with 3 initial users.
    +User Table:
    +  ID: 1, Name: User1
    +  ID: 2, Name: User2
    +  ID: 3, Name: User3
    +
    +=== Shared Memory User Table Menu ===
    +1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: 3
    +Enter user name: Nigel
    +User added.
    +
    +=== Shared Memory User Table Menu ===
    +1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: 2
    +User Table:
    +  ID: 1, Name: User1
    +  ID: 2, Name: User2
    +  ID: 3, Name: User3
    +  ID: 4, Name: Nigel
    +
    +=== Shared Memory User Table Menu ===
    +1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: 5
    +Exiting...
    +
    +
    +
    +

    Second run:

    +
    +
    +
    +
    === Shared Memory User Table Menu ===
    +1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit: 2
    +User Table:
    +  ID: 1, Name: User1
    +  ID: 2, Name: User2
    +  ID: 3, Name: User3
    +  ID: 4, Name: Nigel
    +
    +
    +
    +
    +
    +

    Safely Allow Access from Multiple Processes

    +
    +
    +

    To safely allow multiple processes to access and modify shared memory concurrently in your Boost.Interprocess program, you should use interprocess synchronization primitives — like interprocess_mutex to guard critical sections.

    +
    +
    +
    +
    #include <boost/interprocess/managed_shared_memory.hpp>
    +#include <boost/interprocess/containers/vector.hpp>
    +#include <iostream>
    +
    +namespace bip = boost::interprocess;
    +
    +const char* SHM_NAME = "SharedDatabase";
    +const std::size_t MAX_USERS = 10;
    +
    +struct UserRecord {
    +    int id;
    +    char name[32];
    +};
    +
    +using SegmentManager = bip::managed_shared_memory::segment_manager;
    +using ShmemAllocator = bip::allocator<UserRecord, SegmentManager>;
    +using UserTable = bip::vector<UserRecord, ShmemAllocator>;
    +
    +// Wrap the shared data and the mutex
    +struct SharedData {
    +    bip::interprocess_mutex mutex;
    +    UserTable table;
    +
    +    SharedData(const ShmemAllocator& alloc) : table(alloc) {}
    +};
    +
    +const char* TABLE_NAME = "SharedUserTable";
    +
    +void create_table() {
    +    bip::shared_memory_object::remove(SHM_NAME);
    +
    +    bip::managed_shared_memory segment(bip::create_only, SHM_NAME, 65536);
    +    ShmemAllocator alloc_inst(segment.get_segment_manager());
    +
    +    // Construct SharedData in shared memory
    +    segment.construct<SharedData>(TABLE_NAME)(alloc_inst);
    +
    +    std::cout << "Shared memory table created.\n";
    +}
    +
    +void show_table() {
    +    try {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        SharedData* data = segment.find<SharedData>(TABLE_NAME).first;
    +        if (!data) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);
    +        std::cout << "User Table:\n";
    +        for (const auto& user : data->table) {
    +            std::cout << "  ID: " << user.id << ", Name: " << user.name << "\n";
    +        }
    +    }
    +    catch (...) {
    +        std::cerr << "Error accessing shared memory. Is it created?\n";
    +    }
    +}
    +
    +void add_user() {
    +    try {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        SharedData* data = segment.find<SharedData>(TABLE_NAME).first;
    +        if (!data) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        bip::scoped_lock<bip::interprocess_mutex> lock(data->mutex);
    +
    +        if (data->table.size() >= MAX_USERS) {
    +            std::cerr << "Table is full (max " << MAX_USERS << " users).\n";
    +            return;
    +        }
    +
    +        std::string name;
    +        std::cout << "Enter user name: ";
    +        std::cin.ignore();
    +        std::getline(std::cin, name);
    +
    +        UserRecord user;
    +        user.id = 1 + static_cast<int>(data->table.size());
    +        std::snprintf(user.name, sizeof(user.name) - 1, "%s", name.c_str());
    +        user.name[sizeof(user.name) - 1] = '\0';
    +
    +        data->table.push_back(user);
    +        std::cout << "User added.\n";
    +
    +    }
    +    catch (...) {
    +        std::cerr << "Error accessing shared memory. Is it created?\n";
    +    }
    +}
    +
    +void print_menu() {
    +    std::cout << "\n=== Shared Memory User Table Menu ===\n";
    +    std::cout << "1. Create table   2. Show table   3. Add user   4. Clear shared memory   5. Exit\n";
    +    std::cout << "Choose an option: ";
    +}
    +
    +int main() {
    +    while (true) {
    +        print_menu();
    +
    +        int choice = 0;
    +        std::cin >> choice;
    +
    +        switch (choice) {
    +        case 1:
    +            create_table();
    +            show_table();
    +            break;
    +        case 2:
    +            show_table();
    +            break;
    +        case 3:
    +            add_user();
    +            break;
    +        case 4:
    +            bip::shared_memory_object::remove(SHM_NAME);
    +            std::cout << "Shared memory cleared.\n";
    +            break;
    +        case 5:
    +            std::cout << "Exiting...\n";
    +            return 0;
    +        default:
    +            std::cout << "Invalid option. Try again.\n";
    +        }
    +    }
    +}
    +
    +
    +
    +

    Now it is safe to run this program from two, or more, terminal sessions.

    +
    +
    +
    +
    +

    Add Serialization to Archive the Database

    +
    +
    +

    Finally, let’s add the features of Boost.Serialization to allow us to save and restore snapshots of our shared-memory database, making it persistent across program runs even when the shared memory is cleared. We will extend our sample to serialize the records into an archive format.

    +
    +
    +
    +
    #include <boost/interprocess/managed_shared_memory.hpp>   // For managing shared memory segments
    +#include <boost/interprocess/containers/vector.hpp>       // STL-like vector that works inside shared memory
    +#include <boost/interprocess/sync/named_mutex.hpp>        // Mutex across processes
    +#include <boost/serialization/vector.hpp>                 // Serialization support for std::vector
    +#include <boost/archive/text_oarchive.hpp>                // For saving serialized data to text files
    +#include <boost/archive/text_iarchive.hpp>                // For loading serialized data from text files
    +#include <iostream>
    +#include <fstream>
    +
    +namespace bip = boost::interprocess;
    +
    +// ---- Global configuration constants ----
    +const char* SHM_NAME = "SharedDatabase";                // Name of the shared memory segment
    +const char* TABLE_NAME = "UserTable";                   // Name of the container object inside shared memory
    +const char* MUTEX_NAME = "SharedTableMutex";            // Name of the interprocess mutex
    +const std::size_t MAX_USERS = 10;                       // Maximum number of users allowed in table
    +
    +// ---- User Record structure, supports Boost.Serialization ----
    +struct UserRecord {
    +    int id;                 // Unique user ID
    +    char name[32];          // Fixed-size character buffer for username
    +
    +    // Serialization function used by Boost.Archive
    +    template<class Archive>
    +    void serialize(Archive& ar, const unsigned int) {
    +        ar& id;
    +
    +        // Wrap raw array in make_array so Boost knows how to handle it
    +        ar& boost::serialization::make_array(name, sizeof(name));
    +    }
    +};
    +
    +// ---- Type aliases for clarity ----
    +using ShmemAllocator = bip::allocator<UserRecord, bip::managed_shared_memory::segment_manager>;
    +
    +// Vector of UserRecords in shared memory
    +using UserTable = bip::vector<UserRecord, ShmemAllocator>;
    +
    +// ---- Create a new table in shared memory ----
    +void create_table() {
    +
    +    // Remove any old shared memory segment and mutex (cleanup)
    +    bip::shared_memory_object::remove(SHM_NAME);
    +    bip::named_mutex::remove(MUTEX_NAME);
    +
    +    // Create new shared memory segment of fixed size (64 KB here)
    +    bip::managed_shared_memory segment(bip::create_only, SHM_NAME, 65536);
    +    ShmemAllocator alloc(segment.get_segment_manager());
    +
    +    // Construct a UserTable object inside shared memory
    +    UserTable* table = segment.construct<UserTable>(TABLE_NAME)(alloc);
    +
    +    // Pre-populate with three sample users
    +    for (int i = 0; i < 3; ++i) {
    +        UserRecord user;
    +        user.id = 1 + table->size();
    +        std::snprintf(user.name, sizeof(user.name), "User%d", user.id);
    +        table->push_back(user);
    +    }
    +
    +    std::cout << "Shared memory table created with 3 initial users.\n";
    +}
    +
    +// ---- Display the contents of the table ----
    +void show_table() {
    +    try {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        bip::named_mutex mutex(bip::open_or_create, MUTEX_NAME);
    +
    +        // Lock table to prevent concurrent modifications
    +        bip::scoped_lock<bip::named_mutex> lock(mutex);
    +
    +        // Find UserTable in shared memory
    +        UserTable* table = segment.find<UserTable>(TABLE_NAME).first;
    +        if (!table) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        // Print all users
    +        std::cout << "User Table:\n";
    +        for (const auto& user : *table) {
    +            std::cout << "  ID: " << user.id << ", Name: " << user.name << "\n";
    +        }
    +    }
    +    catch (...) {
    +        std::cerr << "Unable to access shared memory.\n";
    +    }
    +}
    +
    +// ---- Add a user to the shared memory table ----
    +void add_user() {
    +    try {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        bip::named_mutex mutex(bip::open_or_create, MUTEX_NAME);
    +        bip::scoped_lock<bip::named_mutex> lock(mutex);
    +
    +        UserTable* table = segment.find<UserTable>(TABLE_NAME).first;
    +        if (!table || table->size() >= MAX_USERS) {
    +            std::cerr << "Table not found or full.\n";
    +            return;
    +        }
    +
    +        // Get new user name from console
    +        std::string name;
    +
    +        // Discard leftover newline from previous input
    +        std::cin.ignore();
    +
    +        std::cout << "Enter user name: ";
    +        std::getline(std::cin, name);
    +
    +        // Create new record and append
    +        UserRecord user;
    +        user.id = 1 + table->size();
    +        std::snprintf(user.name, sizeof(user.name) - 1, "%s", name.c_str());
    +        table->push_back(user);
    +
    +        std::cout << "User added.\n";
    +    }
    +    catch (...) {
    +        std::cerr << "Failed to add user.\n";
    +    }
    +}
    +
    +// ---- Save snapshot of current table to a text file ----
    +void save_snapshot(const std::string& filename) {
    +    try {
    +        bip::managed_shared_memory segment(bip::open_only, SHM_NAME);
    +        bip::named_mutex mutex(bip::open_or_create, MUTEX_NAME);
    +        bip::scoped_lock<bip::named_mutex> lock(mutex);
    +
    +        UserTable* table = segment.find<UserTable>(TABLE_NAME).first;
    +        if (!table) {
    +            std::cerr << "Table not found.\n";
    +            return;
    +        }
    +
    +        // Copy data from shared memory into std::vector (heap memory)
    +        std::vector<UserRecord> snapshot(table->begin(), table->end());
    +
    +        // Save serialized snapshot to file
    +        std::ofstream ofs(filename);
    +        boost::archive::text_oarchive oa(ofs);
    +        oa << snapshot;
    +
    +        std::cout << "Snapshot saved to " << filename << "\n";
    +    }
    +    catch (...) {
    +        std::cerr << "Failed to save snapshot.\n";
    +    }
    +}
    +
    +// ---- Load snapshot from text file into shared memory ----
    +void load_snapshot(const std::string& filename) {
    +    try {
    +
    +        // Open file and load into vector
    +        std::ifstream ifs(filename);
    +        if (!ifs) {
    +            std::cerr << "Snapshot file not found.\n";
    +            return;
    +        }
    +
    +        std::vector<UserRecord> snapshot;
    +        boost::archive::text_iarchive ia(ifs);
    +        ia >> snapshot;
    +
    +        // Reset shared memory segment and mutex
    +        bip::shared_memory_object::remove(SHM_NAME);
    +        bip::managed_shared_memory segment(bip::create_only, SHM_NAME, 65536);
    +        bip::named_mutex::remove(MUTEX_NAME);
    +        bip::named_mutex mutex(bip::create_only, MUTEX_NAME);
    +        bip::scoped_lock<bip::named_mutex> lock(mutex);
    +
    +        // Recreate UserTable and repopulate
    +        ShmemAllocator alloc(segment.get_segment_manager());
    +        UserTable* table = segment.construct<UserTable>(TABLE_NAME)(alloc);
    +
    +        for (const auto& user : snapshot) {
    +            table->push_back(user);
    +        }
    +
    +        std::cout << "Snapshot loaded from " << filename << "\n";
    +    }
    +    catch (...) {
    +        std::cerr << "Failed to load snapshot.\n";
    +    }
    +}
    +
    +// ---- Clear all shared memory resources ----
    +void clear_shared_memory() {
    +    bip::shared_memory_object::remove(SHM_NAME);
    +    bip::named_mutex::remove(MUTEX_NAME);
    +    std::cout << "Shared memory cleared.\n";
    +}
    +
    +// ---- Print the interactive menu ----
    +void print_menu() {
    +    std::cout << "\n=== Shared Memory Menu ===\n"
    +        << "1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:";
    +}
    +
    +// ---- Program entry point ----
    +int main() {
    +    while (true) {
    +        print_menu();
    +        int choice;
    +        std::cin >> choice;
    +
    +        switch (choice) {
    +        case 1:
    +            create_table();
    +
    +            // Show immediately after creation
    +            show_table();
    +            break;
    +        case 2: show_table(); break;
    +        case 3: add_user(); break;
    +        case 4: save_snapshot("snapshot.txt"); break;
    +        case 5:
    +            load_snapshot("snapshot.txt");
    +            show_table();
    +            break;
    +        case 6: clear_shared_memory(); break;
    +        case 7: return 0;
    +        default: std::cout << "Invalid choice.\n";
    +        }
    +    }
    +}
    +
    +
    +
    +

    Run the sample, and verify that the saved file persists after shared memory has been cleared.

    +
    +
    +
    +
    === Shared Memory Menu ===
    +1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:1
    +Shared memory table created with 3 initial users.
    +User Table:
    +  ID: 1, Name: User1
    +  ID: 2, Name: User2
    +  ID: 3, Name: User3
    +
    +=== Shared Memory Menu ===
    +1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:3
    +Enter user name: Nigel
    +User added.
    +
    +=== Shared Memory Menu ===
    +1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:4
    +Snapshot saved to snapshot.txt
    +
    +=== Shared Memory Menu ===
    +1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:6
    +Shared memory cleared.
    +
    +=== Shared Memory Menu ===
    +1. Create table  2. Show table  3. Add user  4. Save snapshot  5. Load snapshot  6. Clear shared memory  7. Exit:5
    +Snapshot loaded from snapshot.txt
    +User Table:
    +  ID: 1, Name: User1
    +  ID: 2, Name: User2
    +  ID: 3, Name: User3
    +  ID: 4, Name: Nigel
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    In the design of a database, consider all the independent processes, and how they might access persistent memory, for example:

    +
    +
    +
    +database persistent memory +
    +
    +
    +

    Perhaps now consider Boost.Filesystem for file management, and for a heavier duty database engine - integrate Boost.Asio to handle remote database transactions. Referring to the Networking sample would be a good place to start.

    +
    +
    +

    The Boost libraries have a lot to offer this particular scenario!

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-finance.html b/preview/user-guide/task-finance.html new file mode 100644 index 0000000..42d3b01 --- /dev/null +++ b/preview/user-guide/task-finance.html @@ -0,0 +1,1002 @@ + + + + + + + + + + + + + + Finance :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Finance

    +
    +
    +
    +

    Financial applications typically need functionality like secure storage for storing balances and transaction history, networking for interacting with blockchain (1) or other financial APIs, cryptography for secure signing and verifying transactions, and configuration management for handling user settings.

    +
    +
    +

    Of course, we should add highly accurate numerical calculations as an essential feature.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Many Boost libraries should assist you in building a finance app, here are some to consider:

    +
    +
    +
      +
    • +

      Boost.Uuid : A useful utility library for generating unique identifiers.

      +
    • +
    • +

      Boost.Serialization : To save and restore data.

      +
    • +
    • +

      Boost.Hash2 : Boost.Hash2 : Hashing algorithms play a crucial role in financial applications by ensuring data integrity, authentication, and security in various transactions and records. Hashing enables fingerprinting of transactions, invoices, and records to detect duplicate or modified entries. Boost.Hash2 is a new library, first available in Boost version 1.88.

      +
    • +
    • +

      Boost.Interprocess : Allows for shared memory communication and synchronization between processes. It’s useful for creating shared memory regions, handling inter-process communication, managing shared objects, and synchronizing processes.

      +
    • +
    • +

      Boost.Multiprecision : For extended precision arithmetic.

      +
    • +
    • +

      Boost.Asio : If your app has network-related features, and its hard to envisage a finance app that does not, this library provides a consistent asynchronous model for network programming.

      +
    • +
    • +

      Boost.Beast : Built on top of Boost.Asio this library provides implementations of HTTP and WebSocket. These are common protocols for network programming.

      +
    • +
    • +

      Boost.Json : An efficient library for parsing, serializing, and manipulating JSON data. This is useful specifically in client-server communication and web services. Also, if you are working with large JSON payloads, there is support for incremental parsing, so you can feed data to the parser as it arrives over the network.

      +
    • +
    • +

      Boost.ProgramOptions : Allows program options to be defined, with types and default values, and their values to be retrieved from the command line, from config files, and programmatically.

      +
    • +
    • +

      Boost.DateTime or Boost.Chrono: If you need to timestamp changes or edits, or if you’re implementing a version history feature, these libraries provide the required functions.

      +
    • +
    • +

      Boost.PropertyTree : Provides a hierarchical data structure for representing and manipulating structured data, such as XML, JSON, INI, or property list formats. You can use it to parse, validate, and sanitize input data in various formats, ensuring that it conforms to expected schema or constraints before further processing.

      +
      +
      +
      Notes
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +

      In Visual Studio, the C++ Language Standard (in the Project Properties C++ Language section) has been set to ISO C17 Standard (/std:c17). The libsodium library has been installed with the following Git Bash commands:

      +
      +
      +
      +
      git clone https://github.com/Microsoft/vcpkg.git
      +cd vcpkg
      +./bootstrap-vcpkg.bat
      +./vcpkg install libsodium
      +./vcpkg integrate install
      +
      +
      +
      +

      Finally, the location of the libsodium headers has been added to the Additional Include Libraries section of the Project Properties.

      +
      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Signing Transactions

    +
    +
    +

    Encrypting and securing transactions, one of the first tasks developers of a financial app should investigate, is a never-ending journey.

    +
    +
    +

    Public-key cryptography, also known as asymmetric cryptography, was first conceptualized in the 1970s by Whitfield Diffie and Martin Hellman, who introduced the idea of key pairs — one public and one private — for secure communication. This breakthrough solved a major problem in cryptography: how to securely share encryption keys over an untrusted channel. Shortly after, Rivest, Shamir, and Adleman developed the RSA algorithm, which became one of the earliest widely used public-key systems, relying on the mathematical difficulty of factoring large prime numbers.

    +
    +
    +

    As cryptography evolved, new methods based on elliptic curves gained popularity due to their superior security per bit compared to RSA. The ECDSA or Elliptic Curve Digital Signature Algorithm (2) emerged as a widely adopted standard, particularly in financial applications and cryptocurrencies like Bitcoin. However, ECDSA has limitations in security and performance, leading to the development of EdDSA or Edwards-curve Digital Signature Algorithm (3), which offers improved speed, security, and resistance to side-channel attacks. The most well-known variant, Ed25519, is now favored in many modern cryptographic applications for its efficiency and robust security guarantees.

    +
    +
    +

    If you are writing a serious financial app, then you could also research Schnorr Signatures. Unlike ECDSA, where an attacker can slightly modify a valid signature to create a new one, Schnorr Signatures prevent this, improving security in blockchain applications. And in addition, ECDSA (and all elliptic curve cryptography) and possibly Ed25519 can be broken by large-scale quantum computers - Post-Quantum Cryptography (PQC) is designed to resist this by replacing these schemes with lattice-based, hash-based, multivariate, and code-based cryptography - and is a currently developing story!

    +
    +
    +

    The following sample shows signing of a transaction, using Ed25519 public/private key signing with the libsodium library, supported by Boost.Uuid and Boost.Serialization.

    +
    +
    +
    +
    #include <sodium.h>
    +#include <boost/archive/text_oarchive.hpp>
    +#include <boost/archive/text_iarchive.hpp>
    +#include <boost/serialization/string.hpp>
    +#include <boost/uuid/uuid.hpp>
    +#include <boost/uuid/uuid_generators.hpp>
    +#include <boost/uuid/uuid_io.hpp>
    +
    +#include <iostream>
    +#include <sstream>
    +
    +
    +// Transaction Structure
    +struct Transaction {
    +    std::string sender;
    +    std::string receiver;
    +    double amount;
    +    boost::uuids::uuid tx_id;
    +
    +    template<class Archive>
    +    void serialize(Archive& ar, const unsigned int) {
    +        ar& sender;
    +        ar& receiver;
    +        ar& amount;
    +        ar& tx_id;
    +    }
    +};
    +
    +// Serialization Utility
    +std::string serialize_transaction(const Transaction& tx) {
    +    std::ostringstream oss;
    +    boost::archive::text_oarchive oa(oss);
    +    oa << tx;
    +    return oss.str();
    +}
    +
    +// Signing and Verifying
    +bool sign_transaction(const std::string& serialized_tx,
    +    std::array<unsigned char, crypto_sign_BYTES>& signature,
    +    const std::array<unsigned char, crypto_sign_SECRETKEYBYTES>& sk) {
    +    return crypto_sign_detached(signature.data(),
    +        nullptr,
    +        reinterpret_cast<const unsigned char*>(serialized_tx.data()),
    +        serialized_tx.size(),
    +        sk.data()) == 0;
    +}
    +
    +bool verify_transaction(const std::string& serialized_tx,
    +    const std::array<unsigned char, crypto_sign_BYTES>& signature,
    +    const std::array<unsigned char, crypto_sign_PUBLICKEYBYTES>& pk) {
    +    return crypto_sign_verify_detached(signature.data(),
    +        reinterpret_cast<const unsigned char*>(serialized_tx.data()),
    +        serialized_tx.size(),
    +        pk.data()) == 0;
    +}
    +
    +// Main Flow
    +int main() {
    +    if (sodium_init() < 0) {
    +        std::cerr << "Failed to initialize libsodium\n";
    +        return 1;
    +    }
    +
    +    // Key pair
    +    std::array<unsigned char, crypto_sign_PUBLICKEYBYTES> pk;
    +    std::array<unsigned char, crypto_sign_SECRETKEYBYTES> sk;
    +    crypto_sign_keypair(pk.data(), sk.data());
    +
    +    // Create a sample transaction
    +    Transaction tx{
    +        "alice@example.com",
    +        "bob@example.com",
    +        100.5,
    +        boost::uuids::random_generator()()
    +    };
    +
    +    // Serialize the transaction
    +    std::string serialized = serialize_transaction(tx);
    +
    +    // Sign it
    +    std::array<unsigned char, crypto_sign_BYTES> signature;
    +    if (!sign_transaction(serialized, signature, sk)) {
    +        std::cerr << "Signing failed.\n";
    +        return 1;
    +    }
    +
    +    std::cout << "Transaction signed with Ed25519.\n";
    +    std::cout << "Transaction ID: " << tx.tx_id << "\n";
    +
    +    // Verify the signature
    +    if (verify_transaction(serialized, signature, pk)) {
    +        std::cout << "Signature verified\n";
    +    }
    +    else {
    +        std::cout << "Signature verification failed\n";
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Run the program and you should get a verified signature:

    +
    +
    +
    +
    Transaction signed with Ed25519.
    +Transaction ID: 77f104be-815d-4800-b424-244d0e8ee7c0
    +Signature verified
    +
    +
    +
    +
    +
    +

    Sample Wallet with Ed25519 Signing

    +
    +
    +

    Let’s start with a simple wallet that enables transactions from a sender to a receiver, using Ed25519 signing as before.

    +
    +
    +
    +
    #pragma once
    +#include <sodium.h>
    +#include <iostream>
    +#include <fstream>
    +#include <sstream>
    +#include <boost/uuid/uuid.hpp>
    +#include <boost/uuid/random_generator.hpp>
    +#include <boost/uuid/uuid_io.hpp>
    +#include <boost/serialization/string.hpp>
    +#include <boost/serialization/array.hpp>
    +#include <boost/archive/text_oarchive.hpp>
    +#include <boost/archive/text_iarchive.hpp>
    +
    +class Wallet {
    +public:
    +    Wallet() {
    +        crypto_sign_keypair(public_key.data(), private_key.data());
    +        id = boost::uuids::to_string(boost::uuids::random_generator()());
    +    }
    +
    +    std::string get_id() const { return id; }
    +    const std::array<unsigned char, crypto_sign_PUBLICKEYBYTES>& pubkey() const { return public_key; }
    +    const std::array<unsigned char, crypto_sign_SECRETKEYBYTES>& privkey() const { return private_key; }
    +
    +private:
    +    std::string id;
    +    std::array<unsigned char, crypto_sign_PUBLICKEYBYTES> public_key{};
    +    std::array<unsigned char, crypto_sign_SECRETKEYBYTES> private_key{};
    +};
    +
    +
    +struct Transaction {
    +    std::string sender_id;
    +    std::string recipient_id;
    +    double amount;
    +    std::array<unsigned char, crypto_sign_BYTES> signature{};
    +
    +    Transaction() = default;
    +    Transaction(const std::string& sender, const std::string& recipient, double amt)
    +        : sender_id(sender), recipient_id(recipient), amount(amt) {
    +    }
    +
    +    std::string serialize_data() const {
    +        std::ostringstream oss;
    +        oss << sender_id << "|" << recipient_id << "|" << std::fixed << std::setprecision(2) << amount;
    +        return oss.str();
    +    }
    +
    +    void sign(const std::array<unsigned char, crypto_sign_SECRETKEYBYTES>& sk) {
    +        std::string msg = serialize_data();
    +        crypto_sign_detached(signature.data(),
    +            nullptr,
    +            reinterpret_cast<const unsigned char*>(msg.data()),
    +            msg.size(),
    +            sk.data());
    +    }
    +
    +    bool verify(const std::array<unsigned char, crypto_sign_PUBLICKEYBYTES>& pk) const {
    +        std::string msg = serialize_data();
    +        return crypto_sign_verify_detached(signature.data(),
    +            reinterpret_cast<const unsigned char*>(msg.data()),
    +            msg.size(),
    +            pk.data()) == 0;
    +    }
    +
    +private:
    +    friend class boost::serialization::access;
    +    template<class Archive>
    +    void serialize(Archive& ar, const unsigned int) {
    +        ar& sender_id;
    +        ar& recipient_id;
    +        ar& amount;
    +        ar& signature;
    +    }
    +};
    +
    +int main() {
    +    if (sodium_init() < 0) {
    +        std::cerr << "libsodium initialization failed\n";
    +        return 1;
    +    }
    +
    +    Wallet sender;
    +    Wallet recipient;
    +
    +    std::cout << "Created wallets:\n";
    +    std::cout << "Sender ID: " << sender.get_id() << "\n";
    +    std::cout << "Recipient ID: " << recipient.get_id() << "\n";
    +
    +    Transaction tx(sender.get_id(), recipient.get_id(), 123.45);
    +    tx.sign(sender.privkey());
    +
    +    if (tx.verify(sender.pubkey())) {
    +        std::cout << "Signature verified successfully.\n";
    +    }
    +    else {
    +        std::cout << "Signature verification failed.\n";
    +    }
    +
    +    // Block the write code to ensure the write buffers are flushed
    +    {
    +        std::ofstream ofs("transactions.dat");
    +        boost::archive::text_oarchive oa(ofs);
    +        oa << tx;
    +    }
    +    std::cout << "Transaction saved.\n";
    +
    +    Transaction loaded_tx;
    +    std::ifstream ifs("transactions.dat");
    +    boost::archive::text_iarchive ia(ifs);
    +    ia >> loaded_tx;
    +
    +    std::cout << "Loaded transaction: " << loaded_tx.sender_id << " -> "
    +        << loaded_tx.recipient_id << ", $" << loaded_tx.amount << "\n";
    +}
    +
    +
    +
    +

    A sample run of the program might be:

    +
    +
    +
    +
    Created wallets:
    +Sender ID: 782ded6c-4eda-47d6-a62c-d87bcf2c8f79
    +Recipient ID: 48ff8851-f638-4bfc-ad39-33547d82fbcb
    +Signature verified successfully.
    +Transaction saved.
    +Loaded transaction: 782ded6c-4eda-47d6-a62c-d87bcf2c8f79 -> 48ff8851-f638-4bfc-ad39-33547d82fbcb, $123.45
    +
    +
    +
    +
    +
    +

    Wallet with Foreign Currency Exchange

    +
    +
    +

    For a more functional wallet, we should add foreign currency exchange. In this sample the rates are hard-coded, however the Next Steps section includes information on how to access live currency exchange rates.

    +
    +
    +

    Sender:

    +
    +
    +
    +Digital Wallet +
    +
    +
    +

    Recipient:

    +
    +
    +
    +Digital Wallet +
    +
    +
    +
    +
    #include <sodium.h>
    +#include <iostream>
    +#include <fstream>
    +#include <sstream>
    +#include <boost/uuid/uuid.hpp>
    +#include <boost/uuid/random_generator.hpp>
    +#include <boost/uuid/uuid_io.hpp>
    +#include <boost/serialization/string.hpp>
    +#include <boost/serialization/map.hpp>
    +#include <boost/archive/text_oarchive.hpp>
    +#include <boost/archive/text_iarchive.hpp>
    +
    +enum class Currency { USD, EUR, JPY };
    +
    +inline std::string to_string(Currency c) {
    +    switch (c) {
    +    case Currency::USD: return "USD";
    +    case Currency::EUR: return "EUR";
    +    case Currency::JPY: return "JPY";
    +    }
    +    return "UNK";
    +}
    +
    +inline Currency from_string(const std::string& s) {
    +    if (s == "USD") return Currency::USD;
    +    if (s == "EUR") return Currency::EUR;
    +    if (s == "JPY") return Currency::JPY;
    +    throw std::runtime_error("Unknown currency");
    +}
    +
    +static const std::map<std::pair<Currency, Currency>, double> exchange_rates = {
    +    {{Currency::USD, Currency::EUR}, 0.91},
    +    {{Currency::EUR, Currency::USD}, 1.10},
    +    {{Currency::USD, Currency::JPY}, 146.0},
    +    {{Currency::JPY, Currency::USD}, 0.0068},
    +    {{Currency::EUR, Currency::JPY}, 160.0},
    +    {{Currency::JPY, Currency::EUR}, 0.0062}
    +};
    +
    +class Wallet {
    +public:
    +    Wallet(double usd, double eur, double jpy) {
    +        crypto_sign_keypair(public_key.data(), private_key.data());
    +        id = boost::uuids::to_string(boost::uuids::random_generator()());
    +        balances[Currency::USD] = usd;
    +        balances[Currency::EUR] = eur;
    +        balances[Currency::JPY] = jpy;
    +    }
    +
    +    void credit(Currency cur, double amt) {
    +        balances[cur] += amt;
    +    }
    +
    +    bool debit(Currency cur, double amt) {
    +        if (balances[cur] >= amt) {
    +            balances[cur] -= amt;
    +            return true;
    +        }
    +        return false;
    +    }
    +
    +    void print_balances() const {
    +        std::cout << "\nBalances for " << id << ":\n";
    +        for (const auto& [cur, val] : balances) {
    +            std::cout << "  " << to_string(cur) << ": " << val << "\n";
    +        }
    +    }
    +
    +    std::string get_id() const { return id; }
    +    const std::array<unsigned char, crypto_sign_PUBLICKEYBYTES>& pubkey() const { return public_key; }
    +    const std::array<unsigned char, crypto_sign_SECRETKEYBYTES>& privkey() const { return private_key; }
    +
    +private:
    +    std::string id;
    +    std::array<unsigned char, crypto_sign_PUBLICKEYBYTES> public_key{};
    +    std::array<unsigned char, crypto_sign_SECRETKEYBYTES> private_key{};
    +    std::map<Currency, double> balances;
    +};
    +
    +struct Transaction {
    +    std::string sender_id;
    +    std::string recipient_id;
    +    double amount;
    +    Currency sender_currency;
    +    Currency recipient_currency;
    +    std::array<unsigned char, crypto_sign_BYTES> signature{};
    +
    +    Transaction() = default;
    +    Transaction(const std::string& s, const std::string& r, double amt, Currency scur, Currency rcur)
    +        : sender_id(s), recipient_id(r), amount(amt), sender_currency(scur), recipient_currency(rcur) {
    +    }
    +
    +    std::string serialize_data() const {
    +        std::ostringstream oss;
    +        oss << sender_id << "|" << recipient_id << "|" << std::fixed << std::setprecision(2)
    +            << amount << "|" << to_string(sender_currency) << "|" << to_string(recipient_currency);
    +        return oss.str();
    +    }
    +
    +    double converted_amount() const {
    +        if (sender_currency == recipient_currency) return amount;
    +        auto it = exchange_rates.find({ sender_currency, recipient_currency });
    +        if (it != exchange_rates.end()) return amount * it->second;
    +        throw std::runtime_error("No exchange rate available.");
    +    }
    +
    +    void sign(const std::array<unsigned char, crypto_sign_SECRETKEYBYTES>& sk) {
    +        std::string msg = serialize_data();
    +        crypto_sign_detached(signature.data(), nullptr,
    +            reinterpret_cast<const unsigned char*>(msg.data()),
    +            msg.size(), sk.data());
    +    }
    +
    +    bool verify(const std::array<unsigned char, crypto_sign_PUBLICKEYBYTES>& pk) const {
    +        std::string msg = serialize_data();
    +        return crypto_sign_verify_detached(signature.data(),
    +            reinterpret_cast<const unsigned char*>(msg.data()),
    +            msg.size(), pk.data()) == 0;
    +    }
    +
    +private:
    +    friend class boost::serialization::access;
    +    template<class Archive>
    +    void serialize(Archive& ar, const unsigned int) {
    +        ar& sender_id& recipient_id& amount;
    +        std::string scur = to_string(sender_currency);
    +        std::string rcur = to_string(recipient_currency);
    +        ar& scur& rcur;
    +        sender_currency = from_string(scur);
    +        recipient_currency = from_string(rcur);
    +        ar& signature;
    +    }
    +};
    +
    +void make_transaction(Wallet &sender, Wallet &recipient, double amount, Currency scur, Currency rcur)
    +{
    +    Transaction tx(sender.get_id(), recipient.get_id(), amount, scur, rcur);
    +    tx.sign(sender.privkey());
    +
    +    if (tx.verify(sender.pubkey())) {
    +        std::cout << "\nTransaction verified.\n";
    +        if (sender.debit(tx.sender_currency, tx.amount)) {
    +            recipient.credit(tx.recipient_currency, tx.converted_amount());
    +        }
    +        else {
    +            std::cout << "Sender has insufficient funds.\n";
    +        }
    +    }
    +    else {
    +        std::cout << "Transaction verification failed.\n";
    +    }
    +    sender.print_balances();
    +    recipient.print_balances();
    +}
    +
    +int main() {
    +    if (sodium_init() < 0) {
    +        std::cerr << "libsodium initialization failed\n";
    +        return 1;
    +    }
    +
    +    Wallet sender = Wallet(500, 300, 5000);
    +    Wallet recipient = Wallet(0, 0, 0);
    +    std::cout << "Created wallets:\n";
    +    std::cout << "Sender ID: " << sender.get_id() << "\n";
    +    std::cout << "Recipient ID: " << recipient.get_id() << "\n";
    +
    +    make_transaction(sender, recipient, 100.0, Currency::EUR, Currency::USD);
    +    make_transaction(sender, recipient, 2500.0, Currency::JPY, Currency::USD);
    +    make_transaction(recipient, sender, 50.0, Currency::USD, Currency::EUR);
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Wallets contain three amounts, one for each currency. If a transaction is made from a currency the Wallet does not have enough of, amounts are not transferred from the other currencies to cover it. On receipt of a transaction, the amounts are converted to the specified currency.

    +
    +
    +
    +
    +

    Run the program:

    +
    +
    +
    +
    Created wallets:
    +Sender ID: 48b711fd-8197-4e39-bbaf-06e931ab9cc3
    +Recipient ID: fdda420d-820a-4670-99a9-3320864ef990
    +
    +Transaction verified.
    +
    +Balances for 48b711fd-8197-4e39-bbaf-06e931ab9cc3:
    +  USD: 500
    +  EUR: 200
    +  JPY: 5000
    +
    +Balances for fdda420d-820a-4670-99a9-3320864ef990:
    +  USD: 110
    +  EUR: 0
    +  JPY: 0
    +
    +Transaction verified.
    +
    +Balances for 48b711fd-8197-4e39-bbaf-06e931ab9cc3:
    +  USD: 500
    +  EUR: 200
    +  JPY: 2500
    +
    +Balances for fdda420d-820a-4670-99a9-3320864ef990:
    +  USD: 127
    +  EUR: 0
    +  JPY: 0
    +
    +Transaction verified.
    +
    +Balances for fdda420d-820a-4670-99a9-3320864ef990:
    +  USD: 77
    +  EUR: 0
    +  JPY: 0
    +
    +Balances for 48b711fd-8197-4e39-bbaf-06e931ab9cc3:
    +  USD: 500
    +  EUR: 245.5
    +  JPY: 2500
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    Consider using Boost.Beast to make an HTTP request to a public exchange rate API and fetch live rates for currency conversion. The JSON response can be parsed using Boost.Json.

    +
    +
    +

    Consider adding a user interface to the wallet to allow you to make deposits, withdrawals, transfers, and balance checks.

    +
    +
    +

    For some ideas on how to expand this app with remote access, refer to the samples in Networking.

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +Blockchain : A technology that provides a decentralized, tamper-resistant ledger that ensures transparency, security, and trust in digital transactions. By distributing records across a network of nodes and using cryptographic techniques, like hashing and digital signatures, blockchain eliminates the need for intermediaries, reducing fraud and operational costs. Its applications extend beyond cryptocurrencies to areas such as supply chain tracking, smart contracts, secure identity verification, and financial services. The immutability and auditability make it particularly valuable for industries requiring verifiable and trustless interactions, though challenges like scalability and energy consumption remain areas of active development.

    +
    +
    +

    (2) +ECDSA : An Elliptic Curve Digital Signature Algorithm creates a public and private key pair. ECDSA provides a variant of digital signature algorithms that use elliptic-curve cryptography to provide an additional level of complexity to the private key. However, care should be taken when implementing this algorithm - in particular, high-quality randomness in signatures is an absolutely essential.

    +
    +
    +

    (3) +Ed25519 : A high-performance, secure, and efficient public-key signature algorithm based on the Edwards-curve Digital Signature Algorithm (EdDSA), specifically designed for the Curve25519 elliptic curve. It offers 128-bit security, is resistant to side-channel attacks, and provides fast signing and verification speeds while maintaining small key and signature sizes (32-byte public keys and 64-byte signatures). Unlike ECDSA, Ed25519 does not require a secure random k value for signing, eliminating a major source of vulnerabilities. Widely adopted in cryptographic protocols like SSH, TLS, and cryptocurrency systems, Ed25519 is favored for its robustness, simplicity, and efficiency in modern security applications.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-machine-learning.html b/preview/user-guide/task-machine-learning.html new file mode 100644 index 0000000..f8ccc25 --- /dev/null +++ b/preview/user-guide/task-machine-learning.html @@ -0,0 +1,1037 @@ + + + + + + + + + + + + + + Machine Learning :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Machine Learning

    +
    +
    +
    +

    Developing a machine learning library or application involves tasks such as numerical computation, matrix operations, iteration and optimization (endless trial and error), classification and clustering procedures, and sometimes Parallel Computation. It requires not just skillful programming but also a deep understanding of the underlying mathematical and statistical principles.

    +
    +
    +

    This section investigates how you might get started with machine learning processes.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are some Boost libraries that could be helpful for the supporting tasks:

    +
    +
    +
      +
    • +

      Boost.Numeric/ublas : This is Boost’s library for linear algebra. It provides classes for vectors and matrices and operations on them, which are fundamental in many Machine Learning Algorithms.

      +
    • +
    • +

      Boost.Multiprecision: In some machine learning tasks, especially those involving large datasets or sensitive data, high-precision arithmetic can be necessary. Boost.Multiprecision can provide this functionality.

      +
    • +
    • +

      Boost.Math: This library contains many mathematical functions and utilities, some of which are likely to be useful in machine learning, such as statistical distributions and special functions.

      +
    • +
    • +

      Boost.Random: Random number generation is often necessary in machine learning, for tasks like initializing weights, shuffling data, and stochastic gradient descent. Boost.Random can provide this functionality.

      +
    • +
    • +

      Boost.Compute: For accelerating computations using GPUs or other OpenCL devices, you might find this library useful.

      +
    • +
    • +

      Boost.Thread or Boost.Fiber: These libraries can be useful for parallelizing computations, which can significantly speed up many Machine Learning Algorithms.

      +
    • +
    • +

      Boost.Graph: For Machine Learning Algorithms that involve graph computations (like some forms of clustering, graphical models, or neural network architectures), Boost.Graph could be useful.

      +
    • +
    • +

      Boost.PropertyTree or Boost.Spirit: These libraries can be useful for handling input and output, such as reading configuration files or parsing data.

      +
    • +
    • +

      Boost.Gil : A library designed for image processing, offering a flexible way to manipulate and process images.

      +
    • +
    • +

      Boost.Filesystem : This library provides a portable way of querying and manipulating paths, files, and directories.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Machine Learning Algorithms

    +
    +
    +

    Here are some widely used and robust algorithms, each having its own strengths and suitable applications. The best way to identify the "most robust" algorithm is through experimentation: try multiple models and select the one that performs best on your specific task. Also, keep in mind that data quality and the way you pre-process and engineer your features often matter more than the choice of algorithm.

    +
    +
    +
      +
    • +

      Linear Regression / Logistic Regression: These are simple yet powerful algorithms for regression and classification tasks respectively. They’re especially useful for understanding the influence of individual features.

      +
    • +
    +
    +
    +
      +
    • +

      Decision Trees / Random Forests: Decision trees are simple to understand and visualize, and can handle both numerical and categorical data. Random forests, which aggregate the results of many individual decision trees, often have better performance and are less prone to overfitting (1).

      +
    • +
    +
    +
    +
      +
    • +

      Support Vector Machines (SVM): SVMs are effective in high dimensional spaces and are suitable for binary classification tasks. They can handle non-linear classification using what is known as the kernel trick (2).

      +
    • +
    • +

      Gradient Boosting Machines (like XGBoost and LightGBM): These are currently among the top performers for structured data (usually, table-form data), based on their results in machine learning competitions.

      +
    • +
    • +

      Neural Networks / Deep Learning: These models excel at tasks involving unstructured data, such as image recognition, natural language processing, and more. Convolutional Neural Networks (CNNs) are used for image-related tasks, while Recurrent Neural Networks (RNNs), Long Short-Term Memory (LSTM) units, and Transformers are used for sequential data like text or time series.

      +
    • +
    • +

      K-Nearest Neighbors (KNN): This is a simple algorithm that stores all available cases and classifies new cases based on a similarity measure (distance functions). It’s used in both classification and regression.

      +
    • +
    • +

      K-Means: This is a widely-used clustering algorithm for dividing data into distinct groups.

      +
    • +
    +
    +
    +
    +
    +

    Sample of High-Precision Matrix Multiplication

    +
    +
    +

    The following sample demonstrating the use of Boost.Numeric/ublas for matrix operations and Boost.Multiprecision for high-precision arithmetic (ensures 50-digit precision for matrix calculations). This is useful in machine learning applications where precision is critical, such as when dealing with ill-conditioned matrices or when high numerical accuracy is needed.

    +
    +
    +

    Randomized values are commonly used in machine language algorithms, such as Stochastic Gradient Descent (Neural networks and logistic regression), Monte Carlo simulations (simulating stochastic processes like Bayesian inference or Markov chains (3)), and neural network weight initialization. So we’ll also engage the features of Boost.Random.

    +
    +
    +
    +
    #include <boost/numeric/ublas/matrix.hpp>
    +#include <boost/numeric/ublas/io.hpp>
    +#include <boost/multiprecision/cpp_dec_float.hpp>
    +#include <boost/random.hpp>
    +#include <boost/random/random_device.hpp>
    +
    +namespace ublas = boost::numeric::ublas;
    +namespace mp = boost::multiprecision;
    +namespace br = boost::random;
    +
    +int main() {
    +    // Define high-precision floating-point type (50 decimal places)
    +    using high_prec = mp::cpp_dec_float_50;
    +
    +    // Define 3x3 matrices
    +    ublas::matrix<high_prec> A(3, 3), B(3, 3), C(3, 3);
    +
    +    // Random number generation (high-precision floating-point)
    +    br::random_device rd;  // Seed from system entropy
    +    br::mt19937 gen(rd()); // Mersenne Twister RNG
    +    br::uniform_real_distribution<double> dist(0.0, 1.0); // Uniform distribution [0,1]
    +
    +    // Fill matrices A and B with random values
    +    for (std::size_t i = 0; i < A.size1(); ++i) {
    +        for (std::size_t j = 0; j < A.size2(); ++j) {
    +            A(i, j) = dist(gen);  // Random value between 0 and 1
    +            B(i, j) = dist(gen);
    +        }
    +    }
    +
    +    // Perform matrix multiplication: C = A * B
    +    C = prod(A, B);
    +
    +    // Print results
    +    std::cout << "Matrix A (random values):\n" << std::setprecision(51) << A << "\n\n";
    +    std::cout << "Matrix B (random values):\n" << std::setprecision(51) << B << "\n\n";
    +    std::cout << "Result of A * B:\n" << std::setprecision(51) << C << "\n";
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Running the code should give you output similar to the following:

    +
    +
    +
    +
    Matrix A (random values):
    +[3,3]((0.070812058635056018829345703125,0.80709342076443135738372802734375,0.6618001046590507030487060546875),(0.849498252384364604949951171875,0.95166688528843224048614501953125,0.8414736413396894931793212890625),(0.732556092552840709686279296875,0.607468723319470882415771484375,0.10045330529101192951202392578125))
    +
    +Matrix B (random values):
    +[3,3]((0.8722223858349025249481201171875,0.7344769672490656375885009765625,0.66293510119430720806121826171875),(0.36406232439912855625152587890625,0.86651482223533093929290771484375,0.35279963747598230838775634765625),(0.75558476778678596019744873046875,0.78821337711997330188751220703125,0.7253504456020891666412353515625))
    +
    +Result of A * B:
    +[3,3]((0.855642247899371810907712815330583566719724331051111,1.27300793356359748150765862084732304992940044030547,0.811723066325901586521348457514690721836814191192389),(1.72322211665940665047775867679824557399115292355418,2.11183114262540423141214021574008086190588073804975,1.50927322274462834299961835893277850573213072493672),(0.936009285567514438288188455272731403056241106241941,1.14360486900502322343527519810102432984422193840146,0.772815742467169064793160171422670146057498641312122))
    +
    +
    +
    +
    +
    +

    Train a Model with Stochastic Gradient Descent

    +
    +
    +

    Stochastic Gradient Descent (SGD) is an optimization algorithm used to update model parameters (often called "weights") in machine learning by minimizing the error function (usually called "loss").

    +
    +
    +

    A common weight update rule is:

    +
    +
    +
    +Stochastic Gradient Descent +
    +
    +
    +

    Neural networks train with SGD and the many variants of the algorithm (such as Adam, RMSprop, and the alternative Batch Gradient Descent (4)). This approach is efficient for big data and real-time learning.

    +
    +
    +

    The following code shows a linear model of y = w * x + b being trained to fit synthetic data with some added noise.

    +
    +
    +
    +
    #include <boost/numeric/ublas/vector.hpp>
    +#include <boost/numeric/ublas/io.hpp>
    +#include <boost/random.hpp>
    +
    +namespace ublas = boost::numeric::ublas;
    +
    +using Vector = ublas::vector<double>;
    +
    +// Create synthetic training data: y = 2x + 1 + noise
    +void generate_data(std::vector<std::pair<double, double>>& data, int n) {
    +    boost::random::mt19937 rng;
    +    boost::random::uniform_real_distribution<> x_dist(0.0, 10.0);
    +    boost::random::normal_distribution<> noise(0.0, 1.0);
    +
    +    for (int i = 0; i < n; ++i) {
    +        double x = x_dist(rng);
    +        double y = 2.0 * x + 1.0 + noise(rng);  // true model + noise
    +        data.emplace_back(x, y);
    +    }
    +}
    +
    +int main() {
    +    std::vector<std::pair<double, double>> data;
    +    generate_data(data, 100);  // 100 training samples
    +
    +    double w = 0.0;  // weight
    +    double b = 0.0;  // bias
    +    double learning_rate = 0.01;
    +    int epochs = 100;
    +
    +    boost::random::mt19937 rng;
    +    boost::random::uniform_int_distribution<> index_dist(0, data.size() - 1);
    +
    +    for (int epoch = 0; epoch < epochs; ++epoch) {
    +        // SGD: pick one random point
    +        auto [x, y_true] = data[index_dist(rng)];
    +
    +        double y_pred = w * x + b;
    +        double error = y_pred - y_true;
    +
    +        // Update parameters
    +        w -= learning_rate * error * x;
    +        b -= learning_rate * error;
    +
    +        if (epoch % 10 == 0) {
    +            std::cout << "Epoch " << epoch << ": w=" << w << ", b=" << b << ", error=" << error << "\n";
    +        }
    +    }
    +
    +    std::cout << "\nTrained Model: y = " << w << " * x + " << b << "\n";
    +    return 0;
    +}
    +
    +
    +
    +

    Running the code should give you output similar to the following:

    +
    +
    +
    +
    Epoch 0: w=1.51034, b=0.184796, error=-18.4796
    +Epoch 10: w=2.05504, b=0.293644, error=-1.20787
    +Epoch 20: w=2.15505, b=0.327562, error=0.9483
    +Epoch 30: w=2.13036, b=0.345799, error=-1.19758
    +Epoch 40: w=2.10543, b=0.340667, error=-0.0997447
    +Epoch 50: w=2.12241, b=0.352897, error=-0.0906088
    +Epoch 60: w=2.0156, b=0.333943, error=0.738856
    +Epoch 70: w=2.02403, b=0.369294, error=1.36926
    +Epoch 80: w=2.17905, b=0.411506, error=-0.849716
    +Epoch 90: w=2.1482, b=0.430549, error=-0.839941
    +
    +Trained Model: y = 2.11625 * x + 0.455491
    +
    +
    +
    +
    +
    +

    Classify Data using K-Means Clustering

    +
    +
    +

    K-Means Clustering is a classification system to group data points into clusters. The statistical functions of Boost.Math measure Euclidean distances that are the basis of K-Means clustering, which is a centroid-based clustering algorithm that partitions data into K clusters based on the nearest mean (centroid).

    +
    +
    +

    The clustering algorithm goes through the following cycle:

    +
    +
    +
      +
    1. +

      Randomly initialize K centroids

      +
    2. +
    3. +

      Assigns points to the nearest centroid

      +
    4. +
    5. +

      Recalculates centroids

      +
    6. +
    7. +

      Repeats (go back to step 2) until convergence

      +
    8. +
    +
    +
    +

    First let’s download a real dataset, the Iris data contains around 150 entries in the format: sepal_length, sepal_width, petal_length, petal_width, species.

    +
    + +
    +

    The file should look like the following:

    +
    +
    +
    +
    sepal_length,sepal_width,petal_length,petal_width,species
    +5.1, 3.5, 1.4, 0.2, setosa
    +4.9, 3.0, 1.4, 0.2, setosa
    +4.7, 3.2, 1.3, 0.2, setosa
    +...
    +7.0, 3.2, 4.7, 1.4, versicolor
    +6.4, 3.2, 4.5, 1.5, versicolor
    +6.9, 3.1, 4.9, 1.5, versicolor
    +...
    +6.3, 3.3, 6.0, 2.5, virginica
    +5.8, 2.7, 5.1, 1.9, virginica
    +7.1, 3.0, 5.9, 2.1, virginica
    +
    +
    +
    +

    For reference:

    +
    +
    +
    +Iris photo +
    +
    +
    +

    Photo:V.Foss-Turcan

    +
    +
    +

    Save the Iris file to your local computer, and update the following code with the path to it:

    +
    +
    +
    +
    #include <fstream>
    +#include <boost/numeric/ublas/vector.hpp>      // Boost linear algebra: vector, matrix, etc.
    +#include <boost/random.hpp>                    // Boost Random library (random_device, mt19937, distributions)
    +#include <boost/random/random_device.hpp>      // Ensures random_device is available
    +
    +namespace br = boost::random;                  // Alias for convenience
    +using namespace boost::numeric::ublas;         // For uBLAS vector<>
    +using DataPoint = vector<double>;              // A single data point = 4 numeric features
    +using Cluster = std::vector<DataPoint>;        // A cluster = collection of data points
    +
    +// Constants for the Iris dataset and K-Means parameters
    +constexpr size_t FEATURES = 4;                 // Number of features per sample (Iris = 4)
    +constexpr size_t K = 3;                        // Number of clusters (3 Iris species)
    +constexpr size_t MAX_ITER = 100;               // Max number of K-Means iterations
    +
    +// -----------------------------
    +// Load data from CSV file
    +// -----------------------------
    +std::vector<DataPoint> load_iris_csv(const std::string& filename) {
    +    std::ifstream file(filename);
    +    std::vector<DataPoint> data;
    +    std::string line;
    +
    +    if (!file.is_open()) {
    +        throw std::runtime_error("Could not open file.");
    +    }
    +
    +    // Skip header line (contains column names)
    +    std::getline(file, line);
    +
    +    // CSV format: sepal_length, sepal_width, petal_length, petal_width, species
    +    while (std::getline(file, line)) {
    +        std::stringstream ss(line);
    +        std::string token;
    +        DataPoint point(FEATURES);
    +
    +        // Parse first 4 numeric values
    +        for (size_t i = 0; i < FEATURES; ++i) {
    +            if (!std::getline(ss, token, ',')) break;
    +            point(i) = std::stod(token);
    +        }
    +
    +        // Only add valid 4-element vectors
    +        if (point.size() == FEATURES)
    +            data.push_back(point);
    +    }
    +
    +    return data;
    +}
    +
    +// -----------------------------
    +// Euclidean distance function
    +// -----------------------------
    +double euclidean_distance(const DataPoint& a, const DataPoint& b) {
    +    double sum = 0.0;
    +    for (size_t i = 0; i < a.size(); ++i)
    +        sum += std::pow(a[i] - b[i], 2);
    +    return std::sqrt(sum);
    +}
    +
    +// -----------------------------
    +// Find index of nearest centroid
    +// -----------------------------
    +size_t closest_centroid(const DataPoint& point, const std::vector<DataPoint>& centroids) {
    +    double min_dist = std::numeric_limits<double>::max();
    +    size_t index = 0;
    +    for (size_t i = 0; i < centroids.size(); ++i) {
    +        double dist = euclidean_distance(point, centroids[i]);
    +        if (dist < min_dist) {
    +            min_dist = dist;
    +            index = i;
    +        }
    +    }
    +    return index;
    +}
    +
    +// -----------------------------
    +// Compute centroid (mean of cluster points)
    +// -----------------------------
    +DataPoint compute_centroid(const Cluster& cluster) {
    +    DataPoint centroid(FEATURES, 0.0);
    +    if (cluster.empty()) return centroid;
    +
    +    for (const auto& point : cluster)
    +        centroid += point;                     // Sum all data points in cluster
    +
    +    return centroid / static_cast<double>(cluster.size()); // Average each dimension
    +}
    +
    +// -----------------------------
    +// Initialize centroids randomly
    +// -----------------------------
    +std::vector<DataPoint> init_random_centroids(const std::vector<DataPoint>& data, size_t k) {
    +    br::random_device rd;                      // Hardware entropy source
    +    br::mt19937 gen(rd());                     // Mersenne Twister engine
    +    br::uniform_int_distribution<> dist(0, data.size() - 1); // Random index range
    +    std::vector<DataPoint> centroids;
    +    for (size_t i = 0; i < k; ++i)
    +        centroids.push_back(data[dist(gen)]);  // Pick random samples as initial centroids
    +    return centroids;
    +}
    +
    +// -----------------------------
    +// K-Means clustering algorithm
    +// -----------------------------
    +void kmeans(const std::vector<DataPoint>& data, size_t k) {
    +    auto centroids = init_random_centroids(data, k);
    +    std::vector<size_t> assignments(data.size(), 0); // Each data point’s assigned cluster
    +
    +    for (size_t iter = 0; iter < MAX_ITER; ++iter) {
    +        bool changed = false;
    +        std::vector<Cluster> clusters(k);      // One cluster per centroid
    +
    +        // Step 1: Assign each point to the closest centroid
    +        for (size_t i = 0; i < data.size(); ++i) {
    +            size_t idx = closest_centroid(data[i], centroids);
    +            if (idx != assignments[i]) {
    +                changed = true;                // Track if any point changed cluster
    +                assignments[i] = idx;
    +            }
    +            clusters[idx].push_back(data[i]);
    +        }
    +
    +        // Stop early if clusters no longer change
    +        if (!changed) {
    +            std::cout << "\nConverged after " << iter << " iterations.\n";
    +            break;
    +        }
    +
    +        // Step 2: Recompute centroids as cluster means
    +        for (size_t i = 0; i < k; ++i)
    +            centroids[i] = compute_centroid(clusters[i]);
    +    }
    +
    +    // -----------------------------
    +    // Output cluster summaries
    +    // -----------------------------
    +    for (size_t i = 0; i < k; ++i) {
    +        std::cout << "Cluster " << i + 1 << ": "
    +            << std::count(assignments.begin(), assignments.end(), i)
    +            << " samples\n";
    +    }
    +}
    +
    +// -----------------------------
    +// Main program
    +// -----------------------------
    +int main() {
    +    try {
    +        // Load the Iris dataset (CSV path required)
    +        auto data = load_iris_csv("<path>\\iris.csv");
    +        std::cout << "Loaded " << data.size() << " samples.\n";
    +
    +        // Run K-Means clustering
    +        kmeans(data, K);
    +    }
    +    catch (const std::exception& e) {
    +        // Handle file or numeric parsing errors gracefully
    +        std::cerr << "Error: " << e.what() << "\n";
    +        return 1;
    +    }
    +    return 0;
    +}
    +
    +
    +
    +

    Running this code should give you:

    +
    +
    +
    +
    Loaded 150 samples.
    +
    +Converged after 3 iterations.
    +Cluster 1: 22 samples
    +Cluster 2: 31 samples
    +Cluster 3: 97 samples
    +
    +
    +
    +
    +
    Note
    +
    +

    Due to the random element, running the code repeatedly can give slightly different results, typically from 3 to 5 iterations and varying sample sizes.

    +
    +
    +
    +
    +
    +
    +

    Predict Future Values of Time Series Data

    +
    +
    +

    The following code tries to predict the next value in a 1D time series, using a simplified Transformer-style self-attention mechanism (5).

    +
    +
    +
    +
    #include <boost/numeric/ublas/vector.hpp>
    +#include <boost/numeric/ublas/matrix.hpp>
    +#include <boost/random.hpp>
    +
    +
    +namespace ublas = boost::numeric::ublas;
    +
    +using Vector = ublas::vector<double>;
    +using Matrix = ublas::matrix<double>;
    +
    +// Create a simple sine wave time series
    +std::vector<double> generate_time_series(int length) {
    +    std::vector<double> series(length);
    +    for (int i = 0; i < length; ++i)
    +        series[i] = std::sin(i * 0.1) + 0.1 * std::sin(i * 0.5);
    +    return series;
    +}
    +
    +// Apply scaled dot-product attention on a sequence matrix
    +Vector self_attention(const Matrix& sequence) {
    +    const std::size_t seq_len = sequence.size1();
    +    const std::size_t dim = sequence.size2();
    +
    +    Vector attention_output(dim, 0.0);
    +
    +    // Self-attention weights using dot-product of each timestep with others
    +    for (std::size_t t = 0; t < seq_len; ++t) {
    +        double score = 0.0;
    +        for (std::size_t j = 0; j < seq_len; ++j) {
    +            for (std::size_t d = 0; d < dim; ++d)
    +                score += sequence(t, d) * sequence(j, d);
    +        }
    +        score /= (seq_len * dim);  // normalize
    +
    +        for (std::size_t d = 0; d < dim; ++d)
    +            attention_output[d] += score * sequence(t, d);
    +    }
    +
    +    return attention_output;
    +}
    +
    +int main() {
    +    const int sequence_length = 10;
    +    const int embedding_dim = 4;
    +    const int total_samples = 200;
    +
    +    // Generate synthetic sine wave data
    +    auto series = generate_time_series(total_samples);
    +
    +    // Simple random projection into embedding space
    +    boost::random::mt19937 rng;
    +    boost::random::uniform_real_distribution<> dist(-1.0, 1.0);
    +    Matrix embedding(sequence_length, embedding_dim);
    +    for (std::size_t i = 0; i < sequence_length; ++i)
    +        for (std::size_t j = 0; j < embedding_dim; ++j)
    +            embedding(i, j) = dist(rng);
    +
    +    // Feed input sequence through attention
    +    for (int t = 0; t < total_samples - sequence_length - 1; ++t) {
    +        Matrix seq_matrix(sequence_length, embedding_dim);
    +        for (int i = 0; i < sequence_length; ++i) {
    +            for (int d = 0; d < embedding_dim; ++d)
    +                seq_matrix(i, d) = series[t + i] * embedding(i, d);  // embed input
    +        }
    +
    +        Vector context = self_attention(seq_matrix);
    +        double prediction = ublas::sum(context) / embedding_dim;  // crude projection to scalar
    +
    +        double target = series[t + sequence_length];
    +        std::cout << "Predicted: " << prediction << ", Target: " << target << '\n';
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Predicted: 0.0469448, Target: 0.745579
    +Predicted: 0.06675, Target: 0.820653
    +Predicted: 0.0893931, Target: 0.904098
    +Predicted: 0.115752, Target: 0.98507
    +Predicted: 0.147007, Target: 1.05115
    +Predicted: 0.18403, Target: 1.09129
    +Predicted: 0.226992, Target: 1.09851
    +Predicted: 0.274918, Target: 1.07151
    +....
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    Machine learning is a challenging task. This section just touched on some algorithms and processes that might be considered. Investigating decision trees, neural networks, different classification approaches, linear regression algorithms, all might help in gaining a programmers understanding of the daunting issues involved in making smart decisions, and getting smarter over time!

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +Overfitting in the context of machine learning refers to a model that has been trained too well on the training data, to the point where it has started to memorize the noise or outliers in the data rather than generalizing from the underlying patterns or trends. As a result, the model will perform very well on the training data, but poorly on new, unseen data (that is, it will have poor generalization performance). To mitigate overfitting, techniques such as cross-validation, regularization, pruning, or early stopping are often used. Another common strategy is to increase the amount of training data so the model can learn more generalized features.

    +
    +
    +

    (2) +The kernel trick is a method used in machine learning to apply a linear classifier to data that is not linearly separable. It works by mapping the original input features into a higher-dimensional space where a linear classifier can be used to separate the data. This mapping is done using a function known as a kernel function. The "trick" part of the kernel trick comes from the fact that the kernel function allows us to operate in the higher-dimensional space without explicitly computing the coordinates of the data in that space. Instead, the kernel function computes only the inner products between the images of all pairs of data in the higher-dimensional space.

    +
    +
    +

    (3) +Bayesian inference is used to calculate a probability for a hypothesis (using Bayes theorem), based on existing evidence, and then update it as more data becomes available. This approach has proved to be robust as it does not require the sample size to be known in advance, and has a wide range of applications. A Markov chain describes a sequence of possible events, where the probability of an event occurring in the chain is solely dependent on the previous event. Markov chains are popular in statistical modeling, partly because of the simplification it provides in that only the current state of affairs is important - not any previous history. Markov chain Monte Carlo methods are often used to study probability distributions too complex for analytical methods alone.

    +
    +
    +

    (4) +Gradient Descent is an optimization algorithm used to minimize a function by iteratively adjusting parameters in the direction of the steepest descent. There are several variations, each with trade-offs. Stochastic Gradient Descent updates model parameters using a single randomly chosen training sample per iteration, making it computationally efficient but introducing high variance in updates, leading to noisy convergence. Batch Gradient Descent, in contrast, computes gradients over the entire dataset before making an update, leading to stable but computationally expensive iterations. A middle ground is Mini-Batch Gradient Descent, which processes small batches of data per iteration, balancing computational efficiency and convergence stability.

    +
    +
    +

    To improve upon standard gradient descent, adaptive optimization methods like Adam (Adaptive Moment Estimation) and RMSprop (Root Mean Square Propagation) were developed. RMSprop modifies the learning rate for each parameter based on recent gradient magnitudes, helping it navigate noisy gradients efficiently. Adam combines both momentum (which smooths updates) and adaptive learning rates (adjusting step sizes per parameter), making it one of the most widely used optimizers due to its robustness across different problems. These methods help accelerate convergence and handle sparse or non-stationary gradients better than traditional gradient descent techniques.

    +
    +
    +

    (5) +A Transformer-style self-attention mechanism is a powerful technique used in modern machine learning models — especially in natural language processing — to allow a model to weigh the importance of different parts of the input data relative to each other. In simple terms, self-attention enables a model to "look at" all elements of a sequence (like words in a sentence or time steps in a series) and determine how much focus each element should get when processing a specific item. For example, in a sentence, the meaning of a word may depend heavily on another word several positions away. The self-attention mechanism calculates attention scores that capture these dependencies, regardless of distance, and transforms the input into a new representation that highlights the most relevant relationships.

    +
    +
    +

    The Transformer-style part refers to the architecture introduced in the groundbreaking 2017 paper "Attention Is All You Need" (Vaswani et al), which relies on stacking multiple layers of self-attention and feedforward operations without using recurrent or convolutional components. This approach enables parallel processing and captures complex patterns in data, making it a foundation for models like GPT and BERT.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-metaprogramming.html b/preview/user-guide/task-metaprogramming.html new file mode 100644 index 0000000..839a7df --- /dev/null +++ b/preview/user-guide/task-metaprogramming.html @@ -0,0 +1,867 @@ + + + + + + + + + + + + + + Metaprogramming :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Metaprogramming

    +
    +
    +
    +

    Boost provides several libraries that are highly useful in metaprogramming, and can greatly ease the process of building your own metaprogramming-based C++ library. You will need to clearly understand heterogeneous types (1) and tuples (2).

    +
    +
    + +
    +
    +
    +
    +

    Libraries

    +
    +
    +
      +
    • +

      Boost.Mp11: A metaprogramming library that provides a framework of compile-time algorithms, preprocessor directives, sequences and metafunctions, that can greatly facilitate metaprogramming tasks.

      +
    • +
    • +

      Boost.Hana: This is a modern, high-level library for metaprogramming. Like Boost.Fusion, it is used for working with heterogeneous collections, but it uses modern C++ features and can be easier to use than (and can be considered a successor to) both Boost.Mpl and Boost.Fusion.

      +
    • +
    • +

      Boost.TypeTraits: Provides a collection of templates for information about types. This can be useful in many metaprogramming tasks, as it allows for compile-time introspection of types.

      +
    • +
    • +

      Boost.StaticAssert: Provides a macro for compile-time assertions. This can be useful to enforce constraints at compile time.

      +
      +
      +
      Notes
      +
      +

      Boost.Mpl, Boost.Fusion and Boost.Preprocessor, all still available in the Boost library, have been superseded by Boost.Mp11 and Boost.Hana.

      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Metaprogramming Applications

    +
    +
    +

    Metaprogramming, the practice of writing code that generates or manipulates other code, has several powerful applications, particularly in languages like C++ that support compile-time metaprogramming. Be careful though, despite its power, metaprogramming can also lead to complex, hard-to-understand code and should be used judiciously. Here are some of the primary applications of metaprogramming:

    +
    +
    +
      +
    • +

      Code Generation: One of the most common uses of metaprogramming is to automatically generate code. This can help to reduce boilerplate, prevent repetition, and facilitate the adherence to the DRY (Don’t Repeat Yourself) principle.

      +
    • +
    • +

      Optimization: Metaprogramming can be used to generate specialized versions of algorithms or data structures, which can lead to more efficient code. For example, in C++, template metaprogramming can be used to generate unrolled versions of loops, which can be faster because they eliminate the overhead of loop control.

      +
    • +
    • +

      Domain Specific Languages (DSLs): Metaprogramming can be used to create domain-specific languages within a host language. This can make the code more expressive and easier to write and read in specific domains. A classic example in C++ is Boost.Spirit, a library for creating parsers directly in C++ code.

      +
    • +
    • +

      Interface Generation: Metaprogramming can be used to generate interfaces, for example, serialization and deserialization methods for a variety of formats. This can greatly simplify the process of implementing such interfaces.

      +
    • +
    • +

      Reflection and Introspection: Although C++ does not support reflection directly, metaprogramming can be used to emulate some aspects of reflection, such as type traits and type-based dispatch.

      +
    • +
    • +

      Policy-based Design: This is a design paradigm in C++ where behavior is encapsulated in separate classes (policies), and classes are composed by specifying a set of policies as template parameters. This allows for high flexibility and reusability while maintaining performance.

      +
    • +
    +
    +
    +
    +
    +

    Automatic Code Generation Sample

    +
    +
    +

    The scenario is that we want to create a serializer for multiple types (int, double, std::string) without manually writing code for each one.

    +
    +
    +

    We’ll start by using Boost.Mp11 to generate a tuple of types at compile-time, and apply a function to each type automatically.

    +
    +
    +
    +
    #include <boost/mp11.hpp>
    +#include <iostream>
    +
    +namespace mp = boost::mp11;
    +
    +// Example function to "serialize" different types
    +template <typename T>
    +void serialize(const T& value) {
    +    std::cout << "Serializing: " << value << "\n";
    +}
    +
    +// Generate and call functions for multiple types
    +template <typename... Types>
    +void auto_generate_serializers(std::tuple<Types...> data) {
    +
    +    // Iterate over each type and call serialize()
    +    mp::mp_for_each<std::tuple<Types...>>([&](auto type_wrapper) {
    +        using T = decltype(type_wrapper);
    +
    +        serialize(std::get<T>(data));  // Automatically gets the correct type from tuple
    +    });
    +}
    +
    +int main() {
    +
    +    // Define a tuple of different types
    +    std::tuple<int, double, std::string> data(42, 3.14, "Hello, MP11!");
    +
    +    // Automatically generate and call serializers
    +    auto_generate_serializers(data);
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Output

    +
    +
    +
    Serializing: 42
    +Serializing: 3.14
    +Serializing: Hello, MP11!
    +
    +
    +
    +

    The advantages of automatically generating correct functions include compile-time type safety, and eliminating runtime overhead of type checking.

    +
    +
    +
    +
    +
    +

    Serialize a User-Defined Struct

    +
    +
    +

    Our scenario makes more sense if we want to serialize a custom user-defined struct. A simple structure in this example, but it could be quite complex.

    +
    +
    +
    +
    #include <boost/mp11.hpp>
    +#include <iostream>
    +
    +namespace mp = boost::mp11;
    +
    +// Custom struct
    +struct Person {
    +    std::string name;
    +    int age;
    +};
    +
    +// Overload `operator<<` to allow printing of Person objects
    +std::ostream& operator<<(std::ostream& os, const Person& p) {
    +    return os << "{ Name: " << p.name << ", Age: " << p.age << " }";
    +}
    +
    +// Serialize function template
    +template <typename T>
    +void serialize(const T& value) {
    +    std::cout << "Serializing: " << value << "\n";
    +}
    +
    +// Specialization for Person (if needed)
    +template <>
    +void serialize(const Person& p) {
    +    std::cout << "Serializing Person -> Name: " << p.name << ", Age: " << p.age << "\n";
    +}
    +
    +// Automatically process multiple types in a tuple
    +template <typename... Types>
    +void auto_generate_serializers(std::tuple<Types...> data) {
    +    mp::mp_for_each<std::tuple<Types...>>([&](auto type_wrapper) {
    +        using T = decltype(type_wrapper);
    +        serialize(std::get<T>(data));  // Extract correct type from tuple and serialize
    +    });
    +}
    +
    +int main() {
    +
    +    // Define a tuple with primitive types + a custom struct
    +    std::tuple<int, double, std::string, Person> data(42, 3.14, "Hello, MP11!", {"Alice", 30});
    +
    +    // Automatically generate and call serializers
    +    auto_generate_serializers(data);
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    The code supports operator<< for printing, and now mp_for_each automatically handles Person just like other types.

    +
    +
    +
    +
    +

    Output

    +
    +
    +
    Serializing: 42
    +Serializing: 3.14
    +Serializing: Hello, MP11!
    +Serializing Person -> Name: Alice, Age: 30
    +
    +
    +
    +

    The beauty of this approach is that you can just add more types to the tuple, and it just works!

    +
    +
    +
    +
    +
    +

    Compile-time Type Checking

    +
    +
    +

    Let’s extend the sample to integrate Boost.TypeTraits to determine if a type is serializable at compile time. The functions we will use are is_arithmetic<T> to check if T is a number type (int, double, etc.), and is_class<T> to check if T is a user-defined class (Person, etc.). The idea is that the compile-time filtering ensures that the code can only process serializable types.

    +
    +
    +
    +
    Note
    +
    +

    A void is an example of a non-serializable type.

    +
    +
    +
    +
    +
    +
    #include <boost/mp11.hpp>
    +#include <boost/type_traits.hpp>
    +#include <iostream>
    +
    +namespace mp = boost::mp11;
    +
    +// Custom struct
    +struct Person {
    +    std::string name;
    +    int age;
    +};
    +
    +// Overload `operator<<` to allow printing of Person objects
    +std::ostream& operator<<(std::ostream& os, const Person& p) {
    +    return os << "{ Name: " << p.name << ", Age: " << p.age << " }";
    +}
    +
    +// Serialize function template
    +template <typename T>
    +void serialize(const T& value) {
    +    if constexpr (boost::is_arithmetic<T>::value || std::is_same<T, std::string>::value) {
    +        std::cout << "Serializing: " << value << "\n";
    +    } else if constexpr (boost::is_class<T>::value) {
    +        std::cout << "Serializing Class -> ";
    +        std::cout << value << "\n"; // Uses operator<< overload
    +    } else {
    +        std::cout << "Skipping unsupported type!\n";
    +    }
    +}
    +
    +// Automatically process serializable types in a tuple
    +template <typename... Types>
    +void auto_generate_serializers(std::tuple<Types...> data) {
    +    mp::mp_for_each<std::tuple<Types...>>([&](auto type_wrapper) {
    +        using T = decltype(type_wrapper);
    +
    +        // Only serialize supported types
    +        if constexpr (boost::is_arithmetic<T>::value || boost::is_class<T>::value || std::is_same<T, std::string>::value) {
    +            serialize(std::get<T>(data));
    +        } else {
    +            std::cout << "Skipping non-serializable type\n";
    +        }
    +    });
    +}
    +
    +int main() {
    +
    +    // Define a tuple with primitive types, a custom struct, and an unsupported type
    +    std::tuple<int, double, std::string, Person, void*> data(42, 3.14, "Boost Rocks!", {"Alice", 30}, nullptr);
    +
    +    // Automatically generate and call serializers
    +    auto_generate_serializers(data);
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Uses if constexpr for compile-time filtering, and std::string is explicitly handled.

    +
    +
    +
    +
    +

    Output

    +
    +
    +
    Serializing: 42
    +Serializing: 3.14
    +Serializing: Boost Rocks!
    +Serializing Class -> { Name: Alice, Age: 30 }
    +Skipping non-serializable type
    +
    +
    +
    +
    +
    +
    +

    Add Tuple Processing at Runtime

    +
    +
    +

    Boost.Mp11 is for pure type-based metaprogramming (so works only at compile time), whereas Boost.Hana takes a value-based metaprogramming approach (it works at both compile time and runtime). In a real application, you may well choose to use one of these two libraries, and not both!

    +
    +
    +

    Boost.Hana adds efficient tuple handling at runtime (for example, easier access and transformation), in addition to tag-based dispatching to categorize different types (arithmetic, class, etc.), and concise functional-style operations. To summarize when to use each library:

    +
    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FeatureBoost.Mp11Boost.Hana

    Type-based Metaprogramming

    Yes

    Yes

    Value-based Metaprogramming

    No

    Yes

    Compile-time Transformations

    Yes

    Yes

    Runtime Tuple Handling

    No

    Yes

    Easier Type Mapping

    No

    Yes

    Better Compile-Time Speed

    Yes

    No, Slower

    +
    +

    Let’s update our sample to include tag dispatching, so each type is classified at compile time, and runtime tuple processing, so the sample iterates over heterogeneous types at runtime. Not having all metaprogramming processes occur at the same time does add a level to your program complexity!

    +
    +
    +
    +template time machine +
    +
    +
    +
    +
    #include <boost/hana.hpp>
    +#include <boost/mp11.hpp>
    +#include <boost/type_traits.hpp>
    +#include <iostream>
    +
    +namespace hana = boost::hana;
    +namespace mp = boost::mp11;
    +
    +// Custom struct
    +struct Person {
    +    std::string name;
    +    int age;
    +};
    +
    +// Overload `operator<<` for printing
    +std::ostream& operator<<(std::ostream& os, const Person& p) {
    +    return os << "{ Name: " << p.name << ", Age: " << p.age << " }";
    +}
    +
    +// Tag-based dispatching
    +auto classify = hana::make_map(
    +    hana::make_pair(hana::type_c<int>, "Integer"),
    +    hana::make_pair(hana::type_c<double>, "Floating Point"),
    +    hana::make_pair(hana::type_c<std::string>, "String"),
    +    hana::make_pair(hana::type_c<Person>, "Custom Struct")
    +);
    +
    +// Serialize function
    +template <typename T>
    +void serialize(const T& value) {
    +    if constexpr (boost::is_arithmetic<T>::value || std::is_same<T, std::string>::value) {
    +        std::cout << "Serializing (" << hana::find(classify, hana::type_c<T>).value() << "): " << value << "\n";
    +    } else if constexpr (boost::is_class<T>::value) {
    +        std::cout << "Serializing (Custom Struct) -> " << value << "\n";
    +    } else {
    +        std::cout << "Skipping non-serializable type!\n";
    +    }
    +}
    +
    +// Process a tuple
    +template <typename Tuple>
    +void auto_generate_serializers(Tuple data) {
    +    hana::for_each(data, [](auto x) {
    +        serialize(x);
    +    });
    +}
    +
    +int main() {
    +
    +    // Declare a tuple (runtime and compile-time)
    +    auto data = hana::make_tuple(42, 3.14, "Boost Rocks!", Person{"Alice", 30});
    +
    +    // Automatically process serializable elements
    +    auto_generate_serializers(data);
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Tag dispatching is handled by hana::make_map, and runtime tuple processing is managed by hana::for_each.

    +
    +
    +
    +
    +

    Output

    +
    +
    +
    Serializing (Integer): 42
    +Serializing (Floating Point): 3.14
    +Skipping non-serializable type!
    +Serializing (Custom Struct) -> { Name: Alice, Age: 30 }
    +
    +
    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +Heterogeneous refers to data structures or operations that can handle multiple types, rather than being restricted to a single type. This is particularly useful in template-based programming, where different types can be stored and manipulated in a type-safe manner at compile time. A key example is std::tuple or boost::hana::tuple, which allow elements of different types to coexist in a single structure, enabling powerful compile-time computations and flexible generic programming.

    +
    +
    +

    (2) +A tuple is a fixed-size, ordered collection of heterogeneous types, typically represented at compile-time using template-based constructs. Unlike runtime tuples (such as std::tuple), metaprogramming tuples primarily serve as type lists or compile-time containers, enabling static type manipulation, transformations, and computations. Metaprogramming tuples are frequently used in Boost.Mp11, Boost.Hana, and Boost.Fusion, where they allow for:

    +
    +
    +
      +
    1. +

      Type introspection - examining contained types at compile-time

      +
    2. +
    3. +

      Type transformations - modifying types before instantiation

      +
    4. +
    5. +

      Static dispatching - choosing behavior based on type properties

      +
    6. +
    7. +

      Compile-time iteration - for example, mp_for_each in Boost.Mp11

      +
    8. +
    +
    +
    +

    For example, a metaprogramming tuple can represent a heterogeneous list of types:

    +
    +
    +
    +
    using my_types = boost::mp11::mp_list<int, double, std::string>;
    +
    +
    +
    +

    This mp_list is a type-level tuple that can be manipulated without creating runtime instances.

    +
    +
    +

    Unlike std::tuple, which holds actual values, metaprogramming tuples operate entirely at the type level, making them invaluable for zero-runtime-cost template metaprogramming.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-natural-language-parsing.html b/preview/user-guide/task-natural-language-parsing.html new file mode 100644 index 0000000..a882e53 --- /dev/null +++ b/preview/user-guide/task-natural-language-parsing.html @@ -0,0 +1,876 @@ + + + + + + + + + + + + + + Natural Language Processing :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Natural Language Processing

    +
    +
    +
    +

    Developing a natural language parsing model involves tasks such as tokenization, parsing, and possibly dealing with ambiguous or erroneous inputs.

    +
    +
    +

    Natural language processing is a complex field that goes beyond just programming. It involves knowledge of linguistics, and many parsing tasks can be difficult due to the ambiguity and complexity of natural languages. You may want to look into existing tools and libraries specifically designed for natural language processing, like NLTK or SpaCy for Python, in addition to the general-purpose libraries that Boost offers.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +
      +
    • +

      Boost.Spirit: This is Boost’s library for creating parsers and output generation. It includes support for creating grammars, which can be used to define the structure of sentences in English, or other language. You can use it to tokenize and parse input text according to your grammars.

      +
    • +
    • +

      Boost.Phoenix: A library for functional programming, it supports the ability to create inline functions which can be used for defining semantic actions.

      +
    • +
    • +

      Boost.Regex: For some simpler parsing tasks, regular expressions can be sufficient and easier to use than full-blown parsing libraries. You could use Boost.Regex to match specific patterns in your input text, like specific words or phrases, word boundaries, etc.

      +
    • +
    • +

      Boost.String_Algo: Provides various string manipulation algorithms, such as splitting strings, trimming whitespace, or replacing substrings. These can be useful in preprocessing text before parsing it.

      +
    • +
    • +

      Boost.Optional and Boost.Variant: These libraries can be helpful in representing the result of a parsing operation, which could be a successful parse (yielding a specific result), an error, or an ambiguous parse (yielding multiple possible results).

      +
    • +
    • +

      Boost.MultiIndex: Provides data structures that can be indexed in multiple ways. It can be useful for storing and retrieving information about words or phrases in your language model, such as part of speech, frequency, or possible meanings.

      +
    • +
    • +

      Boost.PropertyTree or Boost.Json: These libraries can be useful for handling input and output, such as reading configuration files or producing structured output.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Natural Language Processing Applications

    +
    +
    +

    Natural language parsing (NLP) is a foundational technology that powers many more applications and is a hot area of research and development.

    +
    +
    +
      +
    • +

      Search Engines: Search engines like Google extensively use natural language processing to understand the intent behind user queries and provide accurate and relevant search results.

      +
    • +
    • +

      Machine Translation: Services like Google Translate and DeepL rely on natural language parsing for their operation. These services can now translate text between many different languages with surprising accuracy.

      +
    • +
    • +

      Speech Recognition: Virtual assistants like Apple’s Siri, Amazon’s Alexa, Google Assistant, and Microsoft’s Cortana, use natural language parsing to understand voice commands from users.

      +
    • +
    • +

      Text Summarization: This is used in a variety of contexts, from generating summaries of news articles, scientific papers, to creating summaries of lengthy documents for quicker reading.

      +
    • +
    • +

      Sentiment Analysis: Businesses use NLP to gauge public opinion about their products and services by analyzing social media posts, customer reviews, and other user-generated content.

      +
    • +
    • +

      Chatbots and Virtual Assistants: NLP is key to the operation of automated chatbots, which are used for everything from customer service to mental health support.

      +
    • +
    • +

      Information Extraction: Companies use NLP to extract specific information from unstructured text, like dates, names, or specific keywords.

      +
    • +
    • +

      Text-to-Speech (TTS): Services that convert written text into spoken words often use natural language processing to ensure proper pronunciation, intonation, and timing.

      +
    • +
    • +

      Grammar Checkers: Tools like Grammarly use natural language processing to correct grammar, punctuation, and style in written text.

      +
    • +
    • +

      Content Recommendation: Platforms like YouTube or Netflix use NLP to analyze the content and provide more accurate and personalized recommendations.

      +
    • +
    +
    +
    +
    +
    +

    Simple English Parsing Sample

    +
    +
    +

    Say we wanted to parse a subset of the English language, only sentences of the form: The <adjective> <noun> <verb>. Example sentences are "The quick fox jumps." or "The lazy dog sleeps."

    +
    +
    +

    If the input matches this grammar, the following parser will accept it. Otherwise, it rejects the input.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/spirit/include/qi.hpp>
    +
    +namespace qi = boost::spirit::qi;
    +
    +bool parseSentence(const std::string& input) {
    +
    +    // Grammar: The <adjective> <noun> <verb>.
    +    qi::rule<std::string::const_iterator, std::string()> word = +qi::alpha;
    +    qi::rule<std::string::const_iterator, std::string()> article = qi::lit("The");
    +    qi::rule<std::string::const_iterator, std::string()> adjective = word;
    +    qi::rule<std::string::const_iterator, std::string()> noun = word;
    +    qi::rule<std::string::const_iterator, std::string()> verb = word;
    +
    +    // Full sentence rule
    +    qi::rule<std::string::const_iterator, std::string()> sentence =
    +        article >> qi::lit(' ') >> adjective >> qi::lit(' ') >> noun >> qi::lit(' ') >> verb >> qi::lit('.');
    +
    +    auto begin = input.begin(), end = input.end();
    +    bool success = qi::parse(begin, end, sentence);
    +
    +    return success && (begin == end);  // Ensure full input is consumed
    +}
    +
    +int main() {
    +    std::string input = "";
    +    while (input != "exit")
    +    {
    +        std::cout << "Enter a sentence (format: The <adjective> <noun> <verb>.) Enter exit to quit.\n";
    +        std::getline(std::cin, input);
    +
    +        if (input == "exit")
    +            break;
    +
    +        if (parseSentence(input)) {
    +            std::cout << "Valid sentence!\n";
    +        }
    +        else {
    +            std::cout << "Invalid sentence.\n";
    +        }
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    In this code spaces have to be explicitly entered in the grammar rule. The next example shows how to skip spaces.

    +
    +
    +
    +
    +

    The following shows a successful parse:

    +
    +
    +
    +
    Enter a sentence (format: The <adjective> <noun> <verb>.) Enter exit to quit.
    +The happy cat purrs.
    +Valid sentence!
    +
    +
    +
    +

    And the following shows an unsuccessful parse:

    +
    +
    +
    +
    Enter a sentence (format: The <adjective> <noun> <verb>.) Enter exit to quit.
    +A small dog runs.
    +Invalid sentence.
    +
    +
    +
    +

    Our subset is clearly very limited, as simply replacing the word "The" with "A" results in an error, and a "sentence" such as "The xxx yyy zzz." is valid.

    +
    +
    +
    +
    +

    Add a Dictionary of Valid Words

    +
    +
    +

    The following example shows how to create a vocabulary of valid words, and allow optional adjectives and adverbs.

    +
    +
    +

    The parsing makes repeated use of statements such as -adj_syms[phoenix::ref(adj1) = qi::_1], which in English means "Try to match an adjective from adj_syms. If one is found, store it in adj1. If not found, continue without error.". This functionality is a feature of Boost.Phoenix, the statement attaches a semantic action to adj_syms, so that whenever a match occurs, it will execute adj1 = matched_value. The unary minus in front of adj_syms means this match is optional.

    +
    +
    +
    +
    #include <boost/spirit/include/qi.hpp>
    +#include <boost/spirit/include/phoenix.hpp>
    +#include <iostream>
    +
    +namespace qi = boost::spirit::qi;
    +namespace ascii = boost::spirit::ascii;
    +namespace phoenix = boost::phoenix;
    +
    +// Helper to populate symbol tables
    +template <typename SymbolTable>
    +void add_words(SymbolTable& symbols, const std::vector<std::string>& words) {
    +    for (const auto& word : words) {
    +        symbols.add(word, word);
    +    }
    +}
    +
    +int main() {
    +
    +    // Word categories
    +    std::vector<std::string> determiners = { "The", "A", "My" };
    +    std::vector<std::string> nouns = { "fox", "dog", "cat", "squirrel" };
    +    std::vector<std::string> verbs = { "jumps", "chased", "caught", "scared" };
    +    std::vector<std::string> adjectives = { "quick", "lazy", "sneaky", "clever" };
    +    std::vector<std::string> adverbs = { "loudly", "quickly", "angrily", "silently" };
    +
    +    // Symbol tables for parsing
    +    qi::symbols<char, std::string> dets, noun_syms, verb_syms, adj_syms, adv_syms;
    +    add_words(dets, determiners);
    +    add_words(noun_syms, nouns);
    +    add_words(verb_syms, verbs);
    +    add_words(adj_syms, adjectives);
    +    add_words(adv_syms, adverbs);
    +
    +    // Input
    +    std::string input = "";
    +
    +    while (input != "exit")
    +    {
    +        std::cout << "Enter a sentence (format: <Determiner> [<adjective>] <noun> [<adverb>] <verb> [<adjective>] <noun>.) Enter exit to quit.\n";
    +        std::getline(std::cin, input);
    +
    +        if (input != "exit")
    +        {
    +            // Iterators
    +            auto begin = input.begin();
    +            auto end = input.end();
    +
    +            // Output fields
    +            std::string det1, adj1, noun1, adv, verb, adj2, noun2;
    +
    +            // Grammar: Determiner [adjective] noun [adverb] verb [adjective] noun.
    +            bool success = qi::phrase_parse(
    +                begin, end,
    +                (
    +                    dets[phoenix::ref(det1) = qi::_1] >>
    +                    -adj_syms[phoenix::ref(adj1) = qi::_1] >>
    +                    noun_syms[phoenix::ref(noun1) = qi::_1] >>
    +                    -adv_syms[phoenix::ref(adv) = qi::_1] >>
    +                    verb_syms[phoenix::ref(verb) = qi::_1] >>
    +                    -adj_syms[phoenix::ref(adj2) = qi::_1] >>
    +                    noun_syms[phoenix::ref(noun2) = qi::_1] >>
    +                    qi::lit('.')
    +                    ),
    +                ascii::space
    +            );
    +
    +            // Result
    +            if (success && begin == end) {
    +                std::cout << "\nParsed successfully!\n";
    +                if (!det1.empty())  std::cout << "  Determiner:  " << det1 << "\n";
    +                if (!adj1.empty())  std::cout << "  Adjective 1: " << adj1 << "\n";
    +                std::cout << "  Noun 1:      " << noun1 << "\n";
    +                if (!adv.empty())   std::cout << "  Adverb:      " << adv << "\n";
    +                std::cout << "  Verb:        " << verb << "\n";
    +                if (!adj2.empty())  std::cout << "  Adjective 2: " << adj2 << "\n";
    +                std::cout << "  Noun 2:      " << noun2 << "\n";
    +            }
    +            else {
    +                std::cout << "\nParsing failed.\n";
    +            }
    +        }
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    The ascii::space parameter indicates that spaces should be skipped.

    +
    +
    +
    +
    +

    The following shows a successful parse:

    +
    +
    +
    +
    > My cat scared lazy squirrel.
    +
    +Parsed successfully!
    +  Determiner:  My
    +  Noun 1:      cat
    +  Verb:        scared
    +  Adjective 2: lazy
    +  Noun 2:      squirrel
    +
    +
    +
    +
    +
    +

    Add Detailed Error Reporting

    +
    +
    +

    Let’s not forget to provide useful comments and error messages:

    +
    +
    +
    +
    #include <boost/spirit/include/qi.hpp>       // Boost.Spirit Qi — parsing framework
    +#include <boost/spirit/include/phoenix.hpp>  // Boost.Phoenix — allows assignment actions in parsers
    +#include <iostream>
    +
    +namespace qi = boost::spirit::qi;            // Namespace alias for parser components
    +namespace ascii = boost::spirit::ascii;      // Namespace alias for ASCII space skipping, literals, etc.
    +namespace phoenix = boost::phoenix;          // Namespace alias for expression templates used in actions
    +
    +// -----------------------------------------------------------------------------
    +// Helper: Adds words into a Qi symbol table
    +// Each word is added as both key and value, enabling quick lookup and extraction.
    +// -----------------------------------------------------------------------------
    +template <typename SymbolTable>
    +void add_words(SymbolTable& symbols, const std::vector<std::string>& words) {
    +    for (const auto& word : words) {
    +        symbols.add(word, word);
    +    }
    +}
    +
    +// -----------------------------------------------------------------------------
    +// Helper: Validates a word against a known list
    +// Returns "- valid" or "- invalid" for display when parsing fails.
    +// -----------------------------------------------------------------------------
    +std::string is_valid(std::string word, std::vector<std::string> list)
    +{
    +    if (std::find(list.begin(), list.end(), word) != list.end())
    +        return "- valid";
    +    else
    +        return "- invalid";
    +}
    +
    +// -----------------------------------------------------------------------------
    +// Main function — interactive grammar demo
    +// Uses Boost.Spirit to parse simple English-like sentences with defined syntax.
    +// -----------------------------------------------------------------------------
    +int main() {
    +
    +    // -------------------------------------------------------------------------
    +    // Word categories (predefined vocabulary)
    +    // -------------------------------------------------------------------------
    +    std::vector<std::string> determiners = { "The", "A", "My" };
    +    std::vector<std::string> nouns       = { "fox", "dog", "cat", "squirrel" };
    +    std::vector<std::string> verbs       = { "jumps", "chased", "caught", "scared" };
    +    std::vector<std::string> adjectives  = { "quick", "lazy", "sneaky", "clever" };
    +    std::vector<std::string> adverbs     = { "loudly", "quickly", "angrily", "silently" };
    +
    +    // -------------------------------------------------------------------------
    +    // Create Qi symbol tables for each word type
    +    // qi::symbols maps literal strings to stored values — used as grammar terminals.
    +    // -------------------------------------------------------------------------
    +    qi::symbols<char, std::string> dets, noun_syms, verb_syms, adj_syms, adv_syms;
    +    add_words(dets, determiners);
    +    add_words(noun_syms, nouns);
    +    add_words(verb_syms, verbs);
    +    add_words(adj_syms, adjectives);
    +    add_words(adv_syms, adverbs);
    +
    +    // -------------------------------------------------------------------------
    +    // Interactive input loop
    +    // The user can enter sentences repeatedly until typing "exit".
    +    // -------------------------------------------------------------------------
    +    std::string input = "";
    +
    +    while (input != "exit")
    +    {
    +        std::cout << "Enter a sentence (format: <Determiner> [<adjective>] <noun> "
    +                     "[<adverb>] <verb> [<adjective>] <noun>.) Enter exit to quit.\n";
    +        std::getline(std::cin, input);
    +
    +        if (input != "exit")
    +        {
    +            // -----------------------------------------------------------------
    +            // Iterator pair used by Boost.Spirit parsers
    +            // -----------------------------------------------------------------
    +            auto begin = input.begin();
    +            auto end   = input.end();
    +
    +            // -----------------------------------------------------------------
    +            // Variables to store parsed components of the sentence
    +            // The Phoenix library binds parsed tokens to these variables.
    +            // -----------------------------------------------------------------
    +            std::string det1, adj1, noun1, adv, verb, adj2, noun2;
    +
    +            // -----------------------------------------------------------------
    +            // Grammar definition using Boost.Spirit.Qi
    +            // Sentence pattern:
    +            //   Determiner [Adjective] Noun [Adverb] Verb [Adjective] Noun .
    +            // The '>>' operator sequences parsing rules.
    +            // The '-' operator makes a parser optional.
    +            // The '[phoenix::ref(x) = qi::_1]' assigns the parsed value to 'x'.
    +            // -----------------------------------------------------------------
    +            bool success = qi::phrase_parse(
    +                begin, end,
    +                (
    +                    dets[phoenix::ref(det1) = qi::_1] >>           // Determiner
    +                    -adj_syms[phoenix::ref(adj1) = qi::_1] >>      // Optional adjective
    +                    noun_syms[phoenix::ref(noun1) = qi::_1] >>     // First noun
    +                    -adv_syms[phoenix::ref(adv) = qi::_1] >>       // Optional adverb
    +                    verb_syms[phoenix::ref(verb) = qi::_1] >>      // Verb
    +                    -adj_syms[phoenix::ref(adj2) = qi::_1] >>      // Optional adjective
    +                    noun_syms[phoenix::ref(noun2) = qi::_1] >>     // Second noun
    +                    qi::lit('.')                                   // Sentence must end with '.'
    +                ),
    +                ascii::space                                       // Skips whitespace automatically
    +            );
    +
    +            // -----------------------------------------------------------------
    +            // Result handling
    +            // If parsing succeeded and the entire string was consumed, show parts.
    +            // Otherwise, report failure and show which words are invalid.
    +            // -----------------------------------------------------------------
    +            if (success && begin == end) {
    +                std::cout << "\nParsed successfully!\n";
    +                if (!det1.empty())  std::cout << "  Determiner:  " << det1 << "\n";
    +                if (!adj1.empty())  std::cout << "  Adjective 1: " << adj1 << "\n";
    +                std::cout << "  Noun 1:      " << noun1 << "\n";
    +                if (!adv.empty())   std::cout << "  Adverb:      " << adv << "\n";
    +                std::cout << "  Verb:        " << verb << "\n";
    +                if (!adj2.empty())  std::cout << "  Adjective 2: " << adj2 << "\n";
    +                std::cout << "  Noun 2:      " << noun2 << "\n";
    +            }
    +            else {
    +                std::cout << "\nParsing failed.\n";
    +                std::cout << "The sentence must be of the form:\n";
    +                std::cout << "<Determiner> [<adjective>] <noun> [<adverb>] <verb> [<adjective>] <noun>.\n";
    +
    +                // Display what parts were recognized and whether valid words were used
    +                if (!det1.empty())
    +                    std::cout << "  Determiner:  " << det1 << is_valid(det1, determiners) << "\n";
    +                if (!adj1.empty())
    +                    std::cout << "  Adjective 1: " << adj1 << is_valid(adj1, adjectives) << "\n";
    +                std::cout << "  Noun 1:      " << noun1 << is_valid(noun1, nouns) << "\n";
    +                if (!adv.empty())
    +                    std::cout << "  Adverb:      " << adv << is_valid(adv, adverbs) << "\n";
    +                std::cout << "  Verb:        " << verb << is_valid(verb, verbs) << "\n";
    +                if (!adj2.empty())
    +                    std::cout << "  Adjective 2: " << adj2 << is_valid(adj2, adjectives) << "\n";
    +                std::cout << "  Noun 2:      " << noun2 << is_valid(noun2, nouns) << "\n";
    +            }
    +        }
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    The following shows a successful parse:

    +
    +
    +
    +
    > The lazy dog loudly chased quick squirrel.
    +
    +Parsed successfully!
    +  Determiner:  The
    +  Adjective 1: lazy
    +  Noun 1:      dog
    +  Adverb:      loudly
    +  Verb:        chased
    +  Adjective 2: quick
    +  Noun 2:      squirrel
    +
    +
    +
    +

    And the following shows an unsuccessful parse:

    +
    +
    +
    +
    > The fox chased alligator.
    +
    +Parsing failed.
    +The sentence must be of the form:
    +<Determiner> [<adjective>] <noun> [<adverb>] <verb> [<adjective>] <noun>.
    +  Determiner:  The- valid
    +  Noun 1:      fox- valid
    +  Verb:        chased- valid
    +  Noun 2:      - invalid
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    You will notice how adding more features to a natural language parser starts to considerably increase the code length. This is a normal feature of language parsing - a lot of code can be required to cover all the options of something as flexible as language. For an example of a simpler approach to parsing well-formatted input, refer to the sample code in Text Processing.

    +
    +
    +

    When designing a natural language system, it is good practice to divide the process into three main steps: syntax analysis (parsing), semantic analysis (grammar), and interpretation. Even though it might be possible to combine some grammar checking with the syntax checking, it is often better practice not to do this but complete the syntax checking first - this makes for greater maintainability and comprehension as the code is developed over time. The final stage, interpretation, usually depends on context. In the following sequence, a phrase as simple as "time flies" contains ambiguity:

    +
    +
    +
    +natural language parsing +
    +
    +
    +

    The phrase is so widely known it obscures the interpretation of "flies" as a noun. Context is required during interpretation to treat the input as a phrase, and not as something of the form "horse flies". Natural language parsers can remind us of ambiguity when at first we don’t see it!

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-networking.html b/preview/user-guide/task-networking.html new file mode 100644 index 0000000..21e4549 --- /dev/null +++ b/preview/user-guide/task-networking.html @@ -0,0 +1,1462 @@ + + + + + + + + + + + + + + Networking :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Networking

    +
    +
    +
    +

    Developing a networking application in C++ involves a lot of different components, and the Boost libraries offer support for low-level communications, such as TCP, and for higher-level networking, such as using JSON, WebSockets or MySQL.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are the libraries that are most directly applicable to a networking app:

    +
    +
    +
      +
    • +

      Boost.Asio: This is the most important library for your needs. Boost.Asio is a cross-platform C++ library for network and low-level I/O programming. It provides a consistent asynchronous model using a modern C++ approach. Boost.Asio supports a variety of network protocols, including ICMP, TCP, and UDP, and it can manage other resources such as serial ports, file descriptors, and even regular files.

      +
    • +
    • +

      Boost.Json: An efficient library for parsing, serializing, and manipulating JSON data. This is useful specifically in client-server communication and web services. Also, if you are working with large JSON payloads, there is support for incremental parsing, so you can feed data to the parser as it arrives over the network.

      +
    • +
    • +

      Boost.Beast: This is a library built on top of Boost.Asio that provides implementations of HTTP and WebSocket. These are common protocols for network programming, so if your app needs to work with them, Boost.Beast can be a huge help.

      +
    • +
    • +

      Boost.Mysql: This library is also built on top of Boost.Asio, and provides a C++11 client for the MySQL and MariaDB database servers. As a library it is most useful when your app needs efficient and asynchronous access to one of these servers.

      +
    • +
    • +

      Boost.Redis: Redis (which stands for Remote Dictionary Server) is a popular in-memory data structure store, used in database, cache, and message broker applications. This library implements Redis plain text protocol RESP3. It can multiplex any number of client requests, responses, and server pushes onto a single active socket connection to the Redis server.

      +
    • +
    • +

      Boost.Endian: Provides facilities for dealing with data that is represented in different byte orders. This is a common issue in network programming because different machines may represent multi-byte integers differently.

      +
    • +
    • +

      Boost.Spirit: If you’re creating a new protocol or using a lesser-known one, Boost.Spirit, a parser generator framework, could be useful. It allows you to define grammar rules that can parse complex data structures sent over the network.

      +
    • +
    • +

      Boost.URL: Parses URL strings into components (scheme, user info, host, port, path, query, and fragment), and provides support for building URLs piece by piece. Also, there is support for modifying an existing URL (changing the query parameters, for example) and handling percent-encoded characters. This library basically makes even complex URLs easy to work with.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0. The client-server samples can be run on the same computer, the peer-to-peer chat sample requires two computers to function correctly.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Sample Client-Server Messaging

    +
    +
    +

    The following code is a simple networking chat application using Boost.Asio that allows two computers to send messages to each other over TCP.

    +
    +
    +

    This example assumes that you know the IP address (URL) of one of the computers - to set as the server - and the other computer will act as the client. The server listens for incoming connections, the client must connect to the server to communicate, and messages are exchanged asynchronously between the two computers.

    +
    +
    +

    Server App

    +
    +

    chat_server.cpp

    +
    +
    +
    +
    #include <boost/asio.hpp>
    +#include <iostream>
    +#include <thread>
    +
    +using boost::asio::ip::tcp;
    +
    +void handle_client(tcp::socket socket) {
    +    try {
    +        char data[1024];
    +        while (true) {
    +            std::memset(data, 0, sizeof(data));
    +            boost::system::error_code error;
    +
    +            // Read message from client
    +            size_t length = socket.read_some(boost::asio::buffer(data), error);
    +            if (error == boost::asio::error::eof) break; // Connection closed
    +            else if (error) throw boost::system::system_error(error);
    +
    +            std::cout << "Client: " << data << std::endl;
    +
    +            // Send response
    +            std::string response;
    +            std::cout << "You: ";
    +            std::getline(std::cin, response);
    +            boost::asio::write(socket, boost::asio::buffer(response), error);
    +        }
    +    } catch (std::exception& e) {
    +        std::cerr << "Exception: " << e.what() << std::endl;
    +    }
    +}
    +
    +int main() {
    +    try {
    +        boost::asio::io_context io_context;
    +        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 12345));
    +
    +        std::cout << "Server started. Waiting for client..." << std::endl;
    +
    +        tcp::socket socket(io_context);
    +        acceptor.accept(socket);
    +        std::cout << "Client connected!" << std::endl;
    +
    +        handle_client(std::move(socket));
    +    } catch (std::exception& e) {
    +        std::cerr << "Exception: " << e.what() << std::endl;
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    This sample listens for incoming connections on port 12345, and uses TCP sockets for reliable data transfer.

    +
    +
    +
    +
    +
    +

    Client App

    +
    +

    chat_client.cpp

    +
    +
    +
    +
    #include <boost/asio.hpp>
    +#include <iostream>
    +#include <thread>
    +
    +using boost::asio::ip::tcp;
    +
    +void chat_client(const std::string& server_ip) {
    +    try {
    +        boost::asio::io_context io_context;
    +        tcp::socket socket(io_context);
    +        socket.connect(tcp::endpoint(boost::asio::ip::make_address(server_ip), 12345));
    +
    +        std::cout << "Connected to server at " << server_ip << std::endl;
    +
    +        char data[1024];
    +        while (true) {
    +            std::string message;
    +            std::cout << "You: ";
    +            std::getline(std::cin, message);
    +
    +            boost::system::error_code error;
    +            boost::asio::write(socket, boost::asio::buffer(message), error);
    +
    +            if (error) throw boost::system::system_error(error);
    +
    +            // Read server response
    +            std::memset(data, 0, sizeof(data));
    +            size_t length = socket.read_some(boost::asio::buffer(data), error);
    +            if (error == boost::asio::error::eof) break;
    +            else if (error) throw boost::system::system_error(error);
    +
    +            std::cout << "Server: " << data << std::endl;
    +        }
    +    } catch (std::exception& e) {
    +        std::cerr << "Exception: " << e.what() << std::endl;
    +    }
    +}
    +
    +int main() {
    +    std::string server_ip;
    +    std::cout << "Enter server IP: ";
    +    std::cin >> server_ip;
    +    std::cin.ignore(); // Ignore leftover newline from std::cin
    +    chat_client(server_ip);
    +    return 0;
    +}
    +
    +
    +
    +
    +

    Compile and Run

    +
    +

    Compile both programs. The server and client can now exchange messages - give it a shot!

    +
    +
    +

    First, start the server:

    +
    +
    +
    +
    Server started. Waiting for client...
    +Client connected!
    +Client: Hello from the client
    +You: Hey client, this is the server!
    +
    +
    +
    +

    Now run the client, and enter the server’s IP address when prompted:

    +
    +
    +
    +
    Enter server IP: <IP address in the format xx.x.x.xx>
    +Connected to server at xx.x.x.xx
    +You: Hello from the client
    +Server: Hey client, this is the server!
    +
    +
    +
    +
    +
    +
    +

    Peer to Peer Chat

    +
    +
    +

    Client-server architectures are the most useful and most common, but sometimes a peer-to-peer relationship between computers is more appropriate.

    +
    +
    +

    The following app implements peer-to-peer chatting - that is, both can send and receive messages without a client-server distinction. One key difference in coding is that both computers run the same program. However, one peer must initiate the connection using the other peer’s IP address and port. Once connected, both peers can send and receive messages asynchronously.

    +
    +
    +
    +
    Note
    +
    +

    When testing this code, the server and client programs should be on different computers. In the sample below one is called desktop and the other laptop - both Windows PCs.

    +
    +
    +
    +
    +

    peer_chat.cpp

    +
    +
    +
    +
    #include <boost/asio.hpp>
    +#include <iostream>
    +#include <thread>
    +#include <atomic>
    +
    +using boost::asio::ip::tcp;
    +
    +std::atomic<bool> connected{ false };
    +
    +void receive_messages(tcp::socket& socket) {
    +    try {
    +        char data[1024];
    +        while (true) {
    +            std::memset(data, 0, sizeof(data));
    +            boost::system::error_code error;
    +
    +            size_t length = socket.read_some(boost::asio::buffer(data), error);
    +            if (error == boost::asio::error::eof) {
    +                std::cout << "Connection closed by peer.\n";
    +                connected = false;
    +                break;
    +            }
    +            else if (error) {
    +                throw boost::system::system_error(error);
    +            }
    +
    +            std::cout << "\nPeer: " << data << "\nYou: ";
    +            std::cout.flush();
    +        }
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Receive error: " << e.what() << "\n";
    +    }
    +}
    +
    +void send_messages(tcp::socket& socket) {
    +    try {
    +        std::string message;
    +        while (connected) {
    +            std::cout << "You: ";
    +            std::getline(std::cin, message);
    +            if (message == "/quit") {
    +                socket.close();
    +                break;
    +            }
    +            boost::asio::write(socket, boost::asio::buffer(message));
    +        }
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Send error: " << e.what() << "\n";
    +    }
    +}
    +
    +void run_peer(boost::asio::io_context& io_context, const std::string& peer_ip, int peer_port, int local_port) {
    +    try {
    +        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), local_port));
    +        tcp::socket socket(io_context);
    +
    +        // Attempt outgoing connection
    +        if (!peer_ip.empty()) {
    +            std::cout << "Trying to connect to peer " << peer_ip << ":" << peer_port << "...\n";
    +            socket.connect(tcp::endpoint(boost::asio::ip::make_address(peer_ip), peer_port));
    +        }
    +        else {
    +            std::cout << "Waiting for a peer to connect on port " << local_port << "...\n";
    +            acceptor.accept(socket);
    +        }
    +
    +        std::cout << "Connected!\n";
    +        connected = true;
    +
    +        std::thread receive_thread(receive_messages, std::ref(socket));
    +        send_messages(socket);
    +        receive_thread.join();
    +
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Error: " << e.what() << "\n";
    +    }
    +}
    +
    +int main() {
    +    std::string peer_ip;
    +    int peer_port = 0;
    +    int local_port;
    +
    +    std::cout << "Enter local port to listen on: ";
    +    std::cin >> local_port;
    +
    +    std::cout << "Enter peer IP (leave blank to wait for connection): ";
    +    std::cin.ignore();
    +    std::getline(std::cin, peer_ip);
    +
    +    if (!peer_ip.empty()) {
    +        std::cout << "Enter peer's port: ";
    +        std::cin >> peer_port;
    +    }
    +
    +    boost::asio::io_context io_context;
    +    run_peer(io_context, peer_ip, peer_port, local_port);
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    As before, messages are exchanged over TCP sockets.

    +
    +
    +
    +
    +

    To run the program, on Computer A, set a local port (say, 12345) and leave the peer IP empty to wait for a connection. On Computer B, enter Computer A’s IP and port (12345) to connect. Messages will be exchanged in real-time.

    +
    +
    +

    Start one program, typing <Enter> for the IP:

    +
    +
    +
    +
    Enter local port to listen on: 12345
    +Enter peer IP (leave blank to wait for connection):
    +Waiting for a peer to connect on port 12345...
    +Connected!
    +Peer: Hello from laptop
    +You: Hello from desktop
    +Peer: a working chat!
    +You: yes, fun isn't it
    +
    +
    +
    +
    +
    Enter local port to listen on: 12345
    +Enter peer IP (leave blank to wait for connection): <IP address in the format xx.x.x.xx>
    +Enter peer's port: 12345
    +Trying to connect to peer xx.x.x.xx:12345...
    +Connected!
    +You: Hello from laptop
    +Peer: Hello from desktop
    +You: a working chat!
    +Peer: yes, fun isn't it!
    +
    +
    +
    +

    Type /quit on either computer to exit - which will perform a graceful disconnection.

    +
    +
    +
    +
    +

    Add JSON Requests and Responses

    +
    +
    +

    If we want more than chat, let’s add Boost.Json to handle structured requests and responses.

    +
    +
    +

    This version introduces JSON-based communication, where the client sends JSON-encoded requests, and the server processes and responds accordingly. The appropriate architecture is client-server. The server listens for connections and expects JSON requests. The client sends JSON-formatted messages (for example, { "command": "greet", "name": "Peter" }). The server parses the JSON and returns a JSON response.

    +
    +
    +
    +
    Note
    +
    +

    JSON request and response processing is essential for extensible REST API development (GET, POST, etc.).

    +
    +
    +
    +
    +

    JSON-based Server

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +#include <thread>
    +
    +using boost::asio::ip::tcp;
    +namespace json = boost::json;
    +
    +void handle_client(tcp::socket socket) {
    +    try {
    +        char data[1024];
    +        while (true) {
    +            std::memset(data, 0, sizeof(data));
    +            boost::system::error_code error;
    +            size_t length = socket.read_some(boost::asio::buffer(data), error);
    +
    +            if (error == boost::asio::error::eof) {
    +                std::cout << "Client disconnected.\n";
    +                break;
    +            } else if (error) {
    +                throw boost::system::system_error(error);
    +            }
    +
    +            // Parse JSON request
    +            json::value request_json = json::parse(data);
    +            std::string command = request_json.as_object()["command"].as_string().c_str();
    +
    +            // Generate JSON response
    +            json::object response;
    +            if (command == "greet") {
    +                std::string name = request_json.as_object()["name"].as_string().c_str();
    +                response["message"] = "Hello, " + name + "!";
    +            } else if (command == "status") {
    +                response["message"] = "Server is running.";
    +            } else {
    +                response["error"] = "Unknown command.";
    +            }
    +
    +            std::string response_str = json::serialize(response);
    +            boost::asio::write(socket, boost::asio::buffer(response_str));
    +        }
    +    } catch (std::exception& e) {
    +        std::cerr << "Error handling client: " << e.what() << "\n";
    +    }
    +}
    +
    +int main() {
    +    try {
    +        boost::asio::io_context io_context;
    +        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 5000));
    +
    +        std::cout << "Server listening on port 5000...\n";
    +
    +        while (true) {
    +            tcp::socket socket(io_context);
    +            acceptor.accept(socket);
    +            std::thread(handle_client, std::move(socket)).detach();
    +        }
    +    } catch (std::exception& e) {
    +        std::cerr << "Server error: " << e.what() << "\n";
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Communication is again done over TCP sockets.

    +
    +
    +
    +
    +
    +

    JSON-based Client

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +
    +using boost::asio::ip::tcp;
    +namespace json = boost::json;
    +
    +int main() {
    +    try {
    +        boost::asio::io_context io_context;
    +        tcp::socket socket(io_context);
    +        socket.connect(tcp::endpoint(boost::asio::ip::make_address("127.0.0.1"), 5000));
    +
    +        while (true) {
    +            std::string command, name;
    +            std::cout << "Enter command (greet/status/exit): ";
    +            std::cin >> command;
    +
    +            json::object request;
    +            if (command == "greet") {
    +                std::cout << "Enter name: ";
    +                std::cin >> name;
    +                request["command"] = "greet";
    +                request["name"] = name;
    +            } else if (command == "status") {
    +                request["command"] = "status";
    +            } else if (command == "exit") {
    +                break;
    +            } else {
    +                std::cout << "Invalid command!\n";
    +                continue;
    +            }
    +
    +            std::string request_str = json::serialize(request);
    +            boost::asio::write(socket, boost::asio::buffer(request_str));
    +
    +            char response_data[1024] = {0};
    +            boost::system::error_code error;
    +            size_t length = socket.read_some(boost::asio::buffer(response_data), error);
    +
    +            if (error == boost::asio::error::eof) {
    +                std::cout << "Server disconnected.\n";
    +                break;
    +            } else if (error) {
    +                throw boost::system::system_error(error);
    +            }
    +
    +            json::value response_json = json::parse(response_data);
    +            std::cout << "Server: " << response_json.as_object()["message"].as_string().c_str() << "\n";
    +        }
    +    } catch (std::exception& e) {
    +        std::cerr << "Client error: " << e.what() << "\n";
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +

    Compile and Run

    +
    +

    The following commands are valid:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + +
    CommandDescription

    greet

    Prompts for a name and receives a greeting.

    status

    Returns the server’s status.

    exit

    Closes the client.

    +
    +
    +
    Note
    +
    +

    This sample can cope with multiple clients, using multithreading.

    +
    +
    +
    +
    +

    Start the server:

    +
    +
    +
    +
    Server listening on port 5000...
    +
    +
    +
    +

    Then run the client and enter the commands:

    +
    +
    +
    +
    Enter command (greet/status/exit): status
    +Server: Server is running.
    +Enter command (greet/status/exit): greet
    +Enter name: Peter
    +Server: Hello, Peter!
    +
    +[Server is closed at this point]
    +
    +Enter command (greet/status/exit): status
    +Client error: write: An existing connection was forcibly closed by the remote host [system:10054]
    +
    +
    +
    +
    +
    +
    +

    Add HTTP Requests

    +
    +
    +

    Boost.Beast is built on top of Boost.Asio, and handles HTTP requests - which can be considered a higher-level of communication to TCP sockets. We will stick with the client-server architecture, and useful features of JSON.

    +
    +
    +

    HTTP Server

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/beast.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +
    +namespace asio = boost::asio;
    +namespace beast = boost::beast;
    +namespace http = beast::http;
    +namespace json = boost::json;
    +using tcp = asio::ip::tcp;
    +
    +// Function to handle incoming HTTP requests and produce appropriate responses
    +void handle_request(
    +    http::request<http::string_body> req,         // Incoming HTTP request
    +    http::response<http::string_body>& res        // Outgoing HTTP response (to be filled in)
    +) {
    +    // JSON object to hold the response body
    +    json::object response_json;
    +
    +    // Log request information to the console for debugging
    +    std::cout << "Method: " << req.method() << "...\n";
    +    std::cout << "Target: " << req.target() << "...\n";
    +    std::cout << "Body: " << req.body() << "...\n\n";
    +
    +    // Route: GET /status — return a simple status message
    +    if (req.method() == http::verb::get && req.target() == "/status") {
    +        response_json["status"] = "Server is running!";
    +    }
    +
    +    // Route: POST /greet — expects JSON input and returns a personalized greeting
    +    else if (req.method() == http::verb::post && req.target() == "/greet") {
    +        try {
    +
    +            // Parse the incoming request body as JSON
    +            json::value parsed_body = json::parse(req.body());
    +
    +            // Extract the "name" field from the JSON object
    +            std::string name = parsed_body.as_object()["name"].as_string().c_str();
    +
    +            // Compose a greeting message
    +            response_json["message"] = "Hello, " + name + "!";
    +        }
    +        catch (...) {
    +
    +            // If parsing fails or "name" field is missing, return an error
    +            response_json["error"] = "Invalid JSON format.";
    +        }
    +    }
    +
    +    // Handle all other unknown endpoints or unsupported methods
    +    else {
    +        response_json["error"] = "Unknown endpoint.";
    +    }
    +
    +    // Set the response status to 200 OK
    +    res.result(http::status::ok);
    +
    +    // Specify the content type as JSON
    +    res.set(http::field::content_type, "application/json");
    +
    +    // Serialize the JSON object and assign it to the response body
    +    res.body() = json::serialize(response_json);
    +
    +    // Finalize the response by preparing content-length and other headers
    +    res.prepare_payload();
    +}
    +
    +
    +// HTTP Server function
    +void run_server(asio::io_context& ioc, unsigned short port) {
    +    tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), port));
    +
    +    std::cout << "HTTP Server running on port " << port << "...\n\n";
    +
    +    while (true) {
    +        tcp::socket socket(ioc);
    +        acceptor.accept(socket);
    +
    +        beast::flat_buffer buffer;
    +        http::request<http::string_body> req;
    +        http::read(socket, buffer, req);
    +
    +        http::response<http::string_body> res;
    +        handle_request(req, res);
    +
    +        http::write(socket, res);
    +    }
    +}
    +
    +int main() {
    +    try {
    +        asio::io_context io_context;
    +        run_server(io_context, 8080);
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Server error: " << e.what() << "\n";
    +    }
    +    return 0;
    +}
    +
    +
    +
    +
    +

    HTTP Client

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/beast.hpp>
    +#include <boost/json.hpp>
    +#include <iostream>
    +
    +namespace asio = boost::asio;
    +namespace beast = boost::beast;
    +namespace http = beast::http;
    +namespace json = boost::json;
    +using tcp = asio::ip::tcp;
    +
    +// Function to send a basic HTTP request using Boost.Beast (synchronous, plain TCP)
    +std::string send_request(
    +    const std::string& host,                  // e.g., "api.example.com"
    +    const std::string& port,                  // e.g., "80" or "443" (for HTTPS you'd need SSL setup)
    +    http::verb method,                        // HTTP method, e.g., http::verb::post or http::verb::get
    +    const std::string& target,                // The path/resource being requested, e.g., "/v1/data"
    +    const std::string& body = ""              // Optional request body (for POST/PUT)
    +) {
    +    try {
    +        // Create an I/O context required for all I/O operations
    +        asio::io_context ioc;
    +
    +        // Create a resolver to turn the host name into a TCP endpoint
    +        tcp::resolver resolver(ioc);
    +
    +        // Create the TCP stream for connecting and communicating
    +        beast::tcp_stream stream(ioc);
    +
    +        // Resolve the host and port into a list of endpoints
    +        auto const results = resolver.resolve(host, port);
    +
    +        // Establish a connection to one of the resolved endpoints
    +        stream.connect(results);
    +
    +        // Build the HTTP request message
    +        http::request<http::string_body> req{ method, target, 11 };     // HTTP/1.1
    +        req.set(http::field::host, host);                               // Required: Host header
    +        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);   // Optional: Identifies the client
    +        req.set(http::field::content_type, "application/json");         // Optional: for JSON bodies
    +        req.body() = body;                                              // Set the request body (if any)
    +        req.prepare_payload();                                          // Sets Content-Length and finalizes headers
    +
    +        // Send the HTTP request to the remote host
    +        http::write(stream, req);
    +
    +        // Buffer for receiving data
    +        beast::flat_buffer buffer;
    +
    +        // Container for the HTTP response
    +        http::response<http::string_body> res;
    +
    +        // Receive the response
    +        http::read(stream, buffer, res);
    +
    +        // Return only the response body as a string
    +        return res.body();
    +    }
    +    catch (std::exception& e) {
    +
    +        // Return the exception message prefixed with "Client error:"
    +        return std::string("Client error: ") + e.what();
    +    }
    +}
    +
    +
    +
    +int main() {
    +    std::string host = "127.0.0.1";
    +    std::string port = "8080";
    +
    +    while (true) {
    +        std::string command;
    +        std::cout << "Enter command (status/greet/exit): ";
    +        std::cin >> command;
    +
    +        if (command == "status") {
    +            std::string response = send_request(host, port, http::verb::get, "/status");
    +            std::cout << "Server Response: " << response << "\n\n";
    +        }
    +        else if (command == "greet") {
    +            std::string name;
    +            std::cout << "Enter name: ";
    +            std::cin >> name;
    +
    +            json::object request;
    +            request["name"] = name;
    +            std::string request_str = json::serialize(request);
    +
    +            std::string response = send_request(host, port, http::verb::post, "/greet", request_str);
    +            std::cout << "Server Response: " << response << "\n\n";
    +        }
    +        else if (command == "exit") {
    +            break;
    +        }
    +        else {
    +            std::cout << "Invalid command!\n";
    +        }
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +

    Compile and Run

    +
    +

    The following commands are valid.

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + +
    CommandDescription

    greet

    Prompts for a name and returns a JSON greeting.

    status

    Checks if the server is running.

    exit

    Closes the client.

    +
    +

    Set the server running:

    +
    +
    +
    +
    HTTP Server running on port 8080...
    +
    +
    +
    +

    Enter commands into the client:

    +
    +
    +
    +
    Enter command (status/greet/exit): status
    +Server Response: {"status":"Server is running!"}
    +
    +Enter command (status/greet/exit): greet
    +Enter name: Peter
    +Server Response: {"message":"Hello, Peter!"}
    +
    +Enter command (status/greet/exit): greet
    +Enter name: Johnny
    +Server Response: {"message":"Hello, Johnny!"}
    +
    +Enter command (status/greet/exit): exit
    +
    +
    +
    +

    View the responses on the server:

    +
    +
    +
    +
    HTTP Server running on port 8080...
    +
    +Method: GET...
    +Target: /status...
    +Body: ...
    +
    +Method: POST...
    +Target: /greet...
    +Body: {"name":"Peter"}...
    +
    +Method: POST...
    +Target: /greet...
    +Body: {"name":"Johnny"}...
    +
    +
    +
    +
    +
    +
    +

    Add Websockets

    +
    +
    +

    As a final step, let’s add WebSockets, as this will allow real-time bidirectional communication between the client and server. This is useful for chat applications, game servers, stock updates, and other timing-critical applications.

    +
    +
    +

    We will use the features of Boost.Beast to accept Websocket connections, and echo received messages.

    +
    +
    +

    The Websocket server runs on ws://127.0.0.1:9002.

    +
    +
    +

    Websocket Server

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/beast.hpp>
    +#include <iostream>
    +#include <thread>
    +
    +namespace asio = boost::asio;
    +namespace beast = boost::beast;
    +namespace http = beast::http;
    +namespace websocket = beast::websocket;
    +using tcp = asio::ip::tcp;
    +
    +// WebSocket session to handle each client connection
    +void websocket_session(tcp::socket socket) {
    +    try {
    +        websocket::stream<tcp::socket> ws(std::move(socket));
    +        ws.accept();
    +        std::cout << "Client connected!\n";
    +
    +        beast::flat_buffer buffer;
    +        while (true) {
    +            ws.read(buffer);
    +            std::string msg = beast::buffers_to_string(buffer.data());
    +
    +            std::cout << "\nReceived: " << msg << std::endl;
    +
    +            // Echo message back to client
    +            ws.text(ws.got_text());
    +            ws.write(buffer.data());
    +
    +            buffer.consume(buffer.size()); // Clear buffer for next message
    +        }
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "WebSocket session error: " << e.what() << "\n";
    +    }
    +}
    +
    +// WebSocket Server
    +void run_server(asio::io_context& ioc, unsigned short port) {
    +    tcp::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), port));
    +
    +    std::cout << "WebSocket Server running on ws://127.0.0.1:" << port << "\n\n";
    +
    +    while (true) {
    +        tcp::socket socket(ioc);
    +        acceptor.accept(socket);
    +        std::thread(websocket_session, std::move(socket)).detach(); // Handle client in new thread
    +    }
    +}
    +
    +int main() {
    +    try {
    +        asio::io_context io_context;
    +        run_server(io_context, 9002);
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Server error: " << e.what() << "\n";
    +    }
    +    return 0;
    +}
    +
    +
    +
    +
    +

    Websocket Client

    +
    +
    +
    #include <boost/asio.hpp>
    +#include <boost/beast.hpp>
    +#include <iostream>
    +
    +namespace asio = boost::asio;
    +namespace beast = boost::beast;
    +namespace websocket = beast::websocket;
    +using tcp = asio::ip::tcp;
    +
    +void run_client(const std::string& host, const std::string& port) {
    +    try {
    +        asio::io_context ioc;
    +        tcp::resolver resolver(ioc);
    +        websocket::stream<tcp::socket> ws(ioc);
    +
    +        auto const results = resolver.resolve(host, port);
    +        asio::connect(ws.next_layer(), results);
    +        ws.handshake(host, "/");
    +
    +        std::cout << "Connected to WebSocket server!\n";
    +
    +        std::string message;
    +        while (true) {
    +            std::cout << "\nEnter message (or 'exit' to quit): ";
    +            std::getline(std::cin, message);
    +
    +            if (message == "exit") break;
    +
    +            ws.write(asio::buffer(message));
    +
    +            beast::flat_buffer buffer;
    +            ws.read(buffer);
    +            std::cout << "Server Response: " << beast::buffers_to_string(buffer.data()) << "\n";
    +        }
    +
    +        ws.close(websocket::close_code::normal);
    +    }
    +    catch (std::exception& e) {
    +        std::cerr << "Client error: " << e.what() << "\n";
    +    }
    +}
    +
    +int main() {
    +    run_client("127.0.0.1", "9002");
    +    return 0;
    +}
    +
    +
    +
    +
    +

    Compile and Run

    +
    +

    In the client, type any message and hit Enter. The server should echo the message. Type exit to close the client.

    +
    +
    +
    +
    Connected to WebSocket server!
    +
    +Enter message (or 'exit' to quit): hi there
    +Server Response: hi there
    +
    +Enter message (or 'exit' to quit): we are connected!
    +Server Response: we are connected!
    +
    +Enter message (or 'exit' to quit):
    +
    +
    +
    +

    The server should be responding as follows:

    +
    +
    +
    +
    WebSocket Server running on ws://127.0.0.1:9002
    +
    +Client connected!
    +
    +Received: hi there
    +
    +Received: we are connected!
    +
    +
    +
    +
    +
    +
    +

    Summary

    +
    +
    +

    The samples shown here are portable and cross-platform (Windows/Linux/Mac), and the servers are asynchronous to handle multiple clients.

    +
    +
    +

    The following diagram shows how the different layers work together in the samples:

    +
    +
    +
    +client server layers +
    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-parallel-computation.html b/preview/user-guide/task-parallel-computation.html new file mode 100644 index 0000000..6952603 --- /dev/null +++ b/preview/user-guide/task-parallel-computation.html @@ -0,0 +1,855 @@ + + + + + + + + + + + + + + Parallel Computation :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Parallel Computation

    +
    +
    +
    +

    Parallel computation is an important concept that helps in achieving faster execution by performing multiple operations concurrently.

    +
    +
    +

    Parallel programming can be complex and requires careful handling of shared resources to avoid race conditions, deadlocks, and other concurrency-related bugs. It’s also worth noting that not every problem can be efficiently parallelized; the potential speedup from parallelization is largely determined by the proportion of the computation that can be performed concurrently, as described by Amdahl’s Law.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    The Boost libraries provide several tools that can help in writing parallel code:

    +
    +
    +
      +
    • +

      Boost.Thread: Provides components for creating and managing threads, which can be used to perform multiple tasks concurrently on separate CPU cores.

      +
    • +
    • +

      Boost.Asio: While primarily a Networking library, this library also provides tools for asynchronous programming, which can be used to write concurrent code that performs multiple tasks at the same time without necessarily using multiple CPU cores.

      +
    • +
    • +

      Boost.Compute: This is a GPU/parallel computing library for C++ based on OpenCL. The library provides a high-level, STL-like API and is header-only and does not require any special build steps or linking.

      +
    • +
    • +

      Boost.Fiber: Allows you to write code that works with fibers, which are user-space threads that can be used to write concurrent code. This can be useful in situations where you have many tasks that need to run concurrently but are I/O-bound rather than CPU-bound.

      +
    • +
    • +

      Boost.Phoenix: A library for functional programming, it supports the ability to create inline functions which can be used for defining parallel algorithms.

      +
    • +
    • +

      Boost.Atomic: This library provides low-level atomic operations, with the aim of ensuring correct and efficient concurrent access to shared data without data races or other undesirable behavior.

      +
    • +
    • +

      Boost.Lockfree : Provides lock-free data structures which are useful in multi-threaded applications where you want to avoid locking overhead.

      +
    • +
    • +

      Boost.Chrono: Measures time intervals, which help control the timing of your app.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Parallel Computing Applications

    +
    +
    +

    Parallel computing has been successful in a wide range of applications, especially those involving large-scale computation or data processing. Here are some key areas where parallel computing has been particularly effective:

    +
    +
    +
      +
    • +

      Scientific Computing and Real-Time Simulation: Many problems in physics, chemistry, biology, and engineering involve solving complex mathematical models, often represented as systems of differential equations. This includes simulations in fields like fluid dynamics, molecular dynamics, quantum mechanics, and climate modeling.

      +
    • +
    • +

      Data Analysis and Machine Learning: Training machine learning models, particularly deep neural networks, involves many similar computations (like matrix multiplications), which can be performed in parallel. Similarly, analyzing large datasets (as in big data applications) can often be parallelized.

      +
    • +
    • +

      Graphics and Gaming: Modern GPUs (Graphics Processing Units) are essentially parallel processors, capable of performing many computations simultaneously. This is particularly useful in graphics rendering, which involves applying the same operations to many pixels or vertices. Video games, 3D animation, and virtual reality all benefit from parallel computing.

      +
    • +
    • +

      High-Performance Database Engine and Data Warehouses: Many operations in databases, like searches, sorting, and joins, can be parallelized, leading to faster query times. This is particularly important in large-scale data warehouses.

      +
    • +
    • +

      Cryptocurrency Mining: Cryptocurrencies like Bitcoin require solving complex mathematical problems, a process known as mining. This process is inherently parallel and is typically performed on GPUs or dedicated ASICs (Application-Specific Integrated Circuits).

      +
    • +
    • +

      Genome Analysis and Bioinformatics: Tasks like genome sequencing, protein folding, and other bioinformatics tasks involve large amounts of data and can be greatly sped up using parallel computing.

      +
    • +
    • +

      Weather Forecasting and Climate Research: Simulating weather patterns and climate change requires processing vast amounts of data and performing complex calculations, tasks well-suited to parallel computation.

      +
    • +
    +
    +
    +
    +
    +

    Multi-threaded Sample

    +
    +
    +

    The following code demonstrates using Boost.Thread to do the heavy lifting when you require a single foreground task, and multiple background tasks.

    +
    +
    +

    The sample has the following features:

    +
    +
    +
      +
    • +

      The main thread prints status updates and listens for user input.

      +
    • +
    • +

      Background threads simulate work (for example, processing data, handling network requests), in this case just printing messages every second.

      +
    • +
    • +

      A shared flag (running) signals when to stop the threads.

      +
    • +
    • +

      A boost::mutex ensures synchronized console output to prevent message overlap.

      +
    • +
    • +

      The main thread waits for all background threads (thread.join()), ensuring a clean exit.

      +
    • +
    +
    +
    +
    +
    #include <iostream>
    +#include <vector>
    +#include <boost/thread.hpp>
    +#include <boost/chrono.hpp>
    +#include <boost/atomic.hpp>
    +
    +// Shared flag to signal when to stop background threads
    +boost::atomic<bool> running(true);
    +boost::mutex coutMutex;  // Synchronizes console output
    +
    +// Simulated background task
    +void backgroundTask(int id) {
    +    int count = 0;
    +    while (running) {
    +        {
    +            boost::lock_guard<boost::mutex> lock(coutMutex);
    +            std::cout << count << ": Background Task " << id << " is running...\n";
    +        }
    +        boost::this_thread::sleep_for(boost::chrono::seconds(1));  // Simulate work
    +        ++count;
    +    }
    +
    +    // Final message when thread exits
    +    boost::lock_guard<boost::mutex> lock(coutMutex);
    +    std::cout << "Background Task " << id << " exiting...\n";
    +}
    +
    +// Main foreground task
    +void foregroundTask() {
    +    std::string input;
    +    while (running) {
    +        {
    +            boost::lock_guard<boost::mutex> lock(coutMutex);
    +            std::cout << "Foreground: Type 'x' then <return> to exit.\n\n";
    +        }
    +        std::cin >> input;
    +
    +        if (input == "x") {
    +            std::cout << "\nForeground task exiting...\n\n";
    +            running = false;
    +        }
    +    }
    +}
    +
    +// Entry point
    +int main() {
    +    const int numThreads = 3;  // Number of background threads
    +    std::vector<boost::thread> workers;
    +
    +    // Start background threads
    +    for (int i = 0; i < numThreads; ++i) {
    +        workers.emplace_back(backgroundTask, i + 1);
    +    }
    +
    +    // Start foreground task (user interaction)
    +    foregroundTask();
    +
    +    // Wait for all background threads to finish
    +    for (auto& thread : workers) {
    +        thread.join();
    +    }
    +
    +    std::cout << "All threads exited. Program shutting down.\n";
    +    return 0;
    +}
    +
    +
    +
    +

    Run the program:

    +
    +
    +
    +
    Foreground: Type 'x' then <return> to exit.
    +
    +0: Background Task 3 is running...
    +0: Background Task 2 is running...
    +0: Background Task 1 is running...
    +1: Background Task 1 is running...
    +1: Background Task 3 is running...
    +1: Background Task 2 is running...
    +x
    +
    +Foreground task exiting...
    +
    +Background Task 2 exiting...
    +Background Task 1 exiting...
    +Background Task 3 exiting...
    +All threads exited. Program shutting down.
    +
    +
    +
    +
    +
    +

    Thread-pool Sample

    +
    +
    +

    Starting with the multi-threaded code above. If we engage the thread management features of Boost.Asio, and the thread-safe counting of Boost.Atomic, we reduce the need to manually handle the management of threads. In particular, the updated sample:

    +
    +
    +
      +
    • +

      Uses boost::asio::thread_pool instead of manually managing threads.

      +
    • +
    • +

      Handles atomic operations with boost::atomic for thread-safe counters.

      +
    • +
    • +

      Requires tasks to execute in a pool, instead of fixed background threads.

      +
    • +
    • +

      Adds a graceful shutdown, allowing running tasks to finish before exiting.

      +
    • +
    +
    +
    +
    +
    #include <iostream>
    +#include <boost/asio.hpp>
    +#include <boost/thread.hpp>
    +#include <boost/atomic.hpp>
    +#include <boost/chrono.hpp>
    +
    +boost::atomic<bool> running(true);  // Atomic flag to signal threads to stop
    +boost::atomic<int> taskCounter(0);  // Tracks running tasks
    +boost::mutex coutMutex;             // Synchronizes console output
    +
    +const int max_tasks = 4;
    +
    +// Simulated background task
    +void backgroundTask(int id) {
    +    taskCounter++;  // Increment task count
    +    int count = 0;
    +    while (running) {
    +        {
    +            boost::lock_guard<boost::mutex> lock(coutMutex);
    +            std::cout << count++ << ") Task " << id << " is running... (Active tasks: "
    +                << taskCounter.load() << ")\n";
    +        }
    +        boost::this_thread::sleep_for(boost::chrono::seconds(1));  // Simulate work
    +    }
    +
    +    taskCounter--;  // Decrement task count
    +    boost::lock_guard<boost::mutex> lock(coutMutex);
    +    std::cout << "Task " << id << " exiting...\n";
    +}
    +
    +// Foreground task handling user input
    +void foregroundTask(boost::asio::thread_pool& pool) {
    +    std::string input;
    +    while (running) {
    +        {
    +            boost::lock_guard<boost::mutex> lock(coutMutex);
    +            std::cout << "Foreground: Type 'x' <return> to exit, 'a' <return> to add a task.\n";
    +        }
    +        std::cin >> input;
    +
    +        if (input == "x") {
    +            running = false;
    +        }
    +        else if (input == "a" && taskCounter < max_tasks) {
    +            static boost::atomic<int> taskId(0);
    +            boost::asio::post(pool, [id = ++taskId] { backgroundTask(id); });
    +        }
    +    }
    +}
    +
    +// Main function
    +int main() {
    +    boost::asio::thread_pool pool(max_tasks);  // Thread pool with max_tasks worker threads
    +
    +    // Start foreground task
    +    foregroundTask(pool);
    +
    +    // Wait for all tasks in the pool to complete
    +    pool.join();
    +
    +    std::cout << "\nAll tasks completed. Program shutting down.\n";
    +    return 0;
    +}
    +
    +
    +
    +

    Run the program and you should get output similar to this:

    +
    +
    +
    +
    ...
    +10) Task 1 is running... (Active tasks: 2)
    +a
    +
    +Foreground: Type 'x' <return> to exit, 'a' <return> to add a task.
    +0) Task 3 is running... (Active tasks: 3)
    +5) Task 2 is running... (Active tasks: 3)
    +11) Task 1 is running... (Active tasks: 3)
    +6) Task 2 is running... (Active tasks: 3)
    +1) Task 3 is running... (Active tasks: 3)
    +12) Task 1 is running... (Active tasks: 3)
    +
    +x
    +Task 1 exiting...
    +Task 3 exiting...
    +Task 2 exiting...
    +
    +
    +
    +
    +
    +

    Message-queue Sample

    +
    +
    +

    For message queues, consider the following sample using Boost.Fiber, where you can type messages manually, starting with a receiver Id, and a receiver fiber prints the messages from the queue, if the message is for that receiver.

    +
    +
    +

    This simulates a very lightweight fiber-based message loop using user input. Receivers 1 and 2 only take messages where they have been identified as the desired receiver. Receiver 3 takes any message, and as such is the fallback handler. For example:

    +
    +
    +
    +message queue +
    +
    +
    +

    Now for the code:

    +
    +
    +
    +
    #include <boost/fiber/all.hpp>   // Boost.Fiber for lightweight cooperative threading
    +#include <queue>                 // Standard queue container for storing messages
    +
    +// --------------------------------------
    +// A simple thread/fiber-safe message queue
    +// --------------------------------------
    +class MessageQueue {
    +public:
    +
    +    // Send a message into the queue
    +    void send(const std::string& msg) {
    +
    +        // Lock the queue so only one fiber can access it at a time
    +        std::unique_lock<boost::fibers::mutex> lock(mutex_);
    +        queue_.push(msg);              // Push the new message
    +        cond_.notify_one();            // Wake up one waiting receiver
    +    }
    +
    +    // Receive a message for a given "to" address (like filtering messages)
    +    std::string receive(std::string to) {
    +
    +        // Lock the queue
    +        std::unique_lock<boost::fibers::mutex> lock(mutex_);
    +
    +        // Wait until queue is not empty (blocks this fiber cooperatively)
    +        cond_.wait(lock, [this]() { return !queue_.empty(); });
    +
    +        // Look at the first message in the queue
    +        std::string msg = queue_.front();
    +
    +        // Filter messages:
    +        // - If first char of message == receiver's "to" char
    +        // - OR receiver is "x" (wildcard, accepts everything)
    +        // - OR message is "/quit" (global shutdown signal)
    +
    +        if (msg[0] == to[0] || to[0] == 'x' || msg == "/quit")
    +        {
    +            queue_.pop(); // Remove message from queue since it's consumed
    +            return msg;   // Return it to caller
    +        }
    +        else
    +
    +            // If this message isn't meant for this receiver, just return ""
    +            // (message stays in queue for someone else)
    +            return "";
    +    }
    +
    +private:
    +    std::queue<std::string> queue_;          // FIFO queue of messages
    +    boost::fibers::mutex mutex_;             // Mutex for synchronizing access
    +    boost::fibers::condition_variable cond_; // Condition variable for waiting
    +};
    +
    +// --------------------------------------
    +// MAIN PROGRAM
    +// --------------------------------------
    +int main() {
    +    MessageQueue msg_queue;             // Shared message queue
    +    std::atomic<bool> running(true);    // Atomic flag for stopping all fibers safely
    +    const int num_receivers = 3;        // Number of receivers
    +    std::string to;                     // "Address" string for each receiver
    +
    +        // -----------------------------
    +    // Launch multiple receiver fibers
    +    // -----------------------------
    +    std::vector<boost::fibers::fiber> receivers;
    +    for (int i = 0; i < num_receivers; ++i) {
    +
    +        // Launch fiber with unique receiver ID (1, 2, or 3)
    +        receivers.emplace_back([&, id = i + 1]() {
    +            while (running) {
    +
    +                // Assign "to" value depending on receiver ID:
    +                // Receiver 1 listens for "1", Receiver 2 listens for "2",
    +                // Receiver 3 listens for "x" (wildcard, accepts all messages).
    +                switch (id)
    +                {
    +                case 1: to = "1"; break;
    +                case 2: to = "2"; break;
    +                case 3: to = "x"; break;
    +                }
    +
    +                // Try to receive a message intended for this receiver
    +                std::string msg = msg_queue.receive(to);
    +
    +                // Special case: quit message
    +                if (msg == "/quit") {
    +                    running = false;            // Tell everyone to stop
    +                    msg_queue.send("/quit");    // Re-send quit message so others can see it
    +                    break;                      // Break out of loop, end this fiber
    +                }
    +
    +                // Only print if message was actually for us
    +                if (msg != "")
    +                    std::cout << "[Receiver " << id << "] Received: " << msg << std::endl;
    +
    +                // Yield to allow other fibers to run (cooperative multitasking)
    +                boost::this_fiber::yield();
    +            }
    +            });
    +    }
    +
    +    // -----------------------------
    +    // Main thread handles user input
    +    // -----------------------------
    +    std::string input;
    +    while (running) {
    +        std::cout << "Enter a message starting with the receiver Id (1,2,3) or /quit to exit > ";
    +        std::getline(std::cin, input);
    +
    +        if (!input.empty()) {
    +            msg_queue.send(input);          // Send the input to the message queue
    +            if (input == "/quit") {
    +                break;                      // Stop reading if quit was typed
    +            }
    +            boost::this_fiber::yield();     // Yield so receivers get a chance to process
    +        }
    +    }
    +
    +    // -----------------------------
    +    // Join all receiver fibers
    +    // -----------------------------
    +    for (auto& f : receivers) {
    +
    +        f.join();                           // Wait for each receiver fiber to exit
    +    }
    +
    +    std::cout << "All receivers exited. Program shutting down.\n";
    +    return 0;
    +}
    +
    +
    +
    +

    If you compile and run this sample, the following would be a typical session!

    +
    +
    +
    +
    Enter a message starting with the receiver Id (1,2,3) or /quit to exit > 1 hello
    +[Receiver 1] Received: 1 hello
    +Enter a message starting with the receiver Id (1,2,3) or /quit to exit > 2 hi
    +[Receiver 2] Received: 2 hi
    +Enter a message starting with the receiver Id (1,2,3) or /quit to exit > 3 howdy
    +[Receiver 3] Received: 3 howdy
    +Enter a message starting with the receiver Id (1,2,3) or /quit to exit > 4 anyone
    +[Receiver 3] Received: 4 anyone
    +Enter a message starting with the receiver Id (1,2,3) or /quit to exit > /quit
    +All receivers exited. Program shutting down.
    +
    +
    +
    +

    Parallel computing is an exciting challenge - success should come from focusing on problems that are inherently parallel.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-quantum-computing.html b/preview/user-guide/task-quantum-computing.html new file mode 100644 index 0000000..ea347e2 --- /dev/null +++ b/preview/user-guide/task-quantum-computing.html @@ -0,0 +1,1410 @@ + + + + + + + + + + + + + + Quantum Computing :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Quantum Computing

    +
    +
    +
    +

    Unlike classical bits, which represent either 0 or 1, quantum bits - qubits (1) - can exist in multiple states simultaneously, exponentially increasing processing power for certain tasks. Quantum computing harnesses the principles of quantum mechanics — superposition, entanglement, and quantum interference (2) — to perform computations that are infeasible for classical computers. This allows quantum computers to solve complex problems in cryptography, optimization, and material science at unprecedented speeds.

    +
    +
    +

    Algorithms like Shor’s for factoring large numbers and Grover’s for searching unsorted data showcase quantum speedup, making quantum computing a disruptive force in fields requiring massive parallelism and probabilistic computation. However, challenges in qubit stability, error correction, and scalability still limit practical applications.

    +
    +
    +

    This topic is an educational tutorial on what we might expect from quantum applications, simulating quantum algorithms in C++ where we can. The references to college-level math are frequent and can be somewhat overwhelming - hopefully running the simulations will make things clearer - the long-term implications for brute-force computing are daunting!

    +
    + +
    +
    +
    +

    Quantum Algorithms

    +
    +
    +

    Quantum computing is much easier to understand with a deep dive into some specific algorithms.

    +
    +
    +
    +
    Note
    +
    +

    The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

    +
    +
    +
    +
    +

    The Shor Algorithm

    +
    +

    Shor’s algorithm is a quantum algorithm designed to factor large numbers efficiently, making it a potential threat to classical cryptographic systems like RSA. It leverages quantum mechanics to find the period of a function, which classical methods struggle with. In short, given an integer N, the goal is to find its prime factors:

    +
    +
    +
      +
    1. +

      Choose a random number a such that 1 < a < N. Note that if gcd(a,N) = 1, then we already found a factor.

      +
    2. +
    3. +

      Compute the order r of a modulo N, that is, find the smallest r such that: a^r ≡ 1 mod N. This is done efficiently using quantum phase estimation (3).

      +
    4. +
    5. +

      Check if r is even. If r is odd, restart with a different a.

      +
    6. +
    7. +

      Compute gcd(a^(r/2) - 1, N) and gcd(a^(r/2) + 1, N). If either result is a nontrivial factor, we’re done.

      +
    8. +
    +
    +
    +
    +
    Notes
    +
    +

    The function gcd is the greatest common divisor. The quantum advantage comes from step 2, where a Quantum Fourier Transform - or QFT (4) - is used to efficiently determine the order r. The quantum computer prepares a superposition of states, applies modular exponentiation as a quantum operation, and then uses QFT to extract r.

    +
    +
    +
    +
    +

    Probably easier to understand with an example, lets compute factors with N = 15:

    +
    +
    +
      +
    1. +

      Randomly choose a = 2.

      +
    2. +
    3. +

      Find the order r such that 2^r ≡ 1 mod 15. The smallest such r is 4.

      +
    4. +
    5. +

      Since r is even, compute:

      +
      +
      +GCD equations +
      +
      +
    6. +
    7. +

      Found factors: 3 and 5.

      +
    8. +
    +
    +
    +

    Shor’s algorithm runs exponentially faster than the best-known classical factoring algorithms.

    +
    +
    +

    Let’s write a simulation of Shor’s algorithm that approximates its behavior using classical number theory techniques. Since true quantum computation requires a quantum computer, this version simulates the order-finding step using classical algorithms like modular exponentiation and the greatest common divisor (GCD).

    +
    +
    +
    +
    #include <iostream>
    +#include <cmath>
    +#include <cstdlib>
    +#include <ctime>
    +
    +using namespace std;
    +
    +// Function to compute the greatest common divisor (GCD)
    +int gcd(int a, int b) {
    +    while (b != 0) {
    +        int temp = b;
    +        b = a % b;
    +        a = temp;
    +    }
    +    return a;
    +}
    +
    +// Function for modular exponentiation: (base^exp) % mod
    +int mod_exp(int base, int exp, int mod) {
    +    int result = 1;
    +    base = base % mod;
    +    while (exp > 0) {
    +        if (exp % 2 == 1) { // If exp is odd
    +            result = (result * base) % mod;
    +        }
    +        exp = exp >> 1; // Divide exp by 2
    +        base = (base * base) % mod;
    +    }
    +    return result;
    +}
    +
    +// Function to find the order r of a modulo N
    +int find_order(int a, int N) {
    +    int r = 1;
    +    int value = a;
    +    while (value != 1) {
    +        value = (value * a) % N;
    +        r++;
    +        if (r > N) return -1; // Fail-safe to avoid infinite loops
    +    }
    +    return r;
    +}
    +
    +// Shor's algorithm simulation
    +void shors_algorithm(int N) {
    +    if (N % 2 == 0) { // If even, trivially factor
    +        cout << "Trivial factor: 2" << endl;
    +        return;
    +    }
    +
    +    srand(time(0)); // Seed for randomness
    +
    +    int a, r, factor1, factor2;
    +    while (true) {
    +        a = 2 + rand() % (N - 2); // Choose random a in range [2, N-1]
    +
    +        int gcd_val = gcd(a, N);
    +        if (gcd_val > 1) {
    +            cout << "Found factor (GCD check): " << gcd_val << endl;
    +            return;
    +        }
    +
    +        r = find_order(a, N);
    +        if (r == -1 || r % 2 == 1) continue; // Ignore invalid or odd r
    +
    +        // Compute the factors
    +        factor1 = gcd(mod_exp(a, r / 2, N) - 1, N);
    +        factor2 = gcd(mod_exp(a, r / 2, N) + 1, N);
    +
    +        if (factor1 > 1 && factor2 > 1) {
    +            cout << "Factors found: " << factor1 << " and " << factor2 << endl;
    +            return;
    +        }
    +    }
    +}
    +
    +// Main function
    +int main() {
    +    int N;
    +    cout << "Enter a number to factor: ";
    +    cin >> N;
    +
    +    if (N <= 1) {
    +        cout << "Invalid input. Please enter a number greater than 1." << endl;
    +        return 0;
    +    }
    +
    +    shors_algorithm(N);
    +    return 0;
    +}
    +
    +
    +
    +

    If you compile and run this program, you should get output similar to the following:

    +
    +
    +
    +
    Enter a number to factor: 15
    +Factors found: 3 and 5
    +
    +Enter a number to factor: 21
    +Factors found: 3 and 7
    +
    +
    +
    +

    The order-finding step is deterministic instead of quantum-powered, making it slower for very large numbers. Our simulation works best for small numbers (say, less than 1000).

    +
    +
    +
    +

    The Grover Algorithm

    +
    +

    Grover’s algorithm is a quantum search algorithm that finds a target item in an unsorted database quadratically faster than classical methods. It was developed by Lov Grover in 1996 and is particularly powerful for problems that require brute-force search, such as breaking symmetric cryptographic hashes.

    +
    +
    +

    In a classical search: if you have an unsorted list of N elements, finding a specific item requires checking, on average, N/2 elements, and in the worst case, all N elements. This is O(N) complexity. In a quantum search: Grover’s algorithm finds the target in O(sqrt N) steps — which is way faster, especially with a large number of elements.

    +
    +
    +

    Grover’s algorithm enhances the probability of the correct solution using a technique called amplitude amplification through iterative applications of two main operations:

    +
    +
    +
      +
    1. +

      Oracle Function (Marking the Solution): A quantum function (black box) that inverts the amplitude of the correct answer. Or think of it as labeling the correct item with a negative phase.

      +
    2. +
    3. +

      Diffusion Operator (Amplitude Amplification): This boosts the amplitude of the marked item while reducing others. Acts like a "quantum reflection" across the average amplitude.

      +
    4. +
    +
    +
    +

    By applying these two steps O(sqrt N) times, the probability of measuring the correct answer approaches 100%.

    +
    +
    +

    Let’s explain with a trivial example, imagine searching for the number 3 in the list {0, 1, 2, 3}.

    +
    +
    +
      +
    1. +

      Start with an equal superposition of all four states:

      +
      +
      +equal superposition +
      +
      +
    2. +
    3. +

      The oracle flips the phase of the correct answer (let’s say |3⟩):

      +
      +
      +flip the phase +
      +
      +
    4. +
    5. +

      The diffusion operator boosts the probability of |3⟩ by reflecting all amplitudes around their mean.

      +
    6. +
    7. +

      After one iteration, the probability of measuring |3⟩ is nearly 100%.

      +
    8. +
    +
    +
    +

    In addition to the dubious purpose of cracking cryptographic hashes, this algorithm has the potential to solve NP-complete problems like 3-SAT (5), amd speed up graph search, pathfinding, and database lookups.

    +
    +
    +

    The following code simulates a quantum state as an array of probabilities, and assumes a small dataset - such as searching for 3 in {0,1,2,3,4,5,6,7}).

    +
    +
    +
    +
    #include <iostream>
    +#include <vector>
    +#include <cmath>
    +#include <cstdlib>
    +#include <ctime>
    +
    +using namespace std;
    +
    +// Function to apply the oracle (mark the target state)
    +void applyOracle(vector<double>& state, int target) {
    +    state[target] *= -1; // Flip the phase of the marked state
    +}
    +
    +// Function to apply the diffusion operator (amplitude amplification)
    +void applyDiffusion(vector<double>& state) {
    +    int N = state.size();
    +    double avg = 0;
    +
    +    // Compute the average amplitude
    +    for (double amp : state) avg += amp;
    +    avg /= N;
    +
    +    // Reflect around the mean
    +    for (double& amp : state) {
    +        amp = 2 * avg - amp;
    +    }
    +}
    +
    +// Function to simulate Grover's algorithm
    +int groverSearch(int N, int target) {
    +    vector<double> state(N, 1.0 / sqrt(N)); // Initialize equal superposition
    +
    +    int iterations = round(acos(sqrt(1.0/N)) / (2 * asin(sqrt(1.0/N)))); // O(√N)
    +
    +    for (int i = 0; i < iterations; i++) {
    +        applyOracle(state, target);  // Mark the target state
    +        applyDiffusion(state);       // Amplify the probability
    +    }
    +
    +    // Measure the highest probability state
    +    int maxIndex = 0;
    +    for (int i = 1; i < N; i++) {
    +        if (abs(state[i]) > abs(state[maxIndex])) {
    +            maxIndex = i;
    +        }
    +    }
    +
    +    return maxIndex; // Return the most likely result
    +}
    +
    +// Main function
    +int main() {
    +    int N = 8;         // Number of states (must be a power of 2)
    +    int target = 3;    // Element to search for
    +
    +    srand(time(0));
    +
    +    cout << "Searching for element: " << target << " in range [0, " << N-1 << "]..." << endl;
    +    int result = groverSearch(N, target);
    +
    +    cout << "Grover's Algorithm found: " << result << endl;
    +    return 0;
    +}
    +
    +
    +
    +

    A run of the program will give us:

    +
    +
    +
    +
    Searching for element: 3 in range [0, 7]...
    +Grover's Algorithm found: 3
    +
    +
    +
    +
    +

    One-dimensional Quantum Walks

    +
    +

    A quantum walk is a version of random walks (traversing a graph), offering speedups in graph traversal. This is important for search algorithms and network analysis.

    +
    +
    +

    Unlike classical random walks, where a particle moves left or right with equal probability, quantum walks use superposition and interference, leading to a faster spread over the search space. The probability distribution in a quantum walk spreads quadratically faster than a classical random walk.

    +
    +
    +

    The following program simulates a discrete-time quantum walk using a coin flip (academically known as a Hadamard gate) to create superposition. Conditional movement is based on the coin’s state and there are interference effects that make quantum walks behave differently from classical ones.

    +
    +
    +

    The walker starts at position x = 0 - the middle of the array. It has an internal quantum coin state (spin |0⟩ or |1⟩), and the quantum coin flip (the Hadamard Gate) creates superposition, splitting into two paths: if coin is |0⟩, move left, if coin is |1⟩, move right.

    +
    +
    +

    Unlike a classical random walk (which results in a bell curve), quantum walks create two dominant peaks due to constructive and destructive interference.

    +
    +
    +

    This should be clearer by running a simulation.

    +
    +
    +
    +
    #include <iostream>
    +#include <vector>
    +#include <cmath>
    +#include <complex>
    +
    +using namespace std;
    +
    +const int N = 21;  // Number of positions (should be odd for symmetry)
    +const int STEPS = 10;  // Number of quantum walk steps
    +
    +using Complex = complex<double>;  // Complex number type
    +using State = vector<vector<Complex>>;  // Quantum state storage
    +
    +// Hadamard coin operator
    +const Complex H[2][2] = {
    +    {1 / sqrt(2), 1 / sqrt(2)},
    +    {1 / sqrt(2), -1 / sqrt(2)}
    +};
    +
    +// Function to apply the coin operator (Hadamard gate)
    +void apply_coin(State& psi) {
    +    State new_psi = psi;
    +    for (int pos = 0; pos < N; pos++) {
    +        Complex left = psi[pos][0] * H[0][0] + psi[pos][1] * H[0][1];
    +        Complex right = psi[pos][0] * H[1][0] + psi[pos][1] * H[1][1];
    +        new_psi[pos][0] = left;
    +        new_psi[pos][1] = right;
    +    }
    +    psi = new_psi;
    +}
    +
    +// Function to apply the shift operator (move left or right)
    +void apply_shift(State& psi) {
    +    State new_psi(N, vector<Complex>(2, 0));
    +
    +    for (int pos = 1; pos < N - 1; pos++) {
    +        new_psi[pos - 1][0] += psi[pos][0];  // Left movement
    +        new_psi[pos + 1][1] += psi[pos][1];  // Right movement
    +    }
    +
    +    psi = new_psi;
    +}
    +
    +// Function to compute probability distribution
    +vector<double> get_probabilities(const State& psi) {
    +    vector<double> probabilities(N, 0);
    +    for (int pos = 0; pos < N; pos++) {
    +        probabilities[pos] = norm(psi[pos][0]) + norm(psi[pos][1]);
    +    }
    +    return probabilities;
    +}
    +
    +// Main function
    +int main() {
    +    State psi(N, vector<Complex>(2, 0));  // Initialize quantum state
    +    psi[N / 2][0] = 1.0;  // Start in the middle with |0⟩ spin state
    +
    +    cout << "Quantum Walk Simulation (" << STEPS << " steps)" << endl;
    +
    +    for (int step = 0; step < STEPS; step++) {
    +        apply_coin(psi);
    +        apply_shift(psi);
    +    }
    +
    +    // Get probability distribution
    +    vector<double> probabilities = get_probabilities(psi);
    +
    +    // Print results
    +    for (int i = 0; i < N; i++) {
    +        cout << "Position " << (i - N / 2) << ": " << probabilities[i] << endl;
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    If you run this code you will get something like:

    +
    +
    +
    +
    Quantum Walk Simulation (10 steps)
    +Position -10: 0
    +Position -9: 0.0012
    +Position -8: 0.0041
    +Position -7: 0.0113
    +Position -6: 0.0264
    +Position -5: 0.0492
    +Position -4: 0.0795
    +Position -3: 0.1134
    +Position -2: 0.1421
    +Position -1: 0.1543
    +Position  0: 0.1421
    +Position  1: 0.1134
    +Position  2: 0.0795
    +Position  3: 0.0492
    +Position  4: 0.0264
    +Position  5: 0.0113
    +Position  6: 0.0041
    +Position  7: 0.0012
    +Position  8: 0
    +Position  9: 0
    +
    +
    +
    +

    The result shows the probability distribution of being at any one of the positions at the end of the walk.

    +
    +
    +
    +

    Two-dimensional Quantum Walks

    +
    +

    We can extend the quantum walk example to simulate a walker with an x,y position on a grid. Two coins are tossed: 00 - move left, 01 - move right, 10 - move up, 11 - move down.

    +
    +
    +

    This program simulates a 10 x 10 quantum grid and tracks the probability of the walker being at each position.

    +
    +
    +
    +
    #include <iostream>
    +#include <vector>
    +#include <complex>
    +#include <cmath>
    +#include <iomanip>
    +
    +using namespace std;
    +
    +const int GRID_SIZE = 11; // Must be odd to center the walker
    +const int STEPS = 10;  // Number of quantum walk steps
    +
    +using Complex = complex<double>;
    +using State = vector<vector<vector<Complex>>>;  // 2D grid with 2 coin states
    +
    +// Hadamard gate for a 2-qubit coin (simplified)
    +const Complex H[2][2] = {
    +    {1 / sqrt(2), 1 / sqrt(2)},
    +    {1 / sqrt(2), -1 / sqrt(2)}
    +};
    +
    +// Apply Hadamard gate to the coin state
    +void apply_coin(State& psi) {
    +    State new_psi = psi;
    +
    +    for (int x = 0; x < GRID_SIZE; x++) {
    +        for (int y = 0; y < GRID_SIZE; y++) {
    +            Complex left = psi[x][y][0] * H[0][0] + psi[x][y][1] * H[0][1];
    +            Complex right = psi[x][y][0] * H[1][0] + psi[x][y][1] * H[1][1];
    +            new_psi[x][y][0] = left;
    +            new_psi[x][y][1] = right;
    +        }
    +    }
    +    psi = new_psi;
    +}
    +
    +// Apply conditional movement based on coin state
    +void apply_shift(State& psi) {
    +    State new_psi(GRID_SIZE, vector<vector<Complex>>(GRID_SIZE, vector<Complex>(2, 0)));
    +
    +    for (int x = 1; x < GRID_SIZE - 1; x++) {
    +        for (int y = 1; y < GRID_SIZE - 1; y++) {
    +            // Move left if coin state |0⟩
    +            new_psi[x - 1][y][0] += psi[x][y][0];
    +            // Move right if coin state |1⟩
    +            new_psi[x + 1][y][1] += psi[x][y][1];
    +            // Move up if coin state |0⟩
    +            new_psi[x][y - 1][0] += psi[x][y][0];
    +            // Move down if coin state |1⟩
    +            new_psi[x][y + 1][1] += psi[x][y][1];
    +        }
    +    }
    +
    +    psi = new_psi;
    +}
    +
    +// Compute probability distribution
    +vector<vector<double>> get_probabilities(const State& psi) {
    +    vector<vector<double>> probabilities(GRID_SIZE, vector<double>(GRID_SIZE, 0));
    +
    +    for (int x = 0; x < GRID_SIZE; x++) {
    +        for (int y = 0; y < GRID_SIZE; y++) {
    +            probabilities[x][y] = norm(psi[x][y][0]) + norm(psi[x][y][1]);
    +        }
    +    }
    +    return probabilities;
    +}
    +
    +// Main function
    +int main() {
    +    State psi(GRID_SIZE, vector<vector<Complex>>(GRID_SIZE, vector<Complex>(2, 0)));
    +
    +    int mid = GRID_SIZE / 2;
    +    psi[mid][mid][0] = 1.0;  // Start in the middle with |0⟩ spin state
    +
    +    cout << "2D Quantum Walk Simulation (" << STEPS << " steps)" << endl;
    +
    +    for (int step = 0; step < STEPS; step++) {
    +        apply_coin(psi);
    +        apply_shift(psi);
    +    }
    +
    +    vector<vector<double>> probabilities = get_probabilities(psi);
    +
    +    // Print probability grid
    +    for (int y = 0; y < GRID_SIZE; y++) {
    +        for (int x = 0; x < GRID_SIZE; x++) {
    +            cout << fixed << setprecision(3) << probabilities[x][y] << " ";
    +        }
    +        cout << endl;
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    If you run this code you will get something like:

    +
    +
    +
    +
    2D Quantum Walk Simulation (10 steps)
    +0.000  0.001  0.002  0.003  0.005  0.003  0.002  0.001  0.000  0.000
    +0.001  0.004  0.009  0.016  0.027  0.016  0.009  0.004  0.001  0.000
    +0.004  0.011  0.022  0.040  0.067  0.040  0.022  0.011  0.004  0.001
    +0.009  0.022  0.045  0.079  0.133  0.079  0.045  0.022  0.009  0.002
    +0.016  0.040  0.079  0.139  0.233  0.139  0.079  0.040  0.016  0.003
    +...
    +
    +
    +
    +

    Again, the result shows the probability distribution of being at any one of the positions at the end of the 2D walk.

    +
    +
    +
    +quantum walk simulation +
    +
    +
    +
    +

    Other Quantum Algorithms

    +
    +

    Other algorithms you might like to investigate include Variational Quantum Eigensolver (VQE) - which is a hybrid algorithm that finds the ground state energy of a molecule, and can be used in quantum chemistry (molecular simulation) and optimization problems.

    +
    +
    +

    To simulate in C++ consider implementing a gradient descent optimizer to simulate quantum variational circuits, and use classical matrix exponentiation to approximate Hamiltonian evolution - which refers to the time evolution of a quantum state under a Hamiltonian operator (the energy function of a system).

    +
    +
    +

    Another possibility - the Harrow-Hassidim-Lloyd (HHL) algorithm - solves large linear systems exponentially faster than classical methods, and can be applied in AI (machine learning), big data, finance and differential equations.

    +
    +
    +

    To simulate in C++ we should use classical numerical solvers (for example, Gaussian elimination, LU decomposition) and simulate quantum matrix inversion with iterative phase estimation.

    +
    +
    +
    +
    +
    +

    Libraries

    +
    +
    +

    There are several Boost libraries that show potential for use in quantum computing, or in simulating quantum algorithms:

    +
    +
    +
      +
    • +

      Boost.MultiArray : Quantum computations require multi-dimensional arrays for storing wavefunctions and operators. This library provides high-performance, multi-dimensional array support, say for storing quantum states (annotated as: “|ψ⟩” ) as high-dimensional arrays, or efficiently representing unitary matrices for quantum gates.

      +
      +
      +
      #include <boost/multi_array.hpp>
      +using namespace boost;
      +multi_array<std::complex<double>, 2> quantum_state(boost::extents[4][4]);
      +
      +
      +
    • +
    • +

      Boost.Numeric/ublas : Quantum mechanics heavily relies on matrix operations (for example, unitary transformations, tensor products), and this library provides fast matrix and vector operations, ideal for quantum gate simulations. An example would be computing Quantum Fourier Transforms (QFT) and Grover’s diffusion operator.

      +
      +
      +
      #include <boost/numeric/ublas/matrix.hpp>
      +#include <boost/numeric/ublas/vector.hpp>
      +using namespace boost::numeric::ublas;
      +matrix<std::complex<double>> hadamard(2, 2);
      +
      +
      +
    • +
    • +

      Boost.Compute : Quantum simulations are computationally expensive, especially for large n-qubit systems. This library provides OpenCL-based GPU acceleration for quantum algorithms, such as parallelized quantum state evolution on GPUs, or accelerating quantum circuit simulation for Shor’s algorithm or Grover’s search.

      +
      +
      +
      #include <boost/compute.hpp>
      +namespace compute = boost::compute;
      +
      +
      +
    • +
    • +

      Boost.Random : Quantum systems often require true randomness (for example, simulating quantum measurement collapse or generating random phase shifts in quantum gates).

      +
      +
      +
      #include <boost/random.hpp>
      +boost::random::mt19937 rng;
      +boost::random::uniform_real_distribution<> dist(0, 1);
      +double probability = dist(rng);
      +
      +
      +
    • +
    • +

      Boost.Python : To bridge C++ and Python quantum libraries to allow seamless integration with frameworks like Qiskit or PennyLane. This could be for writing fast C++ quantum gate implementations and exposing them to Python, or perhaps using Qiskit for quantum execution while handling complex classical calculations in C++.

      +
      +
      +
      #include <boost/python.hpp>
      +using namespace boost::python;
      +BOOST_PYTHON_MODULE(my_quantum_module) {
      +    def("quantum_gate_sim", &quantum_gate_sim);
      +}
      +
      +
      +
    • +
    +
    +
    +
      +
    • +

      Boost.Graph : Quantum circuits can be represented as directed acyclic graphs (6). This library should help with optimizing quantum gate sequences, for reordering quantum gates to minimize depth, or finding the shortest path in quantum networks.

      +
      +
      +
      #include <boost/graph/adjacency_list.hpp>
      +using namespace boost;
      +
      +
      +
    • +
    +
    +
    +

    Let’s engage some Boost libraries in our Quantum algorithm simulations.

    +
    +
    +

    Quantum Walk Simulation using Boost.MultiArray

    +
    +

    Let’s simulate a 1D quantum walk using Boost.MultiArray for state representation.

    +
    +
    +
    +
    #include <iostream>
    +#include <complex>
    +#include <boost/multi_array.hpp>
    +
    +using namespace std;
    +using Complex = std::complex<double>;
    +
    +const int NUM_STEPS = 100;
    +const int NUM_POSITIONS = 201; // [-100, 100] range
    +
    +// Initialize the quantum state (walking on a line)
    +void initialize_state(boost::multi_array<Complex, 1>& state) {
    +    // Start at position 0 with full probability
    +    state[NUM_POSITIONS / 2] = 1.0;
    +}
    +
    +// Apply Hadamard gate (equal superposition)
    +void apply_hadamard(boost::multi_array<Complex, 1>& state) {
    +    for (int i = 1; i < NUM_POSITIONS - 1; i++) {
    +        Complex left = state[i - 1];
    +        Complex right = state[i + 1];
    +        state[i] = (left + right) / sqrt(2);
    +    }
    +}
    +
    +// Perform the quantum walk for a specified number of steps
    +void perform_quantum_walk(boost::multi_array<Complex, 1>& state) {
    +    for (int step = 0; step < NUM_STEPS; step++) {
    +        apply_hadamard(state);
    +    }
    +}
    +
    +// Calculate and print the probability distribution
    +void print_probability_distribution(const boost::multi_array<Complex, 1>& state) {
    +    for (int i = 0; i < NUM_POSITIONS; i++) {
    +        cout << i - NUM_POSITIONS / 2 << ": " << norm(state[i]) << endl;
    +    }
    +}
    +
    +int main() {
    +    // Initialize the quantum walk state
    +    boost::multi_array<Complex, 1> state(boost::extents[NUM_POSITIONS]);
    +    initialize_state(state);
    +
    +    // Perform the walk
    +    perform_quantum_walk(state);
    +
    +    // Print the probability distribution
    +    print_probability_distribution(state);
    +
    +    return 0;
    +}
    +
    +
    +
    +

    The output should be similar to the following:

    +
    +
    +
    +
    -100: 0
    +-99: 3.86581e-27
    +-98: 5.02749e-24
    +-97: 2.90701e-21
    +-96: 9.63774e-19
    +-95: 2.08484e-16
    +-94: 3.19241e-14
    +-93: 3.66019e-12
    +-92: 3.27387e-10
    +-91: 2.35719e-08
    +-90: 1.40029e-06
    +...
    +
    +
    +
    +
    +

    Quantum Gate Simulation using Boost Numeric Libraries

    +
    +

    Let’s simulate some quantum gates (a Hadamard gate and a PauliX gate), ensuring high precision with Boost.Multiprecision, and with matrix and vector calculations using Boost.Numeric/ublas. The sample simulates a single qubit as a 2-element complex vector, and applies quantum gates using 2x2 complex matrices.

    +
    +
    +
    +
    Note
    +
    +

    The Pauli gates (PauliX, PauliY, and PauliZ) equate to rotation about the respective axis, in each case by pi radians. The Hadamard gate is the proverbial coin flip.

    +
    +
    +
    +
    +
    +
    #include <iostream>
    +#include <boost/numeric/ublas/matrix.hpp>
    +#include <boost/numeric/ublas/io.hpp>
    +#include <boost/multiprecision/cpp_complex.hpp>
    +#include <boost/math/constants/constants.hpp>
    +
    +namespace ublas = boost::numeric::ublas;
    +namespace mp = boost::multiprecision;
    +
    +using Complex = mp::cpp_complex_100;  // or std::complex<double> for normal precision
    +using Matrix2 = ublas::matrix<Complex>;
    +using Vector2 = ublas::vector<Complex>;
    +
    +const Complex I(0, 1);
    +
    +// Quantum gate definitions
    +Matrix2 Hadamard() {
    +    Matrix2 H(2, 2);
    +    Complex norm = 1.0 / sqrt(2.0);
    +    H(0, 0) = norm; H(0, 1) = norm;
    +    H(1, 0) = norm; H(1, 1) = -norm;
    +    return H;
    +}
    +
    +Matrix2 PauliX() {
    +    Matrix2 X(2, 2);
    +    X(0, 0) = 0; X(0, 1) = 1;
    +    X(1, 0) = 1; X(1, 1) = 0;
    +    return X;
    +}
    +
    +// Print a qubit's state vector
    +void print_state(const Vector2& qubit) {
    +    std::cout << "Qubit state:\n";
    +    std::cout << "  |0⟩: " << qubit(0) << "\n";
    +    std::cout << "  |1⟩: " << qubit(1) << "\n";
    +}
    +
    +int main() {
    +    // Initial state |0⟩ = [1, 0]
    +    Vector2 qubit(2);
    +    qubit(0) = 1.0;
    +    qubit(1) = 0.0;
    +
    +    std::cout << "Initial state:\n";
    +    print_state(qubit);
    +
    +    // Apply Hadamard gate
    +    Matrix2 H = Hadamard();
    +    qubit = ublas::prod(H, qubit);
    +
    +    std::cout << "\nAfter Hadamard gate:\n";
    +    print_state(qubit);
    +
    +    // Apply Pauli-X gate
    +    Matrix2 X = PauliX();
    +    qubit = ublas::prod(X, qubit);
    +
    +    std::cout << "\nAfter Pauli-X gate:\n";
    +    print_state(qubit);
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Running this code should give output simlar to the following:

    +
    +
    +
    +
    Initial state:
    +Qubit state:
    +  |0?: 1
    +  |1?: 0
    +
    +After Hadamard gate:
    +Qubit state:
    +  |0?: 0.707107
    +  |1?: 0.707107
    +
    +After Pauli-X gate:
    +Qubit state:
    +  |0?: 0.707107
    +  |1?: 0.707107
    +
    +
    +
    +
    +

    Hybrid Classic-Quantum Algorithms

    +
    +

    Let’s explore a hybrid quantum-classical algorithm using Boost C++ libraries. A great candidate for this is the Variational Quantum Eigensolver (VQE), a hybrid quantum-classical algorithm used to find the lowest energy state of a quantum system, typically used in quantum chemistry.

    +
    +
    +

    The classic part of VQE is that a classical optimizer is used to find optimal parameters for a parameterized quantum circuit. The quantum part is that a quantum circuit generates quantum states based on these parameters, and the energy expectation is measured. The classical optimizer updates the parameters iteratively, with the quantum part computing the energy each time.

    +
    +
    +

    We’ll simulate a very basic version of this with a quantum Hamiltonian (energy function) and use a classical optimizer (from the functions of Boost.Numeric/ublas) to minimize the energy.

    +
    +
    +

    The quantum state will be parameterized, and the energy will be computed classically, simulating how a quantum system would behave in a real quantum computer.

    +
    +
    +
    +
    #include <boost/numeric/ublas/matrix.hpp>
    +#include <boost/numeric/ublas/io.hpp>
    +#include <boost/numeric/ublas/vector.hpp>
    +#include <cmath>
    +#include <iostream>
    +
    +namespace ublas = boost::numeric::ublas;
    +constexpr double pi = 3.14159265358979323846;
    +
    +// Pauli-Z Hamiltonian
    +ublas::matrix<double> pauli_z() {
    +    ublas::matrix<double> z(2, 2);
    +    z(0, 0) = 1.0; z(0, 1) = 0.0;
    +    z(1, 0) = 0.0; z(1, 1) = -1.0;
    +    return z;
    +}
    +
    +// Rotation around Y-axis (parameterized gate)
    +ublas::matrix<double> ry(double theta) {
    +    ublas::matrix<double> ry_gate(2, 2);
    +    ry_gate(0, 0) = std::cos(theta / 2);
    +    ry_gate(0, 1) = -std::sin(theta / 2);
    +    ry_gate(1, 0) = std::sin(theta / 2);
    +    ry_gate(1, 1) = std::cos(theta / 2);
    +    return ry_gate;
    +}
    +
    +// Expectation value: ⟨ψ|H|ψ⟩
    +double expectation_value(const ublas::matrix<double>& hamiltonian, const ublas::vector<double>& state) {
    +    ublas::vector<double> h_psi = ublas::prod(hamiltonian, state);
    +    return ublas::inner_prod(state, h_psi);
    +}
    +
    +// Normalize a vector
    +void normalize(ublas::vector<double>& v) {
    +    double norm = std::sqrt(ublas::inner_prod(v, v));
    +    if (norm > 0.0) v /= norm;
    +}
    +
    +int main() {
    +    ublas::matrix<double> H = pauli_z();
    +
    +    // Initial state |0> = [1, 0]
    +    ublas::vector<double> init_state(2);
    +    init_state(0) = 1.0;
    +    init_state(1) = 0.0;
    +
    +    // Sweep over theta to minimize expectation value
    +    double min_energy = 1e9;
    +    double best_theta = 0.0;
    +
    +    for (double theta = 0.0; theta <= 2 * pi; theta += 0.01) {
    +        ublas::matrix<double> U = ry(theta);
    +        ublas::vector<double> psi = ublas::prod(U, init_state);
    +        normalize(psi);
    +
    +        double energy = expectation_value(H, psi);
    +        if (energy < min_energy) {
    +            min_energy = energy;
    +            best_theta = theta;
    +        }
    +    }
    +
    +    std::cout << "Minimum energy: " << min_energy << " at theta = " << best_theta << " radians\n";
    +    return 0;
    +}
    +
    +
    +
    +

    Running the code should give you this result:

    +
    +
    +
    +
    Minimum energy: -0.999999 at theta = 3.14 radians
    +
    +
    +
    +
    +
    +
    +

    Next Steps for Quantum Computing

    +
    +
    +

    Quantum Computing is not ready for industrial use just yet. Currently qubits are not nearly reliable enough and need to be better connected (perhaps even photon-based networking for modular quantum computers). Also quantum computers currently need cryogenic cooling (to near absolute zero), and control electronics (such as lasers and microwaves) are bulky and inefficient. Perhaps Cryo-CMOS electronics (quantum chips running at ultra-low temps) with integrated photonics to replace bulky microwave-based control would solve this.

    +
    +
    +

    We also need more and better quantum-classical hybrid algorithms (like the Variational Quantum Eigensolver discussed above).

    +
    +
    +

    The biggest bottleneck right now is error correction and qubit stability. Once this is solved, scaling up becomes much easier, and quantum computing will move from experimental labs to real-world applications.

    +
    +
    +

    Realistically in the short term (say, up to 2030), quantum systems with more than a thousand qubits should be available with some error correction breakthroughs. These might work well with hybrid quantum-classical AI and chemistry applications.

    +
    +
    +

    In the mid term (say 2030 to 2040) we might see fault-tolerant quantum computers with a million or more logical qubits. Real-world applications in cryptography, finance, and materials science could then be tackled.

    +
    +
    +

    In the long-term quantum supremacy might reign over all classical tasks!

    +
    +
    +
    +
    +

    Footnotes

    +
    +
    +

    (1) +A qubit (quantum bit) is the fundamental unit of quantum information, analogous to a classical bit but with unique quantum properties. Unlike a classical bit, which can be either 0 or 1, a qubit exists in a superposition of both states simultaneously, represented as α|0⟩ + β|1⟩, where α and β are complex probability amplitudes. Qubits also exhibit entanglement, allowing them to share information instantaneously over distance, and quantum interference, which enables complex computations by manipulating probability amplitudes. These properties make qubits exponentially more powerful for certain tasks, forming the basis of quantum computing breakthroughs like Shor’s algorithm (for factoring) and Grover’s algorithm (for search). However, qubits are fragile and require error correction and extreme isolation to maintain coherence, making practical quantum computing a significant engineering challenge.

    +
    +
    +

    (2) +Superposition allows a qubit to exist in a combination of both |0⟩ and |1⟩ states simultaneously, enabling quantum computers to process multiple possibilities at once. Entanglement is a quantum phenomenon where qubits become correlated, meaning the state of one qubit instantly influences another, regardless of distance, enabling powerful parallel computations and secure communication. Interference arises from the wave-like nature of quantum states, allowing quantum algorithms to amplify correct answers while canceling out incorrect ones, enhancing computational efficiency.

    +
    +
    +

    (3) +Quantum Phase Estimation (QPE) is a quantum algorithm that determines the eigenvalues of a unitary operator, crucial for quantum computing applications like Shor’s algorithm and quantum chemistry simulations. It works by applying the Quantum Fourier Transform (4) to extract phase information from an eigenvector, effectively finding a highly accurate estimate of the phase. QPE is essential for problems where phase information reveals properties like energy levels in quantum systems, making it a powerful tool for scientific and cryptographic applications.

    +
    +
    +

    (4) +The Quantum Fourier Transform (QFT) is the quantum counterpart of the Discrete Fourier Transform (DFT), efficiently mapping quantum states to their frequency representations using a quantum circuit. It plays a key role in quantum algorithms like Shor’s algorithm for factoring and Quantum Phase Estimation. Unlike the classical O(N²) DFT, QFT runs in O(log² N) time, offering an exponential speedup, but requires careful handling of quantum phase information to be useful in practical computations.

    +
    +
    +

    (5) +3-SAT (3-Satisfiability) is a decision problem where a Boolean formula, expressed in conjunctive normal form (CNF) with exactly three literals per clause, must be determined as satisfiable or not. It is NP-complete, meaning that while any given solution can be verified in polynomial time, no known algorithm can solve all instances efficiently (unless P = NP). Since 3-SAT was one of the first problems proven NP-complete, many other computational problems can be reduced to it, making it a cornerstone of computational complexity theory.

    +
    +
    +

    (6) +A Directed Acyclic Graph (DAG) is a finite directed graph with no cycles, meaning that there is no way to start at a node and return to it by following directed edges. DAGs are widely used in applications such as task scheduling, dependency resolution (such as package managers, build systems like CMake), and blockchain technologies (IOTA’s Tangle). Their acyclic nature ensures that they represent structures with clear progressions, making them ideal for modeling workflows, computations, and hierarchical relationships.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-simulation.html b/preview/user-guide/task-simulation.html new file mode 100644 index 0000000..0fb3cb9 --- /dev/null +++ b/preview/user-guide/task-simulation.html @@ -0,0 +1,972 @@ + + + + + + + + + + + + + + Real-Time Simulation :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Real-Time Simulation

    +
    +
    +
    +

    Creating a real-time simulation of objects or processes involves various aspects, including accurate timing, physical modeling, collisions and deformation, concurrent programming for real-time response, data storage, networking for multi-vehicle simulation, and usually a graphic interface though sometimes logging results is enough.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are some libraries that may be helpful:

    +
    +
    +
      +
    • +

      Boost.Geometry: For spatial computations and geometric algorithms, which you will likely need for modeling the physical behavior and interactions of your vehicles.

      +
    • +
    • +

      Boost.Units: Helps with calculations involving units of measurement. It provides classes and functions that can enforce the correct usage of units and conversions between them, which could be helpful in a physical simulation.

      +
    • +
    • +

      Boost.Algorithm : Provides a variety of utilities for numerical and string processing.

      +
    • +
    • +

      Boost.Graph: In case you need to represent roads or pathways as a graph, this library provides a flexible and powerful way to represent and manipulate graphs. It also includes a number of graph algorithms.

      +
    • +
    • +

      Boost.Chrono: Timing is critical in real-time applications. This library can help you measure time intervals, which could be useful for controlling the timing of your simulation.

      +
    • +
    • +

      Boost.Thread: To achieve real-time performance, you might need to make use of multi-threading. This library provides classes and functions for multi-threading, synchronization, and inter-thread communication.

      +
    • +
    • +

      Boost.Interprocess: If you need to share data between different processes in real-time, this library can be useful. It supports shared memory, memory-mapped files, semaphores, and more.

      +
    • +
    • +

      Boost.Mpi or Boost.Asio: For distributed simulations that run across multiple systems, you might need a library for network communication. Boost.Mpi provides a C++ interface for the Message Passing Interface (MPI) standard for distributed computing. Boost.Asio can also handle networking tasks and it is a bit lower-level.

      +
    • +
    • +

      Boost.Serialization: To save the state of the simulation or to communicate complex data structures over a network, you might find this library helpful.

      +
    • +
    • +

      Boost.Log: Supports severity levels, which you can use to categorize and filter your log messages. This can help you control the amount of log output and focus on what’s important.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Simulate Movement in 3D Space

    +
    +
    +

    The following sample simulates the movement of a geometric shape (a 3D box) in space using Boost.Geometry for shape representation, Boost.Chrono for timing, and Boost.Algorithm for numerical adjustments, such as scaling, normalization and smoothing movement (avoiding unrealistic motion).

    +
    +
    +

    The simulation itself runs for just a few seconds.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/geometry.hpp>
    +#include <boost/chrono.hpp>
    +#include <boost/algorithm/clamp.hpp>
    +#include <boost/thread/thread.hpp>
    +
    +namespace bg = boost::geometry;
    +using namespace boost::chrono;
    +
    +// Define a 3D box with min and max corners
    +using point3d = bg::model::point<double, 3, bg::cs::cartesian>;
    +using box3d = bg::model::box<point3d>;
    +
    +const int xcoord = 0;
    +const int ycoord = 1;
    +const int zcoord = 2;
    +const double increment = 0.2;       // Guideline time increment in seconds
    +
    +// Retrieve a point3d co-ordinate
    +double getCoord(int i, point3d p)
    +{
    +    switch (i)
    +    {
    +    case 0: return bg::get<xcoord>(p);
    +    case 1: return bg::get<ycoord>(p);
    +    case 2: return bg::get<zcoord>(p);
    +    }
    +}
    +
    +// Set a point3d co-ordinate
    +void setCoord(int i, point3d& p, double v)
    +{
    +    switch (i)
    +    {
    +    case 0: bg::set<xcoord>(p, v);
    +        break;
    +
    +    case 1: bg::set<ycoord>(p, v);
    +        break;
    +
    +    case 2: bg::set<zcoord>(p, v);
    +        break;
    +
    +    }
    +}
    +
    +// Update the position of the box
    +void move_box(box3d& box, const point3d& velocity, double delta_time) {
    +
    +    // Temporary variables for use in the movement calculations
    +    point3d min_corner = box.min_corner();
    +    point3d max_corner = box.max_corner();
    +
    +    // Update the box position using velocity * delta time
    +    for (int i = 0; i < 3; ++i) {
    +
    +        double new_min = getCoord(i,min_corner) + (getCoord(i,velocity) * delta_time);
    +        double new_max = getCoord(i,max_corner) + (getCoord(i,velocity) * delta_time);
    +
    +        // Example clamp to avoid excessive movement (Boost.Algorithm)
    +        new_min = boost::algorithm::clamp(new_min, -100.0, 100.0);
    +        new_max = boost::algorithm::clamp(new_max, -100.0, 100.0);
    +
    +        setCoord(i, min_corner, new_min);
    +        setCoord(i, max_corner, new_max);
    +    }
    +
    +    // Update the box with new corners
    +    box = box3d(min_corner, max_corner);
    +}
    +
    +int main() {
    +
    +    // Set the sleep duration based on the guideline increment in seconds
    +    boost::chrono::duration<double> sleep_duration(increment);
    +
    +    // Create a 3D box (min corner and max corner)
    +    box3d box(point3d(0.0, 0.0, 0.0), point3d(1.0, 1.0, 1.0));
    +
    +    // Define velocity (units per second)
    +    point3d velocity(0.5, 0.3, -0.2);
    +
    +    // Start timing
    +    steady_clock::time_point start_time = steady_clock::now();
    +    steady_clock::time_point current_time;
    +    steady_clock::time_point previous_time = start_time;
    +    double elapsed_seconds, increment_seconds;
    +
    +    // Run simulation for 50 increments
    +    for (int i = 0; i < 50; ++i) {
    +
    +        // Measure elapsed time - both from the start, and from the previous move
    +        current_time = steady_clock::now();
    +        elapsed_seconds = duration<double>(current_time - start_time).count();
    +        increment_seconds = duration<double>(current_time - previous_time).count();
    +        previous_time = current_time;
    +
    +        // Move the box every increment, noting the increment will vary by tiny fractions of a second each time.
    +        move_box(box, velocity, increment_seconds);
    +
    +        // Print times and the updated box position
    +        point3d min_corner = box.min_corner();
    +        point3d max_corner = box.max_corner();
    +        std::cout << "Time: " << elapsed_seconds << " sec | "
    +            << "Inc: " << increment_seconds << " sec | "
    +            << "Box Position: Min("
    +            << getCoord(xcoord,min_corner) << ", "
    +            << getCoord(ycoord,min_corner) << ", "
    +            << getCoord(zcoord,min_corner) << ") "
    +            << " Max("
    +            << getCoord(xcoord, max_corner) << ", "
    +            << getCoord(ycoord, max_corner) << ", "
    +            << getCoord(zcoord, max_corner) << ")\n";
    +
    +        boost::this_thread::sleep_for(sleep_duration);
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    An example of the output:

    +
    +
    +
    +
    Time: 0.209428 sec | Inc: 0.209424 sec | Box Position: Min(0.104714, 0.0628285, -0.0418857)  Max(1.10471, 1.06283, 0.958114)
    +Time: 0.429642 sec | Inc: 0.220214 sec | Box Position: Min(0.214821, 0.128893, -0.0859284)  Max(1.21482, 1.12889, 0.914072)
    +Time: 0.648115 sec | Inc: 0.218473 sec | Box Position: Min(0.324058, 0.194435, -0.129623)  Max(1.32406, 1.19443, 0.870377)
    +......
    +
    +
    +
    +
    +
    Note
    +
    +

    The time increment varies slightly on each loop, and this value is used when calculating movement.

    +
    +
    +
    +
    +
    +
    +

    Add Collision Detection

    +
    +
    +

    Most 3D simulations require collision detection, which usually has a significant impact on the performance of a simulation, particularly in three dimensions. We’ll introduce a bounding volume (a larger 3D box representing the environment), and detect when our moving box collides with its boundaries.

    +
    +
    +

    Collision detection is handled by checking if the box’s min/max corners exceed the bounds. Some "bounce" mechanics are added to invert velocity after impact. In this example, the box moves continuously, rebounding off the walls, without consequences!

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/geometry.hpp>
    +#include <boost/chrono.hpp>
    +#include <boost/algorithm/clamp.hpp>
    +#include <boost/thread/thread.hpp>
    +
    +namespace bg = boost::geometry;
    +using namespace boost::chrono;
    +
    +// Define a 3D box with min and max corners
    +using point3d = bg::model::point<double, 3, bg::cs::cartesian>;
    +using box3d = bg::model::box<point3d>;
    +
    +const int xcoord = 0;
    +const int ycoord = 1;
    +const int zcoord = 2;
    +const double increment = 0.2;       // Guideline time increment in seconds
    +
    +// Retrieve a point3d co-ordinate
    +double getCoord(int i, point3d p)
    +{
    +    switch (i)
    +    {
    +    case 0: return bg::get<xcoord>(p);
    +    case 1: return bg::get<ycoord>(p);
    +    case 2: return bg::get<zcoord>(p);
    +    }
    +}
    +
    +// Set a point3d co-ordinate
    +void setCoord(int i, point3d& p, double v)
    +{
    +    switch (i)
    +    {
    +    case 0: bg::set<xcoord>(p, v);
    +        break;
    +
    +    case 1: bg::set<ycoord>(p, v);
    +        break;
    +
    +    case 2: bg::set<zcoord>(p, v);
    +        break;
    +
    +    }
    +}
    +
    +// Update the position of the box
    +void move_box(box3d& box, const point3d& velocity, double delta_time) {
    +
    +    // Temporary variables for use in the movement calculations
    +    point3d min_corner = box.min_corner();
    +    point3d max_corner = box.max_corner();
    +
    +    // Update the box position using velocity * delta time
    +    for (int i = 0; i < 3; ++i) {
    +
    +        double new_min = getCoord(i,min_corner) + (getCoord(i,velocity) * delta_time);
    +        double new_max = getCoord(i,max_corner) + (getCoord(i,velocity) * delta_time);
    +
    +        // Example clamp to avoid excessive movement (Boost.Algorithm)
    +        new_min = boost::algorithm::clamp(new_min, -100.0, 100.0);
    +        new_max = boost::algorithm::clamp(new_max, -100.0, 100.0);
    +
    +        setCoord(i, min_corner, new_min);
    +        setCoord(i, max_corner, new_max);
    +    }
    +
    +    // Update the box with new corners
    +    box = box3d(min_corner, max_corner);
    +}
    +
    +// Function to check and handle collisions with the bounding box
    +void handle_collision(box3d& box, point3d& velocity, const box3d& bounds) {
    +    for (int i = 0; i < 3; ++i) {
    +        double min_pos = getCoord(i, box.min_corner());
    +        double max_pos = getCoord(i, box.max_corner());
    +        double bound_min = getCoord(i, bounds.min_corner());
    +        double bound_max = getCoord(i, bounds.max_corner());
    +
    +        // If box collides with environment limits, reverse velocity
    +        if (min_pos <= bound_min || max_pos >= bound_max) {
    +            setCoord(i, velocity, -getCoord(i, velocity));              // Reverse direction
    +            double impact_force = std::abs(getCoord(i,velocity));       // Impact force = velocity along the impact axis
    +           std::cout << "\nCollision with impact force: " << impact_force << "\n"
    +                << "New velocity : ("
    +                << getCoord(xcoord, velocity) << ", "
    +                << getCoord(ycoord, velocity) << ", "
    +                << getCoord(zcoord, velocity) << ")\n\n";
    +        }
    +    }
    +}
    +
    +
    +int main() {
    +
    +    // Set the sleep duration based on the guideline increment in seconds
    +    boost::chrono::duration<double> sleep_duration(increment);
    +
    +    // Define the 3D simulation space (bounding box)
    +    box3d bounds(point3d(-5.0, -5.0, -5.0), point3d(5.0, 5.0, 5.0));
    +
    +    // Create a 3D box (min corner and max corner)
    +    box3d box(point3d(0.0, 0.0, 0.0), point3d(1.0, 1.0, 1.0));
    +
    +    // Define velocity (units per second)
    +    point3d velocity(0.5, 0.3, -0.2);
    +
    +    // Start timing
    +    steady_clock::time_point start_time = steady_clock::now();
    +    steady_clock::time_point current_time;
    +    steady_clock::time_point previous_time = start_time;
    +    double elapsed_seconds, increment_seconds;
    +
    +    // Run simulation for 80 increments
    +    for (int i = 0; i < 80; ++i) {
    +
    +        // Measure elapsed time - both from the start, and from the previous move
    +        current_time = steady_clock::now();
    +        elapsed_seconds = duration<double>(current_time - start_time).count();
    +        increment_seconds = duration<double>(current_time - previous_time).count();
    +        previous_time = current_time;
    +
    +        // Move the box every increment, noting the increment will vary by tiny fractions of a second each time.
    +        move_box(box, velocity, increment_seconds);
    +
    +        // Check for collision
    +        handle_collision(box, velocity, bounds);
    +
    +        // Print times and the updated box position
    +        point3d min_corner = box.min_corner();
    +        point3d max_corner = box.max_corner();
    +        std::cout << "Time: " << elapsed_seconds << " sec | "
    +            << "Inc: " << increment_seconds << " sec | "
    +            << "Box Position: Min("
    +            << getCoord(xcoord,min_corner) << ", "
    +            << getCoord(ycoord,min_corner) << ", "
    +            << getCoord(zcoord,min_corner) << ") "
    +            << " Max("
    +            << getCoord(xcoord, max_corner) << ", "
    +            << getCoord(ycoord, max_corner) << ", "
    +            << getCoord(zcoord, max_corner) << ")\n";
    +
    +        boost::this_thread::sleep_for(sleep_duration);
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    An unlikely event perhaps, but a collision between the box and two or three sides of the bounding area will be handled by this code.

    +
    +
    +
    +
    +

    An example of the output:

    +
    +
    +
    +
    Time: 7.76744 sec | Inc: 0.2183 sec | Box Position: Min(3.88372, 2.33023, -1.55349)  Max(4.88372, 3.33023, -0.553488)
    +Time: 7.98306 sec | Inc: 0.215622 sec | Box Position: Min(3.99153, 2.39492, -1.59661)  Max(4.99153, 3.39492, -0.596613)
    +
    +Collision with impact force: 0.5
    +New velocity : (-0.5, 0.3, -0.2)
    +
    +Time: 8.19834 sec | Inc: 0.21528 sec | Box Position: Min(4.09917, 2.4595, -1.63967)  Max(5.09917, 3.4595, -0.639669)
    +Time: 8.41678 sec | Inc: 0.218435 sec | Box Position: Min(3.98995, 2.52503, -1.68336)  Max(4.98995, 3.52503, -0.683356)
    +......
    +
    +
    +
    +
    +
    +

    Deformation on Impact

    +
    +
    +

    Collisions rarely have no consequences. To simulate deformation on impact, we can modify the shape of the box when it collides with a boundary.

    +
    +
    +
    +cube deforming in 3D space +
    +
    +
    +

    The box will deform along the axis of impact, based on the velocity.

    +
    +
    +
    +
    #include <iostream>
    +#include <boost/geometry.hpp>
    +#include <boost/chrono.hpp>
    +#include <boost/algorithm/clamp.hpp>
    +#include <boost/thread/thread.hpp>
    +
    +namespace bg = boost::geometry;
    +using namespace boost::chrono;
    +
    +// Define a 3D box with min and max corners
    +using point3d = bg::model::point<double, 3, bg::cs::cartesian>;
    +using box3d = bg::model::box<point3d>;
    +
    +const int xcoord = 0;
    +const int ycoord = 1;
    +const int zcoord = 2;
    +const double increment = 0.2;       // Guideline time increment in seconds
    +
    +// Retrieve a point3d co-ordinate
    +double getCoord(int i, point3d p)
    +{
    +    switch (i)
    +    {
    +    case 0: return bg::get<xcoord>(p);
    +    case 1: return bg::get<ycoord>(p);
    +    case 2: return bg::get<zcoord>(p);
    +    }
    +}
    +
    +// Set a point3d co-ordinate
    +void setCoord(int i, point3d& p, double v)
    +{
    +    switch (i)
    +    {
    +    case 0: bg::set<xcoord>(p, v);
    +        break;
    +
    +    case 1: bg::set<ycoord>(p, v);
    +        break;
    +
    +    case 2: bg::set<zcoord>(p, v);
    +        break;
    +
    +    }
    +}
    +
    +// To verify deformation, calculate the volume of the box
    +double volume(const box3d& box) {
    +    double dx = getCoord(xcoord, box.max_corner()) - getCoord(xcoord, box.min_corner());
    +    double dy = getCoord(ycoord, box.max_corner()) - getCoord(ycoord, box.min_corner());
    +    double dz = getCoord(zcoord, box.max_corner()) - getCoord(zcoord, box.min_corner());
    +    return dx * dy * dz;
    +}
    +
    +// Function to deform the box upon collision
    +void deform_box(box3d& box, int axis, double impact_force) {
    +    // Get the box corners
    +    point3d min_corner = box.min_corner();
    +    point3d max_corner = box.max_corner();
    +
    +    // Deformation ratio (scales based on impact)
    +    double deformation = 1.0 - (impact_force * 0.2);
    +    deformation = boost::algorithm::clamp(deformation, 0.7, 1.0);  // Prevent over-deformation
    +
    +    // Scale the box on the axis of impact
    +    double center = (getCoord(axis,min_corner) + getCoord(axis,max_corner)) / 2.0;
    +    setCoord(axis,min_corner, center - (center - getCoord(axis,min_corner)) * deformation);
    +    setCoord(axis,max_corner, center + (getCoord(axis,max_corner) - center) * deformation);
    +
    +    // Update the box
    +    box = box3d(min_corner, max_corner);
    +}
    +
    +// Update the position of the box
    +void move_box(box3d& box, const point3d& velocity, double delta_time) {
    +
    +    // Temporary variables for use in the movement calculations
    +    point3d min_corner = box.min_corner();
    +    point3d max_corner = box.max_corner();
    +
    +    // Update the box position using velocity * delta time
    +    for (int i = 0; i < 3; ++i) {
    +
    +        double new_min = getCoord(i,min_corner) + (getCoord(i,velocity) * delta_time);
    +        double new_max = getCoord(i,max_corner) + (getCoord(i,velocity) * delta_time);
    +
    +        // Example clamp to avoid excessive movement (Boost.Algorithm)
    +        new_min = boost::algorithm::clamp(new_min, -100.0, 100.0);
    +        new_max = boost::algorithm::clamp(new_max, -100.0, 100.0);
    +
    +        setCoord(i, min_corner, new_min);
    +        setCoord(i, max_corner, new_max);
    +    }
    +
    +    // Update the box with new corners
    +    box = box3d(min_corner, max_corner);
    +}
    +
    +// Function to check and handle collisions with the bounding box
    +void handle_collision(box3d& box, point3d& velocity, const box3d& bounds) {
    +    for (int i = 0; i < 3; ++i) {
    +        double min_pos = getCoord(i, box.min_corner());
    +        double max_pos = getCoord(i, box.max_corner());
    +        double bound_min = getCoord(i, bounds.min_corner());
    +        double bound_max = getCoord(i, bounds.max_corner());
    +
    +        // If box collides with environment limits, reverse velocity
    +        if (min_pos <= bound_min || max_pos >= bound_max) {
    +            setCoord(i, velocity, -getCoord(i, velocity));          // Reverse direction
    +            double impact_force = std::abs(getCoord(i,velocity));   // Higher velocity = more deformation
    +            deform_box(box, i, impact_force);                       // Apply deformation
    +            std::cout << "\nCollision with impact force: " << impact_force << "\n"
    +                << "New velocity : ("
    +                << getCoord(xcoord, velocity) << ", "
    +                << getCoord(ycoord, velocity) << ", "
    +                << getCoord(zcoord, velocity) << "), Volume of box: "
    +                << volume(box) << "\n\n";
    +        }
    +    }
    +}
    +
    +int main() {
    +
    +    // Set the sleep duration based on the guideline increment in seconds
    +    boost::chrono::duration<double> sleep_duration(increment);
    +
    +    // Define the 3D simulation space (bounding box)
    +    box3d bounds(point3d(-5.0, -5.0, -5.0), point3d(5.0, 5.0, 5.0));
    +
    +    // Create a 3D box (min corner and max corner)
    +    box3d box(point3d(0.0, 0.0, 0.0), point3d(1.0, 1.0, 1.0));
    +
    +    // Define velocity (units per second)
    +    point3d velocity(0.5, 0.3, -0.2);
    +
    +    // Start timing
    +    steady_clock::time_point start_time = steady_clock::now();
    +    steady_clock::time_point current_time;
    +    steady_clock::time_point previous_time = start_time;
    +    double elapsed_seconds, increment_seconds;
    +
    +    // Run simulation for 80 increments
    +    for (int i = 0; i < 80; ++i) {
    +
    +        // Measure elapsed time - both from the start, and from the previous move
    +        current_time = steady_clock::now();
    +        elapsed_seconds = duration<double>(current_time - start_time).count();
    +        increment_seconds = duration<double>(current_time - previous_time).count();
    +        previous_time = current_time;
    +
    +        // Move the box every increment, noting the increment will vary by tiny fractions of a second each time.
    +        move_box(box, velocity, increment_seconds);
    +
    +        // Check for collision
    +        handle_collision(box, velocity, bounds);
    +
    +        // Print times and the updated box position
    +        point3d min_corner = box.min_corner();
    +        point3d max_corner = box.max_corner();
    +        std::cout << "Time: " << elapsed_seconds << " sec | "
    +            << "Inc: " << increment_seconds << " sec | "
    +            << "Box Position: Min("
    +            << getCoord(xcoord,min_corner) << ", "
    +            << getCoord(ycoord,min_corner) << ", "
    +            << getCoord(zcoord,min_corner) << ") "
    +            << " Max("
    +            << getCoord(xcoord, max_corner) << ", "
    +            << getCoord(ycoord, max_corner) << ", "
    +            << getCoord(zcoord, max_corner) << ")\n";
    +
    +        boost::this_thread::sleep_for(sleep_duration);
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    An example of the output:

    +
    +
    +
    +
    Time: 7.40482 sec | Inc: 0.20316 sec | Box Position: Min(3.70241, 2.22145, -1.48096)  Max(4.70241, 3.22145, -0.480964)
    +Time: 7.62483 sec | Inc: 0.22001 sec | Box Position: Min(3.81242, 2.28745, -1.52497)  Max(4.81242, 3.28745, -0.524966)
    +Time: 7.8286 sec | Inc: 0.203764 sec | Box Position: Min(3.9143, 2.34858, -1.56572)  Max(4.9143, 3.34858, -0.565719)
    +
    +Collision with impact force:0.5
    +New velocity : (-0.5, 0.3, -0.2), Volume of box: 0.9
    +
    +Time: 8.03252 sec | Inc: 0.203922 sec | Box Position: Min(4.06626, 2.40976, -1.6065)  Max(4.96626, 3.40976, -0.606503)
    +Time: 8.25219 sec | Inc: 0.219674 sec | Box Position: Min(3.95642, 2.47566, -1.65044)  Max(4.85642, 3.47566, -0.650438)
    +
    +
    +
    +

    It is good practice when designing a simulation of real-world activity to clearly define what is to be simulated and what is not. All simulations are simplifications to an extent, though they do tend to be large and challenging programs to write. A complex simulation might have several processes running on different threads. For a sample of multi-threading code, refer to Parallel Computation.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-system.html b/preview/user-guide/task-system.html new file mode 100644 index 0000000..b3d1dc4 --- /dev/null +++ b/preview/user-guide/task-system.html @@ -0,0 +1,832 @@ + + + + + + + + + + + + + + System Components :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    System Components

    +
    +
    +
    +

    Developing a system component for an operating system in C++ involves a wide range of low-level tasks. The relevant Boost libraries will largely depend on the specifics of your project. Some operating systems may not support all of the features of these libraries, and for low-level tasks, it may be more appropriate to use system APIs directly. For higher-level system operations, or cross-platform tasks, Boost libraries have a lot to offer.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are some Boost libraries that are useful in building system components:

    +
    +
    +
      +
    • +

      Boost.Filesystem : This library provides a portable way of querying and manipulating paths, files, and directories. It can be very helpful for system-level tasks that need to interact with the file system.

      +
    • +
    • +

      Boost.ProgramOptions : This library allows program options to be defined, with types and default values, and their values to be retrieved from the command line, from config files, and programmatically.

      +
    • +
    • +

      Boost.System : This library provides simple, light-weight error_code objects that encapsulate system-specific "error codes", distinct from C++ exceptions.

      +
    • +
    • +

      Boost.Chrono : This library provides a set of handy features for measuring time, which might be useful for system-level tasks that need to measure or manipulate time.

      +
    • +
    • +

      Boost.Asio : This library provides a consistent asynchronous model using a modern C++ approach for network and low-level I/O programming. This might be useful for network-related components or any component that interacts with hardware.

      +
    • +
    • +

      Boost.Interprocess : This library provides a way of sharing memory and communicating between processes. It’s useful for creating shared memory regions, handling inter-process communication, managing shared objects, and synchronizing processes.

      +
    • +
    • +

      Boost.Thread : This library provides a portable interface for multithreading. It includes features for creating and managing threads, mutexes, condition variables, and futures.

      +
    • +
    • +

      Boost.Fiber : A fiber is a lightweight thread of execution. Boost.Fiber provides a framework for creating and managing fibers, which can be useful in some system-level programming tasks.

      +
    • +
    • +

      Boost.Container : This provides advanced data structures beyond the ones provided by the C++ standard library, which may be useful in certain scenarios.

      +
    • +
    • +

      Boost.Process : This library allows you to create child processes, setup their environment and provides means to communicate with them asynchronously through various streams.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Sample System File and Error Handling

    +
    +
    +

    Two core features of most systems are in file handling and robust error reporting. For a simpler sample we’ll create an app that uses Boost.Filesystem to manipulate files and directories, and Boost.System to capture and display specific errors.

    +
    +
    +

    The following sample creates a directory (example_directory) if it does not exist, writes a file (example_file.txt.) to the directory, reads from the file, and handles system-specific errors. Finally, it cleans up by deleting the file and directory, still handling any errors.

    +
    +
    +

    For examples of networking and threading code, refer to Networking and Parallel Computation.

    +
    +
    +
    +
    #include <boost/filesystem.hpp>
    +#include <boost/system/error_code.hpp>
    +#include <iostream>
    +#include <fstream>
    +
    +namespace fs = boost::filesystem;
    +namespace sys = boost::system;
    +
    +//  Check and report system-specific errors
    +void handle_error(const sys::error_code& ec, const std::string& action) {
    +    if (ec) {
    +        std::cerr << "Error while " << action << ": " << ec.message()
    +            << " (Code: " << ec.value() << ")\n";
    +    }
    +    else
    +    {
    +        std::cout << "All OK while " << action << '\n';
    +    }
    +}
    +
    +int main() {
    +    fs::path dir = "example_directory";
    +    fs::path file = dir / "example_file.txt";
    +    sys::error_code ec;
    +
    +    // Create directory if it doesn't exist
    +    if (!fs::exists(dir)) {
    +        fs::create_directory(dir, ec);
    +        handle_error(ec, "creating directory");
    +    }
    +
    +    // Write to the file
    +    {
    +        std::ofstream ofs(file.string());
    +        if (!ofs) {
    +            std::cerr << "Failed to open file for writing!\n";
    +            return 1;
    +        }
    +        ofs << "Hello, Boost.Filesystem!\n";
    +    }
    +
    +    // Read from the file
    +    {
    +        std::ifstream ifs(file.string());
    +        if (!ifs) {
    +            std::cerr << "Failed to open file for reading!\n";
    +            return 1;
    +        }
    +        std::string content;
    +        std::getline(ifs, content);
    +        std::cout << "File content: " << content << '\n';
    +    }
    +
    +    // Remove file
    +    fs::remove(file, ec);
    +    handle_error(ec, "removing file");
    +
    +    // Remove directory
    +    fs::remove(dir, ec);
    +    handle_error(ec, "removing directory");
    +
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    Boost.Filesystem ensures directory and file management is platform-independent.

    +
    +
    Tip
    +
    +

    The first time you run this code, comment out the code to remove the file and directory at the end. After running the code, locate example_directory, then you can both verify the content of example_file.txt and record the parent directory of example_directory - which you will need in later examples.

    +
    +
    +
    +
    +
    +
    +

    Support Configuration Settings

    +
    +
    +

    We are now going to include Boost.ProgramOptions to allow configuration settings via command-line arguments and configuration files.

    +
    +
    +

    The code now allows users to specify directory and file names, reads settings from a config.ini file, and uses default values when one is not specified or located.

    +
    +
    +
    +
    #include <boost/filesystem.hpp>
    +#include <boost/system/error_code.hpp>
    +#include <boost/program_options.hpp>
    +#include <iostream>
    +#include <fstream>
    +
    +namespace fs = boost::filesystem;
    +namespace sys = boost::system;
    +namespace po = boost::program_options;
    +
    +//  Check and report system-specific errors
    +void handle_error(const sys::error_code& ec, const std::string& action) {
    +    if (ec) {
    +        std::cerr << "Error while " << action << ": " << ec.message()
    +            << " (Code: " << ec.value() << ")\n";
    +    }
    +    else
    +    {
    +        std::cout << "All OK while " << action << '\n';
    +    }
    +}
    +
    +int main(int argc, char* argv[]) {
    +    // Default configuration values
    +    std::string dir = "default_directory";
    +    std::string filename = "default_file.txt";
    +    std::string config_file = "config.ini";
    +
    +    // Define command-line options
    +    po::options_description desc("Allowed options");
    +    desc.add_options()
    +        ("help,h", "Show help message")
    +        ("dir,d", po::value<std::string>(&dir), "Directory name")
    +        ("file,f", po::value<std::string>(&filename), "File name")
    +        ("config,c", po::value<std::string>(&config_file)->default_value("config.ini"), "Configuration file");
    +
    +    // Parse command-line options
    +    po::variables_map vm;
    +    po::store(po::parse_command_line(argc, argv, desc), vm);
    +    po::notify(vm);
    +
    +    if (vm.count("help")) {
    +        std::cout << desc << std::endl;
    +        return 0;
    +    }
    +
    +    // Read options from configuration file (if available)
    +    std::ifstream ifs(config_file);
    +    if (ifs) {
    +        po::store(po::parse_config_file(ifs, desc), vm);
    +        po::notify(vm);
    +    }
    +
    +    fs::path directory(dir);
    +    fs::path file = directory / filename;
    +    sys::error_code ec;
    +
    +    // Create directory if it doesn't exist
    +    if (!fs::exists(directory)) {
    +        fs::create_directory(directory, ec);
    +        handle_error(ec, "creating directory");
    +    }
    +
    +    // Write to the file
    +    {
    +        std::ofstream ofs(file.string());
    +        if (!ofs) {
    +            std::cerr << "Failed to open file for writing!\n";
    +            return 1;
    +        }
    +        ofs << "Hello, Boost.Program_Options and Boost.Filesystem!\n";
    +    }
    +
    +    // Read from the file
    +    {
    +        std::ifstream ifs(file.string());
    +        if (!ifs) {
    +            std::cerr << "Failed to open file for reading!\n";
    +            return 1;
    +        }
    +        std::string content;
    +        std::getline(ifs, content);
    +        std::cout << "File content: " << content << '\n';
    +    }
    +
    +    // Remove file
    +    fs::remove(file, ec);
    +    handle_error(ec, "removing file");
    +
    +    // Remove directory
    +    fs::remove(directory, ec);
    +    handle_error(ec, "removing directory");
    +
    +    return 0;
    +}
    +
    +
    +
    +

    The command line options accepted by the sample are:

    +
    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    OptionDescription

    --dir or -d

    Specify the directory.

    --file or -f

    Specify the filename.

    --config or -c

    Specify the configuration file.

    --help or -h

    Display available options.

    +
    +

    The following is an example config.ini file, create it and store it to the parent directory you recorded in the previous example.

    +
    +
    +
    +
    dir = my_directory
    +file = my_file.txt
    +
    +
    +
    +

    The following command lines show how to run with defaults, run with options specified manually, and then run with a config file:

    +
    +
    +
    +
    ./program
    +
    +./program --dir=my_data --file=data.txt
    +
    +./program --config=my_config.ini
    +
    +
    +
    +
    +
    +

    Time the System Operations

    +
    +
    +

    It might be important to record the time taken for system operations, both in testing and in the operation of a system app. So, let’s integrate Boost.Chrono to measure the time taken for key filesystem operations, such as creating directories, writing to files, reading files, and deleting files.

    +
    +
    +
    +system timing +
    +
    +
    +
    +
    #include <boost/filesystem.hpp>
    +#include <boost/system/error_code.hpp>
    +#include <boost/program_options.hpp>
    +#include <boost/chrono.hpp>
    +#include <iostream>
    +#include <fstream>
    +
    +namespace fs = boost::filesystem;
    +namespace sys = boost::system;
    +namespace po = boost::program_options;
    +namespace chrono = boost::chrono;
    +
    +//  Check and report system-specific errors
    +void handle_error(const sys::error_code& ec, const std::string& action) {
    +    if (ec) {
    +        std::cerr << "Error while " << action << ": " << ec.message()
    +                  << " (Code: " << ec.value() << ")\n";
    +    }
    +    else
    +    {
    +        std::cout << "All OK while " << action << '\n';
    +    }
    +}
    +
    +int main(int argc, char* argv[]) {
    +
    +    // Default configuration values
    +    std::string dir = "default_directory";
    +    std::string filename = "default_file.txt";
    +    std::string config_file = "config.ini";
    +
    +    // Define command-line options
    +    po::options_description desc("Allowed options");
    +    desc.add_options()
    +        ("help,h", "Show help message")
    +        ("dir,d", po::value<std::string>(&dir), "Directory name")
    +        ("file,f", po::value<std::string>(&filename), "File name")
    +        ("config,c", po::value<std::string>(&config_file)->default_value("config.ini"), "Configuration file");
    +
    +    // Parse command-line options
    +    po::variables_map vm;
    +    po::store(po::parse_command_line(argc, argv, desc), vm);
    +    po::notify(vm);
    +
    +    if (vm.count("help")) {
    +        std::cout << desc << std::endl;
    +        return 0;
    +    }
    +
    +    // Read options from configuration file (if available)
    +    std::ifstream ifs_config(config_file);
    +    if (ifs_config) {
    +        po::store(po::parse_config_file(ifs_config, desc), vm);
    +        po::notify(vm);
    +    }
    +
    +    fs::path directory(dir);
    +    fs::path file = directory / filename;
    +    sys::error_code ec;
    +
    +    // Measure time for directory creation
    +    auto start = chrono::steady_clock::now();
    +    if (!fs::exists(directory)) {
    +        fs::create_directory(directory, ec);
    +        handle_error(ec, "creating directory");
    +    }
    +    auto end = chrono::steady_clock::now();
    +    std::cout << "Directory creation took: "
    +              << chrono::duration_cast<chrono::microseconds>(end - start).count()
    +              << " microseconds\n";
    +
    +    // Measure time for writing to file
    +    start = chrono::steady_clock::now();
    +    {
    +        std::ofstream ofs(file.string());
    +        if (!ofs) {
    +            std::cerr << "Failed to open file for writing!\n";
    +            return 1;
    +        }
    +        ofs << "Hello, Boost.Program_Options, Boost.Filesystem, and Boost.Chrono!\n";
    +    }
    +    end = chrono::steady_clock::now();
    +    std::cout << "File writing took: "
    +              << chrono::duration_cast<chrono::microseconds>(end - start).count()
    +              << " microseconds\n";
    +
    +    // Measure time for reading from file
    +    start = chrono::steady_clock::now();
    +    {
    +        std::ifstream ifs(file.string());
    +        if (!ifs) {
    +            std::cerr << "Failed to open file for reading!\n";
    +            return 1;
    +        }
    +        std::string content;
    +        std::getline(ifs, content);
    +        std::cout << "File content: " << content << '\n';
    +    }
    +    end = chrono::steady_clock::now();
    +    std::cout << "File reading took: "
    +              << chrono::duration_cast<chrono::microseconds>(end - start).count()
    +              << " microseconds\n";
    +
    +    // Measure time for file deletion
    +    start = chrono::steady_clock::now();
    +    fs::remove(file, ec);
    +    handle_error(ec, "removing file");
    +    end = chrono::steady_clock::now();
    +    std::cout << "File deletion took: "
    +              << chrono::duration_cast<chrono::microseconds>(end - start).count()
    +              << " microseconds\n";
    +
    +    // Measure time for directory deletion
    +    start = chrono::steady_clock::now();
    +    fs::remove(directory, ec);
    +    handle_error(ec, "removing directory");
    +    end = chrono::steady_clock::now();
    +    std::cout << "Directory deletion took: "
    +              << chrono::duration_cast<chrono::microseconds>(end - start).count()
    +              << " microseconds\n";
    +
    +    return 0;
    +}
    +
    +
    +
    +

    The following is example output from running the sample:

    +
    +
    +
    +
    All OK while creating directory
    +Directory creation took: 459 microseconds
    +File writing took: 631 microseconds
    +File content: Hello, Boost.Program_Options, Boost.Filesystem, and Boost.Chrono!
    +File reading took: 1385 microseconds
    +All OK while removing file
    +File deletion took: 339 microseconds
    +All OK while removing directory
    +Directory deletion took: 386 microseconds
    +
    +
    +
    +

    Adding timing features to your system operations will help you maintain more robust and performance-aware code, so as code is updated you will have built in the checks and balances so that if something goes awry - you will be able to capture and correct it early in the development cycle.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + + diff --git a/preview/user-guide/task-text-processing.html b/preview/user-guide/task-text-processing.html new file mode 100644 index 0000000..7fb53c3 --- /dev/null +++ b/preview/user-guide/task-text-processing.html @@ -0,0 +1,892 @@ + + + + + + + + + + + + + + Text Processing :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Text Processing

    +
    +
    +
    +

    Developing a word processor, or other text based app, involves handling text, GUI (Graphical User Interface), file operations, and possibly networking for cloud features. Boost does not provide a library for creating a GUI. You may want to consider using a library like Qt or wxWidgets for the GUI part of your word processor.

    +
    + +
    +
    +
    +

    Libraries

    +
    +
    +

    Here are some Boost libraries that might assist you in processing text:

    +
    +
    +
      +
    • +

      Boost.Regex: For some simpler parsing tasks, regular expressions can be sufficient and easier to use than full-blown parsing libraries. You could use these features to match specific patterns in your input text, like specific commands or phrases, word boundaries, etc.

      +
    • +
    • +

      Boost.Locale : This library provides a way of handling and manipulating text in a culturally-aware manner. It provides localization and internationalization facilities, allowing your word processor to be used by people with different languages and locales.

      +
    • +
    • +

      Boost.Spirit : This library is a parser framework that can parse complex data structures. If you’re creating a word processor, it could be useful to interpret different markup and file formats.

      +
    • +
    • +

      Boost.DateTime : If you need to timestamp changes or edits, or if you’re implementing any kind of version history feature, this library can help.

      +
    • +
    • +

      Boost.Filesystem : This library provides a way of manipulating files and directories. This would be critical in a word processor for opening, saving, and managing documents.

      +
    • +
    • +

      Boost.Asio : If your word processor has network-related features, such as real-time collaboration or cloud-based storage, Boost.Asio provides a consistent asynchronous model for network programming.

      +
    • +
    • +

      Boost.Serialization : This library provides a way of serializing and deserializing data, which could be useful for saving and loading documents in a specific format.

      +
    • +
    • +

      Boost.Xpressive : Could be useful for implementing features like search and replace, spell-checking, and more.

      +
    • +
    • +

      Boost.Algorithm : This library includes a variety of algorithms for string and sequence processing, which can be useful for handling text.

      +
    • +
    • +

      Boost.MultiIndex : This library provides a way of maintaining a set of items sorted according to multiple keys, which could be useful for implementing features like an index or a sorted list of items.

      +
    • +
    • +

      Boost.Thread : If your application is multithreaded (for example, if you want to save a document while the user continues to work), this library will be useful.

      +
      +
      +
      Note
      +
      +

      The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.

      +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    Sample of Regular Expression Parsing

    +
    +
    +

    If the text you are parsing is well-formatted then you can use Boost.Regex which we will base our sample on here, rather than a full-blown parser implementation using Boost.Spirit.

    +
    +
    +

    We’ll write a program that scans a string for dates in the format "YYYY-MM-DD" and validates them. The code:

    +
    +
    +
      +
    1. +

      Finds dates in text

      +
    2. +
    3. +

      Validates correct formats (for example, 2024-02-20 is valid, but 2024-15-45 is not)

      +
    4. +
    5. +

      Handles multiple dates in a single input string

      +
    6. +
    +
    +
    +
    +
    #include <iostream>
    +#include <boost/regex.hpp>
    +#include <boost/algorithm/string.hpp>
    +
    +// Function to check if a given date is valid (basic validation)
    +bool is_valid_date(int year, int month, int day) {
    +    if (month < 1 || month > 12 || day < 1 || day > 31) return false;
    +    if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) return false;
    +    if (month == 2) {
    +        bool leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    +        if (day > (leap ? 29 : 28)) return false;
    +    }
    +    return true;
    +}
    +
    +// Function to find and validate dates in a text
    +void find_dates(const std::string& text) {
    +
    +    // Regex pattern: YYYY-MM-DD format
    +    boost::regex date_pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    +    boost::smatch match;
    +    std::string::const_iterator start = text.begin();
    +    std::string::const_iterator end = text.end();
    +
    +    bool found = false;
    +    while (boost::regex_search(start, end, match, date_pattern)) {
    +        int year = std::stoi(match[1]);
    +        int month = std::stoi(match[2]);
    +        int day = std::stoi(match[3]);
    +
    +        if (is_valid_date(year, month, day)) {
    +            std::cout << "Valid date found: " << match[0] << "\n";
    +        } else {
    +            std::cout << "Invalid date: " << match[0] << " (Incorrect month/day)\n";
    +        }
    +
    +        start = match[0].second; // Move to next match
    +        found = true;
    +    }
    +
    +    if (!found) {
    +        std::cout << "No valid dates found in the input text.\n";
    +    }
    +}
    +
    +int main() {
    +    std::string input;
    +    std::cout << "Enter a sentence containing dates (YYYY-MM-DD format):\n";
    +    std::getline(std::cin, input);
    +
    +    find_dates(input);
    +    return 0;
    +}
    +
    +
    +
    +

    The following shows a successful parse:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +Today is 2024-02-19, and tomorrow is 2024-02-20.
    +Valid date found: 2024-02-19
    +Valid date found: 2024-02-20
    +
    +
    +
    +

    And the following shows several unsuccessful parses:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +The deadline is 2024-02-30.
    +Invalid date: 2024-02-30 (Incorrect month/day)
    +
    +Enter a sentence containing dates (YYYY-MM-DD format):
    +There are no dates in this sentence.
    +No valid dates found in the input text.
    +
    +
    +
    +
    +
    +

    Add Robust Date and Time Parsing

    +
    +
    +

    The clunky date validation in the sample above can be improved by integrating Boost.DateTime, which provides functions for handling dates and times correctly.

    +
    +
    +
    +
    #include <boost/regex.hpp>
    +#include <boost/date_time/gregorian/gregorian.hpp>
    +
    +namespace greg = boost::gregorian;
    +
    +// Function to check if a date is valid using Boost.Date_Time
    +bool is_valid_date(int year, int month, int day) {
    +    try {
    +        greg::date test_date(year, month, day);
    +        return true;  // If no exception, it's valid
    +    }
    +    catch (const std::exception& e) {
    +        return false; // Invalid date
    +    }
    +}
    +
    +// Function to find and validate dates in a text
    +void find_dates(const std::string& text) {
    +    boost::regex date_pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    +    boost::smatch match;
    +    std::string::const_iterator start = text.begin();
    +    std::string::const_iterator end = text.end();
    +
    +    bool found = false;
    +    while (boost::regex_search(start, end, match, date_pattern)) {
    +        int year = std::stoi(match[1]);
    +        int month = std::stoi(match[2]);
    +        int day = std::stoi(match[3]);
    +
    +        if (is_valid_date(year, month, day)) {
    +            greg::date valid_date(year, month, day);
    +            std::cout << "Valid date found: " << valid_date << "\n";
    +        }
    +        else {
    +            std::cout << "Invalid date: " << match[0] << " (Does not exist)\n";
    +        }
    +
    +        start = match[0].second; // Move to next match
    +        found = true;
    +    }
    +
    +    if (!found) {
    +        std::cout << "No valid dates found in the input text.\n";
    +    }
    +}
    +
    +int main() {
    +    std::string input;
    +    std::cout << "Enter a sentence containing dates (YYYY-MM-DD format):\n";
    +    std::getline(std::cin, input);
    +
    +    find_dates(input);
    +    return 0;
    +}
    +
    +
    +
    +
    +
    Note
    +
    +

    The code handles leap years correctly, and invalid dates throw an exception.

    +
    +
    +
    +
    +

    The following shows a successful parse:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +Today is 2024-02-29, and tomorrow is 2024-03-01.
    +Valid date found: 2024-Feb-29
    +Valid date found: 2024-Mar-01
    +
    +
    +
    +
    +
    Note
    +
    +

    The "Valid date found" output now includes text for the month name.

    +
    +
    +
    +
    +

    And the following shows several unsuccessful parses:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +The deadline is 2024-02-30.
    +Invalid date: 2024-02-30 (Does not exist)
    +
    +
    +Enter a sentence containing dates (YYYY-MM-DD format):
    +There are no dates in this sentence.
    +No valid dates found in the input text.
    +
    +
    +
    +
    +
    +

    Culturally Aware Date Formatting

    +
    +
    +

    Dates are not represented consistently across the globe. Let’s use Boost.Locale to format dates according to the user’s locale. For example:

    +
    +
    +
      +
    • +

      US: March 15, 2024

      +
    • +
    • +

      UK: 15 March, 2024

      +
    • +
    • +

      France: 15 mars 2024

      +
    • +
    • +

      Germany: 15. März 2024

      +
    • +
    +
    +
    +
    +
    #include <boost/regex.hpp>
    +#include <boost/date_time/gregorian/gregorian.hpp>
    +#include <boost/locale.hpp>
    +
    +namespace greg = boost::gregorian;
    +namespace loc = boost::locale;
    +
    +// Function to check if a date is valid using Boost.Date_Time
    +bool is_valid_date(int year, int month, int day) {
    +    try {
    +        greg::date test_date(year, month, day);
    +        return true;  // If no exception, it's valid
    +    }
    +    catch (const std::exception&) {
    +        return false; // Invalid date
    +    }
    +}
    +
    +// Function to format and display dates based on locale
    +void display_localized_date(const greg::date& date, const std::string& locale_name) {
    +    std::locale locale = loc::generator().generate(locale_name);
    +    std::cout.imbue(locale);  // Apply locale to std::cout
    +
    +    std::cout << locale_name << " formatted date: "
    +        << loc::as::date << date << "\n";
    +}
    +
    +// Function to find and validate dates in a text
    +void find_dates(const std::string& text, const std::string& locale_name) {
    +    boost::regex date_pattern(R"((\d{4})-(\d{2})-(\d{2}))");
    +    boost::smatch match;
    +    std::string::const_iterator start = text.begin();
    +    std::string::const_iterator end = text.end();
    +
    +    bool found = false;
    +    while (boost::regex_search(start, end, match, date_pattern)) {
    +        int year = std::stoi(match[1]);
    +        int month = std::stoi(match[2]);
    +        int day = std::stoi(match[3]);
    +
    +        if (is_valid_date(year, month, day)) {
    +            greg::date valid_date(year, month, day);
    +            std::cout << "Valid date found: " << valid_date << "\n";
    +            display_localized_date(valid_date, locale_name);
    +        }
    +        else {
    +            std::cout << "Invalid date: " << match[0] << " (Does not exist)\n";
    +        }
    +
    +        start = match[0].second; // Move to next match
    +        found = true;
    +    }
    +
    +    if (!found) {
    +        std::cout << "No valid dates found in the input text.\n";
    +    }
    +}
    +
    +int main() {
    +    std::locale::global(loc::generator().generate("en_US.UTF-8")); // Default global locale
    +    std::cout.imbue(std::locale());  // Apply to output stream
    +
    +    std::string input;
    +    std::cout << "Enter a sentence containing dates (YYYY-MM-DD format):\n";
    +    std::getline(std::cin, input);
    +
    +    std::string user_locale;
    +    std::cout << "Enter your preferred locale (e.g., en_US.UTF-8, fr_FR.UTF-8, de_DE.UTF-8): ";
    +    std::cin >> user_locale;
    +
    +    find_dates(input, user_locale);
    +    return 0;
    +}
    +
    +
    +
    +

    The following shows successful parses:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +The meeting is on 2024-03-15.
    +Enter your preferred locale (e.g., en_US.UTF-8, fr_FR.UTF-8, de_DE.UTF-8): en_US.UTF-8
    +Valid date found: 2024-Mar-15
    +en_US.UTF-8 formatted date: March 15, 2024
    +
    +Enter a sentence containing dates (YYYY-MM-DD format):
    +Rendez-vous le 2024-07-20.
    +Enter your preferred locale (e.g., en_US.UTF-8, fr_FR.UTF-8, de_DE.UTF-8): fr_FR.UTF-8
    +Valid date found: 2024-Jul-20
    +fr_FR.UTF-8 formatted date: 20 juillet 2024
    +
    +
    +
    +

    And the following shows an unsuccessful parse:

    +
    +
    +
    +
    Enter a sentence containing dates (YYYY-MM-DD format):
    +The deadline is 2024-02-30.
    +Enter your preferred locale (e.g., en_US.UTF-8, fr_FR.UTF-8, de_DE.UTF-8): en_US.UTF-8
    +Invalid date: 2024-02-30 (Does not exist)
    +
    +
    +
    +
    +
    +

    Local Time

    +
    +
    +

    On a similar global vein, when you install the Boost.DateTime library (or all the Boost libraries), a file containing definitions of time zones across the world is available for your use at: boost_<version>\\libs\\date_time\\data\\date_time_zonespec.csv.

    +
    +
    +

    The following short sample shows how to use the contents of the file. Enter a city and timezone in the IANA format (such as: 'Europe/Berlin' or 'Asia/Tokyo'), and the current date and time will be output.

    +
    +
    +
    +
    #include <boost/date_time/local_time/local_time.hpp>
    +
    +namespace pt = boost::posix_time;
    +namespace lt = boost::local_time;
    +
    +int main() {
    +    try {
    +
    +        //---------------------------------------------
    +        // Load the Boost tz_database from CSV
    +        //---------------------------------------------
    +        lt::tz_database tz_db;
    +        tz_db.load_from_file("<YOUR PATH>\\date_time_zonespec.csv"); // Adjust the path to your Boost installation
    +
    +        // Extract all valid timezone names
    +        std::vector<std::string> valid_timezones;
    +        for (const auto& tz_name : tz_db.region_list()) {
    +            valid_timezones.push_back(tz_name);
    +        }
    +
    +        std::string city;
    +        while (true) {
    +            std::cout << "\nEnter 'city/timezone' (or 'exit' to quit, or 'zones' for list of options): ";
    +            std::getline(std::cin, city);
    +            if (city == "exit") break;
    +
    +            if (city == "zones")
    +            {
    +                std::cout << "Available timezones:\n";
    +                for (const auto& tz : valid_timezones) {
    +                    std::cout << tz << "\n";
    +                }
    +
    +            }
    +            else
    +            {
    +
    +                // Find the timezone (case-sensitive, must match CSV)
    +                lt::time_zone_ptr tz = tz_db.time_zone_from_region(city);
    +                if (!tz) {
    +                    std::cout << "Invalid timezone! Try again.\n";
    +                    continue;
    +                }
    +
    +                // Get current UTC time
    +                pt::ptime utc_now = pt::second_clock::universal_time();
    +
    +                // Convert UTC to local time in the chosen timezone
    +                lt::local_date_time local_now(utc_now, tz);
    +
    +                // Get user's local machine time
    +                pt::ptime user_now = pt::second_clock::local_time();
    +
    +                std::cout << "\nYour local system time:   " << user_now << "\n";
    +
    +                std::cout << "Current local time in " << city << ": " << local_now << "\n";
    +            }
    +        }
    +    }
    +    catch (const std::exception& e) {
    +        std::cerr << "Fatal error: " << e.what() << "\n";
    +        return 1;
    +    }
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Run the program and test out a few options:

    +
    +
    +
    +
    Enter 'city/timezone' (or 'exit' to quit, or 'zones' for list of options): America/New_York
    +
    +Your local system time:   2025-Sep-03 16:38:02
    +Current local time in America/New_York: 2025-Sep-03 19:38:02 EDT
    +
    +Enter 'city/timezone' (or 'exit' to quit, or 'zones' for list of options): Antarctica/South_Pole
    +
    +Your local system time:   2025-Sep-03 16:38:20
    +Current local time in Antarctica/South_Pole: 2025-Sep-04 11:38:20 NZST
    +
    +Enter 'city/timezone' (or 'exit' to quit, or 'zones' for list of options): zones
    +Available timezones:
    +Africa/Abidjan
    +Africa/Accra
    +Africa/Addis_Ababa
    +Africa/Algiers
    +Africa/Asmara
    +Africa/Asmera
    +Africa/Bamako
    +Africa/Bangui
    +Africa/Banjul
    +Africa/Bissau
    +Africa/Blantyre
    +Africa/Brazzaville
    +Africa/Bujumbura
    +Africa/Cairo
    +Africa/Casablanca
    +Africa/Ceuta
    +Africa/Conakry
    +....
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    If more complex input is required, consider the Boost.Spirit approach to parsing, refer to Natural Language Processing.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/testing-debugging.html b/preview/user-guide/testing-debugging.html new file mode 100644 index 0000000..5c1ac57 --- /dev/null +++ b/preview/user-guide/testing-debugging.html @@ -0,0 +1,840 @@ + + + + + + + + + + + + + + Testing and Debugging :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Testing and Debugging

    +
    +
    +
    +

    Debugging code that uses Boost libraries follows the same general principles as debugging any other C++ code, but with the added assistance of test and logging specific libraries, and integration of these libraries into popular tools.

    +
    + +
    +
    +
    +

    Debugging Strategies

    +
    +
    +

    Here are some strategies to consider:

    +
    +
    +
      +
    1. +

      Understanding the Library: Familiarize yourself with the specific Boost libraries that you’re using. Boost is a large and diverse collection of libraries, and each library may have unique behaviors, requirements, or quirks. Understanding the libraries you’re using will help you spot issues more easily.

      +
    2. +
    3. +

      Read the Boost Library Documentation: Boost has extensive and well-maintained documentation. If you’re having trouble with a specific library or function, start by looking up its documentation.

      +
    4. +
    5. +

      Use a Debugger: Tools like gdb or lldb on Unix-like systems, or the Visual Studio debugger on Windows, can be incredibly useful. You can step through your code line by line, inspect variables at any point, and generally see exactly what your code is doing.

      +
    6. +
    7. +

      Compile Warnings and Errors: Boost code will often make extensive use of templates, and errors in template code can sometimes result in complex and confusing compiler error messages. When confronted with such a message, don’t panic. Start at the top and try to decipher what the compiler is telling you. Often, the first few lines of the error message will contain the key to understanding the problem.

      +
    8. +
    9. +

      Unit Testing: Boost provides a testing framework, Boost.Test, which you can use to write unit tests for your code. Writing tests can help you catch errors and regressions, and it can also help you understand your code better. Boost.Test is integrated and available when using Microsoft Visual Studio. Refer to the Using Boost.Test section below.

      +
    10. +
    11. +

      Logging and Debug Output: Sometimes, it can be useful to have your program output diagnostic information while it’s running. You can use std::cerr, std::clog, or a logging library to output information about your program’s state at key points.

      +
    12. +
    13. +

      Code Review: If you’re still stuck, consider asking a fellow developer to review your code. Sometimes, a fresh pair of eyes can spot issues that you might have missed.

      +
    14. +
    15. +

      Online Communities: If you’re still stuck after trying the above steps, you can ask for help online. The Boost developers community is large and generally very helpful. There are forums, mailing lists, and Stack Overflow where you can ask for help.

      +
    16. +
    +
    +
    +

    Remember, debugging is a skill that gets better with practice. The more you work with the Boost libraries, the more you’ll learn about their idiosyncrasies and the better you’ll become at debugging issues with them.

    +
    +
    +
    +
    +

    Other Libraries

    +
    +
    +

    Other libraries that might help you with testing and debugging include:

    +
    +
    +
      +
    • +

      Boost.Stacktrace: Stacktrace can be used to capture, store, and print sequences of function calls and their arguments. This can be a lifesaver when you need to debug complex code or post-mortem crashes.

      +
    • +
    • +

      Boost.Exception: This library enhances the error handling capabilities of C++. It enables attaching arbitrary data to exceptions, transporting of exceptions between threads, and more, thereby providing richer error information during debugging.

      +
    • +
    • +

      Boost.StaticAssert: Provides two macros, BOOST_STATIC_ASSERT and BOOST_STATIC_ASSERT_MSG, which can be used to perform assertions that are checked at compile time rather than at run time. These can be used to catch programming errors as early as possible.

      +
    • +
    • +

      Boost.Bind and Boost.Lambda: These libraries allow for the creation of small, unnamed function objects at the point where they are used. These can be useful in writing concise tests.

      +
    • +
    • +

      Boost.Mp11: A MetaProgramming Library, though not exclusively for testing or debugging, this library can be helpful in writing compile-time tests.

      +
    • +
    +
    +
    +
    +
    +

    Using Boost.Log

    +
    +
    +

    Logging can be a helpful part of debugging, so consider using Boost.Log, as it provides a flexible and customizable logging system. It allows you to log messages from different parts of your application to various targets (e.g., console, file, etc.) and with different severity levels or categories.

    +
    +
    +

    Here is a simple example of how you might use Log:

    +
    +
    +
    +
    #include <boost/log/trivial.hpp>
    +
    +int main(int, char*[])
    +{
    +    BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
    +    BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
    +    BOOST_LOG_TRIVIAL(info) << "An informational severity message";
    +    BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
    +    BOOST_LOG_TRIVIAL(error) << "An error severity message";
    +    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
    +
    +    return 0;
    +}
    +
    +
    +
    +

    Consider creating a Console app, and running the code:

    +
    +
    +
    +
    [2025-07-22 20:24:58.955105] [0x0000094c] [trace]   A trace severity message
    +[2025-07-22 20:24:58.970721] [0x0000094c] [debug]   A debug severity message
    +[2025-07-22 20:24:58.970721] [0x0000094c] [info]    An informational severity message
    +[2025-07-22 20:24:58.970721] [0x0000094c] [warning] A warning severity message
    +[2025-07-22 20:24:58.970721] [0x0000094c] [error]   An error severity message
    +[2025-07-22 20:24:58.970721] [0x0000094c] [fatal]   A fatal severity message
    +
    +
    +
    +

    BOOST_LOG_TRIVIAL is a macro that logs a message with a specified severity level.

    +
    +
    +

    Severity levels are provided for log messages that you can use to indicate the importance or urgency of different logs. In basic usage, these severity levels are represented by an enumeration type:

    +
    +
    +
    +
    namespace trivial = boost::log::trivial;
    +enum severity_level
    +{
    +    trace,
    +    debug,
    +    info,
    +    warning,
    +    error,
    +    fatal
    +};
    +
    +
    +
    +

    Each of these levels can be used to log messages of different importance:

    +
    +
    +
      +
    1. +

      trace: Very detailed logs, typically used for debugging complex issues.

      +
    2. +
    3. +

      debug: Detailed logs useful for development and debugging.

      +
    4. +
    5. +

      info: Information about the normal operation of the program.

      +
    6. +
    7. +

      warning: Indications of potential problems that are not immediate errors.

      +
    8. +
    9. +

      error: Error conditions that may still allow the program to continue running.

      +
    10. +
    11. +

      fatal: Severe errors that may prevent the program from continuing to run.

      +
    12. +
    +
    +
    +

    You can customize these levels to fit your app, and you can also filter logs based on their severity level. For example, in a production environment, you might ignore trace and debug logs and only record info, warning, error, and fatal logs.

    +
    +
    +

    Careful logging of events, not too much information and not to little, will tell a story:

    +
    +
    +
    +logging trace to fatal +
    +
    +
    +
    +
    +

    Using Boost.Test

    +
    +
    +

    Boost.Test is a robust, powerful library designed to facilitate writing unit tests in C++. It provides a framework for creating, managing, and running tests, enabling developers to ensure that their code functions as expected.

    +
    +
    +

    To start using the Test library, include its header in your test file:

    +
    +
    +
    +
    #define BOOST_TEST_MODULE MyTest
    +#include <boost/test/unit_test.hpp>
    +
    +
    +
    +

    The BOOST_TEST_MODULE macro creates a main function for your test executable, meaning you don’t need to write one yourself.

    +
    +
    +

    Boost.Test uses test cases for testing. A test case is a function that performs the test. You can define one using the BOOST_AUTO_TEST_CASE(<test_case_name>) macro. The macro parameter becomes the test case’s name. For example:

    +
    +
    +
    +
    BOOST_AUTO_TEST_CASE(MyTestCase) {
    +    BOOST_TEST(true); // A simple test that always passes
    +}
    +
    +
    +
    +

    The result we all want:

    +
    +
    +
    +
    *** No errors detected
    +
    +
    +
    +

    In this example, MyTestCase is a simple test case. The BOOST_TEST macro checks its argument and, if it’s false, reports an error.

    +
    +
    +

    Boost.Test provides a set of macros for different assertions:

    +
    +
    +
      +
    • +

      BOOST_TEST for basic testing.

      +
    • +
    • +

      BOOST_CHECK for non-critical conditions where the test continues even if the check fails.

      +
    • +
    • +

      BOOST_REQUIRE for critical conditions where the test is aborted if the condition fails.

      +
    • +
    +
    +
    +

    The suite feature is another strength. It allows you to group test cases, making your tests more organized and manageable. To create a suite, you can use the BOOST_AUTO_TEST_SUITE(suite_name) macro:

    +
    +
    +
    +
    BOOST_AUTO_TEST_SUITE(MyTestSuite)
    +
    +BOOST_AUTO_TEST_CASE(TestCase1) {
    +    // Test code here
    +}
    +
    +BOOST_AUTO_TEST_CASE(TestCase2) {
    +    // Test code here
    +}
    +
    +BOOST_AUTO_TEST_SUITE_END()
    +
    +
    +
    +

    In this snippet, MyTestSuite is a test suite that contains TestCase1 and TestCase2.

    +
    +
    +

    Another powerful feature is the fixture. Fixtures are useful when you want to perform setup and teardown operations for your tests. You can create a fixture class and use BOOST_FIXTURE_TEST_CASE to apply it to a test case:

    +
    +
    +
    +
    struct MyFixture {
    +    MyFixture() {
    +        // Setup code here
    +    }
    +
    +    ~MyFixture() {
    +        // Teardown code here
    +    }
    +};
    +
    +BOOST_FIXTURE_TEST_CASE(TestCaseWithFixture, MyFixture) {
    +    // Test code here
    +}
    +
    +
    +
    +

    In this example, MyFixture is a fixture class. Its constructor and destructor are called before and after TestCaseWithFixture, respectively.

    +
    +
    +

    Boost.Test also supports parameterized and data-driven tests, exception handling, and custom log formatting.

    +
    +
    +

    To compile and run your tests, use your preferred C++ compiler to compile the test source file and the Test library. Then, run the resulting executable to execute your tests.

    +
    +
    +
    +
    +

    Boost.Test Tutorial

    +
    +
    +

    This topic is a step-by-step tutorial on how to get going with the Boost.Test library. This is a very substantial library with lots of functions and documentation. It is valuable to understand the concept of adding tests to a simple program, before venturing further.

    +
    +
    +

    Let’s get started with a trivial example.

    +
    +
    +

    Trivial Example

    +
    +

    Here’s a simple example of a test suite with Boost.Test:

    +
    +
    +
      +
    1. +

      In Windows, perhaps use Visual Studio to create a C++ Console application. If not using Windows or Visual Studio, create a Console app, and add the paths to the Boost include and lib folders appropriately.

      +
      +

      If using Visual Studio, in the project Properties for C++/General, locate Additional Include Directories and add the path to your Boost libraries. The path will be something like C:\Users\<your path>\boost_1_88_0. Then, still in Properties, but now for Linker/General add to the Additional Library Directories with the path to your Boost lib folder. This path will be something like C:\Users\<your path>\lib.

      +
      +
    2. +
    3. +

      Replace any boilerplate code with:

      +
      +
      +
      #define BOOST_TEST_MODULE MyTestSuite
      +#include <boost/test/included/unit_test.hpp>
      +
      +BOOST_AUTO_TEST_CASE(MyTestCase)
      +{
      +    BOOST_CHECK(1 + 1 == 2);
      +}
      +
      +
      +
    4. +
    5. +

      There is no need for a main function, as it is automatically generated by #include <boost/test/included/unit_test.hpp> when BOOST_TEST_MODULE is defined.

      +
    6. +
    7. +

      Run the program. You should get:

      +
      +
      +
      Running 1 test case...
      +
      +*** No errors detected
      +
      +
      +
    8. +
    9. +

      Change the code to:

      +
      +
      +
      BOOST_AUTO_TEST_CASE(MyTestCase)
      +{
      +    BOOST_CHECK(1 + 1 == 3);
      +}
      +
      +
      +
    10. +
    11. +

      Run the program. Do you now get a red error message:

      +
      +
      +
      Running 1 test case...
      +... error: in "MyTestCase": check 1 + 1 == 3 has failed
      +
      +*** 1 failure is detected in the test module "MyTestSuite"
      +
      +
      +
    12. +
    +
    +
    +

    This trivial example shows the two kinds of messages we might get. Now let’s move onto something with a bit more substance.

    +
    +
    +
    +

    String Reversal Example

    +
    +
      +
    1. +

      Create a Console app as you did in the previous example, or simply reuse the project already created.

      +
    2. +
    3. +

      Replace any boilerplate or leftover code in the .cpp file with:

      +
      +
      +
      #include <iostream>
      +
      +std::string revString(std::string str)
      +{
      +    int n = (int) str.length();
      +
      +    for (int i = 0; i < n / 2; i++) {
      +        std::swap(str[i], str[n - i - 1]);
      +    }
      +    return str;
      +}
      +
      +int main(int argc, char* argv[])
      +{
      +    std::cout << revString("Reverse String Function") + "\n";
      +    std::cout << revString("Even") + "\n";
      +    std::cout << revString("Odd") + "\n";
      +}
      +
      +
      +
    4. +
    5. +

      Run the program, and ensure you get the three strings reversed appearing in a Console window:

      +
      +
      +rev string test +
      +
      +
    6. +
    7. +

      Good, now let’s see how you would add Boost.Test functions to this.

      +
    8. +
    9. +

      Comment out your main function, as it will be replaced with the Boost.Test main function, whilst the tests are running. It is wise not to delete your main function, as you will need it back when the testing is complete.

      +
    10. +
    11. +

      Your .cpp file should now look like this:

      +
      +
      +
      #define BOOST_TEST_MODULE mytests
      +#include <boost/test/included/unit_test.hpp>
      +#include <iostream>
      +
      +std::string revString(std::string str)
      +{
      +    int n = (int)str.length();
      +
      +    for (int i = 0; i < n / 2; i++) {
      +        std::swap(str[i], str[n - i - 1]);
      +    }
      +    return str;
      +}
      +
      +/*
      +int main(int argc, char* argv[])
      +{
      +    std::cout << revString("Reverse String Function") + "\n";
      +    std::cout << revString("Even") + "\n";
      +    std::cout << revString("Odd") + "\n";
      +}
      +*/
      +
      +BOOST_AUTO_TEST_CASE(check_revString) {
      +    BOOST_TEST(revString("abcd") == "dcba");
      +    BOOST_TEST(revString("12345") == "54321");
      +    BOOST_TEST(revString("Even") == "nevE");
      +
      +    // Add a failure case
      +    BOOST_TEST(revString("Odd") == "DDO");
      +}
      +
      +
      +
    12. +
    13. +

      Run the program. Do you get one error: check revString("Odd") == "DDO" has failed?

      +
    14. +
    15. +

      Correct the error by changing "DDO" to "ddO" in your code.

      +
    16. +
    17. +

      Run the program again. Do you now get *** No errors detected? If so great, the tests have worked.

      +
    18. +
    19. +

      Perhaps add test cases to the BOOST_AUTO_TEST_CASE function, to check the case of an empty string, and for a single character string:

      +
      +
      +
          BOOST_TEST(revString("a") == "a");
      +    BOOST_TEST(revString("") == "");
      +
      +
      +
    20. +
    21. +

      Add and test any other strings that come to mind.

      +
    22. +
    +
    +
    +
    +
    +
    +

    Next Steps

    +
    +
    +

    You can imagine now how you can add unit tests to your existing projects, checking the correct working of many of your functions.

    +
    +
    +

    And check out the full functionality of Boost.Test and Boost.Log.

    +
    +
    +
    + + + +
    +
    + +
    + + diff --git a/preview/user-guide/user-community-introduction.html b/preview/user-guide/user-community-introduction.html new file mode 100644 index 0000000..4691af6 --- /dev/null +++ b/preview/user-guide/user-community-introduction.html @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + Introduction to the User Community :: Boost Site Docs + + + + + + + + + + + + + + + + + + +
    +
    +
    + +

    Introduction to the User Community

    +
    +
    +
    +

    The user community is a vibrant and collaborative group dedicated to the use, development, and maintenance of Boost Libraries. Since its inception, Boost has grown to offer a wide range of libraries that address knarly programming tasks, from algorithms and data structures to system utilities and concurrent programming. Boost users are encouraged to chime in with their thoughts and experiences!

    +
    +
    +
    +
    +

    Reporting Issues

    +
    +
    +

    Users are encouraged to be active in Reporting Issues they encounter with Boost libraries. Users can submit issues directly, providing detailed descriptions, code snippets, and steps to reproduce the problem. This collaboration greatly aids the overall stability and reliability of Boost libraries.

    +
    +
    +
    +
    +

    Boost Mailing Lists

    +
    +
    +

    Communication within the Boost community is primarily conducted through mailing lists. The Boost Users Mailing List is a forum to ask questions, share experiences, and seeking advice. Participation in the mailing lists is open to all.

    +
    +
    +

    Discussion Policy

    +
    +

    Boost maintains a clear and respectful Discussion Policy to ensure productive and courteous interactions within the community. Participants are expected to engage in constructive dialogue, refrain from personal attacks, and respect differing viewpoints.

    +
    +
    +
    +
    +
    +

    Boost Software License

    +
    +
    +

    The Boost Software License (BSL) is a free, open-source license that permits users to use, modify, and distribute Boost libraries with minimal restrictions. The BSL is designed to be compatible with both open-source and proprietary projects.

    +
    +
    +
    +
    +

    Long History

    +
    +
    +

    Boost’s long History is a testament to its enduring relevance and impact. Since its founding in 1998 by the late Beman Dawes, David Abrahams, and Robert Klarer, Boost has been an incubator for cutting-edge C++ techniques and practices.

    +
    +
    +

    Over the years, Boost has grown to include dozens of libraries, each developed and maintained by dedicated contributors from around the world. The libraries are continually updated both to remedy issues and add new features, refer to Release Process for the process and cadence of new releases.

    +
    +
    +
    +
    +

    See Also

    + +
    + + +
    +
    + +
    + +