Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
618ff9b
Update include guard to new path
Bronek Jan 18, 2025
acdd08e
Add dummy expected with tests
Bronek Jan 18, 2025
721f026
Add some basic polyfills with C++20 tests
Bronek Jan 19, 2025
1090cb4
Add pfn tests to coverage reporting
Bronek Jan 19, 2025
d784fbd
Add C++20 tests to workflow
Bronek Jan 19, 2025
f94cb5f
Add phony target cxx20, simplify TargetGenerator.cmake
Bronek Jan 20, 2025
7fe3819
Separate phony cxx20 and cxx23
Bronek Jan 25, 2025
b595920
Add --target all to build workflow
Bronek Jan 25, 2025
89f3e45
Add pfn::unexpected, needs unit tests
Bronek Jan 25, 2025
57291ca
Unit tests for unexpected in progress
Bronek Jan 27, 2025
11c1278
More unit tests for unexpected
Bronek Feb 1, 2025
ce22bd1
Trying more compilers
Bronek Feb 1, 2025
e5ebfc1
Fold nixOS into build.yaml, refactor build
Bronek Feb 2, 2025
8a40b92
Workaround for appleclang build error
Bronek Feb 2, 2025
4ef3afd
Improve unit tests coverage
Bronek Feb 2, 2025
7222f55
Compilation options cleanup
Bronek Feb 8, 2025
261b8ed
Remove static state from test helper
Bronek Mar 2, 2025
fda668f
More expected implementation and unit tests
Bronek Mar 1, 2025
20cb71d
Workarounds for older compilers
Bronek Mar 9, 2025
309dece
Add !is_same_v<remove_cvref_t<U>, unexpect_t>
Bronek Mar 9, 2025
db4ee11
Merge branch 'main' into expected_polyfill
Bronek Mar 10, 2025
6f09902
Merge branch 'main' into expected_polyfill
Bronek Mar 12, 2025
ffe4243
Add continue_on_err and LIBFN_MODE
Bronek Mar 14, 2025
5c46dcf
Add unit tests
Bronek Mar 14, 2025
eed6b4f
Add -fsanitize=address -fno-omit-frame-pointer to Debug build
Bronek Mar 16, 2025
405eeb9
Improve coverage reporting
Bronek Apr 5, 2025
b265c74
Add constructors from unexpected
Bronek Apr 17, 2025
9218685
Implemented assignment operators
Bronek Apr 18, 2025
1c612b0
Merge branch 'main' into expected_polyfill
Bronek Apr 18, 2025
cdb1d5b
Minor cleanup
Bronek Apr 21, 2025
cb48cac
Implement emplace
Bronek Apr 21, 2025
81c17aa
Merge branch 'main' into expected_polyfill
Bronek May 24, 2025
8067a2e
Add appleclang 15
Bronek May 24, 2025
9fafd09
Implement swap
Bronek May 24, 2025
2969a19
Merge branch 'main' into expected_polyfill
Bronek May 26, 2025
dd9fb03
Accessor unit tests
Bronek May 26, 2025
4500820
Implement value_or and error_or
Bronek May 26, 2025
c4dc291
Add empty LIBFN_ASSERT
Bronek May 26, 2025
acef61e
Add monadic functions
Bronek May 26, 2025
278f76e
Merge branch 'main' into expected_polyfill
Bronek Jun 7, 2025
b253914
More unit tests
Bronek Jun 13, 2025
16660ae
Add unit tests for equality
Bronek Jul 5, 2025
da0c3f4
Validate expected unit tests against std::expected in C++23 mode
Bronek Jul 20, 2025
ee5158d
Add expected<void, ...> with complete unit tests
Bronek Jul 6, 2025
fad06aa
Merge branch 'main' into expected_polyfill
Bronek Jul 20, 2025
3bf4228
Decouple test validation from C++23 mode
Bronek Jul 20, 2025
aae61bc
Remove TODO because done
Bronek Jul 20, 2025
ce92e34
Remove redundant tests
Bronek Jul 20, 2025
1f88e4d
Add missing tests
Bronek Jul 20, 2025
1538b07
Workarounds for MSVC errors
Bronek Jul 20, 2025
afdb9dc
Replace workflow modes with matrix.exclude
Bronek Jul 26, 2025
e1840f6
Remove noexcept(...) from expected::~expected()
Bronek Sep 14, 2025
0e11c86
Minor
Bronek Sep 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 162 additions & 35 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ on:
- 'tests/**'
- 'CMakeLists.txt'
- 'cmake/**'
- 'nix/**'
- 'flake.nix'
- 'flake.lock'
pull_request:
branches:
- main
Expand All @@ -19,66 +22,190 @@ on:
- 'tests/**'
- 'CMakeLists.txt'
- 'cmake/**'
- 'nix/**'
- 'flake.nix'
- 'flake.lock'

