diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 37bfdd3a..d2401513 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -33,7 +33,7 @@ jobs: run: ctest - name: Generate coverage report - working-directory: ${{runner.workspace}}/build/test/CMakeFiles/test-libflux.dir + working-directory: ${{runner.workspace}}/build/test/CMakeFiles/test-flux.dir run: | lcov --directory . --capture --gcov gcov-13 --output-file coverage.info lcov --remove coverage.info '*/test/*' --output-file coverage.info @@ -41,5 +41,5 @@ jobs: - name: Upload coverage report uses: codecov/codecov-action@v3 with: - files: ${{runner.workspace}}/build/test/CMakeFiles/test-libflux.dir/coverage.info + files: ${{runner.workspace}}/build/test/CMakeFiles/test-flux.dir/coverage.info diff --git a/CMakeLists.txt b/CMakeLists.txt index e87b3c74..09166113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,121 +1,117 @@ -cmake_minimum_required(VERSION 3.5) -cmake_policy(SET CMP0076 NEW) # remove warning for target_sources(flux...) for < 3.13 -cmake_policy(SET CMP0092 NEW) # remove warning for CMAKE_LANG_FLAG MSVC for < 3.15 +cmake_minimum_required(VERSION 3.23) -project(libflux CXX) +project(flux CXX) include(GNUInstallDirs) include(CMakePackageConfigHelpers) - -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") add_library(flux INTERFACE) -file(GLOB_RECURSE FLUX_HPPS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp" ) -target_sources(flux INTERFACE $) - -if (MSVC) - target_compile_features(flux INTERFACE cxx_std_23) - target_compile_options(flux INTERFACE /permissive-) -else() - target_compile_features(flux INTERFACE cxx_std_20) -endif() - -target_include_directories( - flux - INTERFACE - $ - $ +add_library(flux::flux ALIAS flux) + +file(GLOB_RECURSE FLUX_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp" ) + +target_sources(flux INTERFACE + FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include + FILES ${FLUX_HEADERS}) + +target_compile_features(flux INTERFACE $,cxx_std_23,cxx_std_20>) +set_target_properties(flux PROPERTIES CXX_STANDARD_REQUIRED On) + +add_library(flux-internal INTERFACE) +target_link_libraries(flux-internal INTERFACE flux) +set_target_properties(flux-internal PROPERTIES CXX_EXTENSIONS Off) + +target_compile_options(flux-internal INTERFACE + $<$: + -Wall -Wextra -Wconversion -pedantic + -fno-omit-frame-pointer + -ftemplate-backtrace-limit=0 + > + + $<$: -fconcepts-diagnostics-depth=2> + + $<$: + # Various options for closer standard conformance + /utf-8 /Zc:__cplusplus /Zc:throwingNew /Zc:inline /Zc:externConstexpr + /Zc:templateScope /Zc:checkGwOdr /Zc:enumTypes + /W4 + /wd4459 # local variable name hides global variable + /wd4702 # unreachable code + > ) -set(CMAKE_CXX_EXTENSIONS Off) - option(FLUX_BUILD_DOCS "Build Flux documentation (requires Sphinx)" Off) -option(FLUX_BUILD_EXAMPLES "Build Flux examples" On) -option(FLUX_BUILD_TESTS "Build Flux tests" On) +option(FLUX_BUILD_EXAMPLES "Build Flux examples" ${PROJECT_IS_TOP_LEVEL}) +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_ENABLE_ASAN "Enable Address Sanitizer for tests" Off) option(FLUX_ENABLE_UBSAN "Enable Undefined Behaviour Sanitizer for tests" Off) -if (${FLUX_BUILD_DOCS}) +if (FLUX_BUILD_DOCS) add_subdirectory(docs) endif() -if (${FLUX_BUILD_EXAMPLES}) +if (FLUX_BUILD_EXAMPLES) enable_testing() add_subdirectory(example) endif() -if (${FLUX_BUILD_BENCHMARKS}) +if (FLUX_BUILD_BENCHMARKS) add_subdirectory(benchmark) endif() -if (${FLUX_BUILD_TESTS}) +if (FLUX_BUILD_TESTS) enable_testing() add_subdirectory(test) endif() -if (${FLUX_BUILD_TOOLS}) +if (FLUX_BUILD_TOOLS) add_subdirectory(tools) endif() -if (${FLUX_BUILD_MODULE}) +if (FLUX_BUILD_MODULE) add_subdirectory(module) endif() -set(PORT_NAME flux) -set(CONFIG_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PORT_NAME}") +set(FLUX_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/flux) -# header-only doesn't need architeture differences so clear CMAKE_SIZEOF_VOIDP -# temporarily when creating the version file. -set(ORIGINAL_CMAKE_SIZEOF_VOIDP ${CMAKE_SIZEOF_VOIDP}) -set(CMAKE_SIZEOF_VOIDP "") write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/${PORT_NAME}-version.cmake" + "${PROJECT_BINARY_DIR}/flux-version.cmake" VERSION -1 # When there is a PROJECT_VERSION, remove this line COMPATIBILITY SameMajorVersion - # ARCH_INDEPENDENT # showed up in CMake 3.14 and gets rid of the need to do the CMAKE_SIZEOF_VOIDP thing + ARCH_INDEPENDENT ) -set(CMAKE_SIZEOF_VOIDP ${ORIGINAL_CMAKE_SIZEOF_VOIDP}) configure_package_config_file( - "${PROJECT_SOURCE_DIR}/cmake/${PORT_NAME}-config.cmake.in" - "${PROJECT_BINARY_DIR}/${PORT_NAME}-config.cmake" - INSTALL_DESTINATION "${CONFIG_DESTINATION}" - NO_SET_AND_CHECK_MACRO - NO_CHECK_REQUIRED_COMPONENTS_MACRO + "${PROJECT_SOURCE_DIR}/cmake/flux-config.cmake.in" + "${PROJECT_BINARY_DIR}/flux-config.cmake" + INSTALL_DESTINATION ${FLUX_INSTALL_CMAKE_DIR} ) # set target installation location properties and associates it with the targets files install( - TARGETS ${PORT_NAME} - EXPORT ${PORT_NAME}-targets - ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" - LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + TARGETS flux + EXPORT flux-targets + FILE_SET HEADERS ) #install the targets files install( - EXPORT ${PORT_NAME}-targets - NAMESPACE ${PORT_NAME}:: - DESTINATION "${CONFIG_DESTINATION}" + EXPORT flux-targets + NAMESPACE flux:: + DESTINATION ${FLUX_INSTALL_CMAKE_DIR} ) # install the config and version files install( FILES - "${PROJECT_BINARY_DIR}/${PORT_NAME}-config.cmake" - "${PROJECT_BINARY_DIR}/${PORT_NAME}-version.cmake" - DESTINATION "${CONFIG_DESTINATION}" + "${PROJECT_BINARY_DIR}/flux-config.cmake" + "${PROJECT_BINARY_DIR}/flux-version.cmake" + DESTINATION ${FLUX_INSTALL_CMAKE_DIR} ) - -# install the headers -install( - DIRECTORY "${PROJECT_SOURCE_DIR}/include" - DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/.." - PATTERN "build2file" EXCLUDE -) \ No newline at end of file diff --git a/cmake/flux-config.cmake.in b/cmake/flux-config.cmake.in index 06223ad3..9d9dd21d 100644 --- a/cmake/flux-config.cmake.in +++ b/cmake/flux-config.cmake.in @@ -1,3 +1,4 @@ @PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/flux-targets.cmake") -list(APPEND CMAKE_MODULE_PATH "@PACKAGE_cmakeModulesDir@") \ No newline at end of file + +check_required_components(flux) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 44f5668b..248db317 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,7 +1,7 @@ function(ADD_EXAMPLE NAME SOURCE) add_executable(${NAME} ${SOURCE}) - target_link_libraries(${NAME} flux) + target_link_libraries(${NAME} flux-internal) if(${${NAME}_SKIP_TEST}) #pass else() diff --git a/example/calendar.cpp b/example/calendar.cpp index 249c7b5d..e91c5828 100644 --- a/example/calendar.cpp +++ b/example/calendar.cpp @@ -96,7 +96,8 @@ auto to_week_lines = [](flux::sequence auto&& month) { auto week_lines = FLUX_FWD(month) .chunk_by(week_num) .map(week_to_string); - std::vector pad_lines(max_weeks_in_month - flux::count(week_lines), std::string(week_str_size, ' ')); + std::vector pad_lines(size_t(max_weeks_in_month - flux::count(week_lines)), + std::string(week_str_size, ' ')); return flux::chain(flux::single(std::move(month_str)), std::move(week_lines), std::move(pad_lines), @@ -113,13 +114,14 @@ auto append_column = [](std::vector&& months_per_line, flux::sequen // Out: std::vector (months organized in columns) auto to_columns = [](flux::sequence auto&& month_chunk) { auto n_rows = month_chunk.front()->count(); - return FLUX_FWD(month_chunk).fold(append_column, std::vector(n_rows, col_sep)); + return FLUX_FWD(month_chunk).fold(append_column, + std::vector(size_t(n_rows), col_sep)); }; const auto current_year = ymd{floor(system_clock::now())}.year(); struct app_args_t { - unsigned per_line = 3; + int per_line = 3; ymd from = current_year / January / 1d; ymd to = from + years{1}; }; @@ -146,7 +148,8 @@ app_args_t parse_args(int argc, char** argv) { auto to_pair = [](const auto& s) { auto pos = flux::find(flux::ref(s), '='); - return std::pair{s.substr(0, pos), s.substr(std::min(flux::count(s), pos + 1))}; + return std::pair{s.substr(0, size_t(pos)), + s.substr(size_t(std::min(flux::count(s), pos + 1)))}; }; for (const auto& [key, val] : flux::ref(args).map(to_pair)) { diff --git a/example/docs/adjacent.cpp b/example/docs/adjacent.cpp index 04e2021a..e3701ff7 100644 --- a/example/docs/adjacent.cpp +++ b/example/docs/adjacent.cpp @@ -6,7 +6,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/adjacent_filter.cpp b/example/docs/adjacent_filter.cpp index 1df211c4..f3fd531d 100644 --- a/example/docs/adjacent_filter.cpp +++ b/example/docs/adjacent_filter.cpp @@ -6,7 +6,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/all.cpp b/example/docs/all.cpp index 74ee752d..963049c0 100644 --- a/example/docs/all.cpp +++ b/example/docs/all.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include int main() diff --git a/example/docs/any.cpp b/example/docs/any.cpp index 8c424da1..66f257c7 100644 --- a/example/docs/any.cpp +++ b/example/docs/any.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include int main() diff --git a/example/docs/assert.hpp b/example/docs/assert.hpp new file mode 100644 index 00000000..ac5db8f9 --- /dev/null +++ b/example/docs/assert.hpp @@ -0,0 +1,15 @@ + +// Copyright (c) 2024 Tristan Brindle (tcbrindle at gmail dot com) +// 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) + +#ifndef FLUX_EXAMPLE_DOCS_ASSERT_HPP_INCLUDED +#define FLUX_EXAMPLE_DOCS_ASSERT_HPP_INCLUDED + +#ifdef NDEBUG +#undef NDEBUG +#endif + +#include + +#endif diff --git a/example/docs/compare.cpp b/example/docs/compare.cpp index a23803cb..419f436d 100644 --- a/example/docs/compare.cpp +++ b/example/docs/compare.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include #include diff --git a/example/docs/contains.cpp b/example/docs/contains.cpp index f8c18e85..d82cf2e9 100644 --- a/example/docs/contains.cpp +++ b/example/docs/contains.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include int main() diff --git a/example/docs/count.cpp b/example/docs/count.cpp index cf43c6c3..51d431f1 100644 --- a/example/docs/count.cpp +++ b/example/docs/count.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/cycle.cpp b/example/docs/cycle.cpp index 70747f2e..df5767db 100644 --- a/example/docs/cycle.cpp +++ b/example/docs/cycle.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include #include int main() diff --git a/example/docs/drop.cpp b/example/docs/drop.cpp index 1260203b..a25a0279 100644 --- a/example/docs/drop.cpp +++ b/example/docs/drop.cpp @@ -6,7 +6,7 @@ #include -#include +#include "assert.hpp" #include int main() diff --git a/example/docs/ends_with.cpp b/example/docs/ends_with.cpp index 2b3a80f6..8a032d3e 100644 --- a/example/docs/ends_with.cpp +++ b/example/docs/ends_with.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/find_max.cpp b/example/docs/find_max.cpp index 5fd78ed2..b86121a3 100644 --- a/example/docs/find_max.cpp +++ b/example/docs/find_max.cpp @@ -1,7 +1,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/find_min.cpp b/example/docs/find_min.cpp index bd15f876..d5704573 100644 --- a/example/docs/find_min.cpp +++ b/example/docs/find_min.cpp @@ -1,7 +1,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/find_minmax.cpp b/example/docs/find_minmax.cpp index 9ba185c1..950ab47e 100644 --- a/example/docs/find_minmax.cpp +++ b/example/docs/find_minmax.cpp @@ -1,7 +1,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/mask.cpp b/example/docs/mask.cpp index 184e8766..4aa91d0d 100644 --- a/example/docs/mask.cpp +++ b/example/docs/mask.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/prescan.cpp b/example/docs/prescan.cpp index 336743b0..d703cbe8 100644 --- a/example/docs/prescan.cpp +++ b/example/docs/prescan.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/read_only.cpp b/example/docs/read_only.cpp index b4f023f2..2d5bb4af 100644 --- a/example/docs/read_only.cpp +++ b/example/docs/read_only.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/repeat.cpp b/example/docs/repeat.cpp index 43a2ad70..75c9779e 100644 --- a/example/docs/repeat.cpp +++ b/example/docs/repeat.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include #include using namespace std::string_view_literals; diff --git a/example/docs/scan.cpp b/example/docs/scan.cpp index 0c43676b..953bf1d2 100644 --- a/example/docs/scan.cpp +++ b/example/docs/scan.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/scan_first.cpp b/example/docs/scan_first.cpp index ffec642b..26c87f51 100644 --- a/example/docs/scan_first.cpp +++ b/example/docs/scan_first.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/set_difference.cpp b/example/docs/set_difference.cpp index 17375e4f..e084956d 100644 --- a/example/docs/set_difference.cpp +++ b/example/docs/set_difference.cpp @@ -6,8 +6,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/set_intersection.cpp b/example/docs/set_intersection.cpp index 427c9d16..6269a5e1 100644 --- a/example/docs/set_intersection.cpp +++ b/example/docs/set_intersection.cpp @@ -6,8 +6,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/set_symmetric_difference.cpp b/example/docs/set_symmetric_difference.cpp index 0befe905..cbc6c116 100644 --- a/example/docs/set_symmetric_difference.cpp +++ b/example/docs/set_symmetric_difference.cpp @@ -6,8 +6,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/set_union.cpp b/example/docs/set_union.cpp index fe6588a5..228f8a42 100644 --- a/example/docs/set_union.cpp +++ b/example/docs/set_union.cpp @@ -6,8 +6,8 @@ #include +#include "assert.hpp" #include -#include int main() { diff --git a/example/docs/split.cpp b/example/docs/split.cpp index b8c71cf0..47764c9e 100644 --- a/example/docs/split.cpp +++ b/example/docs/split.cpp @@ -5,8 +5,8 @@ #include +#include "assert.hpp" #include -#include #include #include #include diff --git a/example/docs/starts_with.cpp b/example/docs/starts_with.cpp index 07170180..d61cf7a3 100644 --- a/example/docs/starts_with.cpp +++ b/example/docs/starts_with.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include diff --git a/example/docs/unfold.cpp b/example/docs/unfold.cpp index f9b04c12..a69d6e26 100644 --- a/example/docs/unfold.cpp +++ b/example/docs/unfold.cpp @@ -5,7 +5,7 @@ #include -#include +#include "assert.hpp" #include #include @@ -26,5 +26,5 @@ int main() }, 0u); assert(flux::equal(std::move(fibs).take(10), - std::array{0, 1, 1, 2, 3, 5, 8, 13, 21, 34})); -} \ No newline at end of file + std::array{0, 1, 1, 2, 3, 5, 8, 13, 21, 34})); +} diff --git a/example/histogram.cpp b/example/histogram.cpp index 0779f28f..f15ad071 100644 --- a/example/histogram.cpp +++ b/example/histogram.cpp @@ -30,7 +30,7 @@ flux::generator randn(T mean, T stddev = 1.0) std::normal_distribution dist(mean, stddev); while (true) { - co_yield std::round(dist(rng)); + co_yield static_cast(std::round(dist(rng))); } } @@ -45,7 +45,7 @@ auto to_histogram = [](hist_t&& so_far, auto x) void print_histogram(const hist_t& hist) { for (auto [bin, count]: hist){ - std::cout << std::setw(2) << bin << ' ' << std::string(count / 200, '*') << '\n'; + std::cout << std::setw(2) << bin << ' ' << std::string(std::size_t(count)/200, '*') << '\n'; } }; @@ -58,4 +58,4 @@ int main() std::cout << "Normal distribution with mean 5 and stddev 2\n"; print_histogram(randn(5.0, 2.0).take(10000).fold(to_histogram, hist_t{})); std::cout << '\n'; -} \ No newline at end of file +} diff --git a/example/moving_average.cpp b/example/moving_average.cpp index e8ec09f2..6dd711d6 100644 --- a/example/moving_average.cpp +++ b/example/moving_average.cpp @@ -25,7 +25,7 @@ struct sliding_window_t } int average() const { - return sum / window.size(); + return sum / static_cast(window.size()); } std::size_t size; @@ -64,4 +64,4 @@ int main() { assert(ma2[0] == 4); // (1 + 5 + 6) / 3 assert(ma2[1] == 4); // (5 + 6 + 1) / 3 assert(ma2.back() == 2); // (7 + -1 + 0) / 3 -} \ No newline at end of file +} diff --git a/example/prime_numbers.cpp b/example/prime_numbers.cpp index 11d534ee..c92f7502 100644 --- a/example/prime_numbers.cpp +++ b/example/prime_numbers.cpp @@ -8,9 +8,9 @@ #include #include -flux::generator primes() +flux::generator primes() { - std::vector history; + std::vector history; auto is_prime = [&](auto x) { return flux::none(history, [x](auto prime) { return (x % prime) == 0; }); }; @@ -22,9 +22,9 @@ flux::generator primes() } } -int main(int argc, char** argv) +int main() { // Prints all prime numbers less than 1000 primes().take_while(flux::pred::lt(1000)).write_to(std::cout); std::cout << std::endl; -} \ No newline at end of file +} diff --git a/example/shortest_path.cpp b/example/shortest_path.cpp index 5e90954e..50e4681f 100644 --- a/example/shortest_path.cpp +++ b/example/shortest_path.cpp @@ -76,8 +76,8 @@ class maze { std::uniform_int_distribution dist(1, 9); maze m(width, height); - for (auto i: flux::ints(1, m.fields_.size() - 1)) { - m.fields_[i] = (rng() % 4) == 0 ? wall : dist(rng); + for (auto i: flux::ints(1, flux::size(m.fields_) - 1)) { + m.fields_[size_t(i)] = (rng() % 4) == 0 ? wall : dist(rng); } return m; diff --git a/example/top10/01_trapping_rain_water.cpp b/example/top10/01_trapping_rain_water.cpp index b0a8e4e7..270a1399 100644 --- a/example/top10/01_trapping_rain_water.cpp +++ b/example/top10/01_trapping_rain_water.cpp @@ -11,9 +11,9 @@ * */ -#include +#include // for std::minus -#include +#include auto const rain_water = [](std::initializer_list heights) { diff --git a/example/top10/06_max_gap.cpp b/example/top10/06_max_gap.cpp index ac51b34e..7cdf4d37 100644 --- a/example/top10/06_max_gap.cpp +++ b/example/top10/06_max_gap.cpp @@ -14,8 +14,6 @@ #include -#include - namespace { // std::abs is not constexpr in C++20 @@ -34,6 +32,6 @@ auto const max_gap = [](std::vector nums) int main() { - assert(max_gap({3, 6, 9, 1}) == 3); - assert(max_gap({10}) == 0); + FLUX_ASSERT(max_gap({3, 6, 9, 1}) == 3); + FLUX_ASSERT(max_gap({10}) == 0); } diff --git a/example/top10/07_max_gap_count.cpp b/example/top10/07_max_gap_count.cpp index 3140672c..8de49ee0 100644 --- a/example/top10/07_max_gap_count.cpp +++ b/example/top10/07_max_gap_count.cpp @@ -11,8 +11,6 @@ #include -#include - // GCC 11 doesn't support constexpr std::vector #if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 12 #define COMPILER_IS_GCC11 @@ -77,15 +75,15 @@ int main() { { using namespace version1; - assert(max_gap_count({2, 5, 8, 1}) == 2); - assert(max_gap_count({3, 6, 9, 1}) == 2); - assert(max_gap_count({10}) == 0); + FLUX_ASSERT(max_gap_count({2, 5, 8, 1}) == 2); + FLUX_ASSERT(max_gap_count({3, 6, 9, 1}) == 2); + FLUX_ASSERT(max_gap_count({10}) == 0); } { using namespace version2; - assert(max_gap_count({2, 5, 8, 1}) == 2); - assert(max_gap_count({3, 6, 9, 1}) == 2); - assert(max_gap_count({10}) == 0); + FLUX_ASSERT(max_gap_count({2, 5, 8, 1}) == 2); + FLUX_ASSERT(max_gap_count({3, 6, 9, 1}) == 2); + FLUX_ASSERT(max_gap_count({10}) == 0); } } diff --git a/example/top10/09_skyline.cpp b/example/top10/09_skyline.cpp index d435c90f..20a1059f 100644 --- a/example/top10/09_skyline.cpp +++ b/example/top10/09_skyline.cpp @@ -14,9 +14,6 @@ #include -#include - - auto const skyline = [](std::initializer_list heights) { auto h = flux::ref(heights); diff --git a/example/top10/10_ocean_view.cpp b/example/top10/10_ocean_view.cpp index 0d0116f3..5838298a 100644 --- a/example/top10/10_ocean_view.cpp +++ b/example/top10/10_ocean_view.cpp @@ -14,19 +14,17 @@ * https://leetcode.ca/all/1762.html */ -#include - -#include -#include #include +#include + using index_vec = std::vector; auto const ocean_view = [](std::vector const& heights) -> index_vec { auto indices = flux::zip(flux::ref(heights).cursors().reverse(), flux::ref(heights).reverse().prescan(flux::cmp::max, 0)) - .filter([&](auto pair) { return heights[pair.first] > pair.second; }) + .filter([&](auto pair) { return flux::read_at(heights, pair.first) > pair.second; }) .map([](auto pair) { return pair.first; }) .to(); @@ -37,8 +35,8 @@ auto const ocean_view = [](std::vector const& heights) -> index_vec int main() { - assert(ocean_view({4,2,3,1}) == index_vec({0,2,3})); - assert(ocean_view({4,3,2,1}) == index_vec({0,1,2,3})); - assert(ocean_view({1,3,2,4}) == index_vec{3}); - assert(ocean_view({2,2,2,2}) == index_vec{3}); + FLUX_ASSERT(ocean_view({4,2,3,1}) == index_vec({0,2,3})); + FLUX_ASSERT(ocean_view({4,3,2,1}) == index_vec({0,1,2,3})); + FLUX_ASSERT(ocean_view({1,3,2,4}) == index_vec{3}); + FLUX_ASSERT(ocean_view({2,2,2,2}) == index_vec{3}); } \ No newline at end of file diff --git a/include/flux/op/adjacent.hpp b/include/flux/op/adjacent.hpp index 8e67df2c..e706d1b7 100644 --- a/include/flux/op/adjacent.hpp +++ b/include/flux/op/adjacent.hpp @@ -48,7 +48,7 @@ struct adjacent_sequence_traits_base { { cursor_type out{flux::first(self.base_), }; - for (auto i : flux::ints(1, N)) { + for (auto i : flux::iota(std::size_t{1}, std::size_t{N})) { out.arr[i] = out.arr[i - 1]; if (!flux::is_last(self.base_, out.arr[i])) { flux::inc(self.base_, out.arr[i]); @@ -75,7 +75,7 @@ struct adjacent_sequence_traits_base { cursor_type out{}; out.arr.back() = flux::last(self.base_); auto const first = flux::first(self.base_); - for (auto i : flux::ints(0, N-1).reverse()) { + for (auto i : flux::iota(std::size_t{0}, std::size_t{N}-1).reverse()) { out.arr[i] = out.arr[i + 1]; if (out.arr[i] != first) { flux::dec(self.base_, out.arr[i]); diff --git a/include/flux/op/cycle.hpp b/include/flux/op/cycle.hpp index 8023ba57..774e370e 100644 --- a/include/flux/op/cycle.hpp +++ b/include/flux/op/cycle.hpp @@ -170,7 +170,7 @@ struct cycle_adaptor : inline_sequence_base> { auto off = flux::distance(self.base_, first, cur.base_cur); off = num::checked_add(off, offset); - cur.n += off/sz; + cur.n += static_cast(off/sz); off = off % sz; if (off < 0) { diff --git a/include/flux/source/bitset.hpp b/include/flux/source/bitset.hpp index 1bf3bf7d..22ef34da 100644 --- a/include/flux/source/bitset.hpp +++ b/include/flux/source/bitset.hpp @@ -52,7 +52,7 @@ struct sequence_traits> { static constexpr auto inc(self_t const&, std::size_t& idx, std::ptrdiff_t off) -> std::size_t& { - return idx += off; + return idx += static_cast(off); } static constexpr auto distance(self_t const&, std::size_t from, std::size_t to) @@ -63,7 +63,7 @@ struct sequence_traits> { static constexpr auto last(self_t const&) -> std::size_t { return N; } - static constexpr auto size(self_t const&) -> std::size_t { return N; } + static constexpr auto size(self_t const&) -> std::ptrdiff_t { return N; } }; diff --git a/include/flux/source/repeat.hpp b/include/flux/source/repeat.hpp index c421ea8d..3e5dd531 100644 --- a/include/flux/source/repeat.hpp +++ b/include/flux/source/repeat.hpp @@ -72,7 +72,7 @@ struct repeat_sequence : inline_sequence_base> static constexpr auto inc(self_t const&, std::size_t& cur, distance_t offset) -> void { - cur += offset; + cur += static_cast(offset); } static constexpr auto distance(self_t const&, std::size_t from, std::size_t to) -> distance_t @@ -110,7 +110,7 @@ struct repeat_sequence : inline_sequence_base> static constexpr auto size(self_t const& self) -> distance_t requires (!IsInfinite) { - return self.data_.count; + return checked_cast(self.data_.count); } }; }; diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt index 3c1bf2c0..0ef8f798 100644 --- a/module/CMakeLists.txt +++ b/module/CMakeLists.txt @@ -3,6 +3,7 @@ include(modules) add_module_library(flux-mod flux.cpp) target_link_libraries(flux-mod PUBLIC flux) +set_target_properties(flux-mod PROPERTIES CXX_EXTENSIONS Off) # Squish MSVC warning when building the module, hopefully we're not actually doing anything wrong if(MSVC) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d4b489b..f33dbc23 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,7 +3,7 @@ add_library(catch-main catch_main.cpp) target_compile_features(catch-main PUBLIC cxx_std_20) target_compile_definitions(catch-main PUBLIC -DCATCH_CONFIG_NO_POSIX_SIGNALS) -add_executable(test-libflux +add_executable(test-flux test_concepts.cpp test_overflow.cpp @@ -76,45 +76,32 @@ add_executable(test-libflux test_single.cpp test_unfold.cpp ) -target_link_libraries(test-libflux flux catch-main) -target_compile_definitions(test-libflux PUBLIC +target_link_libraries(test-flux flux-internal catch-main) +target_compile_definitions(test-flux PUBLIC FLUX_UNWIND_ON_ERROR FLUX_ERROR_ON_OVERFLOW FLUX_DISABLE_STATIC_BOUNDS_CHECKING ) if(${FLUX_ENABLE_ASAN}) - target_compile_options(test-libflux PRIVATE -fsanitize=address) - target_link_options(test-libflux PRIVATE -fsanitize=address) + target_compile_options(test-flux PRIVATE -fsanitize=address) + target_link_options(test-flux PRIVATE -fsanitize=address) endif() if(${FLUX_ENABLE_UBSAN}) - target_compile_options(test-libflux PRIVATE -fsanitize=undefined) - target_link_options(test-libflux PRIVATE -fsanitize=undefined) + target_compile_options(test-flux PRIVATE -fsanitize=undefined) + target_link_options(test-flux PRIVATE -fsanitize=undefined) endif() if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") - target_precompile_headers(test-libflux PRIVATE "catch.hpp") -endif() - -if(CMAKE_COMPILER_IS_GNUCXX) - target_compile_options(test-libflux PRIVATE -Wall -Wextra -pedantic - -fno-omit-frame-pointer - -ftemplate-backtrace-limit=0 - -fconcepts-diagnostics-depth=2) -endif() - -if(MSVC) - target_compile_options(test-libflux PRIVATE /W4 - /wd4459 # local variable name hides global variable - /wd4702 # unreachable code - ) + 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) + set_target_properties(test-module-import PROPERTIES CXX_EXTENSIONS Off) endif() include(Catch) -catch_discover_tests(test-libflux) +catch_discover_tests(test-flux) diff --git a/test/test_equal.cpp b/test/test_equal.cpp index fedc99c2..428eb873 100644 --- a/test/test_equal.cpp +++ b/test/test_equal.cpp @@ -71,7 +71,7 @@ constexpr bool test_equal() // Custom comparator { - S arr1[] = {1, 2, 3, 4, 5}; + S arr1[] = {{1}, {2}, {3}, {4}, {5}}; T arr2[] = {1, 2, 3, 4, 5}; STATIC_CHECK(flux::equal(arr1, arr2, [](S const& s, T const& t) { @@ -81,7 +81,7 @@ constexpr bool test_equal() // Test with projections { - S arr1[] = {1, 2, 3, 4, 5}; + S arr1[] = {{1}, {2}, {3}, {4}, {5}}; T arr2[] = {1, 2, 3, 4, 5}; STATIC_CHECK(flux::equal(arr1, arr2, flux::proj2(std::equal_to<>{}, &S::i, &T::get))); diff --git a/test/test_flatten.cpp b/test/test_flatten.cpp index bd455cd3..8cd4387a 100644 --- a/test/test_flatten.cpp +++ b/test/test_flatten.cpp @@ -140,7 +140,7 @@ constexpr bool test_flatten_single_pass() int k = 0; auto seq = flux::ints(0, 2) .map([&k](auto i) { - return flux::ints(0, 2).map([i, &k](int j) { return i + j + k; }); + return flux::ints(0, 2).map([i, &k](auto j) { return i + j + k; }); }) .flatten(); diff --git a/test/test_optional.cpp b/test/test_optional.cpp index 6ceb6892..3afd25e7 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -9,6 +9,12 @@ #include "test_utils.hpp" +// Silence warnings about unneeded comparison functions: in fact they are +// needed during concept checks +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wunneeded-internal-declaration" +#endif + namespace { // GCC11 std::string isn't usable in constexpr, so here's a quick and dirty @@ -1171,7 +1177,6 @@ constexpr bool test_optional_map() auto return_ref = [](int& i) -> int& { return i; }; flux::optional o{3}; - flux::optional empty; STATIC_CHECK(o.map(return_ref).value() == 3); } diff --git a/test/test_sort.cpp b/test/test_sort.cpp index f6b88bbe..9a1f548c 100644 --- a/test/test_sort.cpp +++ b/test/test_sort.cpp @@ -40,7 +40,9 @@ struct span_seq { { return static_cast(to) - static_cast(from); } - static constexpr std::size_t size(span_seq const& self) { return self.sz_; } + static constexpr flux::distance_t size(span_seq const& self) { + return static_cast(self.sz_); + } static constexpr T* data(span_seq const& self) { return self.ptr_; } }; }; @@ -95,7 +97,7 @@ static_assert(test_sort_contexpr()); std::mt19937 gen{}; -void test_already_sorted(int sz) +void test_already_sorted(unsigned sz) { auto* ptr = new int[sz]; std::iota(ptr, ptr + sz, int{0}); @@ -106,7 +108,7 @@ void test_already_sorted(int sz) delete[] ptr; } -void test_reverse_sorted(int sz) +void test_reverse_sorted(unsigned sz) { auto* ptr = new int[sz]; std::iota(ptr, ptr + sz, int{0}); @@ -118,7 +120,7 @@ void test_reverse_sorted(int sz) delete[] ptr; } -void test_randomised(int sz) { +void test_randomised(unsigned sz) { auto* ptr = new int[sz]; std::iota(ptr, ptr + sz, int{0}); std::shuffle(ptr, ptr + sz, gen); @@ -129,7 +131,7 @@ void test_randomised(int sz) { delete[] ptr; } -void test_all_equal(int sz) { +void test_all_equal(unsigned sz) { auto* ptr = new int[sz]; std::fill(ptr, ptr + sz, 10); @@ -139,7 +141,7 @@ void test_all_equal(int sz) { delete[] ptr; } -void test_sort(int sz) +void test_sort(unsigned sz) { test_already_sorted(sz); test_reverse_sorted(sz); @@ -152,7 +154,7 @@ struct Int { Int& operator++() { ++i; return *this; } }; -void test_sort_projected(int sz) +void test_sort_projected(unsigned sz) { auto* ptr = new Int[sz]; std::iota(ptr, ptr + sz, Int{0}); @@ -166,7 +168,7 @@ void test_sort_projected(int sz) delete[] ptr; } -void test_heapsort(int sz) +void test_heapsort(unsigned sz) { auto* ptr = new int[sz]; std::iota(ptr, ptr + sz, 0); @@ -181,7 +183,7 @@ void test_heapsort(int sz) delete[] ptr; } -void test_adapted_deque_sort(int sz) +void test_adapted_deque_sort(unsigned sz) { std::deque deque(sz); std::generate(deque.begin(), deque.end(), [i = 0]() mutable { diff --git a/test/test_zip_algorithms.cpp b/test/test_zip_algorithms.cpp index ac0f754e..bb48b3dc 100644 --- a/test/test_zip_algorithms.cpp +++ b/test/test_zip_algorithms.cpp @@ -37,7 +37,7 @@ constexpr bool test_zip_for_each() static_assert(std::same_as); STATIC_CHECK(c.int_sum == 1 + 2 + 3); - STATIC_CHECK(c.double_sum = 100.0 + 200.0 + 300.0); + STATIC_CHECK(c.double_sum == 100.0 + 200.0 + 300.0); } // zip_for_each with no sequences never calls the fn @@ -131,7 +131,7 @@ constexpr bool test_zip_find_if() auto [cur1, cur2] = flux::zip_find_if(std::not_equal_to{}, arr1, arr2); STATIC_CHECK(*iter1 == arr1[cur1]); - STATIC_CHECK(*iter2 == arr2[cur2]); + STATIC_CHECK(*iter2 == arr2[size_t(cur2)]); }