<feed xmlns='http://www.w3.org/2005/Atom'>
<title>catch3, branch build/cpp17</title>
<subtitle>Progmasoft Catch3: an independently maintained C++17 test framework with a parallel runner, property checks, snapshots and structured results.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/'/>
<entry>
<title>Finish the move to C++17 in POSIX code and the amalgamated files</title>
<updated>2026-10-31T10:36:43+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-31T10:36:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=afe91797e9d50cd4712d3694a2e5fedfc0b966b1'/>
<id>afe91797e9d50cd4712d3694a2e5fedfc0b966b1</id>
<content type='text'>
A lambda in the POSIX half of Process.cpp captured a structured binding,
which needs C++20 and which a Windows build never compiles. The files in
extras still held the C++20 sources, so they are generated again, and the
generator no longer says the runner needs C++20.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A lambda in the POSIX half of Process.cpp captured a structured binding,
which needs C++20 and which a Windows build never compiles. The files in
extras still held the C++20 sources, so they are generated again, and the
generator no longer says the runner needs C++20.
</pre>
</div>
</content>
</entry>
<entry>
<title>Format the sources for C++17</title>
<updated>2026-10-31T10:01:18+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-31T10:01:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=653dde1cc5a2f17faec2ed25f904de9c3cf3c8fa'/>
<id>653dde1cc5a2f17faec2ed25f904de9c3cf3c8fa</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Build Catch3 as C++17</title>
<updated>2026-10-31T10:00:24+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-31T10:00:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=8814bd0b796b2e291fa5b4a1033f0313c8a26065'/>
<id>8814bd0b796b2e291fa5b4a1033f0313c8a26065</id>
<content type='text'>
C++17 is still the widest common target, and a library built on it stays
usable from C++17 and every later standard, while C++20 would have left
out many users.

Concepts become enable_if on named traits in Detail/TypeTraits.hpp, which
also replaces std::remove_cvref_t and std::identity. std::span becomes
std::vector references, std::bit_cast becomes static_cast and memcpy,
template lambdas become helper templates, and std::erase_if, contains,
starts_with and ends_with have their C++17 forms. Random::Between no
longer uses a lambda over a constexpr local, which MSVC rejects outside
/permissive-, so the headers work under its default mode too.

Tests give up designated initializers, which MSVC refuses in C++17. CI
builds the matrix in C++17 and C++20, since the headers promise both.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
C++17 is still the widest common target, and a library built on it stays
usable from C++17 and every later standard, while C++20 would have left
out many users.

Concepts become enable_if on named traits in Detail/TypeTraits.hpp, which
also replaces std::remove_cvref_t and std::identity. std::span becomes
std::vector references, std::bit_cast becomes static_cast and memcpy,
template lambdas become helper templates, and std::erase_if, contains,
starts_with and ends_with have their C++17 forms. Random::Between no
longer uses a lambda over a constexpr local, which MSVC rejects outside
/permissive-, so the headers work under its default mode too.

Tests give up designated initializers, which MSVC refuses in C++17. CI
builds the matrix in C++17 and C++20, since the headers promise both.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #21 from Progmasoft/ci/narrow-macos</title>
<updated>2026-10-30T07:03:25+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-30T07:03:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=6a42cdf6461b2577106ef094d6f98025554b6077'/>
<id>6a42cdf6461b2577106ef094d6f98025554b6077</id>
<content type='text'>
Give macOS one CI job and stop building pull requests twice</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Give macOS one CI job and stop building pull requests twice</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'devel' into ci/narrow-macos</title>
<updated>2026-10-29T21:07:08+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-29T21:07:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=5d713685c54bb491ad1bbb0fd8f80318bfaf7103'/>
<id>5d713685c54bb491ad1bbb0fd8f80318bfaf7103</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #20 from Progmasoft/feature/catch3-json</title>
<updated>2026-10-29T21:06:27+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-29T21:06:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=471756b77331fa1ab77bc94e6aae228baef903e0'/>
<id>471756b77331fa1ab77bc94e6aae228baef903e0</id>
<content type='text'>
Read the options of a project from catch3.json</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Read the options of a project from catch3.json</pre>
</div>
</content>
</entry>
<entry>
<title>Give macOS one CI job and stop building pull requests twice</title>
<updated>2026-10-29T17:03:06+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-29T17:03:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=db9f14bb7f38425e6005ae2212d83f01f9f2f8be'/>
<id>db9f14bb7f38425e6005ae2212d83f01f9f2f8be</id>
<content type='text'>
macOS runners are the bottleneck of Progmasoft's CI: an organization
runs at most five macOS jobs at a time, shared by every repository, and a
pull request of Catch3 asked for about twenty of them. Every workflow
also listened to both push and pull_request, so each pull request ran
everything twice, once for its branch and once for the pull request.

