From 820b3b62bf2a3474288ca4925fadf444dd8c85f3 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Sat, 6 Jan 2024 13:20:54 +0000 Subject: [PATCH 01/13] Use CMake's new module support ...to build the Flux module, rather than modules.cmake. This requires the brand new CMake 3.28, but I imagine that people who want to try this out are probably fine with living on the cutting edge. --- CMakeLists.txt | 6 +- cmake/modules.cmake | 223 ------------------------------------------ module/CMakeLists.txt | 8 +- test/CMakeLists.txt | 4 +- 4 files changed, 14 insertions(+), 227 deletions(-) delete mode 100644 cmake/modules.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 09166113..20904318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,11 @@ if (FLUX_BUILD_TOOLS) endif() if (FLUX_BUILD_MODULE) - add_subdirectory(module) + if(${CMAKE_VERSION} VERSION_LESS "3.28.0") + message(WARNING "Modules support requires CMake v3.28 or later") + else() + add_subdirectory(module) + endif() endif() set(FLUX_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/flux) diff --git a/cmake/modules.cmake b/cmake/modules.cmake deleted file mode 100644 index 7a77ca18..00000000 --- a/cmake/modules.cmake +++ /dev/null @@ -1,223 +0,0 @@ -# A CMake module that provides functions for using C++20 modules in Clang. - -#[[ - Copyright (c) 2018 - present, Victor Zverovich - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --- Optional exception to the license --- - - As an exception, if, as a result of your compiling your source code, portions - of this Software are embedded into a machine-executable object form of such - source code, you may redistribute such embedded portions in such object form - without including the above copyright and permission notices. -]] - - -# Clang requires the CXX_EXTENSIONS property to be set to false to use modules. -# If the user has not set it explicitly, do it here. Otherwise warn if it is not -# set to false. -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - if (NOT DEFINED CMAKE_CXX_EXTENSIONS) - set(CMAKE_CXX_EXTENSIONS OFF) - elseif (CMAKE_CXX_EXTENSIONS) - message( - WARNING - "Clang requires CMAKE_CXX_EXTENSIONS to be set to false to use modules.") - endif () -endif () - -# Receives latest available C++ standard version -# -# Usage: -# modules_get_latest_cxx_std() -# if ( GREATER 17) -# ... -# endif () -function(modules_get_latest_cxx_std result) - # Assume that 98 will be supported even with a broken feature detection. - set(std_version 98) - - # Iterate over features and use the latest one. CMake always sorts features - # from the oldest to the newest. - foreach (compiler_feature ${CMAKE_CXX_COMPILE_FEATURES}) - if (compiler_feature MATCHES "cxx_std_(.*)") - set(std_version ${CMAKE_MATCH_1}) - endif () - endforeach () - - set(${result} ${std_version} PARENT_SCOPE) -endfunction() - -# Checks that the compiler supports C++20 modules. -# -# Usage: -# modules_supported( [STANDARD standard_ver]) -# if () -# ... -# endif () -function(modules_supported result) - cmake_parse_arguments(MS "" "STANDARD" "" ${ARGN}) - - set(${result} FALSE PARENT_SCOPE) - - # Check the standard version. - if (NOT DEFINED MS_STANDARD) - if (DEFINED CMAKE_CXX_STANDARD) - set(MS_STANDARD ${CMAKE_CXX_STANDARD}) - else () - modules_get_latest_cxx_std(MS_STANDARD) - endif () - endif () - - if (MS_STANDARD GREATER_EQUAL 20) - - # Create a simple module file. - set(temp_filepath "${CMAKE_BINARY_DIR}/module_test.cc") - file(WRITE "${temp_filepath}" - "module;\nexport module module_test;\nexport void module_test_fun(){}") - - # Set compiler flags. - set(compiler_flags "") - if (MSVC) - set(compiler_flags "/interface") - elseif (CMAKE_COMPILER_IS_GNUCXX) - set(compiler_flags "-fmodules-ts") - endif () - - # Try to build it. - set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) - try_compile( - compilation_result "${CMAKE_BINARY_DIR}" - SOURCES "${temp_filepath}" - COMPILE_DEFINITIONS "${compiler_flags}" - CXX_STANDARD ${MS_STANDARD} - CXX_STANDARD_REQUIRED ON - OUTPUT_VARIABLE output) - - # Remove the test file. - file(REMOVE ${temp_filepath}) - - # Return the result. - set(${result} ${compilation_result} PARENT_SCOPE) - endif () -endfunction() - - -# Adds a library compiled with C++20 module support. -# `enabled` is a CMake variables that specifies if modules are enabled. -# If modules are disabled `add_module_library` falls back to creating a -# non-modular library. -# -# Usage: -# add_module_library( [sources...] FALLBACK [sources...] [IF enabled]) -function(add_module_library name) - cmake_parse_arguments(AML "" "IF" "FALLBACK" ${ARGN}) - set(sources ${AML_UNPARSED_ARGUMENTS}) - - add_library(${name}) - set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX) - - # Detect module support in case it was not explicitly defined - if(NOT DEFINED AML_IF) - modules_supported(AML_IF) - endif() - - # Add fallback sources to the target in case modules are not supported or - # fallback was explicitly selected. - if (NOT ${AML_IF}) - target_sources(${name} PRIVATE ${AML_FALLBACK}) - return() - endif () - - # Modules require C++20. - target_compile_features(${name} PUBLIC cxx_std_20) - if (CMAKE_COMPILER_IS_GNUCXX) - target_compile_options(${name} PUBLIC -fmodules-ts) - endif () - - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - # `std` is affected by CMake options and may be higher than C++20. - # Clang does not support c++23/c++26 names, so replace it with 2b. - get_target_property(std ${name} CXX_STANDARD) - if (std GREATER 20) - set(std 2b) - endif () - - set(pcms) - foreach (src ${sources}) - get_filename_component(pcm ${src} NAME_WE) - set(pcm ${pcm}.pcm) - - # Propagate -fmodule-file=*.pcm to targets that link with this library. - target_compile_options( - ${name} INTERFACE -fmodule-file=${CMAKE_CURRENT_BINARY_DIR}/${pcm}) - - # Use an absolute path to prevent target_link_libraries prepending -l - # to it. - set(pcms ${pcms} ${CMAKE_CURRENT_BINARY_DIR}/${pcm}) - set(prop "$") - add_custom_command( - OUTPUT ${pcm} - COMMAND ${CMAKE_CXX_COMPILER} - -std=c++${std} -x c++-module --precompile -c - -o ${pcm} ${CMAKE_CURRENT_SOURCE_DIR}/${src} - $ - "$<$:-I$>" - # Required by the -I generator expression above. - COMMAND_EXPAND_LISTS - DEPENDS ${src}) - endforeach () - - # Add .pcm files as sources to make sure they are built before the library. - set(sources) - foreach (pcm ${pcms}) - get_filename_component(pcm_we ${pcm} NAME_WE) - set(obj ${pcm_we}.o) - # Use an absolute path to prevent target_link_libraries prepending -l. - set(sources ${sources} ${pcm} ${CMAKE_CURRENT_BINARY_DIR}/${obj}) - add_custom_command( - OUTPUT ${obj} - COMMAND ${CMAKE_CXX_COMPILER} $ - -c -o ${obj} ${pcm} - # Required by the generator expression above. - COMMAND_EXPAND_LISTS - DEPENDS ${pcm}) - endforeach () - endif () - - target_sources(${name} PRIVATE ${sources}) - - if (MSVC) - foreach (src ${sources}) - # Compile file as a module interface. - set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS /interface) - - # Propagate `/reference *.ifc` to targets that link with this library. - get_filename_component(ifc ${src} NAME_WE) - set(ifc "${CMAKE_CURRENT_BINARY_DIR}/${ifc}.ifc") - target_compile_options(${name} INTERFACE /reference "${ifc}") - - # Track the generated .ifc file. - set_target_properties(${name} PROPERTIES ADDITIONAL_CLEAN_FILES ${ifc}) - set_source_files_properties(${ifc} PROPERTIES GENERATED ON) - endforeach () - endif () -endfunction() diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index 0ef8f798..fdfcd70f 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -1,7 +1,11 @@ -include(modules) +add_library(flux-mod) +target_sources(flux-mod PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS ${PROJECT_SOURCE_DIR}/module + FILES flux.cpp +) -add_module_library(flux-mod flux.cpp) target_link_libraries(flux-mod PUBLIC flux) set_target_properties(flux-mod PROPERTIES CXX_EXTENSIONS Off) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f33dbc23..7beb3387 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -100,7 +100,9 @@ endif() if(${FLUX_BUILD_MODULE}) add_executable(test-module-import test_module_import.cpp) target_link_libraries(test-module-import PUBLIC flux-mod) - set_target_properties(test-module-import PROPERTIES CXX_EXTENSIONS Off) + set_target_properties(test-module-import PROPERTIES + CXX_EXTENSIONS Off + CXX_SCAN_FOR_MODULES On) endif() include(Catch) From 159b52fc4637caae3760487fa21c3951f425e6bf Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Sat, 6 Jan 2024 13:24:10 +0000 Subject: [PATCH 02/13] Add some forgotten exports --- include/flux.hpp | 1 + include/flux/core/concepts.hpp | 1 + include/flux/core/functional.hpp | 3 +++ include/flux/op/to.hpp | 3 ++- module/flux.cpp | 1 + 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/flux.hpp b/include/flux.hpp index ec4441e4..13ffd409 100644 --- a/include/flux.hpp +++ b/include/flux.hpp @@ -63,6 +63,7 @@ #include #include +#include #include #include #include diff --git a/include/flux/core/concepts.hpp b/include/flux/core/concepts.hpp index dac180cf..53e9e9ed 100644 --- a/include/flux/core/concepts.hpp +++ b/include/flux/core/concepts.hpp @@ -322,6 +322,7 @@ concept adaptable_sequence = detail::trivially_copyable_sequence>)) && !detail::is_ilist; +FLUX_EXPORT template struct inline_sequence_base; diff --git a/include/flux/core/functional.hpp b/include/flux/core/functional.hpp index 8f3371c2..5639e3d8 100644 --- a/include/flux/core/functional.hpp +++ b/include/flux/core/functional.hpp @@ -174,18 +174,21 @@ FLUX_EXPORT inline constexpr auto either = [](auto&& p, auto&& or_) { namespace detail { +FLUX_EXPORT template constexpr auto operator!(detail::predicate

