diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f96812..6d8f578 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,14 @@ jobs: build: unit build_type: Debug + - name: "Unit clang19 (libc++) c++23" + cxx: "clang++-19" + cc: "clang-19" + pkg: "clang-19 libc++-19-dev libc++abi-19-dev libc++1-19 libc++abi1-19" + cxx_flags: "-std=c++23 -stdlib=libc++" + build: unit + build_type: Debug + - name: "Unit gcc11 Release" cxx: "g++-11" cc: "gcc-11" @@ -127,6 +135,7 @@ jobs: run: | sudo apt-add-repository --no-update --yes "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main" sudo apt-add-repository --no-update --yes "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" + sudo apt-add-repository --no-update --yes "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main" wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - - name: Configure APT diff --git a/CHANGELOG.md b/CHANGELOG.md index 105c3b9..93b5af4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## unreleased +## [0.20.0] - 2025-08-03 + +First release. "Full C++20 equivalence." ### Progress implementing std::views::X equivalents diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6f7407e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required (VERSION 3.12) + +project (radr LANGUAGES CXX + DESCRIPTION "Range Adaptors Reimagined (radr)." + HOMEPAGE_URL "https://github.com/h-2/radr") + +message(STATUS "Loading the RADR library and implicitly calling find_package.") +find_package (radr REQUIRED HINTS ${CMAKE_CURRENT_LIST_DIR}/cmake) +message(STATUS "Add radr::radr to your program's target_link_libraries.") + +message(STATUS "ATTENTION: Including the project root only includes the library.") +message(STATUS "ATTENTION: To build unit tests, benchmarks or other utilitites, directly cmake one of the directories in tests/ .") diff --git a/cmake/radr-config.cmake b/cmake/radr-config.cmake new file mode 100644 index 0000000..e1ed5f7 --- /dev/null +++ b/cmake/radr-config.cmake @@ -0,0 +1,8 @@ +cmake_minimum_required (VERSION 3.12) + +find_path (RADR_CLONE_DIR NAMES cmake/radr-config.cmake HINTS "${CMAKE_CURRENT_LIST_DIR}/..") +find_path (RADR_INCLUDE_DIR NAMES radr/version.hpp HINTS "${RADR_CLONE_DIR}/include") + +add_library (radr_radr INTERFACE) +target_include_directories (radr_radr INTERFACE "${RADR_INCLUDE_DIR}") +add_library (radr::radr ALIAS radr_radr) diff --git a/include/radr/custom/tags.hpp b/include/radr/custom/tags.hpp index eed3829..94cd483 100644 --- a/include/radr/custom/tags.hpp +++ b/include/radr/custom/tags.hpp @@ -11,6 +11,8 @@ #pragma once +#include "radr/version.hpp" + namespace radr::custom { diff --git a/include/radr/detail/detail.hpp b/include/radr/detail/detail.hpp index f1eb560..c9bb5bd 100644 --- a/include/radr/detail/detail.hpp +++ b/include/radr/detail/detail.hpp @@ -16,6 +16,7 @@ #include #include +#include "../version.hpp" #include "bind_back.hpp" #include "fwd.hpp" diff --git a/include/radr/version.hpp b/include/radr/version.hpp new file mode 100644 index 0000000..460f046 --- /dev/null +++ b/include/radr/version.hpp @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2023-2025 Hannes Hauswedell +// +// Licensed under the Apache License v2.0 with LLVM Exceptions. +// See the LICENSE file for details. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include // makes _LIBCPP_VERSION available +#include // makes __GLIBCXX__ available + +// ============================================================================ +// C++ standard and features +// ============================================================================ + +// C++ standard [required] +#ifdef __cplusplus +static_assert(__cplusplus >= 201709, "RADR requires C++20 or later, make sure that you have set -std=c++20."); +#else +# error "This is not a C++ compiler." +#endif + +#if __has_include() +# include +#endif + +// ============================================================================ +// Compilers +// ============================================================================ + +#if !(defined(__clang_major__) && (__clang_major__ >= 16)) && !(defined(__GNUC__) && (__GNUC__ >= 11)) +# pragma GCC warning "Only Clang >= 16 and GCC >= 11 are officially supported." +#endif + +// ============================================================================ +// Version +// ============================================================================ + +#define RADR_VERSION_MAJOR 0 +#define RADR_VERSION_MINOR 20 +#define RADR_VERSION_PATCH 0 diff --git a/tests/benchmark/CMakeLists.txt b/tests/benchmark/CMakeLists.txt index c2d375c..1dc382b 100644 --- a/tests/benchmark/CMakeLists.txt +++ b/tests/benchmark/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required (VERSION 3.7) -project (radr_benchmark CXX) +cmake_minimum_required (VERSION 3.12) +project (radr_test_benchmark CXX) include(FetchContent) @@ -8,14 +8,12 @@ include(FetchContent) # ---------------------------------------------------------------------------- message(STATUS "Beginning to configure RADR micro benchmarks...") +include (../radr-test.cmake) if (CMAKE_BUILD_TYPE AND NOT ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")) message (WARNING "Benchmarks should typically be built in Release mode! [build type = ${CMAKE_BUILD_TYPE}]") endif () -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) - # ---------------------------------------------------------------------------- # Options # ---------------------------------------------------------------------------- @@ -26,12 +24,7 @@ option(RADR_BENCHMARK_ALIGN_LOOPS "Pass -falign-loops=32 to the benchmark builds # Paths to folders. # ---------------------------------------------------------------------------- -find_path (RADR_BASE_DIR - NAMES include/radr/rad/as_const.hpp - HINTS "${CMAKE_CURRENT_LIST_DIR}/../../") -set (RADR_INCLUDE_DIR "${RADR_BASE_DIR}/include/") -set (RADR_TEST_INCLUDE_DIR "${RADR_BASE_DIR}/tests/include/") -set (RADR_UNIT_TESTS_SRC "${RADR_BASE_DIR}/tests/benchmark/") +set (RADR_BENCHMARKS_DIR "${RADR_CLONE_DIR}/tests/benchmark/") # ---------------------------------------------------------------------------- # Components and dependencies @@ -54,47 +47,26 @@ FetchContent_MakeAvailable(googlebenchmark) # ---------------------------------------------------------------------------- add_library (radr_benchmark INTERFACE) -target_compile_options (radr_benchmark INTERFACE "-pedantic" "-Wall" "-Wextra" "-Werror") target_link_libraries (radr_benchmark INTERFACE "pthread" benchmark::benchmark_main) -target_include_directories (radr_benchmark INTERFACE "${RADR_INCLUDE_DIR}" "${RADR_TEST_INCLUDE_DIR}") add_library (radr::test::benchmark ALIAS radr_benchmark) if (RADR_BENCHMARK_ALIGN_LOOPS) target_compile_options (radr_benchmark INTERFACE "-falign-loops=32") endif () -# ---------------------------------------------------------------------------- -# Test target macro -# ---------------------------------------------------------------------------- - -macro (radr_test unit_test_cpp) - get_filename_component (target_dir "${unit_test_cpp}" DIRECTORY) - get_filename_component (target "${unit_test_cpp}" NAME_WLE) - - add_executable (${target} "${RADR_UNIT_TESTS_SRC}/${unit_test_cpp}") - target_link_libraries (${target} radr::test::benchmark) - - file (MAKE_DIRECTORY ${target_dir}) - set_target_properties(${target} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${target_dir}") - - add_test (NAME "${target_dir}/${target}" COMMAND "${target_dir}/${target}") - - unset (target) - unset (target_dir) -endmacro () - # ---------------------------------------------------------------------------- # Start generating tests # ---------------------------------------------------------------------------- file (GLOB_RECURSE ENTRIES - RELATIVE ${RADR_BASE_DIR}/tests/benchmark - "${RADR_UNIT_TESTS_SRC}/[!.]*cpp") + RELATIVE ${RADR_BENCHMARKS_DIR} + "${RADR_BENCHMARKS_DIR}/[!.]*cpp") foreach (ENTRY ${ENTRIES}) - message(STATUS ${ENTRY}) - radr_test(${ENTRY}) + radr_add_test(${ENTRY}) + get_filename_component (target "${ENTRY}" NAME_WLE) + message(STATUS "Adding benchmark target '${target}' for file ${ENTRY}") + target_link_libraries (${target} radr::test::benchmark) endforeach () message(STATUS "Configuring RADR micro benchmarks DONE.") diff --git a/tests/include/radr/test/gtest_helpers.hpp b/tests/include/radr/test/gtest_helpers.hpp index 99cf314..63d1f19 100644 --- a/tests/include/radr/test/gtest_helpers.hpp +++ b/tests/include/radr/test/gtest_helpers.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/tests/radr-test.cmake b/tests/radr-test.cmake index 69f462c..0d3af7e 100644 --- a/tests/radr-test.cmake +++ b/tests/radr-test.cmake @@ -1,7 +1,7 @@ # -*- CMake -*- #===----------------------------------------------------------------------===// # -# Copyright (c) 2023 Hannes Hauswedell +# Copyright (c) 2023-2025 Hannes Hauswedell # # Licensed under the Apache License v2.0 with LLVM Exceptions. # See the LICENSE file for details. @@ -9,14 +9,15 @@ # #===----------------------------------------------------------------------===// -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.12) # ---------------------------------------------------------------------------- # RADR SETUP # ---------------------------------------------------------------------------- -find_path (RADR_INCLUDE_DIR NAMES radr/rad/as_const.hpp HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../include/" REQUIRED) -find_path (RADR_TEST_INCLUDE_DIR NAMES radr/test/gtest_helpers.hpp HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../include/" REQUIRED) +find_package(radr REQUIRED HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/") + +find_path (RADR_TEST_INCLUDE_DIR NAMES radr/test/gtest_helpers.hpp HINTS "${RADR_CLONE_DIR}/tests/include/" REQUIRED) # ---------------------------------------------------------------------------- # GoogleTest @@ -35,31 +36,29 @@ FetchContent_MakeAvailable(googletest) # Pseudo library to ease target definition # ---------------------------------------------------------------------------- -add_library (radr_test_unit INTERFACE) -target_link_libraries (radr_test_unit INTERFACE gtest_main gtest pthread) -target_include_directories (radr_test_unit INTERFACE "${RADR_INCLUDE_DIR}" "${RADR_TEST_INCLUDE_DIR}") -target_compile_options (radr_test_unit INTERFACE -pedantic -Wall -Wextra -Werror) -add_library (radr::test::unit ALIAS radr_test_unit) +add_library (radr_test_base INTERFACE) +target_link_libraries (radr_test_base INTERFACE radr::radr gtest_main gtest pthread) +target_include_directories (radr_test_base INTERFACE "${RADR_TEST_INCLUDE_DIR}") +target_compile_options (radr_test_base INTERFACE -pedantic -Wall -Wextra -Werror) +add_library (radr::test::base ALIAS radr_test_base) # ---------------------------------------------------------------------------- -# add_subdirectories +# radr_add_test macro # ---------------------------------------------------------------------------- -macro (add_subdirectories_of directory) - file (GLOB ENTRIES - RELATIVE ${directory} - ${directory}/[!.]*) +macro (radr_add_test unit_test_cpp) + get_filename_component (target_dir "${unit_test_cpp}" DIRECTORY) + get_filename_component (target "${unit_test_cpp}" NAME_WLE) - foreach (ENTRY ${ENTRIES}) - if (IS_DIRECTORY ${directory}/${ENTRY}) - if (EXISTS ${directory}/${ENTRY}/CMakeLists.txt) - add_subdirectory (${directory}/${ENTRY} ${CMAKE_CURRENT_BINARY_DIR}/${ENTRY}) - endif () - endif () - endforeach () - unset (ENTRIES) -endmacro () + add_executable (${target} "${unit_test_cpp}") + target_link_libraries (${target} radr::test::base) + + file (MAKE_DIRECTORY ${target_dir}) + set_target_properties(${target} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${target_dir}") + + add_test (NAME "${target_dir}/${target}" COMMAND "${target_dir}/${target}") -macro (add_subdirectories) - add_subdirectories_of(${CMAKE_CURRENT_SOURCE_DIR}) + unset (target) + unset (target_dir) endmacro () diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 886875b..2130fbd 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -1,27 +1,22 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.12) project (radr_test_unit CXX) -include (../radr-test.cmake) +message(STATUS "Beginning to configure RADR unit tests...") -option (RADR_VERBOSE_TESTS "Run each test case individually" OFF) +include (../radr-test.cmake) -function (radr_unit_test test_name) - file (RELATIVE_PATH file_name "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/${test_name}.cpp") - set(target_name ${test_name}) +enable_testing() - add_executable (${target_name} ${test_name}.cpp) - target_link_libraries (${target_name} radr::test::unit) - if (RADR_VERBOSE_TESTS) - gtest_discover_tests(${file_name} TEST_PREFIX "${target_name}::" PROPERTIES TIMEOUT "30") - else () - add_test (NAME "${file_name}" COMMAND ${target_name}) - endif () +set (RADR_UNIT_TESTS_SRC "${RADR_CLONE_DIR}/tests/unit/") - unset (unit_test) - unset (target_name) - unset (file_name) -endfunction () +file (GLOB_RECURSE ENTRIES + RELATIVE ${RADR_UNIT_TESTS_SRC} + "${RADR_UNIT_TESTS_SRC}/[!.]*cpp") -enable_testing() +foreach (ENTRY ${ENTRIES}) + radr_add_test(${ENTRY}) + get_filename_component (target "${ENTRY}" NAME_WLE) + message(STATUS "Adding unit-test target '${target}' for file ${ENTRY}") +endforeach () -add_subdirectories () +message(STATUS "Configuring RADR unit tests done.")