Skip to content

feat: Replace outcome with Boost's version of outcome to remove dependence on quickcpplib. #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ if(BUILD_TESTING AND YSTDLIB_CPP_BUILD_TESTING)
set(YSTDLIB_CPP_ENABLE_TESTS ON)
endif()

find_package(outcome REQUIRED)
if(outcome_FOUND)
message(STATUS "Found outcome.")
find_package(Boost REQUIRED)
if(Boost_FOUND)
message(STATUS "Found Boost ${Boost_VERSION}.")
else()
message(FATAL_ERROR "Could not find libraries for outcome.")
message(STATUS "Could not find libraries for Boost.")
endif()

if(YSTDLIB_CPP_ENABLE_TESTS)
Expand Down
2 changes: 1 addition & 1 deletion src/ystdlib/error_handling/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cpp_library(
Result.hpp
utils.hpp
PUBLIC_LINK_LIBRARIES
outcome::hl
Boost::headers
TESTS_SOURCES
test/constants.hpp
test/test_ErrorCode.cpp
Expand Down
35 changes: 9 additions & 26 deletions src/ystdlib/error_handling/Result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

#include <system_error>

#include <outcome/config.hpp>
#include <outcome/std_result.hpp>
#include <outcome/success_failure.hpp>
#include <outcome/try.hpp>
#include <boost/outcome/config.hpp>
#include <boost/outcome/std_result.hpp>
#include <boost/outcome/success_failure.hpp>
#include <boost/outcome/try.hpp>

namespace ystdlib::error_handling {
/**
Expand All @@ -20,34 +20,16 @@ namespace ystdlib::error_handling {
* @tparam ErrorType The type used to represent errors.
*/
template <typename ReturnType, typename ErrorType = std::error_code>
using Result = OUTCOME_V2_NAMESPACE::std_result<ReturnType, ErrorType>;
using Result = BOOST_OUTCOME_V2_NAMESPACE::std_result<ReturnType, ErrorType>;

/**
* @return A value indicating successful completion of a function that returns a void result (i.e.,
* `Result<void, E>`).
*/
[[nodiscard]] inline auto success() -> OUTCOME_V2_NAMESPACE::success_type<void> {
return OUTCOME_V2_NAMESPACE::success();
[[nodiscard]] inline auto success() -> BOOST_OUTCOME_V2_NAMESPACE::success_type<void> {
return BOOST_OUTCOME_V2_NAMESPACE::success();
}

/**
* A function-style macro that emulates Rust’s try (`?`) operator for error propagation.
*
* @param expr An expression that evaluates to a `Result` object.
*
* Behavior:
* - If `expr` represents an error (i.e., `expr.has_error()` returns true), the macro performs an
* early return from the enclosing function with the contained error.
* - Otherwise, it unwraps and yields the successful value as an rvalue reference (`expr.value()`).
*
* NOTE: This macro is only supported on GCC and Clang due to reliance on compiler-specific
* extensions.
*/
#ifdef OUTCOME_TRYX
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define YSTDLIB_ERROR_HANDLING_TRYX(expr) OUTCOME_TRYX(expr)
#endif

/**
* A function-style macro for propagating errors from expressions that evaluate to a void result
* (`Result<void, E>`).
Expand All @@ -60,7 +42,8 @@ using Result = OUTCOME_V2_NAMESPACE::std_result<ReturnType, ErrorType>;
* - Otherwise, execution continues normally.
*/
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define YSTDLIB_ERROR_HANDLING_TRYV(expr) OUTCOME_TRYV(expr)
#define YSTDLIB_ERROR_HANDLING_TRYV(expr) BOOST_OUTCOME_TRYV(expr)
#define YSTDLIB_ERROR_HANDLING_TRY(val, expr) BOOST_OUTCOME_TRY(auto&& val, expr)
} // namespace ystdlib::error_handling

#endif // YSTDLIB_ERROR_HANDLING_RESULT_HPP
6 changes: 4 additions & 2 deletions src/ystdlib/error_handling/test/test_Result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ TEST_CASE("test_result_int_in_main", "[error_handling][Result]") {

TEST_CASE("test_result_int_propagate", "[error_handling][Result]") {
auto main_func = [&](bool is_error) -> Result<int> {
return YSTDLIB_ERROR_HANDLING_TRYX(cIntFunc(is_error));
YSTDLIB_ERROR_HANDLING_TRY(value, cIntFunc(is_error));
return value;
};
auto const main_no_error{main_func(false)};
REQUIRE_FALSE(main_no_error.has_error());
Expand Down Expand Up @@ -126,7 +127,8 @@ TEST_CASE("test_result_unique_ptr_in_main", "[error_handling][Result]") {

TEST_CASE("test_result_unique_ptr_propagate", "[error_handling][Result]") {
auto main_func = [&](bool is_error) -> Result<std::unique_ptr<int>> {
return YSTDLIB_ERROR_HANDLING_TRYX(cUniquePtrFunc(is_error));
YSTDLIB_ERROR_HANDLING_TRY(value, cUniquePtrFunc(is_error));
return value;
};
auto const main_no_error{main_func(false)};
REQUIRE_FALSE(main_no_error.has_error());
Expand Down
2 changes: 1 addition & 1 deletion taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ includes:
build: "./taskfiles/build.yaml"
deps: "./taskfiles/deps.yaml"
lint: "./taskfiles/lint.yaml"
utils: "tools/yscope-dev-utils/taskfiles/utils.yaml"
utils: "tools/yscope-dev-utils/exports/taskfiles/utils/utils.yaml"

vars:
G_BUILD_DIR: "{{.ROOT_DIR}}/build"
Expand Down
8 changes: 4 additions & 4 deletions taskfiles/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ tasks:
deps:
- "init"
cmds:
- task: ":utils:cmake-build"
- task: ":utils:cmake:build"
vars:
BUILD_DIR: "{{.G_BUILD_DIR}}"

Expand All @@ -21,7 +21,7 @@ tasks:
deps:
- "init"
cmds:
- task: ":utils:cmake-build"
- task: ":utils:cmake:build"
vars:
BUILD_DIR: "{{.G_BUILD_DIR}}"
TARGETS:
Expand Down Expand Up @@ -49,7 +49,7 @@ tasks:
clean:
desc: "Removes all built artifacts."
deps:
- task: ":utils:cmake-clean"
- task: ":utils:cmake:clean"
vars:
BUILD_DIR: "{{.G_BUILD_DIR}}"

Expand All @@ -59,7 +59,7 @@ tasks:
- ":deps:install-all"
run: "once"
cmds:
- task: ":utils:cmake-generate"
- task: ":utils:cmake:generate"
vars:
BUILD_DIR: "{{.G_BUILD_DIR}}"
SOURCE_DIR: "{{.ROOT_DIR}}"
209 changes: 172 additions & 37 deletions taskfiles/deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ version: "3"
vars:
G_CATCH2_LIB_NAME: "Catch2"
G_CATCH2_WORK_DIR: "{{.G_DEPS_DIR}}/{{.G_CATCH2_LIB_NAME}}"
G_OUTCOME_LIB_NAME: "outcome"
G_OUTCOME_WORK_DIR: "{{.G_DEPS_DIR}}/{{.G_OUTCOME_LIB_NAME}}"
G_QUICKCPPLIB_LIB_NAME: "quickcpplib"
G_QUICKCPPLIB_WORK_DIR: "{{.G_DEPS_DIR}}/{{.G_QUICKCPPLIB_LIB_NAME}}"

Expand All @@ -26,8 +24,8 @@ tasks:
install-all-run:
internal: true
deps:
- "install-boost"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Integrate Boost into parallel dependency installation
The PR correctly adds install-boost to the install-all-parallel workflow, replacing the removed standalone Outcome tasks. Ensure downstream CI/CMake configurations pick up this new dependency. For consistency, you may alphabetize the deps list.

🤖 Prompt for AI Agents
In taskfiles/deps.yaml at line 23, add "install-boost" to the
install-all-parallel dependency list to integrate Boost installation into the
parallel workflow. After adding, alphabetize the entire deps list for
consistency. Also, verify that downstream CI and CMake configurations are
updated to recognize and use this new Boost dependency.

- "install-Catch2"
- "install-outcome"

install-all-finish:
internal: true
Expand Down Expand Up @@ -58,53 +56,190 @@ tasks:
internal: true
run: "once"
cmds:
- task: ":utils:cmake-install-remote-tar"
- task: ":utils:cmake:install-remote-tar"
vars:
NAME: "{{.G_CATCH2_LIB_NAME}}"
CMAKE_PACKAGE_NAME: "{{.G_CATCH2_LIB_NAME}}"
WORK_DIR: "{{.G_CATCH2_WORK_DIR}}"
FILE_SHA256: "1ab2de20460d4641553addfdfe6acd4109d871d5531f8f519a52ea4926303087"
URL: "https://github.com/catchorg/Catch2/archive/refs/tags/v3.8.0.tar.gz"
TAR_SHA256: "1ab2de20460d4641553addfdfe6acd4109d871d5531f8f519a52ea4926303087"
TAR_URL: "https://github.com/catchorg/Catch2/archive/refs/tags/v3.8.0.tar.gz"
- task: "add-package-root-to-cmake-settings"
vars:
NAME: "{{.G_CATCH2_LIB_NAME}}"
INSTALL_PREFIX: "{{.G_CATCH2_WORK_DIR}}/{{.G_CATCH2_LIB_NAME}}-install"

install-outcome:
install-boost:
internal: true
run: "once"
deps:
- "install-quickcpplib"
cmds:
- task: ":utils:cmake-install-remote-tar"
vars:
NAME: "{{.G_OUTCOME_LIB_NAME}}"
WORK_DIR: "{{.G_OUTCOME_WORK_DIR}}"
FILE_SHA256: "0382248cbb00806ce4b5f3ce6939797dc3b597c85fd3531614959e31ef488b39"
URL: "https://github.com/ned14/outcome/archive/refs/tags/v2.2.11.tar.gz"
GEN_ARGS:
- "-C {{.G_DEPS_CMAKE_SETTINGS_DIR}}/{{.G_QUICKCPPLIB_LIB_NAME}}.cmake"
- "-DBUILD_TESTING=OFF"
- "-DCMAKE_BUILD_TYPE=Release"
- "-DCMAKE_POLICY_DEFAULT_CMP0074=NEW"
- task: "add-package-root-to-cmake-settings"
- task: "boost-download-and-install"
vars:
NAME: "{{.G_OUTCOME_LIB_NAME}}"
INSTALL_PREFIX: "{{.G_OUTCOME_WORK_DIR}}/{{.G_OUTCOME_LIB_NAME}}-install"
WORK_DIR: "{{.G_DEPS_DIR}}/boost"
FILE_SHA256: "2128a4c96862b5c0970c1e34d76b1d57e4a1016b80df85ad39667f30b1deba26"
URL: "https://github.com/boostorg/boost/releases/download/boost-1.86.0/\
boost-1.86.0-b2-nodocs.tar.gz"
CMAKE_SETTINGS_DIR: "{{.G_DEPS_CMAKE_SETTINGS_DIR}}"
TARGETS:
- "filesystem"
- "iostreams"
- "process"
- "program_options"
- "regex"
- "system"

install-quickcpplib:
# Runs the bootstrap.sh generate step in the given source directory. Boost only supports
# in-source generation and building.
#
# @param {string} SOURCE_DIR Project source directory.
# @param {string} INSTALL_PREFIX Path prefix of where the project should be installed.
# @param {string[]} TARGETS Target libraries to build.
# @param {string[]} [EXTRA_ARGS] Any additional arguments to pass to the generate command.
boost-generate:
internal: true
run: "once"
dir: "{{.SOURCE_DIR}}"
cmds:
- >-
./bootstrap.sh
--prefix="{{.INSTALL_PREFIX}}"
--exec-prefix="{{.INSTALL_PREFIX}}"
--with-libraries={{(join "," .TARGETS)}}
{{- range .EXTRA_ARGS}}
"{{.}}"
{{- end}}

# Runs the b2 build step for boost. The caller must have previously called `generate` on
# `SOURCE_DIR` for this task to succeed.
#
# @param {string} SOURCE_DIR Directory containing the boost source.
# @param {string[]} [EXTRA_ARGS] Any additional arguments to pass to the build command.
# @param {int} [JOBS] The maximum number of concurrent processes to use when building. If
# omitted, the b2 default number is used. Before 1.76.0, the number was 1. Since 1.76.0, the
# default is the number of cores.
boost-build:
internal: true
dir: "{{.SOURCE_DIR}}"
cmds:
- >-
./b2
{{- range .EXTRA_ARGS}}
"{{.}}"
{{- end}}
{{- if .JOBS}}
"-j{{.JOBS}}"
{{- end}}

# Runs the b2 install step for boost. The caller must have previously called `build` on
# `SOURCE_DIR` for this task to succeed. If `CMAKE_SETTINGS_DIR` is set, a settings file will be
# created in that directory, containing a `boost_ROOT` CMake variable that points to
# `INSTALL_PREFIX`.
#
# @param {string} SOURCE_DIR Directory containing the boost source.
# @param {string} INSTALL_PREFIX Path prefix of where the project should be installed.
# @param {string} [CMAKE_SETTINGS_DIR] If set, the directory where the project's CMake settings
# file should be stored.
# @param {string[]} [EXTRA_ARGS] Any additional arguments to pass to the install command.
boost-install:
internal: true
dir: "{{.SOURCE_DIR}}"
cmds:
- task: ":utils:cmake-install-remote-tar"
- >-
./b2
install
{{- range .EXTRA_ARGS}}
"{{.}}"
{{- end}}
- >-
{{- if .CMAKE_SETTINGS_DIR}}
echo "set(BOOST_ROOT
\"{{.INSTALL_PREFIX}}\"
CACHE PATH
\"Package root for boost.\"
)" >> "{{.CMAKE_SETTINGS_DIR}}/boost.cmake"
{{- end}}

# Downloads boost from `URL` and installs boost.
#
# General parameters
# @param {string} [WORK_DIR={{.TASK_DIR}}] Base directory to store the install and src
# directories inside.
# @param {string} [SOURCE_DIR={{.WORK_DIR}}/boost-src] Directory in which to extract the tar
# file.
#
# Download parameters
# @param {string} FILE_SHA256 Content hash to verify the downloaded tar file against.
# @param {string} URL
#
# Boost generate parameters
# @param {string} [INSTALL_PREFIX={{.WORK_DIR}}/boost-install] Path prefix of where the project
# should be installed.
# @param {string[]} TARGETS Target libraries to build.
# @param {string[]} [GEN_ARGS] Any additional arguments to pass to the generate command.
#
# Boost build parameters
# @param {int} [JOBS] The maximum number of concurrent processes to use when building. If
# omitted, the b2 default number is used. Before 1.76.0, the number was 1. Since 1.76.0, the
# default is the number of cores.
# @param {string[]} [BUILD_ARGS] Any additional arguments to pass to the build command.
#
# Boost install parameters
# @param {string[]} [INSTALL_ARGS] Any additional arguments to pass to the install command.
# @param {string} [CMAKE_SETTINGS_DIR] If set, the directory where the project's CMake settings
# file should be stored.
boost-download-and-install:
internal: true
label: "{{.TASK}}:{{.URL}}-{{.INSTALL_PREFIX}}"
vars:
# General parameters
WORK_DIR: >-
{{default .ROOT_DIR .WORK_DIR}}
SOURCE_DIR: >-
{{default (printf "%s/boost-src" .WORK_DIR) .SOURCE_DIR}}

# Boost generate parameters
INSTALL_PREFIX: >-
{{default (printf "%s/boost-install" .WORK_DIR) .INSTALL_PREFIX}}
TARGETS:
ref: "default (list) .TARGETS"
GEN_ARGS:
ref: "default (list) .GEN_ARGS"

# Boost build parameters
BUILD_ARGS:
ref: "default (list) .BUILD_ARGS"
JOBS: >-
{{default "" .JOBS}}

# Boost install parameters
INSTALL_ARGS:
ref: "default (list) .INSTALL_ARGS"
CMAKE_SETTINGS_DIR: >-
{{default "" .CMAKE_SETTINGS_DIR}}
requires:
vars: ["FILE_SHA256", "URL"]
deps:
- task: ":utils:remote:download-and-extract-tar"
vars:
NAME: "{{.G_QUICKCPPLIB_LIB_NAME}}"
WORK_DIR: "{{.G_QUICKCPPLIB_WORK_DIR}}"
FILE_SHA256: "5d4c9b2d6fa177d3fb14f3fe3086867e43b44f4a7a944eb10ee4616b2b0f3c05"
URL: "https://github.com/ned14/quickcpplib/archive/f3e452e.tar.gz"
GEN_ARGS:
- "-DBUILD_TESTING=OFF"
- "-DCMAKE_BUILD_TYPE=Release"
- task: "add-package-root-to-cmake-settings"
FILE_SHA256: "{{.FILE_SHA256}}"
OUTPUT_DIR: "{{.SOURCE_DIR}}"
URL: "{{.URL}}"
cmds:
- task: "boost-generate"
vars:
SOURCE_DIR: "{{.SOURCE_DIR}}"
INSTALL_PREFIX: "{{.INSTALL_PREFIX}}"
TARGETS:
ref: ".TARGETS"
EXTRA_ARGS:
ref: ".GEN_ARGS"
- task: "boost-build"
vars:
SOURCE_DIR: "{{.SOURCE_DIR}}"
JOBS: "{{.JOBS}}"
EXTRA_ARGS:
ref: ".BUILD_ARGS"
- task: "boost-install"
vars:
NAME: "{{.G_QUICKCPPLIB_LIB_NAME}}"
INSTALL_PREFIX: "{{.G_QUICKCPPLIB_WORK_DIR}}/{{.G_QUICKCPPLIB_LIB_NAME}}-install"
SOURCE_DIR: "{{.SOURCE_DIR}}"
INSTALL_PREFIX: "{{.INSTALL_PREFIX}}"
CMAKE_SETTINGS_DIR: "{{.CMAKE_SETTINGS_DIR}}"
EXTRA_ARGS:
ref: ".INSTALL_ARGS"
Loading
Loading