Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
13 changes: 2 additions & 11 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,12 @@ jobs:
run: "npm install -g @go-task/cli"

- if: "'macos-14' == matrix.os"
name: "Install macOS 14 deps: coreutils (for md5sum) and Apple Clang 16 (for C++20)"
name: "Install macOS 14 deps: coreutils (for md5sum) and LLVM Clang 15 (for Velox)"
run: |-
brew install coreutils
brew install llvm@16
brew install llvm@15

- name: "Run unit tests and examples"
env: >-
${{
'macos-14' == matrix.os
&& fromJson('{
"CC": "/opt/homebrew/opt/llvm@16/bin/clang",
"CXX": "/opt/homebrew/opt/llvm@16/bin/clang++"
}')
|| fromJson('{}')
}}
# Currently unit tests rely on cassert and fail to compile in release mode.
run: |-
task test:run-debug
Expand Down
28 changes: 7 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
cmake_minimum_required(VERSION 3.23)

# Toolchain setup must come before the first project() call in the entire CMake buildsystem.
# If ystdlib is not the top-level project, the following setup has no effect.
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/utils.cmake")
setup_toolchains()

project(ystdlib VERSION "0.1.0" LANGUAGES CXX)

validate_compiler_versions()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
Expand All @@ -10,27 +17,6 @@ include(ystdlib-helpers)
option(BUILD_SHARED_LIBS "Build using shared libraries." OFF)
option(ystdlib_BUILD_TESTING "Build the testing tree for ystdlib." ON)