jobs:
build-linux:
linux:
runs-on:
group: runners-arm64
strategy:
fail-fast: false
matrix:
mode:
- cxx20
- cxx23
configuration:
- Debug
- Release
- Debug
- Release
compiler:
- gcc:13
- gcc:14
- gcc:15
- clang:18
- clang:19
- clang:20
- "gcc:12"
- "clang:16"
- "clang:17"
- "gcc:13"
- "gcc:14"
- "gcc:15"
- "clang:18"
- "clang:19"
- "clang:20"
exclude:
- mode: cxx23
compiler: "gcc:12"
- mode: cxx23
compiler: "clang:16"
- mode: cxx23
compiler: "clang:17"
container: libfn/ci-build-${{ matrix.compiler }}
steps:
- uses: actions/checkout@v4

- name: Verify compiler compatibility
env:
SOURCE: |
#include <optional>
#include <expected>
#include <cstdio>
int main() {
using type1=std::expected<int, const char*>;
using type2=std::optional<int>;
return type1{1}.and_then([](int i) -> type1 { std::puts("OK expected"); return {i-1}; }).value()
+ type2{2}.and_then([](int i) -> type2 { std::puts("OK optional"); return {i-2}; }).value();
}
- name: Prepare build
run: |
printf "CXX=%s\nCXXFLAGS=%s\n" "$CXX" "$CXXFLAGS"
$CXX --version | head -1
FILE=$(mktemp --tmpdir XXXXXX.cpp)
printf "$SOURCE\n" > $FILE
OUT=$(mktemp --tmpdir XXXXXX)
$CXX -std=c++2b $CXXFLAGS -Wall $FILE -o $OUT
$OUT
mkdir .build
cd .build
cmake -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} ..
COMPILER=$( grep -iE "^CMAKE_CXX_COMPILER:FILEPATH=" CMakeCache.txt | sed -n 's/^[^=]*=//p' )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS(_${{ matrix.configuration }})?:STRING" CMakeCache.txt | sed -n 's/^[^=]*=//p' | tr '\n' ' ' )
printf "C++ compiler path: %s\n" "$COMPILER"
"$COMPILER" --version
printf "C++ compilation options: %s\n" "$FLAGS"

- name: Build and test ${{ matrix.mode }}
run: |
cd .build
cmake --build . --target ${{ matrix.mode }}
ctest -L ${{ matrix.mode }} --output-on-failure

# Build and test all for one arbitrary configuration
- name: Build and test all
if: ${{ matrix.compiler == 'gcc:14' && matrix.mode == 'cxx23' }}
run: |
cd .build
cmake --build . --target clean
cmake --build .
ctest --output-on-failure

macos:
runs-on: macos-${{ matrix.osver }}
strategy:
fail-fast: false
matrix:
mode:
- cxx20
- cxx23
configuration:
- Debug
- Release
compiler:
- appleclang
- clang
osver:
- 14
- 15
clangrelease:
- NA
- 18
exclude:
- compiler: clang
osver: 14
- compiler: clang
clangrelease: NA
- compiler: appleclang
clangrelease: 18
- mode: cxx23
compiler: appleclang
osver: 14
steps:
- uses: actions/checkout@v4

