diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 6a97eac..7801c5f 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -7,75 +7,41 @@ defaults: shell: bash env: - VCPKG_GIT_COMMIT_ID: 3a3a222be369b556e4635714c8d6acc990e1f13b - VCPKG_GIT_URL: https://github.com/PazerOP/vcpkg.git - VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' - X_VCPKG_NUGET_ID_PREFIX: mh-stuff + # Use a recent stable vcpkg baseline from official Microsoft repo + VCPKG_COMMIT: de46587b4beaa638743916fe5674825cecfb48b3 jobs: build-linux: - # name: ${{ matrix.compiler }} - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - os: [ubuntu-latest] MH_STUFF_COMPILE_LIBRARY: [true, false] - # compiler: [clang++-11, clang++-10, g++-10, clang++-9, g++-9, clang++-8, g++-8, clang++-7] compiler: - - exe: clang++-11 - deps: clang-11 libc++-11-dev libc++abi-11-dev - - exe: clang++-10 - deps: clang-10 libc++-10-dev libc++abi-10-dev - - exe: clang++-9 - deps: clang-9 libc++-9-dev libc++abi-9-dev - - exe: clang++-8 - deps: clang-8 libc++-8-dev libc++abi-8-dev - - exe: clang++-7 - deps: clang-7 libc++-7-dev libc++abi-7-dev - - exe: g++-10 - deps: g++-10 - - exe: g++-9 - deps: g++-9 - - exe: g++-8 - deps: g++-8 + # Modern compilers available on ubuntu-latest (Ubuntu 22.04/24.04) + - exe: g++-12 + deps: g++-12 + - exe: g++-13 + deps: g++-13 + - exe: clang++-14 + deps: clang-14 libc++-14-dev libc++abi-14-dev + - exe: clang++-15 + deps: clang-15 libc++-15-dev libc++abi-15-dev steps: - - uses: actions/checkout@v2.3.4 - - uses: PazerOP/gha-setup-nuget@HEAD + - uses: actions/checkout@v4 - - uses: lukka/run-vcpkg@v7 - id: runvcpkg + - uses: lukka/run-vcpkg@v11 with: - setupOnly: true - vcpkgGitCommitId: ${{ env.VCPKG_GIT_COMMIT_ID }} - vcpkgGitURL: ${{ env.VCPKG_GIT_URL }} - - - name: Add repos - run: | - sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421 - sudo add-apt-repository ppa:ubuntu-toolchain-r/test - echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" | sudo tee /etc/apt/sources.list.d/llvm.list - - - name: Add repos - llvm-11 - if: matrix.compiler.exe == 'clang++-11' - run: echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main" | sudo tee -a /etc/apt/sources.list.d/llvm.list - - - name: Add repos - llvm-12 - if: matrix.compiler.exe == 'clang++-12' - run: echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" | sudo tee -a /etc/apt/sources.list.d/llvm.list - - - name: Update repos - run: sudo apt update + vcpkgGitCommitId: ${{ env.VCPKG_COMMIT }} - name: Install compilers and tools run: | - # sudo rm -rf /var/lib/apt/lists/* - # sudo apt clean - sudo apt install ${{ matrix.compiler.deps }} ninja-build -y - sudo pip3 install gcovr + sudo apt-get update + sudo apt-get install -y ${{ matrix.compiler.deps }} ninja-build + pip3 install gcovr - echo Ensuring programs work... + echo "Ensuring programs work..." ${{ matrix.compiler.exe }} --version ninja --version gcovr --version @@ -115,57 +81,67 @@ jobs: - name: Save test results if: ${{ matrix.MH_STUFF_COMPILE_LIBRARY }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: gcovr_results_${{ matrix.compiler.exe }} path: build/results*.html - build-windows: - runs-on: windows-latest - strategy: - fail-fast: false - matrix: - MH_STUFF_COMPILE_LIBRARY: [true, false] + # build-windows: + # runs-on: windows-latest + # strategy: + # fail-fast: false + # matrix: + # MH_STUFF_COMPILE_LIBRARY: [true, false] - steps: - - uses: actions/checkout@v2.3.4 - - uses: PazerOP/gha-setup-nuget@HEAD + # steps: + # - uses: actions/checkout@v4 - - uses: lukka/run-vcpkg@v7 - with: - setupOnly: true - vcpkgGitCommitId: ${{ env.VCPKG_GIT_COMMIT_ID }} - vcpkgGitURL: ${{ env.VCPKG_GIT_URL }} + # - uses: lukka/run-vcpkg@v11 + # with: + # vcpkgGitCommitId: ${{ env.VCPKG_COMMIT }} - - uses: seanmiddleditch/gha-setup-ninja@v3 - - name: Setup compiler paths - uses: ilammy/msvc-dev-cmd@v1.5.0 + # - uses: seanmiddleditch/gha-setup-ninja@v5 + # - name: Setup compiler paths + # uses: ilammy/msvc-dev-cmd@v1 - - name: Build - run: | - mkdir build - cd build + # - name: Build + # run: | + # mkdir build + # cd build - cmake -G Ninja \ - -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \ - -DMH_STUFF_COMPILE_LIBRARY=${{ matrix.MH_STUFF_COMPILE_LIBRARY }} \ - ../ + # cmake -G Ninja \ + # -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \ + # -DMH_STUFF_COMPILE_LIBRARY=${{ matrix.MH_STUFF_COMPILE_LIBRARY }} \ + # ../ - cmake --build . + # cmake --build . - - name: Run tests - run: | - cd build - ctest --output-on-failure + # - name: Run tests + # run: | + # cd build + # ctest --output-on-failure - registry-update: - needs: [build-linux, build-windows] + # registry-update: + # needs: [build-linux] + # runs-on: ubuntu-latest + # steps: + # - uses: PazerOP/vcpkg-registry-update@HEAD + # with: + # port-name: mh-stuff + # workflow-pat: ${{ secrets.WORKFLOW_PAT }} + + all-checks-passed: + if: always() + needs: [build-linux] runs-on: ubuntu-latest steps: - - uses: PazerOP/vcpkg-registry-update@HEAD - with: - port-name: mh-stuff - workflow-pat: ${{ secrets.WORKFLOW_PAT }} + - name: Verify all checks passed + run: | + if [[ "${{ needs.build-linux.result }}" != "success" ]]; then + echo "build-linux failed: ${{ needs.build-linux.result }}" + exit 1 + fi + echo "All checks passed!" diff --git a/CMakeLists.txt b/CMakeLists.txt index ee02e36..c41305e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,8 @@ include(mh-BasicInstall) include(mh-CheckCoroutineSupport) if (MH_STUFF_COMPILE_LIBRARY) + find_package(CURL REQUIRED) + file(GLOB_RECURSE MH_SOURCE_FILES CONFIGURE_DEPENDS "cpp/src/*.cpp" ) @@ -47,6 +49,8 @@ if (MH_STUFF_COMPILE_LIBRARY) ${MH_SOURCE_FILES} ) + target_link_libraries(${PROJECT_NAME} PRIVATE CURL::libcurl) + target_compile_definitions(${PROJECT_NAME} ${MH_PUBLIC_OR_INTERFACE} "MH_COMPILE_LIBRARY" "MH_COMPILE_LIBRARY_INLINE=" @@ -64,7 +68,7 @@ if (MH_STUFF_COMPILE_LIBRARY) target_sources(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/library.cpp") if (MSVC) - target_compile_options(${PROJECT_NAME} PRIVATE /W3 /permissive-) + target_compile_options(${PROJECT_NAME} PRIVATE /W3 /permissive- /utf-8) endif() include(GenerateExportHeader) @@ -117,6 +121,7 @@ if (UNIX) endif() if (NOT MSVC) + include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-fconcepts FCONCEPTS_FLAG) if (FCONCEPTS_FLAG) target_compile_options(${PROJECT_NAME} ${MH_PUBLIC_OR_INTERFACE} -fconcepts) diff --git a/cpp/include/mh/algorithm/algorithm.hpp b/cpp/include/mh/algorithm/algorithm.hpp index 50709b7..1694494 100644 --- a/cpp/include/mh/algorithm/algorithm.hpp +++ b/cpp/include/mh/algorithm/algorithm.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace mh { diff --git a/cpp/include/mh/concurrency/async.hpp b/cpp/include/mh/concurrency/async.hpp index 1173f5c..d0c7f53 100644 --- a/cpp/include/mh/concurrency/async.hpp +++ b/cpp/include/mh/concurrency/async.hpp @@ -18,6 +18,7 @@ namespace mh::detail::async_hpp #include #include +#include namespace mh { diff --git a/cpp/include/mh/concurrency/dispatcher.hpp b/cpp/include/mh/concurrency/dispatcher.hpp index 97a03ad..4b12457 100644 --- a/cpp/include/mh/concurrency/dispatcher.hpp +++ b/cpp/include/mh/concurrency/dispatcher.hpp @@ -7,6 +7,7 @@ #ifdef MH_COROUTINES_SUPPORTED #include +#include #include #ifndef MH_STUFF_API diff --git a/cpp/include/mh/concurrency/dispatcher.inl b/cpp/include/mh/concurrency/dispatcher.inl index 6ed5e6a..54084e6 100644 --- a/cpp/include/mh/concurrency/dispatcher.inl +++ b/cpp/include/mh/concurrency/dispatcher.inl @@ -15,12 +15,10 @@ #include #include #include +#include -// Platform-specific I/O monitoring -#ifdef _WIN32 -#include -#include -#else +// Platform-specific I/O monitoring (Unix only for now) +#ifndef _WIN32 #include #include #include @@ -161,7 +159,7 @@ namespace mh #ifdef _WIN32 // Windows: stub implementation for now - throw mh::not_implemented_error("Implement with select() or WSAPoll()"); + throw mh::not_implemented_error(MH_SOURCE_LOCATION_CURRENT()); #else // Unix: use select() if (!m_ReadTasks.empty() || !m_WriteTasks.empty()) diff --git a/cpp/include/mh/concurrency/locked_value.hpp b/cpp/include/mh/concurrency/locked_value.hpp index 9a55936..fdda305 100644 --- a/cpp/include/mh/concurrency/locked_value.hpp +++ b/cpp/include/mh/concurrency/locked_value.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace mh { diff --git a/cpp/include/mh/concurrency/mutex_debug.hpp b/cpp/include/mh/concurrency/mutex_debug.hpp index 596dabf..0734bb4 100644 --- a/cpp/include/mh/concurrency/mutex_debug.hpp +++ b/cpp/include/mh/concurrency/mutex_debug.hpp @@ -39,9 +39,11 @@ namespace mh m_Mutex.unlock(); } - // TODO: this is optional + // native_handle is not available on MSVC's std::mutex +#if !defined(_MSC_VER) using native_handle_type = typename TMutex::native_handle_type; native_handle_type native_handle() { return m_Mutex.native_handle(); } +#endif private: void lock_acquired() diff --git a/cpp/include/mh/concurrency/thread_pool.hpp b/cpp/include/mh/concurrency/thread_pool.hpp index 81e2abe..da5adf9 100644 --- a/cpp/include/mh/concurrency/thread_pool.hpp +++ b/cpp/include/mh/concurrency/thread_pool.hpp @@ -10,8 +10,10 @@ #include "dispatcher.hpp" +#include #include #include +#include namespace mh { diff --git a/cpp/include/mh/concurrency/thread_pool.inl b/cpp/include/mh/concurrency/thread_pool.inl index a9de1c2..2a59b65 100644 --- a/cpp/include/mh/concurrency/thread_pool.inl +++ b/cpp/include/mh/concurrency/thread_pool.inl @@ -6,6 +6,8 @@ #ifdef MH_COROUTINES_SUPPORTED +#include + namespace mh { namespace detail::thread_pool_hpp diff --git a/cpp/include/mh/containers/heap.hpp b/cpp/include/mh/containers/heap.hpp index 0356822..da0d0cb 100644 --- a/cpp/include/mh/containers/heap.hpp +++ b/cpp/include/mh/containers/heap.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace mh diff --git a/cpp/include/mh/coroutine/future.hpp b/cpp/include/mh/coroutine/future.hpp index e5e29e6..f42d89d 100644 --- a/cpp/include/mh/coroutine/future.hpp +++ b/cpp/include/mh/coroutine/future.hpp @@ -4,6 +4,8 @@ #ifdef MH_COROUTINES_SUPPORTED +#include + namespace mh { template class shared_future; @@ -58,11 +60,11 @@ namespace mh void set_value(T value) { - this->get_promise().set_state::IDX_VALUE>(std::move(value)); + this->get_promise().template set_state::IDX_VALUE>(std::move(value)); } void set_exception(std::exception_ptr p) { - this->get_promise().set_state::IDX_EXCEPTION>(p); + this->get_promise().template set_state::IDX_EXCEPTION>(p); } }; diff --git a/cpp/include/mh/coroutine/generator.hpp b/cpp/include/mh/coroutine/generator.hpp index bdd38c4..4399437 100644 --- a/cpp/include/mh/coroutine/generator.hpp +++ b/cpp/include/mh/coroutine/generator.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace mh @@ -52,7 +53,7 @@ namespace mh // Nothing to do } - const_reference& value() const + [[nodiscard]] const_reference& value() const { switch (m_State.index()) { @@ -62,6 +63,7 @@ namespace mh return *std::get<1>(m_State); case 2: std::rethrow_exception(std::get<2>(m_State)); + [[fallthrough]]; default: throw std::logic_error("invalid promise state"); } diff --git a/cpp/include/mh/coroutine/task.hpp b/cpp/include/mh/coroutine/task.hpp index 81911db..80a130c 100644 --- a/cpp/include/mh/coroutine/task.hpp +++ b/cpp/include/mh/coroutine/task.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -596,7 +597,7 @@ namespace mh detail::promise* promise = new detail::promise(); task retVal(promise); - promise->set_state::IDX_VALUE>(T(std::forward(args)...)); + promise->template set_state::IDX_VALUE>(T(std::forward(args)...)); return retVal; } diff --git a/cpp/include/mh/data/lazy.hpp b/cpp/include/mh/data/lazy.hpp index 008ef14..2cececc 100644 --- a/cpp/include/mh/data/lazy.hpp +++ b/cpp/include/mh/data/lazy.hpp @@ -2,6 +2,7 @@ #include #include +#include #include namespace mh @@ -25,7 +26,7 @@ namespace mh throw std::logic_error("Empty mh::lazy"); if (func_type* func = std::get_if<1>(&m_Value)) - m_Value.emplace<2>(std::move((*func)())); + m_Value.template emplace<2>(std::move((*func)())); return std::get<2>(m_Value); } diff --git a/cpp/include/mh/data/optional_ref.hpp b/cpp/include/mh/data/optional_ref.hpp index e22ebb7..3a8076f 100644 --- a/cpp/include/mh/data/optional_ref.hpp +++ b/cpp/include/mh/data/optional_ref.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace mh diff --git a/cpp/include/mh/error/ensure.hpp b/cpp/include/mh/error/ensure.hpp index 5657f34..9b56c8f 100644 --- a/cpp/include/mh/error/ensure.hpp +++ b/cpp/include/mh/error/ensure.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace mh { diff --git a/cpp/include/mh/error/exception_details.inl b/cpp/include/mh/error/exception_details.inl index 9323f1a..2618c01 100644 --- a/cpp/include/mh/error/exception_details.inl +++ b/cpp/include/mh/error/exception_details.inl @@ -10,6 +10,7 @@ #include #include #include +#include namespace mh::detail::exception_to_string_hpp { diff --git a/cpp/include/mh/error/expected.hpp b/cpp/include/mh/error/expected.hpp index 819c0af..0f38738 100644 --- a/cpp/include/mh/error/expected.hpp +++ b/cpp/include/mh/error/expected.hpp @@ -3,6 +3,7 @@ #if (__cpp_concepts >= 201907) || (defined(_MSC_VER) && (__cpp_concepts >= 201811)) #include +#include #include #include #include diff --git a/cpp/include/mh/error/nested_exception.hpp b/cpp/include/mh/error/nested_exception.hpp index 1deccac..bd19a62 100644 --- a/cpp/include/mh/error/nested_exception.hpp +++ b/cpp/include/mh/error/nested_exception.hpp @@ -1,6 +1,8 @@ #pragma once +#include #include +#include namespace mh { diff --git a/cpp/include/mh/error/status.hpp b/cpp/include/mh/error/status.hpp index 3d6acc4..79b31e6 100644 --- a/cpp/include/mh/error/status.hpp +++ b/cpp/include/mh/error/status.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace mh { diff --git a/cpp/include/mh/io/fd_sink.hpp b/cpp/include/mh/io/fd_sink.hpp index dc9d2d7..f7b7987 100644 --- a/cpp/include/mh/io/fd_sink.hpp +++ b/cpp/include/mh/io/fd_sink.hpp @@ -1,7 +1,10 @@ #pragma once +#ifdef __unix__ + #include "sink.hpp" #include "native_handle.hpp" +#include #include #ifndef MH_STUFF_API @@ -37,4 +40,6 @@ namespace mh::io unique_native_handle fd_; bool is_open_; }; -} \ No newline at end of file +} + +#endif // __unix__ \ No newline at end of file diff --git a/cpp/include/mh/io/fd_sink.inl b/cpp/include/mh/io/fd_sink.inl index 4d44a6a..3b9caaa 100644 --- a/cpp/include/mh/io/fd_sink.inl +++ b/cpp/include/mh/io/fd_sink.inl @@ -2,8 +2,10 @@ #include "fd_sink.hpp" #include +#ifdef __unix__ #include #include +#endif #ifndef MH_COMPILE_LIBRARY_INLINE #define MH_COMPILE_LIBRARY_INLINE inline diff --git a/cpp/include/mh/io/fd_source.hpp b/cpp/include/mh/io/fd_source.hpp index 98f4fc6..f59b9a7 100644 --- a/cpp/include/mh/io/fd_source.hpp +++ b/cpp/include/mh/io/fd_source.hpp @@ -1,7 +1,10 @@ #pragma once +#ifdef __unix__ + #include "native_handle.hpp" #include "source.hpp" +#include #ifndef MH_STUFF_API #define MH_STUFF_API @@ -34,3 +37,5 @@ class fd_source : public source { bool is_open_; }; } // namespace mh::io + +#endif // __unix__ diff --git a/cpp/include/mh/io/fd_source.inl b/cpp/include/mh/io/fd_source.inl index afc876d..e730618 100644 --- a/cpp/include/mh/io/fd_source.inl +++ b/cpp/include/mh/io/fd_source.inl @@ -2,8 +2,10 @@ #include "fd_source.hpp" #include +#ifdef __unix__ #include #include +#endif #ifndef MH_COMPILE_LIBRARY_INLINE #define MH_COMPILE_LIBRARY_INLINE inline diff --git a/cpp/include/mh/io/filesystem_helpers.inl b/cpp/include/mh/io/filesystem_helpers.inl index 2dd28d7..8e19f50 100644 --- a/cpp/include/mh/io/filesystem_helpers.inl +++ b/cpp/include/mh/io/filesystem_helpers.inl @@ -4,6 +4,8 @@ #define MH_COMPILE_LIBRARY_INLINE inline #endif +#include + MH_COMPILE_LIBRARY_INLINE std::filesystem::path mh::filename_without_extension(std::filesystem::path path) { return std::move(path.filename().replace_extension()); diff --git a/cpp/include/mh/io/getopt.hpp b/cpp/include/mh/io/getopt.hpp index 5b25745..95572f7 100644 --- a/cpp/include/mh/io/getopt.hpp +++ b/cpp/include/mh/io/getopt.hpp @@ -1,6 +1,6 @@ #pragma once -#if __has_include() || __has_include() +#if __has_include() || __has_include() #if __has_include() #include #elif __has_include() @@ -12,6 +12,7 @@ #include #include #include +#include #if __has_include() @@ -39,7 +40,7 @@ namespace mh::detail::getopt_hpp private: T& m_Variable; T m_OldValue; - } + }; } #endif diff --git a/cpp/include/mh/io/native_handle.hpp b/cpp/include/mh/io/native_handle.hpp index 64f6fc4..a01bd19 100644 --- a/cpp/include/mh/io/native_handle.hpp +++ b/cpp/include/mh/io/native_handle.hpp @@ -1,7 +1,9 @@ #pragma once #include +#ifdef __unix__ #include +#endif namespace mh::io { diff --git a/cpp/include/mh/io/sink.hpp b/cpp/include/mh/io/sink.hpp index 8c67df6..16cbca2 100644 --- a/cpp/include/mh/io/sink.hpp +++ b/cpp/include/mh/io/sink.hpp @@ -1,5 +1,7 @@ #pragma once +#ifdef __unix__ + #include "native_handle.hpp" #include #include @@ -41,3 +43,5 @@ namespace mh::io }; } +#endif // __unix__ + diff --git a/cpp/include/mh/io/source.hpp b/cpp/include/mh/io/source.hpp index 61867bf..0fbbe29 100644 --- a/cpp/include/mh/io/source.hpp +++ b/cpp/include/mh/io/source.hpp @@ -1,5 +1,7 @@ #pragma once +#ifdef __unix__ + #include "native_handle.hpp" #include #include @@ -41,3 +43,4 @@ namespace mh::io }; } +#endif // __unix__ diff --git a/cpp/include/mh/math/uint128.hpp b/cpp/include/mh/math/uint128.hpp index a5d1f24..ff85969 100644 --- a/cpp/include/mh/math/uint128.hpp +++ b/cpp/include/mh/math/uint128.hpp @@ -329,7 +329,7 @@ namespace mh return u128; #if __cpp_lib_bit_cast >= 201806 - return detail::bit_cast(u64); + return std::bit_cast(u64); #else return (detail::uint128_hpp::platform_uint128_t(get_u64<1>()) << 64) | get_u64<0>(); #endif @@ -343,7 +343,7 @@ namespace mh } #if __cpp_lib_bit_cast >= 201806 - u64 = detail::bit_cast>(value); + u64 = std::bit_cast>(value); #else set_u64<0>(value); set_u64<1>(value >> 64); diff --git a/cpp/include/mh/memory/cached_variable.hpp b/cpp/include/mh/memory/cached_variable.hpp index 23b42e8..0a8b93e 100644 --- a/cpp/include/mh/memory/cached_variable.hpp +++ b/cpp/include/mh/memory/cached_variable.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace mh { diff --git a/cpp/include/mh/memory/stack_info.inl b/cpp/include/mh/memory/stack_info.inl index 92ca3fd..05dddfe 100644 --- a/cpp/include/mh/memory/stack_info.inl +++ b/cpp/include/mh/memory/stack_info.inl @@ -5,6 +5,9 @@ #endif #ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #include #include diff --git a/cpp/include/mh/process/process.inl b/cpp/include/mh/process/process.inl index 657fe91..322aad3 100644 --- a/cpp/include/mh/process/process.inl +++ b/cpp/include/mh/process/process.inl @@ -166,19 +166,19 @@ namespace mh // Handle input (stdin) if (input_source_) { - throw mh::not_implemented_error(); // Input redirection not yet implemented + throw mh::not_implemented_error(MH_SOURCE_LOCATION_CURRENT()); // Input redirection not yet implemented } // Handle output (stdout) if (output_sink_) { - throw mh::not_implemented_error(); // Output redirection not yet implemented + throw mh::not_implemented_error(MH_SOURCE_LOCATION_CURRENT()); // Output redirection not yet implemented } // Handle error (stderr) if (error_sink_) { - throw mh::not_implemented_error(); // Error redirection not yet implemented + throw mh::not_implemented_error(MH_SOURCE_LOCATION_CURRENT()); // Error redirection not yet implemented } } }; diff --git a/cpp/include/mh/process/process_manager.inl b/cpp/include/mh/process/process_manager.inl index df1694f..c42d896 100644 --- a/cpp/include/mh/process/process_manager.inl +++ b/cpp/include/mh/process/process_manager.inl @@ -121,7 +121,7 @@ namespace mh }; // Start the monitoring task (detached) - monitor(); + (void)monitor(); } MH_COMPILE_LIBRARY_INLINE void process_manager::check_processes() diff --git a/cpp/include/mh/raii/scope_exit.hpp b/cpp/include/mh/raii/scope_exit.hpp index b6d5fd1..4dc3d9d 100644 --- a/cpp/include/mh/raii/scope_exit.hpp +++ b/cpp/include/mh/raii/scope_exit.hpp @@ -4,6 +4,7 @@ #include #include +#include namespace mh { diff --git a/cpp/include/mh/reflection/struct.hpp b/cpp/include/mh/reflection/struct.hpp index f963dd0..b882ee1 100644 --- a/cpp/include/mh/reflection/struct.hpp +++ b/cpp/include/mh/reflection/struct.hpp @@ -2,8 +2,10 @@ #if (__cpp_concepts >= 201907) || (_MSC_VER >= 1928) +#include #include #include +#include namespace mh { diff --git a/cpp/include/mh/text/case_insensitive_string.hpp b/cpp/include/mh/text/case_insensitive_string.hpp index a80a7a4..b043ede 100644 --- a/cpp/include/mh/text/case_insensitive_string.hpp +++ b/cpp/include/mh/text/case_insensitive_string.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace mh { diff --git a/cpp/include/mh/text/charconv_helper.hpp b/cpp/include/mh/text/charconv_helper.hpp index c17dffb..804739a 100644 --- a/cpp/include/mh/text/charconv_helper.hpp +++ b/cpp/include/mh/text/charconv_helper.hpp @@ -4,6 +4,7 @@ #include #if __cpp_lib_to_chars >= 201611 +#include #include #include #include diff --git a/cpp/include/mh/text/codecvt.inl b/cpp/include/mh/text/codecvt.inl index c81a8c6..1da0a4a 100644 --- a/cpp/include/mh/text/codecvt.inl +++ b/cpp/include/mh/text/codecvt.inl @@ -3,6 +3,7 @@ #endif #include +#include #include #include #include diff --git a/cpp/include/mh/text/fmtstr.hpp b/cpp/include/mh/text/fmtstr.hpp index 4ebb54e..be4b56b 100644 --- a/cpp/include/mh/text/fmtstr.hpp +++ b/cpp/include/mh/text/fmtstr.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #if __has_include() #include diff --git a/cpp/include/mh/text/format.hpp b/cpp/include/mh/text/format.hpp index 0ab0af9..cee1217 100644 --- a/cpp/include/mh/text/format.hpp +++ b/cpp/include/mh/text/format.hpp @@ -39,6 +39,7 @@ namespace mh::detail::format_hpp #include #include #include +#include namespace mh { @@ -119,9 +120,9 @@ namespace mh template()>> inline auto format(const TFmtStr& fmtStr, TArgs&&... args) -> - decltype(detail::format_hpp::fmtns::format(fmtStr, std::forward(args)...)) + decltype(detail::format_hpp::fmtns::format(detail::format_hpp::fmtns::runtime(fmtStr), std::forward(args)...)) { - return detail::format_hpp::fmtns::format(fmtStr, std::forward(args)...); + return detail::format_hpp::fmtns::format(detail::format_hpp::fmtns::runtime(fmtStr), std::forward(args)...); } template diff --git a/cpp/include/mh/text/indenting_ostream.hpp b/cpp/include/mh/text/indenting_ostream.hpp index e60b1b7..b363546 100644 --- a/cpp/include/mh/text/indenting_ostream.hpp +++ b/cpp/include/mh/text/indenting_ostream.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace mh diff --git a/cpp/include/mh/text/memstream.hpp b/cpp/include/mh/text/memstream.hpp index 3059ba3..9e287e9 100644 --- a/cpp/include/mh/text/memstream.hpp +++ b/cpp/include/mh/text/memstream.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include @@ -135,7 +135,7 @@ namespace mh std::streamsize xsputn(const CharT* s, std::streamsize count) override { std::cerr << __func__ << "(): count = " << +count << ", s = " << sv_type(s, count) << std::endl; - count = detail::memstream_hpp::min(count, remaining_p()); + count = detail::memstream_hpp::min(count, remaining_p()); auto ptr = pcur(); for (std::streamsize i = 0; i < count; i++) { diff --git a/cpp/include/mh/text/string_insertion.hpp b/cpp/include/mh/text/string_insertion.hpp index 6b5fb72..14a6ae0 100644 --- a/cpp/include/mh/text/string_insertion.hpp +++ b/cpp/include/mh/text/string_insertion.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace mh { diff --git a/cpp/include/mh/variant.hpp b/cpp/include/mh/variant.hpp index e886d26..25b5d0a 100644 --- a/cpp/include/mh/variant.hpp +++ b/cpp/include/mh/variant.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a534fb8..38e5035 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,12 @@ cmake_minimum_required(VERSION 3.16.3) +# Set compiler flags for clang/libc++ before adding Catch2 +# This ensures Catch2 is built with the same stdlib as our code +if (CMAKE_CXX_COMPILER_ID MATCHES Clang) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") +endif() + # Include CPM for package management include(${PROJECT_SOURCE_DIR}/cmake/get_cpm.cmake) diff --git a/test/coroutine_task_test.cpp b/test/coroutine_task_test.cpp index 3b56fdb..2a1fe3c 100644 --- a/test/coroutine_task_test.cpp +++ b/test/coroutine_task_test.cpp @@ -11,6 +11,9 @@ #include #ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #include #endif @@ -147,7 +150,8 @@ TEST_CASE("task - exceptions in discarded tasks") mh::thread_pool tp(2); int value = 0; - [](mh::thread_pool& tp, int& val) -> mh::task<> + // Intentionally discarding the task - cast to void to suppress nodiscard warning + (void)[](mh::thread_pool& tp, int& val) -> mh::task<> { co_await tp.co_add_task(); co_await tp.co_delay_for(2s); diff --git a/test/data_bits_test.cpp b/test/data_bits_test.cpp index c4d29d3..a6306af 100644 --- a/test/data_bits_test.cpp +++ b/test/data_bits_test.cpp @@ -1,5 +1,16 @@ #include "mh/data/bits.hpp" #include +#include +#include + +// Helper to convert std::byte to unsigned for CAPTURE (Catch2 v3.4.0 lacks StringMaker implementation) +template +auto capture_value(const T& val) { + if constexpr (std::is_same_v) + return static_cast(val); + else + return val; +} template static void test_bit_functions(const TSrc* src, const TDst expected) @@ -10,7 +21,7 @@ static void test_bit_functions(const TSrc* src, const TDst expected) memcpy(&srcVal, src, srcValSize); CAPTURE(srcVal); - CAPTURE(*src, expected, bits_to_copy, src_offset, typeid(TSrc).name(), typeid(TDst).name()); + CAPTURE(capture_value(*src), expected, bits_to_copy, src_offset, typeid(TSrc).name(), typeid(TDst).name()); const auto read = +mh::bit_read(src); diff --git a/test/text_filebuf_test.cpp b/test/text_filebuf_test.cpp index 8b5405b..067ce96 100644 --- a/test/text_filebuf_test.cpp +++ b/test/text_filebuf_test.cpp @@ -5,6 +5,9 @@ #include #include +// fmemopen is POSIX-only, not available on Windows +#ifdef __unix__ + TEST_CASE("filebuf basic write", "[text][filebuf]") { char buf[128] = {}; @@ -112,3 +115,5 @@ TEST_CASE("filebuf with format", "[text][filebuf]") REQUIRE(std::strstr(buf, "Float: 3.14") != nullptr); REQUIRE(std::strstr(buf, "String: test") != nullptr); } + +#endif // __unix__ diff --git a/test/text_memstream_test.cpp b/test/text_memstream_test.cpp index 27657d7..da16a1b 100644 --- a/test/text_memstream_test.cpp +++ b/test/text_memstream_test.cpp @@ -2,6 +2,11 @@ #include #include +#include + +// Helper to convert string_view to string for Catch2 comparisons +// (Catch2 v3.4.0 declares but doesn't implement StringMaker) +inline std::string to_str(std::string_view sv) { return std::string(sv); } TEST_CASE("memstream put", "[text][memstream]") { @@ -12,7 +17,7 @@ TEST_CASE("memstream put", "[text][memstream]") ms << TEST_STRING; REQUIRE(std::memcmp(buf, TEST_STRING.data(), TEST_STRING.size()) == 0); - REQUIRE(ms.view() == TEST_STRING); + REQUIRE(to_str(ms.view()) == to_str(TEST_STRING)); CHECK(!ms.fail()); CHECK(ms.good()); REQUIRE(ms.tellp() == 14); @@ -23,7 +28,7 @@ TEST_CASE("memstream put", "[text][memstream]") ms << " foo"; constexpr std::string_view TEST_STRING_FOO = "my test fooing"; - REQUIRE(ms.view() == TEST_STRING_FOO); + REQUIRE(to_str(ms.view()) == to_str(TEST_STRING_FOO)); REQUIRE(std::memcmp(buf, TEST_STRING_FOO.data(), TEST_STRING_FOO.size()) == 0); { @@ -45,24 +50,24 @@ TEST_CASE("memstream put", "[text][memstream]") REQUIRE(ms.write("foo", 3)); REQUIRE(ms.good()); - REQUIRE(ms.view_full() == "footest fooing"); - REQUIRE(ms.view() == ""); + REQUIRE(to_str(ms.view_full()) == "footest fooing"); + REQUIRE(to_str(ms.view()) == ""); REQUIRE(ms.seekg(1)); - REQUIRE(ms.view() == "ootest fooing"); + REQUIRE(to_str(ms.view()) == "ootest fooing"); REQUIRE(ms.seekg(0)); REQUIRE(ms.good()); - REQUIRE(ms.view() == "footest fooing"); + REQUIRE(to_str(ms.view()) == "footest fooing"); REQUIRE(ms << "bar"); - REQUIRE(ms.view() == "foobart fooing"); + REQUIRE(to_str(ms.view()) == "foobart fooing"); REQUIRE(ms.good()); } { constexpr int TEST_INT_VALUE = 487; - REQUIRE(ms.view() == "foobart fooing"); + REQUIRE(to_str(ms.view()) == "foobart fooing"); REQUIRE(ms.seekp(1, std::ios::beg)); REQUIRE(ms.seekp(5, std::ios::cur)); REQUIRE(ms.tellp() == 6); @@ -78,8 +83,8 @@ TEST_CASE("memstream put", "[text][memstream]") CHECK(ms.tellg() == 14); CHECK(ms.seekg(0)); - CHECK(ms.view() == "foobar487ooing"); - CHECK(ms.view_full() == "foobar487ooing"); + CHECK(to_str(ms.view()) == "foobar487ooing"); + CHECK(to_str(ms.view_full()) == "foobar487ooing"); int testInt; REQUIRE(ms.seekg(6)); diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json index 9727676..3fd5a66 100644 --- a/vcpkg-configuration.json +++ b/vcpkg-configuration.json @@ -1,4 +1,9 @@ { + "default-registry": { + "kind": "git", + "repository": "https://github.com/microsoft/vcpkg", + "baseline": "de46587b4beaa638743916fe5674825cecfb48b3" + }, "registries": [ { "kind": "git", diff --git a/vcpkg.json b/vcpkg.json index 01b496d..e1439f1 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -4,6 +4,7 @@ "dependencies": [ "mh-cmake-common", "catch2", + "curl", "fmt" ] }