# Require compiler versions that support the C++20 features necessary for compiling ystdlib
if("AppleClang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "16")
elseif("Clang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "16")
elseif("GNU" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION "11")
else()
message(
FATAL_ERROR
"Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}. Please use AppleClang, Clang, or GNU."
)
endif()
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "${ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION}")
message(
FATAL_ERROR
"${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION} is too low. Must be at \
least ${ystdlib_CMAKE_CXX_COMPILER_MIN_VERSION}."
)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS
ON
CACHE BOOL
Expand Down
21 changes: 21 additions & 0 deletions cmake/Toolchains/llvm-clang-15-toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
message(STATUS "Setting up LLVM v15 toolchain...")

execute_process(
COMMAND
"brew" "--prefix" "llvm@15"
RESULT_VARIABLE BREW_RESULT
OUTPUT_VARIABLE LLVM_TOOLCHAIN_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT 0 EQUAL BREW_RESULT)
message(
FATAL_ERROR
"Failed to locate LLVM v15 using Homebrew. Please ensure llvm@15 is installed: 'brew \
install llvm@15'"
)
endif()

set(CMAKE_C_COMPILER "${LLVM_TOOLCHAIN_PREFIX}/bin/clang")
set(CMAKE_CXX_COMPILER "${LLVM_TOOLCHAIN_PREFIX}/bin/clang++")
set(CMAKE_AR "${LLVM_TOOLCHAIN_PREFIX}/bin/llvm-ar")
set(CMAKE_RANLIB "${LLVM_TOOLCHAIN_PREFIX}/bin/llvm-ranlib")
49 changes: 49 additions & 0 deletions cmake/Toolchains/utils.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This file contains utility functions for setting up toolchains and validating toolchain versions
# to ensure compatibility with the C++20 features required by the project.

# Sets up the appropriate toolchain file based on the host system.
function(setup_toolchains)
# For macOS versions below 15, use the LLVM 15 Clang toolchain.
if("Darwin" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}")
execute_process(
COMMAND
"sw_vers" "--productVersion"
OUTPUT_VARIABLE MACOS_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if("${MACOS_VERSION}" VERSION_LESS "15")
set(CMAKE_TOOLCHAIN_FILE
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Toolchains/llvm-clang-15-toolchain.cmake"
CACHE STRING
"Toolchain file"
)
endif()
endif()
endfunction()

# Checks if the compiler ID and version meet the minimum requirements to support C++20 features
# required by the project:
# - AppleClang: version 15+
# - Clang: version 15+
# - GNU: version 11+
function(validate_compiler_versions)
if("AppleClang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(CXX_COMPILER_MIN_VERSION "15")
elseif("Clang" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(CXX_COMPILER_MIN_VERSION "15")
elseif("GNU" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
set(CXX_COMPILER_MIN_VERSION "11")
else()
message(
FATAL_ERROR
"Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}. Please use AppleClang, Clang, or GNU."
)
endif()
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "${CXX_COMPILER_MIN_VERSION}")
message(
FATAL_ERROR
"${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION} is too low. Must be at \
least ${CXX_COMPILER_MIN_VERSION}."
)
endif()
endfunction()
2 changes: 1 addition & 1 deletion cmake/ystdlib-helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function(add_cpp_library)
)
endfunction()

# Adds a C++ 20 test executable named `unit-test-NAME` that will be built with `SOURCES` and linked
# Adds a C++20 test executable named `unit-test-NAME` that will be built with `SOURCES` and linked
# with `LINK_LIBRARIES`, in addition to Catch2.
#
# @param {string} NAME
Expand Down
2 changes: 1 addition & 1 deletion src/ystdlib/containers/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Array {
// NOLINTNEXTLINE(*-avoid-c-arrays)
: m_data{std::make_unique<T[]>(list.size())},
m_size{list.size()} {
std::ranges::copy(list, m_data.get());
std::copy(list.begin(), list.end(), m_data.get());
}

// Disable copy constructor and assignment operator
Expand Down
39 changes: 24 additions & 15 deletions src/ystdlib/containers/test/test_Array.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <algorithm>
#include <concepts>
#include <cstddef>
#include <ranges>
#include <stdexcept>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -66,9 +65,12 @@ void test_list_initialization_in_function_call(
ystdlib::containers::Array<PolymorphicConstructors> const& arr,
std::vector<size_t> const& data
) {
REQUIRE(std::ranges::equal(
arr | std::views::transform([](auto const& obj) { return obj.get_value(); }),
data
REQUIRE(std::equal(
arr.begin(),
arr.end(),
data.begin(),
data.end(),
[](auto const& obj, size_t v) { return obj.get_value() == v; }
));
}
} // namespace
Expand All @@ -88,7 +90,7 @@ TEST_CASE("test_array_reference", "[containers][Array]") {
arr.at(idx) = idx;
}
auto const& arr_const_ref = arr;
REQUIRE(std::ranges::equal(arr, arr_const_ref));
REQUIRE(std::equal(arr.begin(), arr.end(), arr_const_ref.begin(), arr_const_ref.end()));
}

TEST_CASE("test_array_ranged_copy", "[containers][Array]") {
Expand All @@ -97,8 +99,8 @@ TEST_CASE("test_array_ranged_copy", "[containers][Array]") {
vec.push_back(idx);
}
Array<size_t> arr(cBufferSize);
std::ranges::copy(vec, arr.begin());
REQUIRE(std::ranges::equal(vec, arr));
std::copy(vec.begin(), vec.end(), arr.begin());
REQUIRE(std::equal(vec.cbegin(), vec.cend(), arr.begin(), arr.end()));
}

TEST_CASE("test_array_movable", "[containers][Array]") {
Expand All @@ -109,7 +111,12 @@ TEST_CASE("test_array_movable", "[containers][Array]") {
reference_array.at(idx) = idx;
}
auto const arr_moved{std::move(arr)};
REQUIRE(std::ranges::equal(reference_array, arr_moved));
REQUIRE(std::equal(
reference_array.begin(),
reference_array.end(),
arr_moved.begin(),
arr_moved.end()
));
}

TEST_CASE("test_array_illegal_access", "[containers][Array]") {
Expand Down Expand Up @@ -143,8 +150,8 @@ TEMPLATE_TEST_CASE(
) {
REQUIRE(std::is_fundamental_v<TestType>);
Array<TestType> arr(cBufferSize);
std::ranges::for_each(arr, [](auto const& p) -> void {
REQUIRE((static_cast<TestType>(0) == p));
std::for_each(arr.begin(), arr.end(), [](auto const& p) {
REQUIRE(static_cast<TestType>(0) == p);
});
}

Expand All @@ -158,7 +165,7 @@ TEST_CASE("test_array_list_initialization", "[containers][Array]") {
vec{"yscope", "clp", "ystdlib", "ystdlib::containers::Array", "default_initializable"};
Array<std::string> const
arr{"yscope", "clp", "ystdlib", "ystdlib::containers::Array", "default_initializable"};
REQUIRE(std::ranges::equal(vec, arr));
REQUIRE(std::equal(vec.cbegin(), vec.cend(), arr.begin(), arr.end()));

// Test polymorphic list initialization
REQUIRE(std::is_copy_constructible_v<PolymorphicConstructors>);
Expand All @@ -174,10 +181,12 @@ TEST_CASE("test_array_list_initialization", "[containers][Array]") {
cTestNum0,
std::string{cTestStr},
ExplicitConstructor{cTestNum1}};
REQUIRE(std::ranges::equal(
list_init_arr
| std::views::transform([](auto const& obj) { return obj.get_value(); }),
data
REQUIRE(std::equal(
list_init_arr.begin(),
list_init_arr.end(),
data.cbegin(),
data.cend(),
[](auto const& obj, auto const& v) { return obj.get_value() == v; }
));
}

Expand Down
2 changes: 0 additions & 2 deletions src/ystdlib/error_handling/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ add_cpp_library(
NAMESPACE ystdlib
PUBLIC_HEADERS
ErrorCode.hpp
TraceableException.hpp
Result.hpp
utils.hpp
PUBLIC_LINK_LIBRARIES
Expand All @@ -30,7 +29,6 @@ if(ystdlib_ENABLE_TESTS)
SOURCES
test/test_ErrorCode.cpp
test/test_Result.cpp
test/test_TraceableException.cpp
test/types.cpp
UNIFIED_TEST_TARGET "${UNIFIED_UNIT_TEST_TARGET}"
)
Expand Down
78 changes: 0 additions & 78 deletions src/ystdlib/error_handling/TraceableException.hpp

This file was deleted.

19 changes: 13 additions & 6 deletions src/ystdlib/error_handling/test/test_ErrorCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,18 @@ TEST_CASE("test_error_code", "[error_handling][ErrorCode]") {

TEST_CASE("test_error_code_failure_condition", "[error_handling][ErrorCode]") {
std::error_code const failure_error_code{BinaryErrorCode{BinaryErrorCodeEnum::Failure}};
std::ranges::for_each(cFailureConditions, [&](auto const& failure_condition) {
REQUIRE((failure_error_code == failure_condition));
});
std::ranges::for_each(cNoneFailureConditions, [&](auto const& none_failure_condition) {
REQUIRE((failure_error_code != none_failure_condition));
});
std::for_each(
cFailureConditions.cbegin(),
cFailureConditions.cend(),
[&](auto const& failure_condition) { REQUIRE(failure_error_code == failure_condition); }
);

std::for_each(
cNoneFailureConditions.cbegin(),
cNoneFailureConditions.cend(),
[&](auto const& none_failure_condition) {
REQUIRE(failure_error_code != none_failure_condition);
}
);
}
} // namespace ystdlib::error_handling::test
Loading
Loading