macOS now has one job, as in the Tala compiler: macOS 26 on Apple
Silicon, Debug, C++17, with AddressSanitizer and UndefinedBehaviorSanitizer
over the most-tests preset, examples and extra tests. The C++14 and C++17,
Debug and Release matrix stays on Ubuntu and Fedora, where it already ran.
ThreadSanitizer, which ran only on macOS, moves to a new Ubuntu job.

The build systems that tested Windows and macOS (Bazel, Meson, Xmake,
Premake) test Windows and Ubuntu instead, with Clang, so their Unix side
is still covered and Linux is covered for the first time. The jobs that do
not depend on the platform leave macOS: CodeQL (build mode none), the
header and license checks, and native coverage, which now builds with
the Clang and LLVM tools of Ubuntu instead of those of Xcode.

Pushes build only devel; pull requests build their branches. The weekly
CodeQL schedule stays.

The required check "Bazel on macos-15" becomes "Bazel on ubuntu-26.04" in
the branch protection and the ruleset when this is merged.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
macOS runners are the bottleneck of Progmasoft's CI: an organization
runs at most five macOS jobs at a time, shared by every repository, and a
pull request of Catch3 asked for about twenty of them. Every workflow
also listened to both push and pull_request, so each pull request ran
everything twice, once for its branch and once for the pull request.

macOS now has one job, as in the Tala compiler: macOS 26 on Apple
Silicon, Debug, C++17, with AddressSanitizer and UndefinedBehaviorSanitizer
over the most-tests preset, examples and extra tests. The C++14 and C++17,
Debug and Release matrix stays on Ubuntu and Fedora, where it already ran.
ThreadSanitizer, which ran only on macOS, moves to a new Ubuntu job.

The build systems that tested Windows and macOS (Bazel, Meson, Xmake,
Premake) test Windows and Ubuntu instead, with Clang, so their Unix side
is still covered and Linux is covered for the first time. The jobs that do
not depend on the platform leave macOS: CodeQL (build mode none), the
header and license checks, and native coverage, which now builds with
the Clang and LLVM tools of Ubuntu instead of those of Xcode.

Pushes build only devel; pull requests build their branches. The weekly
CodeQL schedule stays.

The required check "Bazel on macos-15" becomes "Bazel on ubuntu-26.04" in
the branch protection and the ruleset when this is merged.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Compare whole numbers in catch3.json without floating-point equality</title>
<updated>2026-10-29T16:30:46+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-29T16:30:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=0b4b57a0688f2943f4c797c20d68d533cf70fd15'/>
<id>0b4b57a0688f2943f4c797c20d68d533cf70fd15</id>
<content type='text'>
Clang's -Wfloat-equal, an error in the development builds, rejected the
version check, which compared the JSON number with 1.0 by ==. The version
is now read through the same whole-number check as the counts and
compared as an integer, and that check asks whether the number exceeds
its floor instead of comparing the two for equality. The test of the
confidence interval compares within 1e-12. The amalgamated source is
regenerated.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Clang's -Wfloat-equal, an error in the development builds, rejected the
version check, which compared the JSON number with 1.0 by ==. The version
is now read through the same whole-number check as the counts and
compared as an integer, and that check asks whether the number exceeds
its floor instead of comparing the two for equality. The test of the
confidence interval compares within 1e-12. The amalgamated source is
regenerated.
</pre>
</div>
</content>
</entry>
<entry>
<title>Read the options of a project from catch3.json</title>
<updated>2026-10-29T16:22:21+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-10-29T16:22:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=f41a9c3c01b4df1100e24a63987716cb4dbf28f2'/>
<id>f41a9c3c01b4df1100e24a63987716cb4dbf28f2</id>
<content type='text'>
A project can now keep the options it always wants in a catch3.json
instead of repeating them in every CTest, Bazel or CI command line.