- name: Prepare build
run: |
mkdir .build
cd .build
if [[ "${{ matrix.compiler }}" == "appleclang" ]]; then
export CXX="$(which clang++)"
export CC="$(which clang)"
fi
if [[ "${{ matrix.compiler }}" == "clang" ]]; then
export CXX="$(brew --prefix llvm@${{ matrix.clangrelease }})/bin/clang++"
export CC="$(brew --prefix llvm@${{ matrix.clangrelease }})/bin/clang"
fi
cmake -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} ..
COMPILER=$( grep -E "^CMAKE_CXX_COMPILER:FILEPATH=" CMakeCache.txt | sed -e "s|^[^=]*=||" )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS:STRING=" CMakeCache.txt | sed -e "s|^[^=]*=||" )
printf "C++ compiler: %s\n" "$COMPILER"
printf "C++ compiler version: %s\n" "$( $COMPILER --version | head -1 )"
COMPILER=$( grep -iE "^CMAKE_CXX_COMPILER:FILEPATH=" CMakeCache.txt | sed -n 's/^[^=]*=//p' )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS(_${{ matrix.configuration }})?:STRING" CMakeCache.txt | sed -n 's/^[^=]*=//p' | tr '\n' ' ' )
printf "C++ compiler path: %s\n" "$COMPILER"
"$COMPILER" --version
printf "C++ compilation options: %s\n" "$FLAGS"

- name: Build all
- name: Build and test ${{ matrix.mode }}
run: |
cd .build
cmake --build . --target all
cmake --build . --target ${{ matrix.mode }}
ctest -L ${{ matrix.mode }} --output-on-failure

- name: Run tests
# Build and test all for one arbitrary configuration
- name: Build and test all
if: ${{ matrix.compiler == 'appleclang' && matrix.osver == '15' && matrix.mode == 'cxx23' }}
run: |
cd .build
cmake --build . --target clean
cmake --build .
ctest --output-on-failure

windows:
runs-on: windows-${{ matrix.osver }}
strategy:
fail-fast: false
matrix:
mode:
- cxx20
configuration:
- Debug
- Release
compiler:
- "Visual Studio 17 2022"
osver:
- 2025
steps:
- uses: actions/checkout@v4

- name: Prepare build
shell: bash
run: |
mkdir .build
cd .build
cmake -G "${{ matrix.compiler }}" -A x64 ..
LINKER=$( grep -iE "^CMAKE_LINKER:FILEPATH=" CMakeCache.txt | sed -n 's/^[^=]*=//p' )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS(_${{ matrix.configuration }})?:STRING" CMakeCache.txt | sed -n 's/^[^=]*=//p' | tr '\n' ' ' )
printf "C++ linker path: %s\n" "$LINKER"
"$LINKER" . || true
printf "C++ compilation options: %s\n" "$FLAGS"

- name: Build and test ${{ matrix.mode }}
shell: bash
run: |
cd .build
cmake --build . --target ${{ matrix.mode }} --config ${{ matrix.configuration }}
ctest -L ${{ matrix.mode }} -C ${{ matrix.configuration }} --output-on-failure

nixos:
runs-on:
group: runners-intel
strategy:
fail-fast: false
matrix:
compiler:
- gcc
- clang
steps:
- uses: actions/checkout@v4

- name: Install Nix
uses: cachix/install-nix-action@v30
with:
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}

