diff --git a/.appveyor.yml b/.appveyor.yml index 4aa8f3a09..60ba3dfb4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -43,12 +43,7 @@ build_script: - IF EXIST build RMDIR /S /Q build - MKDIR build - cd build - - cmake -G "Visual Studio 15 Win64" -D BOOST_ROOT=C:/Libraries/boost_1_65_1 -D CMAKE_BUILD_TYPE=debug -D stlab_testing=ON -D coroutine=ON .. - - cmake --build . - - test\Debug\stlab.test.channel.test --log_level=message - - test\Debug\stlab.test.cow.test --log_level=message - - test\Debug\stlab.test.future.test --log_level=message - - test\Debug\stlab.test.serial_queue.test.exe - - test\Debug\stlab.test.task.test --log_level=message - - test\Debug\stlab.test.tuple.test --log_level=message + - cmake -G "Visual Studio 15 2017 Win64" -D BOOST_ROOT=C:/Libraries/boost_1_65_1 -D CMAKE_BUILD_TYPE=debug -D Boost_USE_STATIC_LIBS=ON .. + - cmake --build . --config Release + - ctest -C Release diff --git a/.travis.yml b/.travis.yml index 5a75f3244..ad57b7eb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,17 +10,16 @@ cache: addons: apt: sources: - - sourceline: "deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.8 main" - key_url : "http://apt.llvm.org/llvm-snapshot.gpg.key" + - sourceline: deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.8 main + key_url: http://apt.llvm.org/llvm-snapshot.gpg.key - ubuntu-toolchain-r-test -# - george-edison55-precise-backports packages: - g++-5 - clang-3.8 branches: except: /pr\/.*/ - + matrix: include: # @@ -34,13 +33,14 @@ matrix: - brew upgrade python - brew uninstall libyaml - pip3 install --no-cache-dir pyyaml - - pip3 install conan + - pip3 install --user conan + - export PATH=$PATH:/Users/travis/Library/Python/3.7/bin - ./enhance_conan.sh env: build_type=debug - options="-D stlab_testing=ON" - + options="" + - os: osx compiler: clang osx_image: xcode9 @@ -49,27 +49,40 @@ matrix: - brew upgrade python - brew uninstall libyaml - pip3 install --no-cache-dir pyyaml - - pip3 install conan + - pip3 install --user conan + - export PATH=$PATH:/Users/travis/Library/Python/3.7/bin - ./enhance_conan.sh env: build_type=release - options="-D stlab_testing=ON" + options="" # - # Linux Clang, Debug & Release + # Linux Clang, Debug & Release, with and without coroutines # - os: linux compiler: clang env: build_type=debug - options="-D stlab_testing=ON" - + options="" + - os: linux compiler: clang env: build_type=release - options="-D stlab_testing=ON" + options="" + +# - os: linux +# compiler: clang +# env: +# build_type=debug +# options="-Dstlab.coroutines=ON" +# +# - os: linux +# compiler: clang +# env: +# build_type=release +# options="-Dstlab.coroutines=ON" # # Linux GCC, Debug & Release @@ -78,13 +91,13 @@ matrix: compiler: gcc env: build_type=debug - options="-D stlab_testing=ON" + options="" - os: linux compiler: gcc env: build_type=release - options="-D stlab_testing=ON" + options="" # # Address sanitizer @@ -93,8 +106,8 @@ matrix: compiler: clang env: build_type=debug - flags="-fsanitize=address;-fno-omit-frame-pointer;" - options="-D stlab_testing=ON" + flags="-fsanitize=address -fno-omit-frame-pointer -fno-sanitize-recover=all" + options="" # # Undefined behavior sanitizer @@ -103,8 +116,8 @@ matrix: compiler: clang env: build_type=debug - flags="-fsanitize=undefined;-fno-omit-frame-pointer;" - options="-D stlab_testing=ON" + flags="-fsanitize=undefined -fno-omit-frame-pointer -fno-sanitize-recover=all" + options="" # # Thread sanitizer @@ -114,8 +127,8 @@ matrix: env: build_type=debug TSAN_OPTIONS="suppressions=${TRAVIS_BUILD_DIR}/test/sanitizer_suppressions" - flags="-fsanitize=thread;-fno-omit-frame-pointer;" - options="-D stlab_testing=ON" + flags="-fsanitize=thread -fno-omit-frame-pointer -fno-sanitize-recover=all" + options="" # # Coverage @@ -125,7 +138,7 @@ matrix: env: build_type=debug coverage=TRUE - options="-D stlab_testing=ON -D coverage=ON" + options="-D stlab.coverage=ON" packages: - lcov after_success: @@ -139,7 +152,7 @@ matrix: compiler: clang env: build_type=debug - options="-D stlab_testing=ON" + options="" before_install: - pip install --user conan - ./enhance_conan.sh @@ -147,10 +160,9 @@ matrix: addons: apt: sources: - - sourceline: "deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.8 main" - key_url : "http://apt.llvm.org/llvm-snapshot.gpg.key" + - sourceline: deb http://apt.llvm.org/precise/ llvm-toolchain-precise-3.8 main + key_url: http://apt.llvm.org/llvm-snapshot.gpg.key - ubuntu-toolchain-r-test -# - george-edison55-precise-backports packages: - g++-5 - clang-3.8 @@ -166,9 +178,9 @@ matrix: before_install: - pip install --user conan - - ./enhance_conan.sh - - + - ./enhance_conan.sh + + install: ############################################################################ # All the dependencies are installed in ${HOME}/deps/ @@ -188,17 +200,17 @@ install: brew install cmake || brew upgrade cmake fi - cmake --version - + ############################################################################ # Go back to the root of the project and setup the build directory ############################################################################ - cd "${TRAVIS_BUILD_DIR}" - - + + script: - .travis/build.sh - + notifications: recipients: - felix@petriconi.net diff --git a/.travis/build.sh b/.travis/build.sh index b983accd8..8fd2ccaad 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -27,8 +27,7 @@ if [ "$NPROC" == "" ] ; then NPROC=`nproc` fi -if [ ! -z "$flags" ]; then extra_flags="-D stlab_appended_flags=$flags"; fi - +if [ ! -z "$flags" ]; then extra_flags="-D CMAKE_CXX_FLAGS=$flags"; fi cmake -D CMAKE_BUILD_TYPE=$build_type $options $extra_flags .. if [ $? -ne 0 ]; then exit 1; fi diff --git a/CHANGES.md b/CHANGES.md index f2ac931da..c23f8d94e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,12 @@ +## v1.3.3 - 2018 - October - 25 + +- Fixed Issues + - [#154](https://github.com/stlab/libraries/issues/154) : Compilation error with gcc + - Race condition in timed blocking_get + +- Enhancements + - The library can now be included as cmake dependency (Many thanks to Austin McCartney) + ## v1.3.2 - 2018 - July - 28 - Fixed Issues diff --git a/CMakeLists.txt b/CMakeLists.txt index 16a1970d4..7e0fb17ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,61 +1,269 @@ -cmake_minimum_required( VERSION 3.2 ) -set( CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Supported configuration types" FORCE ) +cmake_minimum_required( VERSION 3.5 ) -project( stlab LANGUAGES C CXX ) +# +# Here we check whether stlab is being configured in isolation or as a component +# of a larger proeject. To do so, we query whether the `PROJECT_NAME` CMake +# variable has been defined. In the case it has, we can conclude stlab is a +# subproject. +# +# This convention has been borrowed from the Catch C++ unit testing library. +# +if( DEFINED PROJECT_NAME ) + set( subproject ON ) +else() + set( subproject OFF ) +endif() -option( coverage "Enable binary instrumentation to collect test coverage information in the DEBUG configuration" ) -option( stlab_testing "Compile the stlab tests and integrate with ctest" ${BUILD_TESTING} ) +project( stlab VERSION 1.0 LANGUAGES CXX ) -set( Boost_MULTITHREADED ON ) -set( Boost_USE_STATIC_LIBS ON ) +include( CTest ) +include( CMakeDependentOption ) -if( EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake ) - include( ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake ) - set( CONAN_SYSTEM_INCLUDES ON ) - conan_basic_setup() -else() - find_package( Boost 1.60.0 COMPONENTS unit_test_framework) -endif() +# +# The `stlab.testing` and `stlab.coverage` options only appear as +# cmake-gui and ccmake options iff stlab is the highest level project. +# In the case that stlab is a subproject, these options are hidden from +# the user interface and set to `OFF` +# +cmake_dependent_option( stlab.testing + "Compile the stlab tests and integrate with ctest" + ${BUILD_TESTING} "NOT subproject" OFF ) -set( CMAKE_THREAD_PREFER_PTHREAD TRUE ) -find_package( Threads ) +cmake_dependent_option( stlab.coverage + "Enable binary instrumentation to collect test coverage information in the DEBUG configuration" + OFF "NOT subproject" OFF ) + +option( stlab.boost_variant "Prefer Boost::variant to std::variant" OFF ) +option( stlab.boost_optional "Prefer Boost::optional to std::optional" OFF ) +option( stlab.coroutines "Leverage the coroutine TS in stlab" OFF ) + +mark_as_advanced( stlab.coroutines stlab.boost_variant stlab.boost_optional ) +# +# stlab has no compiled components. As such, we declare it as an `INTERFACE` +# library, which denotes a collection of target propeties to be applied +# transitively to linking targets. In our case, this ammounts to an include +# directory, compile flags, linking flags, and links to system libraries. +# add_library( stlab INTERFACE ) +add_library( stlab::stlab ALIAS stlab ) -target_include_directories( stlab INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}" - INTERFACE "${Boost_INCLUDE_DIRS}" ) - -target_link_libraries( stlab INTERFACE ${CMAKE_THREAD_LIBS_INIT} - INTERFACE ${CONAN_LIBS} ) - -target_sources( stlab INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/channel.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/config.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/default_executor.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/executor_base.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/future.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/immediate_executor.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/main_executor.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/optional.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/progress.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/system_timer.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/task.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/traits.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/tuple_algorithm.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/utility.hpp" - "${CMAKE_CURRENT_SOURCE_DIR}/stlab/concurrency/variant.hpp") - -set( flags "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CMAKE_CXX_COMPILER_ID}.cmake" ) -if( EXISTS ${flags} ) - include( ${flags} ) -else() - message( WARNING "No stlab-defined flags for ${CMAKE_CXX_COMPILER_ID} C++ compiler") - message( STATUS "Only CMake defaults will be used") +# +# stlab requires C++ 14 support, at a minimum. Setting the `cxx_std_14` compile +# features ensures that the corresponding C++ standard flag is populated in +# targets linking to stlab. +# +target_compile_features( stlab INTERFACE cxx_std_14 ) + +# +# The include directory for stlab can be expected to vary between build +# and installaion. Here we use a CMake generator expression to dispatch +# on how the configuration under which this library is being consumed. +# +target_include_directories( stlab INTERFACE + $ + $ ) + +# +# As of CMake version 3.1, the FindThreads CMake module supplies an imported +# target called `Thread::Thread` which transitively supplies inlude directories, +# compiler flags, and linker flags to CMake targets linking to it. +# +set( CMAKE_THREAD_PREFER_PTHREAD TRUE ) +find_package( Threads REQUIRED ) +target_link_libraries( stlab INTERFACE Threads::Threads ) + +# +# Several definitions are specified for the microsoft compiler. These have +# the following effects. +# +# + NOMINMAX +# disable the `min` and `max` macros defined in the windows.h header +# +target_compile_definitions( stlab INTERFACE $<$:NOMINMAX> ) + +add_subdirectory( stlab/concurrency ) + +if ( stlab.testing OR stlab.boost_variant OR stlab.boost_optional ) + if( EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) + include( ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake ) + + # + # using the `TARGETS` keyword in the `conan_basic_setup` invocation + # will populate targets for each conan package specified in the + # conanfile.txt + # + conan_basic_setup( TARGETS ) + + # + # We provide aliases to the conan target to mimic the native findBoost + # functionality + # + add_library( Boost::boost INTERFACE IMPORTED ) + add_library( Boost::unit_test_framework INTERFACE IMPORTED ) + set_property( TARGET Boost::boost Boost::unit_test_framework + APPEND PROPERTY INTERFACE_LINK_LIBRARIES CONAN_PKG::boost ) + else() + + # + # Request compiled unit testing component only if testing is `ON` + # + if( stlab.testing ) + find_package( Boost 1.60.0 REQUIRED COMPONENTS unit_test_framework ) + else() + find_package( Boost 1.60.0 REQUIRED ) + endif() + endif() + + + if(NOT TARGET Boost::unit_test_framework) + message(FATAL_ERROR "Could not find Boost unit test framework.") + endif() + + + string( APPEND either_generator + "$," + "$>" ) + + # + # Link to the `Boost::boost` target is either `stlab.boost_optional` + # or `stlab.boost_variant` are set `ON`, which provides the include + # directory for the boost header. + # + target_link_libraries( stlab INTERFACE $<${either_generator}:Boost::boost> ) + + # + # Conditionally specify the corresponding compiler definitions for + # each boost algebraic data type library. In the case that either + # is specified, a preprocessor definition is used to specify that + # `auto_ptr` should not be used in the boost headers. + # + target_compile_definitions( stlab INTERFACE + $<$:STLAB_FORCE_BOOST_OPTIONAL> + $<$:STLAB_FORCE_BOOST_VARIANT> ) + + unset( either_generator ) endif() -target_compile_options( stlab INTERFACE ${stlab_interface_flags} ) - -if ( stlab_testing ) - enable_testing() + +list( APPEND CMAKE_MODULE_PATH "${stlab_SOURCE_DIR}/cmake" ) +include( stlab/coroutines ) +target_link_libraries( stlab INTERFACE stlab::coroutines ) + +if ( stlab.testing ) + include( stlab/development ) + + # + # Establish a convenience target to encapsulate the properties common to the + # stlab tests and establish an alias for uniformity. + # + add_library( testing INTERFACE ) + add_library( stlab::testing ALIAS testing ) + + # + # CMake targets linking to the stlab::testing target will (transitively) + # link to the Boost::unit_test_framework and to stlab::stlab target. + # + target_link_libraries( testing INTERFACE + Boost::unit_test_framework + stlab::development + stlab::stlab ) + + # + # Linking to the Boost unit test framework requires an additional + # preprocessor definition when the unit test compiled resources are + # provided by a shared library rather than a static library. + # + target_compile_definitions( testing INTERFACE + $<$>:BOOST_TEST_DYN_LINK>) + add_subdirectory( test ) endif() +include( CMakePackageConfigHelpers ) # provides `write_basic_package_version_file` + +# +# We generate a CMake version file for later installation to be consumed by +# CMake's `find_package` intrinsic. Here we specify a semantic version +# convention, i.e., backwards compatability can be assumed within a Major +# version. +# +write_basic_package_version_file( + "${stlab_BINARY_DIR}/stlabConfigVersion.cmake" + VERSION ${stlab_VERSION} + COMPATIBILITY SameMajorVersion ) + +# +# As a header-only library, there are no target components to be installed +# directly (the PUBLIC_HEADER property is not white listed for INTERFACE +# targets for some reason). +# +# However, it is worthwhile export our target description in order to later +# generate a CMake configuration file for consumption by CMake's `find_package` +# intrinsic +# +install( TARGETS stlab coroutines EXPORT stlabTargets ) + +# +# Non-testing header files (preserving relative paths) are installed to the +# `include` subdirectory of the `$INSTALL_DIR/${CMAKE_INSTALL_PREFIX}` +# directory. Source file permissions preserved. +# +install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/stlab + DESTINATION include + USE_SOURCE_PERMISSIONS + FILES_MATCHING + PATTERN "*.hpp" + PATTERN "*test*" EXCLUDE ) + +# +# A CMake configuration file is generated describing the stlab exported targets. +# This file is included by (and installed with) the cmake/CMakeConfig.cmake file +# under version control. +# +install( EXPORT stlabTargets + FILE stlabTargets.cmake + NAMESPACE stlab:: + DESTINATION share/cmake/stlab ) + +# +# Install the CMake configuration files to the `share/cmake/stlab` subdirectory +# of `$INSTALL_DIR/${CMAKE_INSTALL_PREFIX}`. This path will be searched by +# default by the `find_package` intrinsic, provided +# `$INSTALL_DIR/${CMAKE_INSTALL_PREFIX}` is an element of the +# `CMAKE_PREFIX_PATH` environment variable. +# +install( FILES + "${stlab_SOURCE_DIR}/cmake/stlabConfig.cmake" + "${stlab_BINARY_DIR}/stlabConfigVersion.cmake" + DESTINATION share/cmake/stlab ) + +# +# Rudimentary CPack support. +# +# CPack provides a mechanism to generate installation packaging for a project, +# e.g., self-extracting shell scripts, compressed tarballs, Debian Package files, +# RPM Package Manager files, Windows NSIS installation wizards, +# Apple Disk Images (.dmg), etc. +# +# Any system libraries required (runtimes, threading, etc) should be bundled +# with the project for this type of installation. The +# `InstallRequiredSystemLibraries` CMake module attempts to provide this +# functionality in an automated way. Additional libraries may be specified as +# +# ```cmake +# list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ) +# ``` +# +# A packaged installation can be generated by calling +# +# ```sh +# cpack -G --config CPackConfig.cmake +# ``` +# +# See `cpack --help` or the CPack documentation for more information. +# +include( InstallRequiredSystemLibraries ) +set( CPACK_PACKAGE_VENDOR "Adobe Software Technology Lab" ) +set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" ) +set( CMAKE_PROJECT_HOMEPAGE_URL "http://stlab.cc/libraries/" ) +include( CPack ) diff --git a/cmake/AppleClang.cmake b/cmake/AppleClang.cmake deleted file mode 100644 index 6c472b1ee..000000000 --- a/cmake/AppleClang.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set( stlab_base_flags "-Wall;-ftemplate-backtrace-limit=0;" ) -set( stlab_debug_flags "-gdwarf-3;" ) -set( stlab_coverage_flags "-fprofile-arcs;-ftest-coverage;" ) -set( stlab_release_flags "" ) -set( stlab_interface_flags "-std=c++14;") diff --git a/cmake/Clang.cmake b/cmake/Clang.cmake deleted file mode 100644 index a4637ae20..000000000 --- a/cmake/Clang.cmake +++ /dev/null @@ -1,7 +0,0 @@ -set( stlab_base_flags "-Wall;-ftemplate-backtrace-limit=0;" ) -set( stlab_debug_flags "-gdwarf-3;" ) -set( stlab_coverage_flags "-fprofile-arcs;-ftest-coverage;" ) -set( stlab_release_flags "" ) -set( stlab_interface_flags "-std=c++latest;-DBOOST_NO_AUTO_PTR=1;") -set( stlab_coroutine_flags "-fcoroutines-ts;") - diff --git a/cmake/GNU.cmake b/cmake/GNU.cmake deleted file mode 100644 index 1426385fc..000000000 --- a/cmake/GNU.cmake +++ /dev/null @@ -1,8 +0,0 @@ -set( stlab_base_flags "-Wall;-ftemplate-backtrace-limit=0;" ) -set( stlab_debug_flags "-gdwarf-3;" ) -set( stlab_coverage_flags "-fprofile-arcs;-ftest-coverage;" ) -set( stlab_release_flags "" ) -# gcc version < 7 has a bug in static constexpr members and reports tons of errors/warnings. -# By using -fpermissive and -w is the only way to shut the compiler up -# Remove when we remove to C++17 -set( stlab_interface_flags "-std=gnu++14;-fpermissive;-w") diff --git a/cmake/MSVC.cmake b/cmake/MSVC.cmake deleted file mode 100644 index b1b6828ab..000000000 --- a/cmake/MSVC.cmake +++ /dev/null @@ -1,6 +0,0 @@ -set( stlab_base_flags "" ) # removed /EHsc -set( stlab_debug_flags "" ) -set( stlab_coverage_flags "" ) -set( stlab_release_flags "" ) -set( stlab_interface_flags "-D_WIN32_WINNT=0x0601;/DNOMINMAX;/std:c++latest;/D_HAS_AUTO_PTR_ETC=1;/bigobj;/D_SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING") -set( stlab_coroutine_flags "/std:c++latest;/await;") diff --git a/cmake/stlab.cmake b/cmake/stlab.cmake new file mode 100644 index 000000000..f8c440c23 --- /dev/null +++ b/cmake/stlab.cmake @@ -0,0 +1,2 @@ +include(stlab/development) +include(stlab/coroutines) diff --git a/cmake/stlab/coroutines.cmake b/cmake/stlab/coroutines.cmake new file mode 100644 index 000000000..3d3d813d7 --- /dev/null +++ b/cmake/stlab/coroutines.cmake @@ -0,0 +1,28 @@ +add_library( coroutines INTERFACE ) +add_library( stlab::coroutines ALIAS coroutines ) + +include( stlab/coroutines/AppleClang ) +include( stlab/coroutines/Clang ) +include( stlab/coroutines/GNU ) +include( stlab/coroutines/MSVC ) + +if( stlab.coroutines ) + # + # If the `stlab.coroutines` variable is set to `ON`, then a custom target + # interface property `COROUTINES` is established and added to the coroutines + # target and appended to the `COMPATIBLE_INTERFACE_BOOL` property list + # property. The latter step ensures the property will propagate to targets + # linking to the coroutines target. + # + set_target_properties( coroutines PROPERTIES INTERFACE_COROUTINES ON ) + set_property( TARGET coroutines APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL COROUTINES ) +endif() + +# +# If coroutines are not enabled on the target, the minimum C++ version is +# increased to C++17 +# +target_compile_features( coroutines INTERFACE + $<$>:cxx_std_17> ) + + diff --git a/cmake/stlab/coroutines/AppleClang.cmake b/cmake/stlab/coroutines/AppleClang.cmake new file mode 100644 index 000000000..9bbae120b --- /dev/null +++ b/cmake/stlab/coroutines/AppleClang.cmake @@ -0,0 +1,12 @@ +# +# If the current compiler doesn't support coroutines and coroutine support +# has been requested, issue a warning indicating the tests will not exercise +# the coroutine integration in the stlab library. +# +# As of writing, no version of the Apple Clang (as opposed to the LLVM Clang) +# compiler supports the coroutines TS. +# +if( CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND stlab.coroutines ) + message( WARNING "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} does not support coroutines." ) + message( STATUS "Coroutines will not be used in testing" ) +endif() diff --git a/cmake/stlab/coroutines/Clang.cmake b/cmake/stlab/coroutines/Clang.cmake new file mode 100644 index 000000000..d9c902d84 --- /dev/null +++ b/cmake/stlab/coroutines/Clang.cmake @@ -0,0 +1,40 @@ +# +# If the current compiler doesn't support coroutines and coroutine support +# has been requested, issue a warning indicating the tests will not exercise +# the coroutine integration in the stlab library. +# +if( CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0 + AND stlab.coroutines ) + message( WARNING "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} does not support coroutines." ) + message( STATUS "Coroutines will not be used in testing" ) +endif() + +# +# If the `COROUTINE` property has been established on the target and set +# to `ON` and the Clang compiler version is sufficient to support the +# coroutine TS, return 1. +# +# Otherwise return 0. +# +string( CONCAT active + "$>" + ",$,5>>>" ) + +# +# If using Clang and active, set the coroutines flag +# +string( CONCAT flag_generator + "$<$,${active}>:-fcoroutines-ts>" ) + +target_compile_options( coroutines INTERFACE ${flag_generator} ) + +# +# If using Clang and not active, set a preprocessor definition to disable +# the use of coroutines in the headers. +# +string( CONCAT definition_generator + "$<$,$>" + ":STLAB_FUTURE_COROUTINES=1>" ) + +target_compile_definitions( coroutines INTERFACE ${definition_generator} ) diff --git a/cmake/stlab/coroutines/GNU.cmake b/cmake/stlab/coroutines/GNU.cmake new file mode 100644 index 000000000..df408eab9 --- /dev/null +++ b/cmake/stlab/coroutines/GNU.cmake @@ -0,0 +1,11 @@ +# +# If the current compiler doesn't support coroutines and coroutine support +# has been requested, issue a warning indicating the tests will not exercise +# the coroutine integration in the stlab library. +# +# As of writing, no version of the GNU C++ compiler supports the coroutines TS. +# +if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND stlab.coroutines ) + message( WARNING "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} does not support coroutines." ) + message( STATUS "Coroutines will not be used in testing" ) +endif() diff --git a/cmake/stlab/coroutines/MSVC.cmake b/cmake/stlab/coroutines/MSVC.cmake new file mode 100644 index 000000000..7bc4550ab --- /dev/null +++ b/cmake/stlab/coroutines/MSVC.cmake @@ -0,0 +1,53 @@ +# +# If the current compiler doesn't support coroutines and coroutine support +# has been requested, issue a warning indicating the tests will not exercise +# the coroutine integration in the stlab library. +# +# TODO: Version 15.0.0 may be overly restrictive here. The minimum viable MSVC compiler +# version should be explored at some point in the future. +# +if( CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" + AND stlab.coroutines ) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0.0) + message( WARNING "${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION} does not support coroutines (as used by stlab)." ) + message( STATUS "Coroutines will not be used in testing" ) + elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 99.99.99) + # TODO: replace version number + # 99.99.99 is a place holder for a future microsoft compiler version that resolves + # the await/co_await issue in the channels header observed in current MSVC compilers. + message( WARNING "${CMAKE_CXX_COMPILER}-${CMAKE_CXX_COMPILER_VERSION} cannot accomodate the stlab/concurrency/channels header when compiling with coroutines enabled." ) + message( "This header will be excluded from the project definition." ) + message( "The corresponding tests will not be compiled." ) + endif() +endif() + +# +# If the `COROUTINE` property has been established on the target and set +# to `ON` and the MSVC compiler version is sufficient to support the +# coroutine TS, return 1. +# +# Otherwise return 0. +# +string( CONCAT activate + "$>" + ",$,15.0.0>" + ">" + ">" ) + +# +# If using MSVC and active, set the coroutines flag +# +target_compile_options( coroutines INTERFACE + $<$,${active}>:/await> ) + +# +# If using MSVC and active, set a preprocessor definition to enable +# the use of coroutines in the headers and disable C++17 depreciation warnings. +# +string( CONCAT definition_generator + "$<$,${active}>" + ":_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS;" + "STLAB_FUTURE_COROUTINES=1;" + ">" ) + +target_compile_definitions( coroutines INTERFACE ${definition_generator} ) diff --git a/cmake/stlab/development.cmake b/cmake/stlab/development.cmake new file mode 100644 index 000000000..2390d1404 --- /dev/null +++ b/cmake/stlab/development.cmake @@ -0,0 +1,7 @@ +add_library( development INTERFACE ) +add_library( stlab::development ALIAS development ) + +include( stlab/development/AppleClang ) +include( stlab/development/Clang ) +include( stlab/development/GNU ) +include( stlab/development/MSVC ) diff --git a/cmake/stlab/development/AppleClang.cmake b/cmake/stlab/development/AppleClang.cmake new file mode 100644 index 000000000..a2db6a3ae --- /dev/null +++ b/cmake/stlab/development/AppleClang.cmake @@ -0,0 +1,21 @@ +set( stlab_AppleClang_base_flags -Wall -Wextra -Wpedantic -Werror -ftemplate-backtrace-limit=0 ) +set( stlab_AppleClang_debug_flags -gdwarf-3 ) +set( stlab_AppleClang_coverage_flags --coverage ) +set( stlab_AppleClang_release_flags ) + +string(CONCAT generator + "${stlab_AppleClang_base_flags};" + "$<$," + "$>:${stlab_AppleClang_debug_flags};>" + "$<$," + "$," + "$>:${stlab_AppleClang_release_flags};>" + "$<$," + "$>:${stlab_AppleClang_debug_flags};>") + +target_compile_options(development INTERFACE + $<$:${generator}>) + +target_link_libraries(development INTERFACE + $<$:${generator}>) + diff --git a/cmake/stlab/development/Clang.cmake b/cmake/stlab/development/Clang.cmake new file mode 100644 index 000000000..2fb257795 --- /dev/null +++ b/cmake/stlab/development/Clang.cmake @@ -0,0 +1,21 @@ +set( stlab_Clang_base_flags -Wall -Wextra -Wpedantic -Werror -ftemplate-backtrace-limit=0 ) +set( stlab_Clang_debug_flags -gdwarf-3 ) +set( stlab_Clang_coverage_flags --coverage ) +set( stlab_Clang_release_flags ) + +string(CONCAT generator + "${stlab_Clang_base_flags};" + "$<$," + "$>:${stlab_Clang_debug_flags};>" + "$<$," + "$," + "$>:${stlab_Clang_release_flags};>" + "$<$," + "$>:${stlab_Clang_debug_flags};>") + +target_compile_options(development INTERFACE + $<$:${generator}>) + +target_link_libraries(development INTERFACE + $<$:${generator}>) + diff --git a/cmake/stlab/development/GNU.cmake b/cmake/stlab/development/GNU.cmake new file mode 100644 index 000000000..20f8e0049 --- /dev/null +++ b/cmake/stlab/development/GNU.cmake @@ -0,0 +1,20 @@ +set( stlab_GNU_base_flags -Wall -Wextra -Wpedantic -Werror -ftemplate-backtrace-limit=0 ) +set( stlab_GNU_debug_flags -gdwarf-3 ) +set( stlab_GNU_coverage_flags --coverage ) +set( stlab_GNU_release_flags ) + +string(CONCAT generator + "${stlab_GNU_base_flags};" + "$<$," + "$>:${stlab_GNU_debug_flags};>" + "$<$," + "$," + "$>:${stlab_GNU_release_flags};>" + "$<$," + "$>:${stlab_GNU_debug_flags};>") + +target_compile_options(development INTERFACE + $<$:${generator}>) + +target_link_libraries(development INTERFACE + $<$:${generator}>) diff --git a/cmake/stlab/development/MSVC.cmake b/cmake/stlab/development/MSVC.cmake new file mode 100644 index 000000000..eb39ceb69 --- /dev/null +++ b/cmake/stlab/development/MSVC.cmake @@ -0,0 +1,17 @@ +set( stlab_MSVC_base_flags /W3 /WX ) +set( stlab_MSVC_debug_flags ) +set( stlab_MSVC_coverage_flags ) +set( stlab_MSVC_release_flags ) + +string(CONCAT generator + "${stlab_MSVC_base_flags};" + "$<$," + "$>:${stlab_MSVC_debug_flags};>" + "$<$," + "$," + "$>:${stlab_MSVC_release_flags};>" + "$<$," + "$>:${stlab_MSVC_debug_flags};>") + +target_compile_options(development INTERFACE + $<$:${generator}>) diff --git a/cmake/stlabConfig.cmake b/cmake/stlabConfig.cmake new file mode 100644 index 000000000..f90f3bf9c --- /dev/null +++ b/cmake/stlabConfig.cmake @@ -0,0 +1,4 @@ +include( CMakeFindDependencyMacro ) +find_dependency(Boost 1.60.0) +find_dependency(Threads) +include( "${CMAKE_CURRENT_LIST_DIR}/stlabTargets.cmake" ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index c55c401ab..000000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -project(future C CXX) - -include_directories("${PROJECT_SOURCE_DIR}/..") - -#set(SOURCE -#) - -set(HEADERS - ../stlab/concurrency/channel.hpp - ../stlab/concurrency/config.hpp - ../stlab/concurrency/default_executor.hpp - ../stlab/concurrency/executor_base.hpp - ../stlab/concurrency/future.hpp - ../stlab/concurrency/immediate_executor.hpp - ../stlab/concurrency/main_executor.hpp - ../stlab/concurrency/progress.hpp - ../stlab/concurrency/system_timer.hpp - ../stlab/concurrency/traits.hpp - ../stlab/concurrency/tuple_algorithm.hpp - ../stlab/concurrency/utility.hpp) - -include_directories(${Boost_INCLUDE_DIRS}) diff --git a/stlab/concurrency/CMakeLists.txt b/stlab/concurrency/CMakeLists.txt new file mode 100644 index 000000000..7cbd45ecf --- /dev/null +++ b/stlab/concurrency/CMakeLists.txt @@ -0,0 +1,46 @@ +target_sources( stlab INTERFACE + $ + $) + +if(CXX_COMPILER_ID MATCHES MSVC) + if(CXX_COMPILER_VERSION VERSION_LESS 99) + get_target_property(wants_coroutines stlab COROUTINES) + if(wants_coroutines) + message(STATUS "Not including concurrency/channel.hpp in the target sources for stlab") + return() + endif() + endif() +endif() + +target_sources(stlab INTERFACE + $ + $) diff --git a/stlab/concurrency/channel.hpp b/stlab/concurrency/channel.hpp index 986e759e5..400dc1571 100644 --- a/stlab/concurrency/channel.hpp +++ b/stlab/concurrency/channel.hpp @@ -312,7 +312,7 @@ auto get_process_state(const stlab::optional& x) } template -auto get_process_state(const stlab::optional& x) +auto get_process_state(const stlab::optional&) -> std::enable_if_t, process_state_scheduled> { return await_forever; } @@ -332,7 +332,7 @@ auto set_process_error(P& process, std::exception_ptr&& error) } template -auto set_process_error(P&, std::exception_ptr&& error) +auto set_process_error(P&, std::exception_ptr&&) -> std::enable_if_t, void> {} /**************************************************************************************************/ diff --git a/stlab/concurrency/config.hpp b/stlab/concurrency/config.hpp index ea7f1134f..80bbdf445 100644 --- a/stlab/concurrency/config.hpp +++ b/stlab/concurrency/config.hpp @@ -65,6 +65,10 @@ #define STLAB_CPP_VERSION 14 #endif +#ifndef STLAB_FUTURE_COROUTINES +#define STLAB_FUTURE_COROUTINES 0 +#endif + /**************************************************************************************************/ #endif diff --git a/stlab/concurrency/future.hpp b/stlab/concurrency/future.hpp index 9829d7719..f75c0cf92 100644 --- a/stlab/concurrency/future.hpp +++ b/stlab/concurrency/future.hpp @@ -30,11 +30,11 @@ // as long as VS 2017 still accepts await as keyword, it is necessary to disable coroutine // support for the channels tests #ifdef __has_include -#if __has_include() && !defined(STLAB_DISABLE_FUTURE_COROUTINES) +#if __has_include() && STLAB_FUTURE_COROUTINES +#define STLAB_FUTURE_COROUTINES_SUPPORT #include #include #include -#define STLAB_FUTURE_COROUTINE_SUPPORT #endif #endif @@ -782,7 +782,7 @@ class future> { } void detach() const { - then([_hold = _p](auto f) {}, [](const auto&) {}); + then([_hold = _p](auto) {}, [](const auto&) {}); } void reset() { _p.reset(); } @@ -873,7 +873,7 @@ class future { } void detach() const { - then([_hold = _p](auto f) {}, []() {}); + then([_hold = _p](auto) {}, []() {}); } void reset() { _p.reset(); } @@ -946,7 +946,7 @@ class future> { } void detach() const { - _p->then_r(unique_usage(_p), [_hold = _p](auto f) {}, [](auto&&) {}); + _p->then_r(unique_usage(_p), [_hold = _p](auto) {}, [](auto&&) {}); } void reset() { _p.reset(); } @@ -995,7 +995,7 @@ struct assign_ready_future { template <> struct assign_ready_future> { template - static void assign(T& x, future& f) { + static void assign(T& x, future&) { x = std::move(typename T::value_type()); // to set the optional } }; @@ -1081,7 +1081,7 @@ struct when_any_shared { } template - void done(FF&& f) { + void done(FF&&) { auto before = _value_received.test_and_set(); if (before == false) { _index = index; @@ -1690,7 +1690,7 @@ auto shared_base::recover(E&& executor, F&& f) template auto shared_base>::reduce(future>&& r) -> future { - return std::move(r).then([](auto f) {}); + return std::move(r).then([](auto) {}); } template @@ -1710,7 +1710,7 @@ auto shared_base>::reduce(future>&& r) -> /**************************************************************************************************/ inline auto shared_base::reduce(future>&& r) -> future { - return std::move(r).then([](auto f) {}); + return std::move(r).then([](auto) {}); } template @@ -1732,7 +1732,7 @@ auto shared_base::reduce(future>&& r) -> future { /**************************************************************************************************/ -#ifdef STLAB_FUTURE_COROUTINE_SUPPORT +#if STLAB_FUTURE_COROUTINES_SUPPORT template struct std::experimental::coroutine_traits, Args...> { diff --git a/stlab/concurrency/main_executor.hpp b/stlab/concurrency/main_executor.hpp index eaeb6c392..1670113f9 100644 --- a/stlab/concurrency/main_executor.hpp +++ b/stlab/concurrency/main_executor.hpp @@ -9,7 +9,7 @@ #ifndef STLAB_CONCURRENCY_MAIN_EXECUTOR_HPP #define STLAB_CONCURRENCY_MAIN_EXECUTOR_HPP -#include "config.hpp" +#include #define STLAB_MAIN_EXECUTOR_LIBDISPATCH 1 #define STLAB_MAIN_EXECUTOR_EMSCRIPTEN 2 diff --git a/stlab/concurrency/serial_queue.hpp b/stlab/concurrency/serial_queue.hpp index 065842962..457d1b500 100644 --- a/stlab/concurrency/serial_queue.hpp +++ b/stlab/concurrency/serial_queue.hpp @@ -18,7 +18,9 @@ #include +#ifndef STLAB_DISABLE_FUTURE_COROUTINES #define STLAB_DISABLE_FUTURE_COROUTINES +#endif #include #include diff --git a/stlab/concurrency/task.hpp b/stlab/concurrency/task.hpp index 9dde37290..abf09526e 100644 --- a/stlab/concurrency/task.hpp +++ b/stlab/concurrency/task.hpp @@ -82,10 +82,12 @@ class task { static auto const_pointer(const void* self) noexcept -> const void* { return &static_cast(self)->_f; } - - static constexpr concept _vtable = {dtor, move_ctor, invoke, - target_type, pointer, const_pointer}; - +#if defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__) + static const concept _vtable; +#else + static constexpr concept _vtable = { dtor, move_ctor, invoke, + target_type, pointer, const_pointer }; +#endif F _f; }; @@ -110,8 +112,12 @@ class task { return static_cast(self)->_p.get(); } - static constexpr concept _vtable = {dtor, move_ctor, invoke, - target_type, pointer, const_pointer}; +#if defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__) + static const concept _vtable; +#else + static constexpr concept _vtable = { dtor, move_ctor, invoke, + target_type, pointer, const_pointer }; +#endif std::unique_ptr _p; }; @@ -124,8 +130,12 @@ class task { static auto pointer(void*) noexcept -> void* { return nullptr; } static auto const_pointer(const void*) noexcept -> const void* { return nullptr; } - static constexpr concept _vtable = {dtor, move_ctor, invoke, - target_type_, pointer, const_pointer}; +#if defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__) + static const concept _vtable; +#else + static constexpr concept _vtable = { dtor, move_ctor, invoke, + target_type_, pointer, const_pointer }; +#endif const concept* _vtable_ptr = &_vtable; @@ -216,8 +226,18 @@ class task { #if STLAB_CPP_VERSION < 17 // In C++17 constexpr implies inline and these definitions are deprecated -template -const typename task::concept task::_vtable; + + +#if defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__) + template + const typename task::concept task::_vtable = { dtor, move_ctor, invoke, + target_type_, pointer, const_pointer }; +#else + template + const typename task::concept task::_vtable; +#endif + + #ifdef _MSC_VER @@ -231,6 +251,20 @@ const typename task::concept task::model::_vtab #else +#if defined(__GNUC__) && __GNUC__ < 7 && !defined(__clang__) + +template +template +const typename task::concept task::template model::_vtable = { dtor, move_ctor, invoke, + target_type, pointer, const_pointer }; + +template +template +const typename task::concept task::template model::_vtable = { dtor, move_ctor, invoke, + target_type, pointer, const_pointer }; + +#else + template template const typename task::concept task::template model::_vtable; @@ -243,6 +277,8 @@ const typename task::concept task::template model blocking_get(future x, const std::chrono::nanoseconds& tim { std::unique_lock lock{state->m}; state->flag = true; + state->condition.notify_one(); } - state->condition.notify_one(); }); { @@ -185,8 +185,8 @@ inline bool blocking_get(future x, const std::chrono::nanoseconds& timeout { std::unique_lock lock(state->m); state->flag = true; + state->condition.notify_one(); } - state->condition.notify_one(); }); { diff --git a/stlab/version.hpp b/stlab/version.hpp index 568ba7234..74f86ee65 100644 --- a/stlab/version.hpp +++ b/stlab/version.hpp @@ -19,13 +19,13 @@ // STLAB_VERSION / 100 % 1000 is the minor version // STLAB_VERSION / 100000 is the major version -#define STLAB_VERSION 100302 +#define STLAB_VERSION 100303 // // STLAB_LIB_VERSION must be defined to be the same as STLAB_VERSION // but as a *string* in the form "x_y[_z]" where x is the major version // number, y is the minor version number, and z is the patch level if not 0. -#define STLAB_LIB_VERSION "1_3_2" +#define STLAB_LIB_VERSION "1_3_3" #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f80a5c621..1fdeaea3e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,251 +1,112 @@ -#################################################################################################### - -add_executable( stlab.test.channel.test - "${CMAKE_CURRENT_SOURCE_DIR}/channel_functor_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_merge_round_robin_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_merge_unordered_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_merge_zip_with_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_process_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_test_helper.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/tuple_algorithm_test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/channel_test_helper.hpp" ) - -# This syntax is a CMake generator expression. +if( NOT ( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" + AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS "99.99.99" + AND stlab.coroutines ) ) + add_executable( stlab.test.channel + channel_functor_tests.cpp + channel_merge_round_robin_tests.cpp + channel_merge_unordered_tests.cpp + channel_merge_zip_with_tests.cpp + channel_process_tests.cpp + channel_test_helper.cpp + channel_tests.cpp + tuple_algorithm_test.cpp + main.cpp + channel_test_helper.hpp ) +endif() + +target_link_libraries( stlab.test.channel PUBLIC stlab::testing ) +add_test( NAME stlab.test.channel COMMAND stlab.test.channel ) + +################################################################################ + +add_executable( stlab.test.future + future_recover_tests.cpp + future_test_helper.cpp + future_tests.cpp + future_then_tests.cpp + future_when_all_arguments_tests.cpp + future_when_all_range_tests.cpp + future_when_any_arguments_tests.cpp + future_when_any_range_tests.cpp + tuple_algorithm_test.cpp + main.cpp + future_test_helper.hpp ) + +target_sources( stlab.test.future PUBLIC + $<$>:future_coroutine_tests.cpp> ) +target_link_libraries( stlab.test.future PUBLIC stlab::testing ) +add_test( NAME stlab.test.future COMMAND stlab.test.future ) + +################################################################################ + +add_executable( stlab.test.serial_queue + serial_queue_test.cpp ) + +target_link_libraries( stlab.test.serial_queue PUBLIC stlab::testing ) +add_test( NAME stlab.test.serial_queue COMMAND stlab.test.serial_queue ) + +################################################################################ + +add_executable( stlab.test.cow + cow_test.cpp + main.cpp ) + +target_link_libraries( stlab.test.cow PUBLIC stlab::testing ) +add_test( NAME stlab.test.cow COMMAND stlab.test.cow ) + +################################################################################ + +add_executable( stlab.test.task + task_test.cpp + main.cpp ) + +target_link_libraries( stlab.test.task PUBLIC stlab::testing ) +add_test( NAME stlab.test.task COMMAND stlab.test.task ) + +################################################################################ + +add_executable( stlab.test.tuple + tuple_test.cpp + main.cpp ) + +target_link_libraries( stlab.test.tuple PUBLIC stlab::testing ) +add_test( NAME stlab.test.tuple COMMAND stlab.test.tuple ) + +################################################################################ + # -# Here we defer the compiler flags decision-making to generation time -# (for tools which support distinct configuration and generation steps) -# based on a generation time configuration. +# tests are compiled without compiler extensions to ensure the stlab headers +# are not dependent upon any such extension. # -# Here, we provide support for a DEBUG and RELEASE configurations, line 32 -# providing the former and line 33 providing the latter. -target_compile_options( stlab.test.channel.test - PUBLIC ${stlab_base_flags} - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.channel.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.channel.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.channel.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.channel.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.channel.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.channel.test PUBLIC - "${stlab_appended_flags}" ) +set_target_properties( + stlab.test.channel + stlab.test.future + stlab.test.serial_queue + stlab.test.cow + stlab.test.task + stlab.test.tuple + PROPERTIES CXX_EXTENSIONS OFF ) -set_property(TARGET stlab.test.channel.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.channel.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.channel COMMAND stlab.test.channel.test ) - - -#################################################################################################### - -add_executable( stlab.test.future.test - "${CMAKE_CURRENT_SOURCE_DIR}/future_coroutine_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_recover_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_test_helper.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_then_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_when_all_arguments_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_when_all_range_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_when_any_arguments_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_when_any_range_tests.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/tuple_algorithm_test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/future_test_helper.hpp" ) - -# This syntax is a CMake generator expression. # -# Here we defer the compiler flags decision-making to generation time -# (for tools which support distinct configuration and generation steps) -# based on a generation time configuration. +# Many of the stlab tests are executed using the system executor which defaults +# to a number of threads equal to the system parallelism. +# +# Here we (attempt to) query the system processor count and store the value in +# the `nProcessors` variable, where a non-zeros value indicates success. +# +# Provided the query was successful, we inform ctest of the test parallism. # -# Here, we provide support for a DEBUG and RELEASE configurations, line 32 -# providing the former and line 33 providing the latter. -target_compile_options( stlab.test.future.test - PUBLIC ${stlab_base_flags} - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_coroutine_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.future.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.future.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.future.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.future.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.future.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.future.test PUBLIC - "${stlab_appended_flags}" ) - -set_property(TARGET stlab.test.future.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.future.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.future COMMAND stlab.test.future.test ) - -#################################################################################################### - -add_executable( stlab.test.serial_queue.test - "${CMAKE_CURRENT_SOURCE_DIR}/serial_queue_test.cpp" ) - -target_compile_options( stlab.test.serial_queue.test - PUBLIC "${stlab_base_flags}" - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.serial_queue.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.serial_queue.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.serial_queue.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.serial_queue.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.serial_queue.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.serial_queue.test PUBLIC - "${stlab_appended_flags}" ) - -set_property(TARGET stlab.test.serial_queue.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.serial_queue.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.serial_queue COMMAND stlab.test.serial_queue.test ) - -#################################################################################################### - -add_executable( stlab.test.cow.test - "${CMAKE_CURRENT_SOURCE_DIR}/cow_test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ) - -target_compile_options( stlab.test.cow.test - PUBLIC "${stlab_base_flags}" - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.cow.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.cow.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.cow.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.cow.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.cow.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.cow.test PUBLIC - "${stlab_appended_flags}" ) - -set_property(TARGET stlab.test.cow.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.cow.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.cow COMMAND stlab.test.cow.test ) - -#################################################################################################### - -add_executable( stlab.test.task.test - "${CMAKE_CURRENT_SOURCE_DIR}/task_test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ) - -target_compile_options( stlab.test.task.test - PUBLIC "${stlab_base_flags}" - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.task.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.task.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.task.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.task.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.task.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.task.test PUBLIC - "${stlab_appended_flags}" ) - -set_property(TARGET stlab.test.task.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.task.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.task COMMAND stlab.test.task.test ) - -#################################################################################################### - -add_executable( stlab.test.tuple.test - "${CMAKE_CURRENT_SOURCE_DIR}/tuple_test.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ) - -target_compile_options( stlab.test.tuple.test - PUBLIC "${stlab_base_flags}" - $<$:$<$:${stlab_coverage_flags}>${stlab_debug_flags}> - $<$:${stlab_release_flags}> - ${stlab_appended_flags} ) - -target_link_libraries( stlab.test.tuple.test - PUBLIC ${Boost_LIBRARIES} - PUBLIC stlab ) - -target_link_libraries( stlab.test.tuple.test PUBLIC - "${stlab_base_flags}" ) - -target_link_libraries( stlab.test.tuple.test PUBLIC - "$<$:${stlab_debug_flags}>" ) - -target_link_libraries( stlab.test.tuple.test PUBLIC - "$<$:$<$:${stlab_coverage_flags}>>" ) - -target_link_libraries( stlab.test.tuple.test PUBLIC - "$<$:${stlab_release_flags}>" ) - -target_link_libraries( stlab.test.tuple.test PUBLIC - "${stlab_appended_flags}" ) - -set_property(TARGET stlab.test.tuple.test PROPERTY CXX_STANDARD 14) -set_property(TARGET stlab.test.tuple.test PROPERTY CXX_STANDARD_REQUIRED ON) - -add_test( NAME stlab.test.tuple COMMAND stlab.test.tuple.test ) +include(ProcessorCount) +ProcessorCount(nProcessors) + +if(nProcessors) + set_tests_properties( + stlab.test.channel + stlab.test.future + stlab.test.serial_queue + stlab.test.cow + stlab.test.task + stlab.test.tuple + PROPERTIES PROCESSORS ${nProcessors}) +endif() diff --git a/test/channel_functor_tests.cpp b/test/channel_functor_tests.cpp index 553ad5d34..44e5f8319 100644 --- a/test/channel_functor_tests.cpp +++ b/test/channel_functor_tests.cpp @@ -8,7 +8,6 @@ #include -#define STLAB_DISABLE_FUTURE_COROUTINES #include #include #include diff --git a/test/channel_merge_round_robin_tests.cpp b/test/channel_merge_round_robin_tests.cpp index b9ad2c5a1..fc8a233eb 100644 --- a/test/channel_merge_round_robin_tests.cpp +++ b/test/channel_merge_round_robin_tests.cpp @@ -8,7 +8,6 @@ #include -#define STLAB_DISABLE_FUTURE_COROUTINES #include #include #include diff --git a/test/channel_merge_unordered_tests.cpp b/test/channel_merge_unordered_tests.cpp index af83b46a9..bc5f35734 100644 --- a/test/channel_merge_unordered_tests.cpp +++ b/test/channel_merge_unordered_tests.cpp @@ -8,7 +8,6 @@ #include -#define STLAB_DISABLE_FUTURE_COROUTINES #include #include #include diff --git a/test/channel_merge_zip_with_tests.cpp b/test/channel_merge_zip_with_tests.cpp index 9ea464a82..699b4ff8a 100644 --- a/test/channel_merge_zip_with_tests.cpp +++ b/test/channel_merge_zip_with_tests.cpp @@ -8,7 +8,6 @@ #include -#define STLAB_DISABLE_FUTURE_COROUTINES #include #include #include diff --git a/test/channel_process_tests.cpp b/test/channel_process_tests.cpp index 4805618c2..1d761b0a1 100644 --- a/test/channel_process_tests.cpp +++ b/test/channel_process_tests.cpp @@ -8,8 +8,6 @@ #include -#define STLAB_DISABLE_FUTURE_COROUTINES - #include #include #include @@ -305,9 +303,9 @@ struct process_with_set_error { std::atomic_bool& _check; - void await(int n) { throw std::runtime_error{""}; } + void await(int) { throw std::runtime_error{""}; } - void set_error(std::exception_ptr error) { _check = true; } + void set_error(std::exception_ptr) { _check = true; } int yield() { return 42; } @@ -329,7 +327,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_set_error_is_called_on_upstream_error) throw std::runtime_error{""}; return v; } | - process_with_set_error{check} | [](int x) {}; + process_with_set_error{check} | [](int) {}; receive.set_ready(); send(42); @@ -347,7 +345,7 @@ struct process_with_close { std::atomic_bool& _check; - void await(int n) { throw std::runtime_error{""}; } + void await(int) { throw std::runtime_error{""}; } void close() { _check = true; } @@ -371,7 +369,7 @@ BOOST_AUTO_TEST_CASE(int_channel_process_close_is_called_on_upstream_error) { throw std::runtime_error{""}; return v; } | - process_with_close{check} | [](int x) {}; + process_with_close{check} | [](int) {}; receive.set_ready(); send(42); diff --git a/test/channel_test_helper.hpp b/test/channel_test_helper.hpp index 21c7c8d71..d5e5705fe 100644 --- a/test/channel_test_helper.hpp +++ b/test/channel_test_helper.hpp @@ -6,10 +6,9 @@ /**************************************************************************************************/ -#ifndef CHANNEL_TEST_HELPER_ -#define CHANNEL_TEST_HELPER_ +#ifndef CHANNEL_TEST_HELPER +#define CHANNEL_TEST_HELPER -#define STLAB_DISABLE_FUTURE_COROUTINES #include #include #include diff --git a/test/channel_tests.cpp b/test/channel_tests.cpp index c8c537922..6268d5090 100644 --- a/test/channel_tests.cpp +++ b/test/channel_tests.cpp @@ -8,7 +8,10 @@ #include +#ifndef STLAB_DISABLE_FUTURE_COROUTINES #define STLAB_DISABLE_FUTURE_COROUTINES +#endif + #include #include #include @@ -466,4 +469,4 @@ BOOST_AUTO_TEST_CASE(sender_receiver_swap_tests) { BOOST_REQUIRE_EQUAL(1, result2); BOOST_REQUIRE_EQUAL(2, result1); } -} \ No newline at end of file +} diff --git a/test/future_coroutine_tests.cpp b/test/future_coroutine_tests.cpp index f17e65cc7..2fd11904b 100644 --- a/test/future_coroutine_tests.cpp +++ b/test/future_coroutine_tests.cpp @@ -18,7 +18,7 @@ #include "future_test_helper.hpp" -#ifdef STLAB_FUTURE_COROUTINE_SUPPORT +#if STLAB_FUTURE_COROUTINES using namespace stlab; using namespace future_test_helper; @@ -117,4 +117,4 @@ BOOST_AUTO_TEST_CASE(future_coroutine_combined_void_int) { BOOST_REQUIRE(boolCheck.load()); } -#endif \ No newline at end of file +#endif diff --git a/test/future_tests.cpp b/test/future_tests.cpp index f3732652c..c678ab170 100644 --- a/test/future_tests.cpp +++ b/test/future_tests.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { BOOST_TEST_MESSAGE("running async lambda argument of type rvalue -> value"); annotate_counters counters; - async(immediate_executor, [](annotate x) {}, annotate(counters)); + async(immediate_executor, [](annotate) {}, annotate(counters)); BOOST_REQUIRE(counters.remaining() == 0); BOOST_REQUIRE(counters._copy_ctor == 0); } @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate x) {}, x); + async(immediate_executor, [](annotate) {}, x); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 1); } @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate x) {}, std::ref(x)); + async(immediate_executor, [](annotate) {}, std::ref(x)); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 1); } @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate x) {}, std::cref(x)); + async(immediate_executor, [](annotate) {}, std::cref(x)); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 1); } @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { BOOST_TEST_MESSAGE("running async lambda argument of type rvalue -> &"); annotate_counters counters; - async(immediate_executor, [](annotate& x){ }, annotate(counters)); + async(immediate_executor, [](annotate&){ }, annotate(counters)); BOOST_REQUIRE(counters.remaining() == 0); BOOST_REQUIRE(counters._copy_ctor == 0); } @@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate& x){ }, x); + async(immediate_executor, [](annotate&){ }, x); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 1); } @@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate& x){ }, std::cref(x)); + async(immediate_executor, [](annotate&){ }, std::cref(x)); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 1); } @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate&& x){ }, std::ref(x)); + async(immediate_executor, [](annotate&&){ }, std::ref(x)); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 0); } @@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(async_lambda_arguments) { annotate_counters counters; annotate x(counters); - async(immediate_executor, [](annotate&& x){ }, std::cref(x)); + async(immediate_executor, [](annotate&&){ }, std::cref(x)); BOOST_REQUIRE(counters.remaining() == 1); BOOST_REQUIRE(counters._copy_ctor == 0); } @@ -538,7 +538,7 @@ BOOST_AUTO_TEST_CASE(future_int_detach_without_execution) { bool check = true; { auto p = package(stlab::immediate_executor, [] { return 42; }); - p.second.then([a = stlab::annotate(counter), &_check = check](int x) { _check = false; }).detach(); + p.second.then([a = stlab::annotate(counter), &_check = check](int) { _check = false; }).detach(); } std::cout << counter; @@ -552,7 +552,7 @@ BOOST_AUTO_TEST_CASE(future_move_only_detach_without_execution) { bool check = true; { auto p = package(stlab::immediate_executor, [] { return move_only{42}; }); - auto r = std::move(p.second).then([a = stlab::annotate(counter), &_check = check](auto&& x) { _check = false; }); + auto r = std::move(p.second).then([a = stlab::annotate(counter), &_check = check](auto&&) { _check = false; }); r.detach(); } std::cout << counter; diff --git a/test/future_then_tests.cpp b/test/future_then_tests.cpp index 13a2584c5..eb9d1404c 100644 --- a/test/future_then_tests.cpp +++ b/test/future_then_tests.cpp @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(future_continuation_moving_move_only_capture_to_result) { stlab::v1::move_only m{42}; sut = async(custom_scheduler<0>(), [] { return stlab::v1::move_only{10}; }) - .then([& _m = m](auto x) mutable { return std::move(_m); }); + .then([& _m = m](auto) mutable { return std::move(_m); }); check_valid_future(sut); auto result = wait_until_future_r_completed(sut); @@ -396,7 +396,7 @@ BOOST_AUTO_TEST_CASE(future_continuation_async_mutable_move_move_only_capture_to stlab::v1::move_only m{42}; sut = async(custom_scheduler<0>(), []() mutable { return stlab::v1::move_only{10}; }) - .then([& _m = m](auto x) mutable { return std::move(_m); }); + .then([& _m = m](auto) mutable { return std::move(_m); }); check_valid_future(sut); auto result = wait_until_future_r_completed(sut); diff --git a/test/serial_queue_test.cpp b/test/serial_queue_test.cpp index 74b834522..737ffd51b 100644 --- a/test/serial_queue_test.cpp +++ b/test/serial_queue_test.cpp @@ -86,7 +86,7 @@ inline std::uint64_t str_hash(const std::string& x) { inline std::uint64_t hash_combine(std::uint64_t hash, const std::string& x) { return hash ^ (str_hash(x) << 1); -}; +} /**************************************************************************************************/ @@ -169,7 +169,7 @@ void test1(stlab::schedule_mode mode) { /**************************************************************************************************/ -int main(int argc, const char* argv[]) { +int main(int, const char*[]) { test0(stlab::schedule_mode::single); std::cout << "-=-=-=-=-\n"; diff --git a/test/task_test.cpp b/test/task_test.cpp index 1232411bf..821ff9d6a 100644 --- a/test/task_test.cpp +++ b/test/task_test.cpp @@ -194,6 +194,11 @@ BOOST_AUTO_TEST_CASE(task_type_tests) { BOOST_CHECK(!t); } + { + task t(nullptr); + BOOST_CHECK(!t); + } + { // large model task t = large_model(); diff --git a/test/tuple_algorithm_test.cpp b/test/tuple_algorithm_test.cpp index db9eb019f..62cf5e092 100644 --- a/test/tuple_algorithm_test.cpp +++ b/test/tuple_algorithm_test.cpp @@ -16,7 +16,7 @@ BOOST_AUTO_TEST_SUITE(tuple_find_test) BOOST_AUTO_TEST_CASE(empty_tuple) { std::tuple<> t; - BOOST_REQUIRE_EQUAL(std::size_t(1), stlab::tuple_find(t, [](const auto& t) { return false; })); + BOOST_REQUIRE_EQUAL(std::size_t(1), stlab::tuple_find(t, [](const auto&) { return false; })); } BOOST_AUTO_TEST_CASE(one_element_tuple_that_fails) { diff --git a/test/tuple_test.cpp b/test/tuple_test.cpp index 685defdf8..d017ff7e8 100644 --- a/test/tuple_test.cpp +++ b/test/tuple_test.cpp @@ -13,7 +13,10 @@ #include // stlab +#ifndef STLAB_DISABLE_FUTURE_COROUTINES #define STLAB_DISABLE_FUTURE_COROUTINES +#endif + #include #include #include @@ -75,7 +78,7 @@ BOOST_AUTO_TEST_CASE(add_placeholder_test) { /**************************************************************************************************/ template -void when_all_typecheck(F f, future... args) { +void when_all_typecheck(F, future...) { using pt_t = placeholder_tuple; using opt_t = optional_placeholder_tuple; using vt_t = voidless_tuple;