Where it is found: the runner looks in the working directory and in each
directory above it, up to the root of the Git repository that holds the
working directory, and reads the nearest file. Outside a repository it
looks only in the working directory, so a stray file in a home directory
never applies. --config=FILE names a file instead (relative to the
working directory) and --no-config reads none; the last of the two wins.
Workers, --help and --version read no file, so a broken file never stands
in the way of help, and workers keep taking everything from their runner.

What it says: strict JSON with "version": 1 required and "$schema"
allowed for editors. The keys are the long options of the command line,
and each value becomes the arguments it stands for and goes through the
same parser, so there is one set of checks and one set of messages; the
file and the key are named in front of them. Values are typed: switches
take true (false for the negated adaptive-timeout and bisect), counts
take whole numbers, timeout and the confidence interval take numbers,
retries and seed take a number or a word, tests and warn take arrays,
verbosity takes quiet, normal or verbose, and history takes a path or
false. Paths are relative to the directory of the file. An unknown key is
an error with a suggestion when it is close to a known one; a key that
names an option for one run (shard, section, list, replay, ...) is told
that it belongs on the command line. Repeated keys are refused.

Precedence: the file's options are applied first and the command line on
top, so the command line wins; test specs on the command line replace the
file's tests instead of widening them with "or". --verbose names the file
that was read.

Options gains --config and --no-config, a ParseOptions overload that
starts from given options, and a public EditDistance for the suggestions.
The new ProjectConfig module holds the search, the key table and
ParseCommandLine, which Runner now calls in place of ParseOptions.

Tests cover the search (nearest file, the repository boundary, outside a
repository), every key, words and defaults, relative and absolute paths,
the messages for wrong files, precedence, --config, --no-config and the
modes that read no file. A fuzzer reads arbitrary file text and checks
that the worker arguments of the result parse again. The command line
reference, the runner guide and the release notes describe the file; the
amalgamated sources are regenerated.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A project can now keep the options it always wants in a catch3.json
instead of repeating them in every CTest, Bazel or CI command line.

Where it is found: the runner looks in the working directory and in each
directory above it, up to the root of the Git repository that holds the
working directory, and reads the nearest file. Outside a repository it
looks only in the working directory, so a stray file in a home directory
never applies. --config=FILE names a file instead (relative to the
working directory) and --no-config reads none; the last of the two wins.
Workers, --help and --version read no file, so a broken file never stands
in the way of help, and workers keep taking everything from their runner.

What it says: strict JSON with "version": 1 required and "$schema"
allowed for editors. The keys are the long options of the command line,
and each value becomes the arguments it stands for and goes through the
same parser, so there is one set of checks and one set of messages; the
file and the key are named in front of them. Values are typed: switches
take true (false for the negated adaptive-timeout and bisect), counts
take whole numbers, timeout and the confidence interval take numbers,
retries and seed take a number or a word, tests and warn take arrays,
verbosity takes quiet, normal or verbose, and history takes a path or
false. Paths are relative to the directory of the file. An unknown key is
an error with a suggestion when it is close to a known one; a key that
names an option for one run (shard, section, list, replay, ...) is told
that it belongs on the command line. Repeated keys are refused.

Precedence: the file's options are applied first and the command line on
top, so the command line wins; test specs on the command line replace the
file's tests instead of widening them with "or". --verbose names the file
that was read.

Options gains --config and --no-config, a ParseOptions overload that
starts from given options, and a public EditDistance for the suggestions.
The new ProjectConfig module holds the search, the key table and
ParseCommandLine, which Runner now calls in place of ParseOptions.

Tests cover the search (nearest file, the repository boundary, outside a
repository), every key, words and defaults, relative and absolute paths,
the messages for wrong files, precedence, --config, --no-config and the
modes that read no file. A fuzzer reads arbitrary file text and checks
that the worker arguments of the result parse again. The command line
reference, the runner guide and the release notes describe the file; the
amalgamated sources are regenerated.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #19 from Progmasoft/feature/yyjson-pugixml</title>
<updated>2026-10-29T09:18:33+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-10-29T09:18:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/catch3/commit/?id=1d48419b7ef642917ebf7dfd16c3bc1b3050d8f1'/>
<id>1d48419b7ef642917ebf7dfd16c3bc1b3050d8f1</id>
<content type='text'>
Read and write JSON with yyjson and JUnit XML with pugixml</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Read and write JSON with yyjson and JUnit XML with pugixml</pre>
</div>
</content>
</entry>
</feed>