- name: Build and test
run: nix -L build '.#${{matrix.compiler}}'
11 changes: 5 additions & 6 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,19 @@ jobs:
mkdir .build
cd .build
cmake -DCMAKE_C_FLAGS="$COVERAGE_OPTS" -DCMAKE_CXX_FLAGS="$COVERAGE_OPTS" ..
COMPILER=$( grep -E "^CMAKE_CXX_COMPILER:FILEPATH=" CMakeCache.txt | sed -e "s|^[^=]*=||" )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS:STRING=" CMakeCache.txt | sed -e "s|^[^=]*=||" )
printf "C++ compiler: %s\n" "$COMPILER"
printf "C++ compiler version: %s\n" "$( $COMPILER --version | head -1 )"
COMPILER=$( grep -iE "^CMAKE_CXX_COMPILER:FILEPATH=" CMakeCache.txt | sed -n 's/^[^=]*=//p' )
FLAGS=$( grep -iE "^CMAKE_CXX_FLAGS(_${{ matrix.configuration }})?:STRING" CMakeCache.txt | sed -n 's/^[^=]*=//p' | tr '\n' ' ' )
printf "C++ compiler path: %s\n" "$COMPILER"
$COMPILER --version
printf "C++ compilation options: %s\n" "$FLAGS"
printf "gcov version: %s\n" "$( $GCOV --version | head -1 )"
[[ "$( realpath $CXX )" == "$( realpath $COMPILER )" ]] || exit 13

- name: Run coverage target
shell: bash
run: |
cd .build
cmake --build .
ctest -L tests_fn -j1 # generate .gcda files
ctest -L 'tests_p?fn' -j1 # generate .gcda files
$GCOV -pbc -r -s $( realpath .. ) $( find tests -type f -name '*.gcno' ) # generate .gcov files

- name: Upload .gcov files
Expand Down
53 changes: 0 additions & 53 deletions .github/workflows/nix.yml

This file was deleted.

12 changes: 3 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,11 @@ endif()
include(Ccache)

set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(
-stdlib=libc++
)
add_link_options(
-lc++
)
endif()
# Phony targets for all supported C++ versions
add_custom_target(cxx20)
add_custom_target(cxx23)

add_subdirectory(include)

Expand Down
60 changes: 60 additions & 0 deletions cmake/CompilationOptions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Add compilation options appropriate for the current compiler

# Note, we do not select libc++ like an example below. Instead the user should
# use the CXXFLAGS environment variable for this option.
#
# if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND (NOT APPLE))
# add_compile_options(-stdlib=libc++)
# add_link_options(-lc++)
# endif()


function(append_compilation_options)
set(options WARNINGS OPTIMIZATION INTERFACE)
set(Options_NAME ${ARGV0})
cmake_parse_arguments(Options "${options}" "" "" ${ARGN})

if(NOT DEFINED Options_NAME)
message(FATAL_ERROR "NAME must be set")
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if(Options_WARNINGS)
# disable C4456: declaration of 'b' hides previous local declaration
# disable C4244: 'initializing': conversion from '_Ty' to '_Ty', possible loss of data
# disable C4101: 'e': unreferenced local variable
target_compile_options(${Options_NAME} PRIVATE /W4 /wd4456 /wd4244 /wd4101 )
endif()

if(Options_OPTIMIZATION)
target_compile_options(${Options_NAME} PRIVATE $<IF:$<CONFIG:Debug>,/Od,/Ox>)
endif()

if(Options_INTERFACE)
target_compile_options(${Options_NAME} INTERFACE /Za /permissive-)
# This will disable `unexpected` in global namespace from eh.h
target_compile_definitions(${Options_NAME} INTERFACE _HAS_CXX23)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang")
if(Options_WARNINGS)
target_compile_options(${Options_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror -Wno-redundant-move)
endif()

if(Options_OPTIMIZATION)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(${Options_NAME} PRIVATE -O0 -fsanitize=address -static-libasan -fno-omit-frame-pointer)
target_link_options(${Options_NAME} PRIVATE -fsanitize=address)
else()
target_compile_options(${Options_NAME} PRIVATE $<IF:$<CONFIG:Debug>,-O0 -fno-omit-frame-pointer,-O2>)
endif()
endif()

if(Options_INTERFACE)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(${Options_NAME} INTERFACE -Wno-non-template-friend)
endif()

target_compile_options(${Options_NAME} INTERFACE -Wno-missing-braces)
endif()
endif()
endfunction()
Loading