pred) { return not_(std::move(pred)); } +FLUX_EXPORT template constexpr auto operator&&(detail::predicate lhs, detail::predicate rhs) { return both(std::move(lhs), std::move(rhs)); } +FLUX_EXPORT template constexpr auto operator||(detail::predicate lhs, detail::predicate rhs) { diff --git a/include/flux/op/to.hpp b/include/flux/op/to.hpp index 1d393a22..d0ff6d61 100644 --- a/include/flux/op/to.hpp +++ b/include/flux/op/to.hpp @@ -12,11 +12,12 @@ namespace flux { +FLUX_EXPORT struct from_sequence_t { explicit from_sequence_t() = default; }; -inline constexpr auto from_sequence = from_sequence_t{}; +FLUX_EXPORT inline constexpr auto from_sequence = from_sequence_t{}; namespace detail { diff --git a/module/flux.cpp b/module/flux.cpp index 5560da71..3141bf41 100644 --- a/module/flux.cpp +++ b/module/flux.cpp @@ -2,6 +2,7 @@ module; #include +#include #include #include #include From f9c028e5fccecdbade8d2be80daa47b3499aedb2 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Sat, 6 Jan 2024 13:51:54 +0000 Subject: [PATCH 03/13] Make runtime_error() non-inlined... ...when using modules. We're building a library anyway, we may as well put this function in it since we never actually want it to be inlined. --- include/flux/core/assert.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/flux/core/assert.hpp b/include/flux/core/assert.hpp index 9e32c298..03758072 100644 --- a/include/flux/core/assert.hpp +++ b/include/flux/core/assert.hpp @@ -25,8 +25,8 @@ namespace detail { struct runtime_error_fn { [[noreturn]] - inline void operator()(char const* msg, - std::source_location loc = std::source_location::current()) const + void operator()(char const* msg, + std::source_location loc = std::source_location::current()) const { if constexpr (config::on_error == error_policy::unwind) { char buf[1024]; From fc837ff41e6f8782242224cf0c074bff69713891 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Sat, 6 Jan 2024 14:14:44 +0000 Subject: [PATCH 04/13] Build tests using modules... ...when both FLUX_BUILD_TESTS and FLUX_BUILD_MODULE CMake options are set. This is a big change set, but it mostly consists of reordering things so that all #includes come before `import flux`. In some cases we were testing (or using) things in the `detail` namespace, which are now no longer exported; these are currently just ifdef'd out. --- test/CMakeLists.txt | 13 +++++++++++++ test/test_adjacent.cpp | 9 ++++++--- test/test_adjacent_filter.cpp | 4 +--- test/test_adjacent_map.cpp | 4 +--- test/test_all_any_none.cpp | 4 ++++ test/test_apply.cpp | 2 -- test/test_array_ptr.cpp | 6 ++---- test/test_bitset.cpp | 7 ++----- test/test_bounds_checked.cpp | 2 -- test/test_cache_last.cpp | 2 -- test/test_cartesian_product.cpp | 7 ------- test/test_cartesian_product_with.cpp | 2 -- test/test_chain.cpp | 7 ++----- test/test_chunk.cpp | 26 ++++++++++++++++++++------ test/test_chunk_by.cpp | 6 ++---- test/test_compare.cpp | 8 ++++---- test/test_concepts.cpp | 4 ++++ test/test_contains.cpp | 4 +--- test/test_count.cpp | 4 ---- test/test_count_if.cpp | 3 --- test/test_cursors.cpp | 6 ++---- test/test_cycle.cpp | 6 ++---- test/test_drop.cpp | 6 ++---- test/test_drop_while.cpp | 4 +--- test/test_empty.cpp | 4 ++++ test/test_ends_with.cpp | 2 -- test/test_equal.cpp | 6 +----- test/test_fill.cpp | 5 ----- test/test_filter.cpp | 6 ++---- test/test_find.cpp | 12 ++++++++---- test/test_find_min_max.cpp | 2 -- test/test_flatten.cpp | 3 +-- test/test_fold.cpp | 4 +--- test/test_for_each.cpp | 4 +--- test/test_from_range.cpp | 7 +++---- test/test_front_back.cpp | 6 ++---- test/test_generator.cpp | 5 ++--- test/test_getlines.cpp | 6 ++---- test/test_iota.cpp | 6 ++---- test/test_istream.cpp | 4 +--- test/test_istreambuf.cpp | 2 -- test/test_map.cpp | 5 ++--- test/test_mask.cpp | 6 ++---- test/test_minmax.cpp | 2 -- test/test_optional.cpp | 2 -- test/test_output_to.cpp | 5 ----- test/test_overflow.cpp | 10 ++++++++-- test/test_predicates.cpp | 6 ++---- test/test_range_iface.cpp | 3 +-- test/test_read_only.cpp | 4 +--- test/test_repeat.cpp | 6 ++---- test/test_reverse.cpp | 6 ++---- test/test_scan.cpp | 6 ++---- test/test_set_adaptors.cpp | 6 ++---- test/test_simple_sequence.cpp | 16 ++++++---------- test/test_single.cpp | 2 -- test/test_slide.cpp | 4 +--- test/test_sort.cpp | 10 +++++----- test/test_split.cpp | 7 ++----- test/test_starts_with.cpp | 2 -- test/test_stride.cpp | 28 ++++++++++++++++++++++------ test/test_take.cpp | 6 ++---- test/test_take_while.cpp | 4 +--- test/test_to.cpp | 2 -- test/test_unchecked.cpp | 4 +--- test/test_unfold.cpp | 4 +--- test/test_utils.hpp | 9 ++++++--- test/test_write_to.cpp | 8 ++++++-- test/test_zip.cpp | 6 ++---- test/test_zip_algorithms.cpp | 6 ++---- 70 files changed, 180 insertions(+), 235 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7beb3387..373d6097 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -93,6 +93,19 @@ if(${FLUX_ENABLE_UBSAN}) target_link_options(test-flux PRIVATE -fsanitize=undefined) endif() +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") + if (${FLUX_BUILD_MODULE}) + target_sources(test-flux PUBLIC + FILE_SET CXX_MODULES + BASE_DIRS ${PROJECT_SOURCE_DIR}/module + FILES ${PROJECT_SOURCE_DIR}/module/flux.cpp + ) + + target_compile_definitions(test-flux PRIVATE -DUSE_MODULES) + set_target_properties(test-flux PROPERTIES CXX_SCAN_FOR_MODULES On) + endif() +endif() + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") target_precompile_headers(test-flux PRIVATE "catch.hpp") endif() diff --git a/test/test_adjacent.cpp b/test/test_adjacent.cpp index c6a526e0..9bc153eb 100644 --- a/test/test_adjacent.cpp +++ b/test/test_adjacent.cpp @@ -5,12 +5,15 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - +#ifndef USE_MODULES +#include +#else +import flux; +#endif namespace { diff --git a/test/test_adjacent_filter.cpp b/test/test_adjacent_filter.cpp index a60fc271..bf22c058 100644 --- a/test/test_adjacent_filter.cpp +++ b/test/test_adjacent_filter.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_adjacent_filter() diff --git a/test/test_adjacent_map.cpp b/test/test_adjacent_map.cpp index 3393eb4b..eb1b69fd 100644 --- a/test/test_adjacent_map.cpp +++ b/test/test_adjacent_map.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_pairwise_map() { diff --git a/test/test_all_any_none.cpp b/test/test_all_any_none.cpp index fe4b454e..479c0e6b 100644 --- a/test/test_all_any_none.cpp +++ b/test/test_all_any_none.cpp @@ -5,7 +5,11 @@ #include "catch.hpp" +#ifdef USE_MODULES +import flux; +#else #include +#endif namespace { diff --git a/test/test_apply.cpp b/test/test_apply.cpp index d436822c..e61c1b58 100644 --- a/test/test_apply.cpp +++ b/test/test_apply.cpp @@ -1,8 +1,6 @@ #include "catch.hpp" -#include - #include #include diff --git a/test/test_array_ptr.cpp b/test/test_array_ptr.cpp index fb65fa35..4a02eb65 100644 --- a/test/test_array_ptr.cpp +++ b/test/test_array_ptr.cpp @@ -5,14 +5,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { struct Base { diff --git a/test/test_bitset.cpp b/test/test_bitset.cpp index d956cba1..2b61c499 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset.cpp @@ -5,14 +5,11 @@ #include "catch.hpp" -#include -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_bitset() diff --git a/test/test_bounds_checked.cpp b/test/test_bounds_checked.cpp index 75700b36..7148ea46 100644 --- a/test/test_bounds_checked.cpp +++ b/test/test_bounds_checked.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_cache_last.cpp b/test/test_cache_last.cpp index bc8e5af6..a24c6485 100644 --- a/test/test_cache_last.cpp +++ b/test/test_cache_last.cpp @@ -1,8 +1,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_cartesian_product.cpp b/test/test_cartesian_product.cpp index d22723d2..ce2f3a59 100644 --- a/test/test_cartesian_product.cpp +++ b/test/test_cartesian_product.cpp @@ -7,13 +7,6 @@ #include "catch.hpp" -#include -#include -#include -#include -#include -#include - #include #include #include diff --git a/test/test_cartesian_product_with.cpp b/test/test_cartesian_product_with.cpp index 7845cd6e..56a91625 100644 --- a/test/test_cartesian_product_with.cpp +++ b/test/test_cartesian_product_with.cpp @@ -1,8 +1,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_chain.cpp b/test/test_chain.cpp index cd76599d..9d3c7e2c 100644 --- a/test/test_chain.cpp +++ b/test/test_chain.cpp @@ -5,15 +5,12 @@ #include "catch.hpp" -#include -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_chain() diff --git a/test/test_chunk.cpp b/test/test_chunk.cpp index d736051c..b2aaf9a9 100644 --- a/test/test_chunk.cpp +++ b/test/test_chunk.cpp @@ -5,15 +5,13 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include #include +#include "test_utils.hpp" + namespace { #ifdef _MSC_VER @@ -33,8 +31,24 @@ struct NotBidir : flux::inline_sequence_base> { constexpr Base& base() & { return base_; } constexpr Base const& base() const& { return base_; } - struct flux_sequence_traits : flux::detail::passthrough_traits_base { - static void dec(...) = delete; + struct flux_sequence_traits { + static constexpr auto first(auto& self) { return flux::first(self.base_); } + + static constexpr bool is_last(auto& self, auto const& cur) { + return flux::is_last(self.base_, cur); + } + + static constexpr void inc(auto& self, auto& cur) { + flux::inc(self.base_, cur); + } + + static constexpr decltype(auto) read_at(auto& self, auto const& cur) { + return flux::read_at(self.base_, cur); + } + + static constexpr auto last(auto& self) { return flux::last(self.base_); } + + static constexpr auto size(auto& self) { return flux::size(self.base_); } }; }; diff --git a/test/test_chunk_by.cpp b/test/test_chunk_by.cpp index 07fd0825..1a7e073a 100644 --- a/test/test_chunk_by.cpp +++ b/test/test_chunk_by.cpp @@ -16,13 +16,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_chunk_by() { diff --git a/test/test_compare.cpp b/test/test_compare.cpp index f362a9bd..af74c417 100644 --- a/test/test_compare.cpp +++ b/test/test_compare.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { struct Test { @@ -77,7 +75,9 @@ constexpr bool test_compare() // empty sequences are equal { // ...but still require the element types to be comparable - static_assert(not std::invocable, flux::detail::empty_sequence>); + static_assert(not std::invocable), + decltype(flux::empty)>); auto r = flux::compare(flux::empty, flux::empty); static_assert(std::same_as); diff --git a/test/test_concepts.cpp b/test/test_concepts.cpp index 7fa9faa6..0c18ec5f 100644 --- a/test/test_concepts.cpp +++ b/test/test_concepts.cpp @@ -5,7 +5,11 @@ #include "catch.hpp" +#ifdef USE_MODULES +import flux; +#else #include +#endif namespace { diff --git a/test/test_contains.cpp b/test/test_contains.cpp index 2a726f7e..d9ff3298 100644 --- a/test/test_contains.cpp +++ b/test/test_contains.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { struct Test { diff --git a/test/test_count.cpp b/test/test_count.cpp index 55607625..63a0efea 100644 --- a/test/test_count.cpp +++ b/test/test_count.cpp @@ -5,12 +5,8 @@ #include "catch.hpp" -#include -#include - #include "test_utils.hpp" - namespace { struct S { diff --git a/test/test_count_if.cpp b/test/test_count_if.cpp index 2ee1217f..1626f204 100644 --- a/test/test_count_if.cpp +++ b/test/test_count_if.cpp @@ -5,9 +5,6 @@ #include "catch.hpp" -#include -#include - #include "test_utils.hpp" diff --git a/test/test_cursors.cpp b/test/test_cursors.cpp index d4932be1..6028f824 100644 --- a/test/test_cursors.cpp +++ b/test/test_cursors.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_cursors() diff --git a/test/test_cycle.cpp b/test/test_cycle.cpp index 1d945d9a..25e6fae0 100644 --- a/test/test_cycle.cpp +++ b/test/test_cycle.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_cycle() { diff --git a/test/test_drop.cpp b/test/test_drop.cpp index b15cd211..9fd67d44 100644 --- a/test/test_drop.cpp +++ b/test/test_drop.cpp @@ -5,10 +5,6 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include @@ -16,6 +12,8 @@ #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_drop() { diff --git a/test/test_drop_while.cpp b/test/test_drop_while.cpp index 2ff7a9c2..14d5a425 100644 --- a/test/test_drop_while.cpp +++ b/test/test_drop_while.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_drop_while() diff --git a/test/test_empty.cpp b/test/test_empty.cpp index d1937060..d01e398b 100644 --- a/test/test_empty.cpp +++ b/test/test_empty.cpp @@ -5,7 +5,11 @@ #include "catch.hpp" +#ifdef USE_MODULES +import flux; +#else #include +#endif namespace { diff --git a/test/test_ends_with.cpp b/test/test_ends_with.cpp index 7f7b0ab6..0282af6f 100644 --- a/test/test_ends_with.cpp +++ b/test/test_ends_with.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include diff --git a/test/test_equal.cpp b/test/test_equal.cpp index 428eb873..bce793da 100644 --- a/test/test_equal.cpp +++ b/test/test_equal.cpp @@ -1,14 +1,10 @@ #include "catch.hpp" -#include -#include -#include +#include #include "test_utils.hpp" -#include - namespace { struct S { diff --git a/test/test_fill.cpp b/test/test_fill.cpp index eaafcad9..405c5075 100644 --- a/test/test_fill.cpp +++ b/test/test_fill.cpp @@ -5,11 +5,6 @@ #include "catch.hpp" -#include -#include -#include -#include - #include #include "test_utils.hpp" diff --git a/test/test_filter.cpp b/test/test_filter.cpp index 85e6c343..8f10b8fa 100644 --- a/test/test_filter.cpp +++ b/test/test_filter.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include "test_utils.hpp" - -#include - #include #include +#include "test_utils.hpp" + namespace { constexpr auto is_even = [](int i) { return i % 2 == 0; }; diff --git a/test/test_find.cpp b/test/test_find.cpp index cdb7d07c..b218a60d 100644 --- a/test/test_find.cpp +++ b/test/test_find.cpp @@ -5,14 +5,18 @@ #include "catch.hpp" -#include -#include -#include - #include #include #include +#ifdef USE_MODULES +import flux; +#else +#include +#include +#include +#endif + namespace { struct S { diff --git a/test/test_find_min_max.cpp b/test/test_find_min_max.cpp index 158097a0..f5e83c9f 100644 --- a/test/test_find_min_max.cpp +++ b/test/test_find_min_max.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_flatten.cpp b/test/test_flatten.cpp index 8cd4387a..8538ed5a 100644 --- a/test/test_flatten.cpp +++ b/test/test_flatten.cpp @@ -5,11 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include #if defined(_GLIBCXX_RELEASE) # if _GLIBCXX_RELEASE < 12 diff --git a/test/test_fold.cpp b/test/test_fold.cpp index 7810efb4..8f1dc808 100644 --- a/test/test_fold.cpp +++ b/test/test_fold.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_fold() diff --git a/test/test_for_each.cpp b/test/test_for_each.cpp index 3912c37a..0ea12a90 100644 --- a/test/test_for_each.cpp +++ b/test/test_for_each.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { struct S { diff --git a/test/test_from_range.cpp b/test/test_from_range.cpp index 7cb3fc0f..7aaef946 100644 --- a/test/test_from_range.cpp +++ b/test/test_from_range.cpp @@ -5,16 +5,15 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include #include +#include #include +#include "test_utils.hpp" + #if defined(_GLIBCXX_RELEASE) # if _GLIBCXX_RELEASE < 12 # define RVALUE_VIEWS_NOT_SUPPORTED diff --git a/test/test_front_back.cpp b/test/test_front_back.cpp index e4c94db2..0bb96a15 100644 --- a/test/test_front_back.cpp +++ b/test/test_front_back.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_front() diff --git a/test/test_generator.cpp b/test/test_generator.cpp index 970332b2..00cb4d46 100644 --- a/test/test_generator.cpp +++ b/test/test_generator.cpp @@ -5,9 +5,8 @@ #include "catch.hpp" -#include -#include - +#include +#include #include "test_utils.hpp" diff --git a/test/test_getlines.cpp b/test/test_getlines.cpp index 59107a79..c2c77f62 100644 --- a/test/test_getlines.cpp +++ b/test/test_getlines.cpp @@ -4,14 +4,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + constexpr const auto& test_str1 = "Line1\nLine2\nLine3"; TEST_CASE("getlines") diff --git a/test/test_iota.cpp b/test/test_iota.cpp index a0c262c7..179f97d8 100644 --- a/test/test_iota.cpp +++ b/test/test_iota.cpp @@ -4,13 +4,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_iota_basic() diff --git a/test/test_istream.cpp b/test/test_istream.cpp index 9bb444b3..27741c5a 100644 --- a/test/test_istream.cpp +++ b/test/test_istream.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - TEST_CASE("istream") { { diff --git a/test/test_istreambuf.cpp b/test/test_istreambuf.cpp index 2caf9eaf..9c16f960 100644 --- a/test/test_istreambuf.cpp +++ b/test/test_istreambuf.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include diff --git a/test/test_map.cpp b/test/test_map.cpp index 0064adf9..c833fa9a 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -5,12 +5,11 @@ #include "catch.hpp" -#include +#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_map() diff --git a/test/test_mask.cpp b/test/test_mask.cpp index b862fa6d..3b3865e0 100644 --- a/test/test_mask.cpp +++ b/test/test_mask.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include "test_utils.hpp" - -#include - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_mask() diff --git a/test/test_minmax.cpp b/test/test_minmax.cpp index b3516e57..a532bfef 100644 --- a/test/test_minmax.cpp +++ b/test/test_minmax.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_optional.cpp b/test/test_optional.cpp index 3afd25e7..bc8133eb 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include "test_utils.hpp" // Silence warnings about unneeded comparison functions: in fact they are diff --git a/test/test_output_to.cpp b/test/test_output_to.cpp index b11488a3..45cbebc0 100644 --- a/test/test_output_to.cpp +++ b/test/test_output_to.cpp @@ -5,11 +5,6 @@ #include "catch.hpp" -#include -#include -#include -#include - #include #include #include diff --git a/test/test_overflow.cpp b/test/test_overflow.cpp index 51a5e289..ba7890ae 100644 --- a/test/test_overflow.cpp +++ b/test/test_overflow.cpp @@ -5,10 +5,14 @@ #include "catch.hpp" -#include - #include +#ifdef USE_MODULES +import flux; +#else +#include +#endif + namespace { template @@ -92,10 +96,12 @@ void test_mul() REQUIRE_THROWS_AS(mul(min, T{-1}), flux::unrecoverable_error); +#ifndef USE_MODULES // FIXME: Raises sigfpe when not using built-in overflow checking if constexpr (flux::num::detail::use_builtin_overflow_ops) { REQUIRE_THROWS_AS(mul(T{-1}, min), flux::unrecoverable_error); } +#endif REQUIRE_THROWS_AS(mul(max, T{2}), flux::unrecoverable_error); REQUIRE_THROWS_AS(mul(T{2}, max), flux::unrecoverable_error); diff --git a/test/test_predicates.cpp b/test/test_predicates.cpp index 22654614..bffb18bd 100644 --- a/test/test_predicates.cpp +++ b/test/test_predicates.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { namespace pred = flux::pred; diff --git a/test/test_range_iface.cpp b/test/test_range_iface.cpp index d393ee76..84bd0ad1 100644 --- a/test/test_range_iface.cpp +++ b/test/test_range_iface.cpp @@ -5,11 +5,10 @@ #include "catch.hpp" -#include - #include #include #include +#include #include "test_utils.hpp" diff --git a/test/test_read_only.cpp b/test/test_read_only.cpp index 622554fb..338ccfdc 100644 --- a/test/test_read_only.cpp +++ b/test/test_read_only.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_read_only() { diff --git a/test/test_repeat.cpp b/test/test_repeat.cpp index c4abf74b..56b0a363 100644 --- a/test/test_repeat.cpp +++ b/test/test_repeat.cpp @@ -5,14 +5,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { struct S { diff --git a/test/test_reverse.cpp b/test/test_reverse.cpp index b5781845..20233ec0 100644 --- a/test/test_reverse.cpp +++ b/test/test_reverse.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_reverse() diff --git a/test/test_scan.cpp b/test/test_scan.cpp index 4cf07d0a..30b58c03 100644 --- a/test/test_scan.cpp +++ b/test/test_scan.cpp @@ -5,14 +5,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_inclusive_scan() diff --git a/test/test_set_adaptors.cpp b/test/test_set_adaptors.cpp index c06a11b3..bdcadd7f 100644 --- a/test/test_set_adaptors.cpp +++ b/test/test_set_adaptors.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_set_union() diff --git a/test/test_simple_sequence.cpp b/test/test_simple_sequence.cpp index 010254b1..d6ebd7bf 100644 --- a/test/test_simple_sequence.cpp +++ b/test/test_simple_sequence.cpp @@ -4,12 +4,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { template @@ -51,7 +49,9 @@ constexpr bool test_simple_sequence() auto iter = array_iterator(arr); using I = decltype(iter); +#ifndef USE_MODULES static_assert(flux::detail::simple_sequence); +#endif static_assert(flux::sequence); static_assert(not flux::multipass_sequence); static_assert(not flux::sized_sequence); @@ -67,7 +67,9 @@ constexpr bool test_simple_sequence() } { +#ifndef USE_MODULES static_assert(flux::detail::simple_sequence); +#endif static_assert(flux::sequence); static_assert(flux::infinite_sequence); static_assert(not flux::multipass_sequence); @@ -76,13 +78,7 @@ constexpr bool test_simple_sequence() static_assert(std::same_as, int>); static_assert(std::same_as, int const&&>); - // FIXME: ints{}.take(10).sum() - int sum = 0; - ints{}.take(10).for_each([&sum](int const& i) { - sum += i; - }); - - STATIC_CHECK(sum == 45); + STATIC_CHECK(ints{}.take(10).sum() == 45); } // Check that we can restart iteration diff --git a/test/test_single.cpp b/test/test_single.cpp index 2597d062..0dbdafe5 100644 --- a/test/test_single.cpp +++ b/test/test_single.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include "test_utils.hpp" namespace { diff --git a/test/test_slide.cpp b/test/test_slide.cpp index b9e5e0c8..f8ffd223 100644 --- a/test/test_slide.cpp +++ b/test/test_slide.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_slide() diff --git a/test/test_sort.cpp b/test/test_sort.cpp index 9a1f548c..5547361d 100644 --- a/test/test_sort.cpp +++ b/test/test_sort.cpp @@ -1,11 +1,6 @@ #include "catch.hpp" -//#define FLUX_ENABLE_BOUNDS_CHECKING -#include - -#include "test_utils.hpp" - #include #include #include @@ -17,6 +12,7 @@ #include #include +#include "test_utils.hpp" namespace { @@ -168,6 +164,7 @@ void test_sort_projected(unsigned sz) delete[] ptr; } +#ifndef USE_MODULES void test_heapsort(unsigned sz) { auto* ptr = new int[sz]; @@ -182,6 +179,7 @@ void test_heapsort(unsigned sz) CHECK(std::is_sorted(ptr, ptr + sz)); delete[] ptr; } +#endif void test_adapted_deque_sort(unsigned sz) { @@ -223,6 +221,7 @@ TEST_CASE("sort") test_adapted_deque_sort(100'000); +#ifndef USE_MODULES // Test our heapsort implementation, because I don't know how to // synthesise a test case in which pqdsort hits this test_heapsort(0); @@ -230,4 +229,5 @@ TEST_CASE("sort") test_heapsort(10); test_heapsort(100); test_heapsort(100'000); +#endif } \ No newline at end of file diff --git a/test/test_split.cpp b/test/test_split.cpp index 4ab0598e..61e20975 100644 --- a/test/test_split.cpp +++ b/test/test_split.cpp @@ -5,16 +5,13 @@ #include "catch.hpp" -#include -#include - -#include "test_utils.hpp" - #include #include #include #include +#include "test_utils.hpp" + namespace { constexpr auto to_string_view = [](Seq&& seq) // danger Will Robinson diff --git a/test/test_starts_with.cpp b/test/test_starts_with.cpp index 4c54639a..aa223d9b 100644 --- a/test/test_starts_with.cpp +++ b/test/test_starts_with.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include "test_utils.hpp" diff --git a/test/test_stride.cpp b/test/test_stride.cpp index a7d1b793..246776ca 100644 --- a/test/test_stride.cpp +++ b/test/test_stride.cpp @@ -5,14 +5,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { template @@ -24,8 +22,24 @@ struct NotBidir : flux::inline_sequence_base> { constexpr Base& base() & { return base_; } constexpr Base const& base() const& { return base_; } - struct flux_sequence_traits : flux::detail::passthrough_traits_base { - static void dec(...) = delete; + struct flux_sequence_traits { + static constexpr auto first(auto& self) { return flux::first(self.base_); } + + static constexpr bool is_last(auto& self, auto const& cur) { + return flux::is_last(self.base_, cur); + } + + static constexpr void inc(auto& self, auto& cur) { + flux::inc(self.base_, cur); + } + + static constexpr decltype(auto) read_at(auto& self, auto const& cur) { + return flux::read_at(self.base_, cur); + } + + static constexpr auto last(auto& self) { return flux::last(self.base_); } + + static constexpr auto size(auto& self) { return flux::size(self.base_); } }; }; @@ -352,6 +366,7 @@ TEST_CASE("stride") REQUIRE(rev.sum() == 12); } +#ifndef USE_MODULES // detail::advance tests to keep CodeCov happy { { @@ -378,4 +393,5 @@ TEST_CASE("stride") REQUIRE(r == 0); } } +#endif } \ No newline at end of file diff --git a/test/test_take.cpp b/test/test_take.cpp index 6d6365c4..858cb387 100644 --- a/test/test_take.cpp +++ b/test/test_take.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { struct Tester : flux::simple_sequence_base { diff --git a/test/test_take_while.cpp b/test/test_take_while.cpp index 357280f6..99f19700 100644 --- a/test/test_take_while.cpp +++ b/test/test_take_while.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { struct ints { diff --git a/test/test_to.cpp b/test/test_to.cpp index ae1e4a75..9174524c 100644 --- a/test/test_to.cpp +++ b/test/test_to.cpp @@ -5,8 +5,6 @@ #include "catch.hpp" -#include - #include #include #include diff --git a/test/test_unchecked.cpp b/test/test_unchecked.cpp index 92b457ef..79df1133 100644 --- a/test/test_unchecked.cpp +++ b/test/test_unchecked.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_unchecked() diff --git a/test/test_unfold.cpp b/test/test_unfold.cpp index 98cb543e..65a130cb 100644 --- a/test/test_unfold.cpp +++ b/test/test_unfold.cpp @@ -5,12 +5,10 @@ #include "catch.hpp" -#include +#include #include "test_utils.hpp" -#include - namespace { constexpr bool test_unfold() diff --git a/test/test_utils.hpp b/test/test_utils.hpp index 4ff0840f..0c3860a2 100644 --- a/test/test_utils.hpp +++ b/test/test_utils.hpp @@ -7,9 +7,12 @@ #pragma once -#include -#include -#include +#ifndef USE_MODULES +#include +#else +#include +import flux; +#endif #define STATIC_CHECK(...) if (!(__VA_ARGS__)) throw std::runtime_error("Test assertion failed") diff --git a/test/test_write_to.cpp b/test/test_write_to.cpp index 6828a272..c619e791 100644 --- a/test/test_write_to.cpp +++ b/test/test_write_to.cpp @@ -5,11 +5,15 @@ #include "catch.hpp" -#include - #include #include +#ifdef USE_MODULES +import flux; +#else +#include +#endif + TEST_CASE("write to") { SECTION("Basic write_to") diff --git a/test/test_zip.cpp b/test/test_zip.cpp index 415e44b0..bbb6ecb6 100644 --- a/test/test_zip.cpp +++ b/test/test_zip.cpp @@ -5,14 +5,12 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_zip() diff --git a/test/test_zip_algorithms.cpp b/test/test_zip_algorithms.cpp index bb48b3dc..123e3d9c 100644 --- a/test/test_zip_algorithms.cpp +++ b/test/test_zip_algorithms.cpp @@ -5,13 +5,11 @@ #include "catch.hpp" -#include - -#include "test_utils.hpp" - #include #include +#include "test_utils.hpp" + namespace { constexpr bool test_zip_for_each() From 8d247cadda734d778f048c46c19ccd906da12276 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Sat, 6 Jan 2024 14:42:14 +0000 Subject: [PATCH 05/13] Disable module building on Windows CI ...at least until the Github Actions image includes CMake 3.28 --- .github/workflows/windows.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b596eb28..29d4f51c 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -27,7 +27,6 @@ jobs: run: | cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ -DFLUX_BUILD_BENCHMARKS=${{matrix.build_type == 'Release'}} \ - -DFLUX_BUILD_MODULE=On \ -A ${{matrix.platform}} \ $GITHUB_WORKSPACE From 2e769b56a28d5f4289b15ef8f2f8f3e658ab14dc Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 14:33:12 +0000 Subject: [PATCH 06/13] Add namespaced alias for the flux-mod CMake target Good practise, apparently --- module/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index fdfcd70f..feba9dcd 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -1,12 +1,15 @@ add_library(flux-mod) +add_library(flux::module ALIAS flux-mod) + target_sources(flux-mod PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR}/module FILES flux.cpp ) -target_link_libraries(flux-mod PUBLIC flux) +target_link_libraries(flux-mod PRIVATE flux) +target_compile_features(flux-mod PUBLIC $,cxx_std_23,cxx_std_20>) set_target_properties(flux-mod PROPERTIES CXX_EXTENSIONS Off) # Squish MSVC warning when building the module, hopefully we're not actually doing anything wrong From e8ba4476f46492019bb978c31ce58e5f8757db51 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 17:41:33 +0000 Subject: [PATCH 07/13] Move assert macros to macros.hpp Seems like a good place for them --- include/flux/core/assert.hpp | 4 ---- include/flux/core/macros.hpp | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/flux/core/assert.hpp b/include/flux/core/assert.hpp index 03758072..c6a580a7 100644 --- a/include/flux/core/assert.hpp +++ b/include/flux/core/assert.hpp @@ -100,10 +100,6 @@ FLUX_EXPORT inline constexpr auto assert_ = detail::assert_fn{}; FLUX_EXPORT inline constexpr auto bounds_check = detail::bounds_check_fn{}; FLUX_EXPORT inline constexpr auto indexed_bounds_check = detail::indexed_bounds_check_fn{}; -#define FLUX_ASSERT(cond) (::flux::assert_(cond, "assertion '" #cond "' failed")) - -#define FLUX_DEBUG_ASSERT(cond) (::flux::assert_(!::flux::config::enable_debug_asserts || (cond), "assertion '" #cond "' failed")); - } // namespace flux #endif // FLUX_CORE_ASSERT_HPP_INCLUDED diff --git a/include/flux/core/macros.hpp b/include/flux/core/macros.hpp index 69d32203..e781bad0 100644 --- a/include/flux/core/macros.hpp +++ b/include/flux/core/macros.hpp @@ -27,6 +27,10 @@ ::flux::inc(_flux_seq_, _flux_cur_)) \ if (_flux_var_decl_ = ::flux::read_at(_flux_seq_, _flux_cur_); true) +#define FLUX_ASSERT(cond) (::flux::assert_(cond, "assertion '" #cond "' failed")) + +#define FLUX_DEBUG_ASSERT(cond) (::flux::assert_(!::flux::config::enable_debug_asserts || (cond), "assertion '" #cond "' failed")); + #ifdef FLUX_MODULE_INTERFACE #define FLUX_EXPORT export #else From 23cf47762b218a8d05847851c3b6447752b6d0ca Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 18:03:57 +0000 Subject: [PATCH 08/13] Move macros.hpp to include/flux We want to export it as flux/macros.hpp and provide it alongside our module --- include/flux/core.hpp | 1 - include/flux/core/concepts.hpp | 1 - include/flux/core/config.hpp | 2 +- include/flux/core/functional.hpp | 2 +- include/flux/{core => }/macros.hpp | 0 test/test_utils.hpp | 2 +- 6 files changed, 3 insertions(+), 5 deletions(-) rename include/flux/{core => }/macros.hpp (100%) diff --git a/include/flux/core.hpp b/include/flux/core.hpp index b9334df1..88cec54e 100644 --- a/include/flux/core.hpp +++ b/include/flux/core.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/include/flux/core/concepts.hpp b/include/flux/core/concepts.hpp index 53e9e9ed..84f9039f 100644 --- a/include/flux/core/concepts.hpp +++ b/include/flux/core/concepts.hpp @@ -6,7 +6,6 @@ #ifndef FLUX_CORE_CONCEPTS_HPP_INCLUDED #define FLUX_CORE_CONCEPTS_HPP_INCLUDED -#include #include #include diff --git a/include/flux/core/config.hpp b/include/flux/core/config.hpp index 03f2d76c..b7859528 100644 --- a/include/flux/core/config.hpp +++ b/include/flux/core/config.hpp @@ -6,7 +6,7 @@ #ifndef FLUX_CORE_CONFIG_HPP_INCLUDED #define FLUX_CORE_CONFIG_HPP_INCLUDED -#include +#include #include #include diff --git a/include/flux/core/functional.hpp b/include/flux/core/functional.hpp index 5639e3d8..54751088 100644 --- a/include/flux/core/functional.hpp +++ b/include/flux/core/functional.hpp @@ -6,7 +6,7 @@ #ifndef FLUX_CORE_FUNCTIONAL_HPP_INCLUDED #define FLUX_CORE_FUNCTIONAL_HPP_INCLUDED -#include +#include #include #include diff --git a/include/flux/core/macros.hpp b/include/flux/macros.hpp similarity index 100% rename from include/flux/core/macros.hpp rename to include/flux/macros.hpp diff --git a/test/test_utils.hpp b/test/test_utils.hpp index 0c3860a2..058e1336 100644 --- a/test/test_utils.hpp +++ b/test/test_utils.hpp @@ -10,7 +10,7 @@ #ifndef USE_MODULES #include #else -#include +#include import flux; #endif From c168826c8606ac9f593a60610cbc1fe92b65fc80 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 18:05:54 +0000 Subject: [PATCH 09/13] Provide flux/macros.hpp with flux::module target Even if, at some future date, we're all using modules, there are still some useful macros in here -- so we may as well make them available to consumers --- module/CMakeLists.txt | 6 ++++++ test/test_module_import.cpp | 3 +++ 2 files changed, 9 insertions(+) diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index feba9dcd..0203601b 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -8,6 +8,12 @@ target_sources(flux-mod PUBLIC FILES flux.cpp ) +target_sources(flux-mod PUBLIC + FILE_SET HEADERS + BASE_DIRS ${PROJECT_SOURCE_DIR}/include + FILES ${PROJECT_SOURCE_DIR}/include/flux/macros.hpp +) + target_link_libraries(flux-mod PRIVATE flux) target_compile_features(flux-mod PUBLIC $,cxx_std_23,cxx_std_20>) set_target_properties(flux-mod PROPERTIES CXX_EXTENSIONS Off) diff --git a/test/test_module_import.cpp b/test/test_module_import.cpp index f588d70c..af085cf6 100644 --- a/test/test_module_import.cpp +++ b/test/test_module_import.cpp @@ -3,10 +3,13 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#include + import flux; int main() { + FLUX_ASSERT(1 != 2); constexpr int arr[] = {1, 2, 3, 4, 5}; static_assert(flux::sum(arr) == 15); } From 381c1056c176f0c01aa6999176f9664e59b06779 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 18:32:20 +0000 Subject: [PATCH 10/13] Unconditionally precompile catch.hpp We're already requiring a new enough CMake --- test/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 373d6097..35316999 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -82,6 +82,7 @@ target_compile_definitions(test-flux PUBLIC FLUX_ERROR_ON_OVERFLOW FLUX_DISABLE_STATIC_BOUNDS_CHECKING ) +target_precompile_headers(test-flux PRIVATE "catch.hpp") if(${FLUX_ENABLE_ASAN}) target_compile_options(test-flux PRIVATE -fsanitize=address) @@ -106,10 +107,6 @@ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") endif() endif() -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") - target_precompile_headers(test-flux PRIVATE "catch.hpp") -endif() - if(${FLUX_BUILD_MODULE}) add_executable(test-module-import test_module_import.cpp) target_link_libraries(test-module-import PUBLIC flux-mod) From 5a7852f29a9fc3362daa51a90c45580f3c30195d Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 18:37:03 +0000 Subject: [PATCH 11/13] Add a separate option for testing with modules Right now MSVC can build the Flux module, but seemingly has some bugs which prevent it from compiling all the tests when using imports. So for now we'll split this into a separate option. --- CMakeLists.txt | 1 + test/CMakeLists.txt | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20904318..782ecb1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ option(FLUX_BUILD_TESTS "Build Flux tests" ${PROJECT_IS_TOP_LEVEL}) option(FLUX_BUILD_BENCHMARKS "Build Flux benchmarks" Off) option(FLUX_BUILD_TOOLS "Build single-header generator tool" Off) option(FLUX_BUILD_MODULE "Build C++20 module (experimental)" Off) +option(FLUX_BUILD_TESTS_USING_MODULE "Build tests using modules (experimental)" Off) option(FLUX_ENABLE_ASAN "Enable Address Sanitizer for tests" Off) option(FLUX_ENABLE_UBSAN "Enable Undefined Behaviour Sanitizer for tests" Off) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 35316999..8d4aef04 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -84,18 +84,18 @@ target_compile_definitions(test-flux PUBLIC ) target_precompile_headers(test-flux PRIVATE "catch.hpp") -if(${FLUX_ENABLE_ASAN}) +if(FLUX_ENABLE_ASAN) target_compile_options(test-flux PRIVATE -fsanitize=address) target_link_options(test-flux PRIVATE -fsanitize=address) endif() -if(${FLUX_ENABLE_UBSAN}) +if(FLUX_ENABLE_UBSAN) target_compile_options(test-flux PRIVATE -fsanitize=undefined) target_link_options(test-flux PRIVATE -fsanitize=undefined) endif() if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") - if (${FLUX_BUILD_MODULE}) + if (FLUX_BUILD_TESTS_USING_MODULE) target_sources(test-flux PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${PROJECT_SOURCE_DIR}/module @@ -107,7 +107,7 @@ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") endif() endif() -if(${FLUX_BUILD_MODULE}) +if(FLUX_BUILD_MODULE) add_executable(test-module-import test_module_import.cpp) target_link_libraries(test-module-import PUBLIC flux-mod) set_target_properties(test-module-import PROPERTIES From 358bb4dfc33b571b571095d54b2504f79a7c3691 Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Tue, 9 Jan 2024 23:59:28 +0000 Subject: [PATCH 12/13] Silence MSVC warning when building test module There are plenty more errors once you try *using* the test module though... --- test/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8d4aef04..6077a4a0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -104,6 +104,13 @@ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.28.0") target_compile_definitions(test-flux PRIVATE -DUSE_MODULES) set_target_properties(test-flux PROPERTIES CXX_SCAN_FOR_MODULES On) + + # Squish MSVC warning when building the module, hopefully we're not actually doing anything wrong + if(MSVC) + target_compile_options(test-flux PRIVATE + /wd5244 # '#include ' in the purview of module 'flux' appears erroneous + ) + endif() endif() endif() From f57cad528b38e7f640dacfee1bba3c3b782e451c Mon Sep 17 00:00:00 2001 From: Tristan Brindle Date: Wed, 10 Jan 2024 00:50:38 +0000 Subject: [PATCH 13/13] Hard error on FLUX_BUILD_MODULE with CMake < 3.28 As I've just found out, a warning is too easy to miss in an IDE, leaving you wondering why the module target isn't appearing --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 782ecb1a..3277cbc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,8 +77,8 @@ if (FLUX_BUILD_TOOLS) endif() if (FLUX_BUILD_MODULE) - if(${CMAKE_VERSION} VERSION_LESS "3.28.0") - message(WARNING "Modules support requires CMake v3.28 or later") + if(CMAKE_VERSION VERSION_LESS "3.28.0") + message(FATAL_ERROR "Modules support requires CMake v3.28 or later (currently v${CMAKE_VERSION})") else() add_subdirectory(module) endif()