mirror of
https://github.com/BlackMATov/promise.hpp.git
synced 2025-12-13 03:46:29 +07:00
@@ -1,12 +1,45 @@
|
|||||||
version: "{build}"
|
|
||||||
shallow_clone: true
|
|
||||||
image:
|
image:
|
||||||
- Visual Studio 2015
|
|
||||||
- Visual Studio 2017
|
- Visual Studio 2017
|
||||||
- Visual Studio 2019 Preview
|
- Visual Studio 2019
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
- Win32
|
- x86
|
||||||
- x64
|
- x64
|
||||||
build_script:
|
|
||||||
- scripts\build_all.bat
|
configuration:
|
||||||
test: off
|
- Debug
|
||||||
|
- Release
|
||||||
|
|
||||||
|
for:
|
||||||
|
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- platform: x86
|
||||||
|
configuration: Debug
|
||||||
|
build_script:
|
||||||
|
- scripts\build_debug_x86.bat
|
||||||
|
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- platform: x64
|
||||||
|
configuration: Debug
|
||||||
|
build_script:
|
||||||
|
- scripts\build_debug_x64.bat
|
||||||
|
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- platform: x86
|
||||||
|
configuration: Release
|
||||||
|
build_script:
|
||||||
|
- scripts\build_release_x86.bat
|
||||||
|
|
||||||
|
-
|
||||||
|
matrix:
|
||||||
|
only:
|
||||||
|
- platform: x64
|
||||||
|
configuration: Release
|
||||||
|
build_script:
|
||||||
|
- scripts\build_release_x64.bat
|
||||||
|
|||||||
198
.travis.yml
198
.travis.yml
@@ -1,81 +1,159 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
|
||||||
|
#
|
||||||
|
# windows (MSVC 2017)
|
||||||
|
#
|
||||||
|
|
||||||
|
- os: windows
|
||||||
|
stage: windows
|
||||||
|
name: debug, MSVC 2017, x86
|
||||||
|
script: ./scripts/build_debug_x86.bat
|
||||||
|
|
||||||
|
- os: windows
|
||||||
|
stage: windows
|
||||||
|
name: release, MSVC 2017, x86
|
||||||
|
script: ./scripts/build_release_x86.bat
|
||||||
|
|
||||||
|
- os: windows
|
||||||
|
stage: windows
|
||||||
|
name: debug, MSVC 2017, x64
|
||||||
|
script: ./scripts/build_debug_x64.bat
|
||||||
|
|
||||||
|
- os: windows
|
||||||
|
stage: windows
|
||||||
|
name: release, MSVC 2017, x64
|
||||||
|
script: ./scripts/build_release_x64.bat
|
||||||
|
|
||||||
|
#
|
||||||
|
# linux (g++-7)
|
||||||
|
#
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-4.9"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=gcc-4.9 && CXX=g++-4.9"
|
name: debug, g++-7
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-7"] } }
|
||||||
|
env: CC=gcc-7 CXX=g++-7
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-5"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
|
name: release, g++-7
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-7"] } }
|
||||||
|
env: CC=gcc-7 CXX=g++-7
|
||||||
|
script: ./scripts/build_release.sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# linux (g++-8)
|
||||||
|
#
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-6"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"
|
name: debug, g++-8
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-8"] } }
|
||||||
|
env: CC=gcc-8 CXX=g++-8
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-7"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
|
name: release, g++-8
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test"], packages: ["g++-8"] } }
|
||||||
|
env: CC=gcc-8 CXX=g++-8
|
||||||
|
script: ./scripts/build_release.sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# linux (clang++-5.0)
|
||||||
|
#
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ubuntu-toolchain-r-test, packages: ["xorg-dev", "g++-8"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=gcc-8 && CXX=g++-8"
|
name: debug, clang++-5.0
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-5.0"], packages: ["g++-7", "clang-5.0"] } }
|
||||||
|
env: CC=clang-5.0 CXX=clang++-5.0
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.8"], packages: ["xorg-dev", "clang-3.8", "g++-5"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8"
|
name: release, clang++-5.0
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-5.0"], packages: ["g++-7", "clang-5.0"] } }
|
||||||
|
env: CC=clang-5.0 CXX=clang++-5.0
|
||||||
|
script: ./scripts/build_release.sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# linux (clang++-6.0)
|
||||||
|
#
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-precise-3.9"], packages: ["xorg-dev", "clang-3.9", "g++-5"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=clang-3.9 && CXX=clang++-3.9"
|
name: debug, clang++-6.0
|
||||||
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-6.0"], packages: ["g++-7", "clang-6.0"] } }
|
||||||
|
env: CC=clang-6.0 CXX=clang++-6.0
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: xenial
|
||||||
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-4.0"], packages: ["xorg-dev", "clang-4.0", "g++-5"] } }
|
stage: linux
|
||||||
env: MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
|
name: release, clang++-6.0
|
||||||
- os: linux
|
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-xenial-6.0"], packages: ["g++-7", "clang-6.0"] } }
|
||||||
dist: trusty
|
env: CC=clang-6.0 CXX=clang++-6.0
|
||||||
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-5.0"], packages: ["xorg-dev", "clang-5.0", "g++-7"] } }
|
script: ./scripts/build_release.sh
|
||||||
env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
|
|
||||||
- os: linux
|
#
|
||||||
dist: trusty
|
# macosx (xcode10)
|
||||||
addons: { apt: { sources: ["ubuntu-toolchain-r-test", "llvm-toolchain-trusty-6.0"], packages: ["xorg-dev", "clang-6.0", "g++-7"] } }
|
#
|
||||||
env: MATRIX_EVAL="CC=clang-6.0 && CXX=clang++-6.0"
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode8.3
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode9
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode9.1
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode9.2
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode9.3
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
|
||||||
osx_image: xcode9.4
|
|
||||||
compiler: clang
|
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode10
|
osx_image: xcode10
|
||||||
compiler: clang
|
stage: macosx
|
||||||
|
name: debug, xcode10
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode10
|
||||||
|
stage: macosx
|
||||||
|
name: release, xcode10
|
||||||
|
script: ./scripts/build_release.sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# macosx (xcode11)
|
||||||
|
#
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11
|
||||||
|
stage: macosx
|
||||||
|
name: debug, xcode11
|
||||||
|
script: ./scripts/build_debug.sh
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode11
|
||||||
|
stage: macosx
|
||||||
|
name: release, xcode11
|
||||||
|
script: ./scripts/build_release.sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# coverage
|
||||||
|
#
|
||||||
|
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode10
|
||||||
|
stage: coverage
|
||||||
|
name: coverage, xcode10
|
||||||
addons: { homebrew: { packages: ["lcov"] } }
|
addons: { homebrew: { packages: ["lcov"] } }
|
||||||
after_success: ./scripts/upload_coverage.sh
|
script: ./scripts/upload_coverage.sh
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- eval "${MATRIX_EVAL}"
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == 'osx' ]; then
|
|
||||||
brew update;
|
|
||||||
brew upgrade cmake;
|
|
||||||
brew install git-lfs;
|
|
||||||
fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" == 'linux' ]; then
|
- if [ "$TRAVIS_OS_NAME" == 'linux' ]; then
|
||||||
mkdir $HOME/cmake;
|
mkdir $HOME/cmake;
|
||||||
export PATH="$HOME/cmake/bin:$PATH";
|
export PATH="$HOME/cmake/bin:$PATH";
|
||||||
travis_retry wget -q https://cmake.org/files/v3.11/cmake-3.11.4-Linux-x86_64.sh;
|
travis_retry wget -q https://cmake.org/files/v3.11/cmake-3.11.4-Linux-x86_64.sh;
|
||||||
sh cmake-3.11.4-Linux-x86_64.sh --prefix=$HOME/cmake --exclude-subdir --skip-license;
|
sh cmake-3.11.4-Linux-x86_64.sh --prefix=$HOME/cmake --exclude-subdir --skip-license;
|
||||||
fi
|
fi
|
||||||
script:
|
|
||||||
- ./scripts/build_all.sh
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# 3.8 version is required for `cxx_std_14`
|
# 3.8 version is required for `cxx_std_17`
|
||||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||||
|
|
||||||
if(NOT DEFINED PROJECT_NAME)
|
if(NOT DEFINED PROJECT_NAME)
|
||||||
@@ -9,7 +9,7 @@ project(promise.hpp)
|
|||||||
|
|
||||||
add_library(${PROJECT_NAME} INTERFACE)
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
||||||
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
|
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
|
||||||
|
|
||||||
if(BUILD_AS_STANDALONE)
|
if(BUILD_AS_STANDALONE)
|
||||||
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)
|
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)
|
||||||
|
|||||||
@@ -1,248 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* This file is part of the "https://github.com/blackmatov/invoke.hpp"
|
|
||||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
|
||||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <utility>
|
|
||||||
#include <functional>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#define INVOKE_HPP_NOEXCEPT_RETURN(...) \
|
|
||||||
noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
|
|
||||||
|
|
||||||
#define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \
|
|
||||||
noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; }
|
|
||||||
|
|
||||||
//
|
|
||||||
// void_t
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template < typename... Args >
|
|
||||||
struct make_void {
|
|
||||||
using type = void;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename... Args >
|
|
||||||
using void_t = typename impl::make_void<Args...>::type;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// is_reference_wrapper
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template < typename T >
|
|
||||||
struct is_reference_wrapper_impl
|
|
||||||
: std::false_type {};
|
|
||||||
|
|
||||||
template < typename U >
|
|
||||||
struct is_reference_wrapper_impl<std::reference_wrapper<U>>
|
|
||||||
: std::true_type {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename T >
|
|
||||||
struct is_reference_wrapper
|
|
||||||
: impl::is_reference_wrapper_impl<std::remove_cv_t<T>> {};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// invoke
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// invoke_member_object_impl
|
|
||||||
//
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename Derived,
|
|
||||||
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
std::forward<Derived>(ref).*f)
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename RefWrap,
|
|
||||||
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
ref.get().*f)
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename Pointer,
|
|
||||||
typename std::enable_if_t<
|
|
||||||
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
|
|
||||||
!is_reference_wrapper<std::decay_t<Pointer>>::value
|
|
||||||
, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
(*std::forward<Pointer>(ptr)).*f)
|
|
||||||
|
|
||||||
//
|
|
||||||
// invoke_member_function_impl
|
|
||||||
//
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename Derived, typename... Args,
|
|
||||||
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
(std::forward<Derived>(ref).*f)(std::forward<Args>(args)...))
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename RefWrap, typename... Args,
|
|
||||||
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
(ref.get().*f)(std::forward<Args>(args)...))
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename Base, typename F, typename Pointer, typename... Args,
|
|
||||||
typename std::enable_if_t<
|
|
||||||
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
|
|
||||||
!is_reference_wrapper<std::decay_t<Pointer>>::value
|
|
||||||
, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
((*std::forward<Pointer>(ptr)).*f)(std::forward<Args>(args)...))
|
|
||||||
}
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename F, typename... Args,
|
|
||||||
typename std::enable_if_t<!std::is_member_pointer<std::decay_t<F>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke(F&& f, Args&&... args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
std::forward<F>(f)(std::forward<Args>(args)...))
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename F, typename T,
|
|
||||||
typename std::enable_if_t<std::is_member_object_pointer<std::decay_t<F>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke(F&& f, T&& t)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
impl::invoke_member_object_impl(std::forward<F>(f), std::forward<T>(t)))
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename F, typename... Args,
|
|
||||||
typename std::enable_if_t<std::is_member_function_pointer<std::decay_t<F>>::value, int> = 0
|
|
||||||
>
|
|
||||||
constexpr auto invoke(F&& f, Args&&... args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
|
||||||
impl::invoke_member_function_impl(std::forward<F>(f), std::forward<Args>(args)...))
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// invoke_result
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
struct invoke_result_impl_tag {};
|
|
||||||
|
|
||||||
template < typename Void, typename F, typename... Args >
|
|
||||||
struct invoke_result_impl {};
|
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
|
||||||
struct invoke_result_impl<void_t<invoke_result_impl_tag, decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...))>, F, Args...> {
|
|
||||||
using type = decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
|
||||||
struct invoke_result
|
|
||||||
: impl::invoke_result_impl<void, F, Args...> {};
|
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
|
||||||
using invoke_result_t = typename invoke_result<F, Args...>::type;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// is_invocable
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
struct is_invocable_r_impl_tag {};
|
|
||||||
|
|
||||||
template < typename Void, typename R, typename F, typename... Args >
|
|
||||||
struct is_invocable_r_impl
|
|
||||||
: std::false_type {};
|
|
||||||
|
|
||||||
template < typename R, typename F, typename... Args >
|
|
||||||
struct is_invocable_r_impl<void_t<is_invocable_r_impl_tag, invoke_result_t<F, Args...>>, R, F, Args...>
|
|
||||||
: std::conditional_t<
|
|
||||||
std::is_void<R>::value,
|
|
||||||
std::true_type,
|
|
||||||
std::is_convertible<invoke_result_t<F, Args...>, R>> {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename R, typename F, typename... Args >
|
|
||||||
struct is_invocable_r
|
|
||||||
: impl::is_invocable_r_impl<void, R, F, Args...> {};
|
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
|
||||||
using is_invocable = is_invocable_r<void, F, Args...>;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// apply
|
|
||||||
//
|
|
||||||
|
|
||||||
namespace invoke_hpp
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template < typename F, typename Tuple, std::size_t... I >
|
|
||||||
constexpr decltype(auto) apply_impl(F&& f, Tuple&& args, std::index_sequence<I...>)
|
|
||||||
INVOKE_HPP_NOEXCEPT_RETURN(
|
|
||||||
invoke_hpp::invoke(
|
|
||||||
std::forward<F>(f),
|
|
||||||
std::get<I>(std::forward<Tuple>(args))...))
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename F, typename Tuple >
|
|
||||||
constexpr decltype(auto) apply(F&& f, Tuple&& args)
|
|
||||||
INVOKE_HPP_NOEXCEPT_RETURN(
|
|
||||||
impl::apply_impl(
|
|
||||||
std::forward<F>(f),
|
|
||||||
std::forward<Tuple>(args),
|
|
||||||
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef INVOKE_HPP_NOEXCEPT_RETURN
|
|
||||||
#undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN
|
|
||||||
@@ -6,22 +6,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <mutex>
|
|
||||||
#include <atomic>
|
|
||||||
#include <thread>
|
|
||||||
#include <chrono>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
#include <exception>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#include "promise.hpp"
|
#include "promise.hpp"
|
||||||
|
|
||||||
namespace jobber_hpp
|
namespace jobber_hpp
|
||||||
@@ -58,7 +42,7 @@ namespace jobber_hpp
|
|||||||
std::size_t>;
|
std::size_t>;
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
template < typename F, typename... Args >
|
||||||
using async_invoke_result_t = invoke_hpp::invoke_result_t<
|
using async_invoke_result_t = std::invoke_result_t<
|
||||||
std::decay_t<F>,
|
std::decay_t<F>,
|
||||||
std::decay_t<Args>...>;
|
std::decay_t<Args>...>;
|
||||||
|
|
||||||
@@ -74,6 +58,10 @@ namespace jobber_hpp
|
|||||||
void resume() noexcept;
|
void resume() noexcept;
|
||||||
bool is_paused() const noexcept;
|
bool is_paused() const noexcept;
|
||||||
|
|
||||||
|
std::size_t thread_count() const noexcept;
|
||||||
|
std::thread::id thread_id(std::size_t i) const;
|
||||||
|
std::vector<std::thread::id> thread_ids() const;
|
||||||
|
|
||||||
jobber_wait_status wait_all() const noexcept;
|
jobber_wait_status wait_all() const noexcept;
|
||||||
active_wait_result_t active_wait_all() noexcept;
|
active_wait_result_t active_wait_all() noexcept;
|
||||||
active_wait_result_t active_wait_one() noexcept;
|
active_wait_result_t active_wait_one() noexcept;
|
||||||
@@ -205,6 +193,23 @@ namespace jobber_hpp
|
|||||||
return paused_;
|
return paused_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::size_t jobber::thread_count() const noexcept {
|
||||||
|
return threads_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::thread::id jobber::thread_id(std::size_t i) const {
|
||||||
|
return threads_[i].get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<std::thread::id> jobber::thread_ids() const {
|
||||||
|
std::vector<std::thread::id> ids;
|
||||||
|
ids.reserve(threads_.size());
|
||||||
|
for ( const std::thread& t : threads_ ) {
|
||||||
|
ids.push_back(t.get_id());
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
inline jobber_wait_status jobber::wait_all() const noexcept {
|
inline jobber_wait_status jobber::wait_all() const noexcept {
|
||||||
std::unique_lock<std::mutex> lock(tasks_mutex_);
|
std::unique_lock<std::mutex> lock(tasks_mutex_);
|
||||||
cond_var_.wait(lock, [this](){
|
cond_var_.wait(lock, [this](){
|
||||||
@@ -378,7 +383,7 @@ namespace jobber_hpp
|
|||||||
template < typename R, typename F, typename... Args >
|
template < typename R, typename F, typename... Args >
|
||||||
void jobber::concrete_task<R, F, Args...>::run() noexcept {
|
void jobber::concrete_task<R, F, Args...>::run() noexcept {
|
||||||
try {
|
try {
|
||||||
R value = invoke_hpp::apply(std::move(f_), std::move(args_));
|
R value = std::apply(std::move(f_), std::move(args_));
|
||||||
promise_.resolve(std::move(value));
|
promise_.resolve(std::move(value));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
promise_.reject(std::current_exception());
|
promise_.reject(std::current_exception());
|
||||||
@@ -408,7 +413,7 @@ namespace jobber_hpp
|
|||||||
template < typename F, typename... Args >
|
template < typename F, typename... Args >
|
||||||
void jobber::concrete_task<void, F, Args...>::run() noexcept {
|
void jobber::concrete_task<void, F, Args...>::run() noexcept {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::apply(std::move(f_), std::move(args_));
|
std::apply(std::move(f_), std::move(args_));
|
||||||
promise_.resolve();
|
promise_.resolve();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
promise_.reject(std::current_exception());
|
promise_.reject(std::current_exception());
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -24,8 +25,6 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
#include "invoke.hpp"
|
|
||||||
|
|
||||||
namespace promise_hpp
|
namespace promise_hpp
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -180,7 +179,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF,T> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF,T> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
is_promise<ResolveFR>::value && std::is_void<typename ResolveFR::value_type>::value,
|
is_promise<ResolveFR>::value && std::is_void<typename ResolveFR::value_type>::value,
|
||||||
promise<typename ResolveFR::value_type>>
|
promise<typename ResolveFR::value_type>>
|
||||||
@@ -191,7 +190,7 @@ namespace promise_hpp
|
|||||||
n = next,
|
n = next,
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
auto np = invoke_hpp::invoke(
|
auto np = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
std::move(np).then([n]() mutable {
|
std::move(np).then([n]() mutable {
|
||||||
@@ -207,7 +206,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF,T> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF,T> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
is_promise<ResolveFR>::value && !std::is_void<typename ResolveFR::value_type>::value,
|
is_promise<ResolveFR>::value && !std::is_void<typename ResolveFR::value_type>::value,
|
||||||
promise<typename ResolveFR::value_type>>
|
promise<typename ResolveFR::value_type>>
|
||||||
@@ -218,7 +217,7 @@ namespace promise_hpp
|
|||||||
n = next,
|
n = next,
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
auto np = invoke_hpp::invoke(
|
auto np = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
std::move(np).then([n](auto&& nv) mutable {
|
std::move(np).then([n](auto&& nv) mutable {
|
||||||
@@ -238,7 +237,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
return make_all_promise(std::move(r));
|
return make_all_promise(std::move(r));
|
||||||
@@ -250,7 +249,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
return make_race_promise(std::move(r));
|
return make_race_promise(std::move(r));
|
||||||
@@ -262,7 +261,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
return make_tuple_promise(std::move(r));
|
return make_tuple_promise(std::move(r));
|
||||||
@@ -271,7 +270,7 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename RejectF
|
, typename RejectF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF,T> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF,T> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
@@ -286,7 +285,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF,T> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF,T> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
@@ -443,7 +442,7 @@ namespace promise_hpp
|
|||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
if ( has_reject ) {
|
if ( has_reject ) {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
e);
|
e);
|
||||||
n.resolve();
|
n.resolve();
|
||||||
@@ -460,7 +459,7 @@ namespace promise_hpp
|
|||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
n.resolve();
|
n.resolve();
|
||||||
@@ -488,7 +487,7 @@ namespace promise_hpp
|
|||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
if ( has_reject ) {
|
if ( has_reject ) {
|
||||||
try {
|
try {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
e);
|
e);
|
||||||
n.resolve(std::move(r));
|
n.resolve(std::move(r));
|
||||||
@@ -505,7 +504,7 @@ namespace promise_hpp
|
|||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
](auto&& v) mutable {
|
](auto&& v) mutable {
|
||||||
try {
|
try {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
std::forward<decltype(v)>(v));
|
std::forward<decltype(v)>(v));
|
||||||
n.resolve(std::move(r));
|
n.resolve(std::move(r));
|
||||||
@@ -521,11 +520,11 @@ namespace promise_hpp
|
|||||||
template < typename ResolveF, typename RejectF >
|
template < typename ResolveF, typename RejectF >
|
||||||
void add_handlers_(ResolveF&& resolve, RejectF&& reject) {
|
void add_handlers_(ResolveF&& resolve, RejectF&& reject) {
|
||||||
if ( status_ == status::resolved ) {
|
if ( status_ == status::resolved ) {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<ResolveF>(resolve),
|
std::forward<ResolveF>(resolve),
|
||||||
storage_.value());
|
storage_.value());
|
||||||
} else if ( status_ == status::rejected ) {
|
} else if ( status_ == status::rejected ) {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<RejectF>(reject),
|
std::forward<RejectF>(reject),
|
||||||
exception_);
|
exception_);
|
||||||
} else {
|
} else {
|
||||||
@@ -616,7 +615,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
is_promise<ResolveFR>::value && std::is_void<typename ResolveFR::value_type>::value,
|
is_promise<ResolveFR>::value && std::is_void<typename ResolveFR::value_type>::value,
|
||||||
promise<typename ResolveFR::value_type>>
|
promise<typename ResolveFR::value_type>>
|
||||||
@@ -627,7 +626,7 @@ namespace promise_hpp
|
|||||||
n = next,
|
n = next,
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto np = invoke_hpp::invoke(
|
auto np = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
std::move(np).then([n]() mutable {
|
std::move(np).then([n]() mutable {
|
||||||
n.resolve();
|
n.resolve();
|
||||||
@@ -642,7 +641,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
is_promise<ResolveFR>::value && !std::is_void<typename ResolveFR::value_type>::value,
|
is_promise<ResolveFR>::value && !std::is_void<typename ResolveFR::value_type>::value,
|
||||||
promise<typename ResolveFR::value_type>>
|
promise<typename ResolveFR::value_type>>
|
||||||
@@ -653,7 +652,7 @@ namespace promise_hpp
|
|||||||
n = next,
|
n = next,
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto np = invoke_hpp::invoke(
|
auto np = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
std::move(np).then([n](auto&& nv) mutable {
|
std::move(np).then([n](auto&& nv) mutable {
|
||||||
n.resolve(std::forward<decltype(nv)>(nv));
|
n.resolve(std::forward<decltype(nv)>(nv));
|
||||||
@@ -672,7 +671,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
return make_all_promise(std::move(r));
|
return make_all_promise(std::move(r));
|
||||||
});
|
});
|
||||||
@@ -683,7 +682,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
return make_race_promise(std::move(r));
|
return make_race_promise(std::move(r));
|
||||||
});
|
});
|
||||||
@@ -694,7 +693,7 @@ namespace promise_hpp
|
|||||||
return then([
|
return then([
|
||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
return make_tuple_promise(std::move(r));
|
return make_tuple_promise(std::move(r));
|
||||||
});
|
});
|
||||||
@@ -702,7 +701,7 @@ namespace promise_hpp
|
|||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename RejectF
|
, typename RejectF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
@@ -717,7 +716,7 @@ namespace promise_hpp
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename ResolveF
|
template < typename ResolveF
|
||||||
, typename ResolveFR = invoke_hpp::invoke_result_t<ResolveF> >
|
, typename ResolveFR = std::invoke_result_t<ResolveF> >
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
!is_promise<ResolveFR>::value,
|
!is_promise<ResolveFR>::value,
|
||||||
promise<ResolveFR>>
|
promise<ResolveFR>>
|
||||||
@@ -869,7 +868,7 @@ namespace promise_hpp
|
|||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
if ( has_reject ) {
|
if ( has_reject ) {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
e);
|
e);
|
||||||
n.resolve();
|
n.resolve();
|
||||||
@@ -886,7 +885,7 @@ namespace promise_hpp
|
|||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
n.resolve();
|
n.resolve();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -913,7 +912,7 @@ namespace promise_hpp
|
|||||||
](std::exception_ptr e) mutable {
|
](std::exception_ptr e) mutable {
|
||||||
if ( has_reject ) {
|
if ( has_reject ) {
|
||||||
try {
|
try {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f),
|
std::forward<decltype(f)>(f),
|
||||||
e);
|
e);
|
||||||
n.resolve(std::move(r));
|
n.resolve(std::move(r));
|
||||||
@@ -930,7 +929,7 @@ namespace promise_hpp
|
|||||||
f = std::forward<ResolveF>(on_resolve)
|
f = std::forward<ResolveF>(on_resolve)
|
||||||
]() mutable {
|
]() mutable {
|
||||||
try {
|
try {
|
||||||
auto r = invoke_hpp::invoke(
|
auto r = std::invoke(
|
||||||
std::forward<decltype(f)>(f));
|
std::forward<decltype(f)>(f));
|
||||||
n.resolve(std::move(r));
|
n.resolve(std::move(r));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -945,10 +944,10 @@ namespace promise_hpp
|
|||||||
template < typename ResolveF, typename RejectF >
|
template < typename ResolveF, typename RejectF >
|
||||||
void add_handlers_(ResolveF&& resolve, RejectF&& reject) {
|
void add_handlers_(ResolveF&& resolve, RejectF&& reject) {
|
||||||
if ( status_ == status::resolved ) {
|
if ( status_ == status::resolved ) {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<ResolveF>(resolve));
|
std::forward<ResolveF>(resolve));
|
||||||
} else if ( status_ == status::rejected ) {
|
} else if ( status_ == status::rejected ) {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<RejectF>(reject),
|
std::forward<RejectF>(reject),
|
||||||
exception_);
|
exception_);
|
||||||
} else {
|
} else {
|
||||||
@@ -1032,7 +1031,7 @@ namespace promise_hpp
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
invoke_hpp::invoke(
|
std::invoke(
|
||||||
std::forward<F>(f),
|
std::forward<F>(f),
|
||||||
std::move(resolver),
|
std::move(resolver),
|
||||||
std::move(rejector));
|
std::move(rejector));
|
||||||
|
|||||||
@@ -6,21 +6,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <mutex>
|
|
||||||
#include <atomic>
|
|
||||||
#include <chrono>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
#include <exception>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <condition_variable>
|
|
||||||
|
|
||||||
#include "promise.hpp"
|
#include "promise.hpp"
|
||||||
|
|
||||||
namespace scheduler_hpp
|
namespace scheduler_hpp
|
||||||
@@ -57,7 +42,7 @@ namespace scheduler_hpp
|
|||||||
std::size_t>;
|
std::size_t>;
|
||||||
|
|
||||||
template < typename F, typename... Args >
|
template < typename F, typename... Args >
|
||||||
using schedule_invoke_result_t = invoke_hpp::invoke_result_t<
|
using schedule_invoke_result_t = std::invoke_result_t<
|
||||||
std::decay_t<F>,
|
std::decay_t<F>,
|
||||||
std::decay_t<Args>...>;
|
std::decay_t<Args>...>;
|
||||||
|
|
||||||
@@ -286,7 +271,7 @@ namespace scheduler_hpp
|
|||||||
template < typename R, typename F, typename... Args >
|
template < typename R, typename F, typename... Args >
|
||||||
void scheduler::concrete_task<R, F, Args...>::run() noexcept {
|
void scheduler::concrete_task<R, F, Args...>::run() noexcept {
|
||||||
try {
|
try {
|
||||||
R value = invoke_hpp::apply(std::move(f_), std::move(args_));
|
R value = std::apply(std::move(f_), std::move(args_));
|
||||||
promise_.resolve(std::move(value));
|
promise_.resolve(std::move(value));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
promise_.reject(std::current_exception());
|
promise_.reject(std::current_exception());
|
||||||
@@ -316,7 +301,7 @@ namespace scheduler_hpp
|
|||||||
template < typename F, typename... Args >
|
template < typename F, typename... Args >
|
||||||
void scheduler::concrete_task<void, F, Args...>::run() noexcept {
|
void scheduler::concrete_task<void, F, Args...>::run() noexcept {
|
||||||
try {
|
try {
|
||||||
invoke_hpp::apply(std::move(f_), std::move(args_));
|
std::apply(std::move(f_), std::move(args_));
|
||||||
promise_.resolve();
|
promise_.resolve();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
promise_.reject(std::current_exception());
|
promise_.reject(std::current_exception());
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
@echo off
|
@echo off
|
||||||
set SCRIPT_DIR=%~dp0%
|
set SCRIPT_DIR=%~dp0%
|
||||||
call %SCRIPT_DIR%\build_debug.bat || goto :error
|
call %SCRIPT_DIR%\build_debug_x86.bat || goto :error
|
||||||
call %SCRIPT_DIR%\build_release.bat || goto :error
|
call %SCRIPT_DIR%\build_debug_x64.bat || goto :error
|
||||||
|
call %SCRIPT_DIR%\build_release_x86.bat || goto :error
|
||||||
|
call %SCRIPT_DIR%\build_release_x64.bat || goto :error
|
||||||
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
mkdir -p $BUILD_DIR/debug
|
mkdir -p $BUILD_DIR/Debug
|
||||||
cd $BUILD_DIR/debug
|
cd $BUILD_DIR/Debug
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug ../..
|
cmake -DCMAKE_BUILD_TYPE=Debug ../..
|
||||||
cmake --build . -- -j8
|
cmake --build .
|
||||||
ctest --verbose
|
ctest --verbose
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
@echo off
|
@echo off
|
||||||
set BUILD_DIR=%~dp0%\..\build
|
set BUILD_DIR=%~dp0%\..\build
|
||||||
mkdir %BUILD_DIR%\debug || goto :error
|
mkdir %BUILD_DIR%\Debug\x64 || goto :error
|
||||||
cd %BUILD_DIR%\debug || goto :error
|
cd %BUILD_DIR%\Debug\x64 || goto :error
|
||||||
cmake ../.. || goto :error
|
cmake ..\..\.. -A x64 || goto :error
|
||||||
cmake --build . --config Debug || goto :error
|
cmake --build . --config Debug || goto :error
|
||||||
ctest --verbose || goto :error
|
ctest --verbose || goto :error
|
||||||
cd ..\.. || goto :error
|
cd ..\..\.. || goto :error
|
||||||
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
|
||||||
14
scripts/build_debug_x86.bat
Normal file
14
scripts/build_debug_x86.bat
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@echo off
|
||||||
|
set BUILD_DIR=%~dp0%\..\build
|
||||||
|
mkdir %BUILD_DIR%\Debug\x86 || goto :error
|
||||||
|
cd %BUILD_DIR%\Debug\x86 || goto :error
|
||||||
|
cmake ..\..\.. -A Win32 || goto :error
|
||||||
|
cmake --build . --config Debug || goto :error
|
||||||
|
ctest --verbose || goto :error
|
||||||
|
cd ..\..\.. || goto :error
|
||||||
|
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:error
|
||||||
|
echo Failed with error #%errorlevel%.
|
||||||
|
exit /b %errorlevel%
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
||||||
mkdir -p $BUILD_DIR/release
|
mkdir -p $BUILD_DIR/Release
|
||||||
cd $BUILD_DIR/release
|
cd $BUILD_DIR/Release
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ../..
|
cmake -DCMAKE_BUILD_TYPE=Release ../..
|
||||||
cmake --build . -- -j8
|
cmake --build .
|
||||||
ctest --verbose
|
ctest --verbose
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
@echo off
|
@echo off
|
||||||
set BUILD_DIR=%~dp0%\..\build
|
set BUILD_DIR=%~dp0%\..\build
|
||||||
mkdir %BUILD_DIR%\release || goto :error
|
mkdir %BUILD_DIR%\Release\x64 || goto :error
|
||||||
cd %BUILD_DIR%\release || goto :error
|
cd %BUILD_DIR%\Release\x64 || goto :error
|
||||||
cmake ../.. || goto :error
|
cmake ..\..\.. -A x64 || goto :error
|
||||||
cmake --build . --config Release || goto :error
|
cmake --build . --config Release || goto :error
|
||||||
ctest --verbose || goto :error
|
ctest --verbose || goto :error
|
||||||
cd ..\.. || goto :error
|
cd ..\..\.. || goto :error
|
||||||
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
|
||||||
14
scripts/build_release_x86.bat
Normal file
14
scripts/build_release_x86.bat
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@echo off
|
||||||
|
set BUILD_DIR=%~dp0%\..\build
|
||||||
|
mkdir %BUILD_DIR%\Release\x86 || goto :error
|
||||||
|
cd %BUILD_DIR%\Release\x86 || goto :error
|
||||||
|
cmake ..\..\.. -A Win32 || goto :error
|
||||||
|
cmake --build . --config Release || goto :error
|
||||||
|
ctest --verbose || goto :error
|
||||||
|
cd ..\..\.. || goto :error
|
||||||
|
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:error
|
||||||
|
echo Failed with error #%errorlevel%.
|
||||||
|
exit /b %errorlevel%
|
||||||
@@ -5,13 +5,13 @@ BUILD_DIR=`dirname "$BASH_SOURCE"`/../build
|
|||||||
mkdir -p $BUILD_DIR/coverage
|
mkdir -p $BUILD_DIR/coverage
|
||||||
cd $BUILD_DIR/coverage
|
cd $BUILD_DIR/coverage
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_WITH_COVERAGE=ON ../..
|
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_WITH_COVERAGE=ON ../..
|
||||||
cmake --build . -- -j8
|
cmake --build .
|
||||||
|
|
||||||
lcov -d . -z
|
lcov -d . -z
|
||||||
ctest --verbose
|
ctest --verbose
|
||||||
|
|
||||||
lcov -d . -c -o "coverage.info"
|
lcov -d . -c -o "coverage.info"
|
||||||
lcov -r "coverage.info" "*/usr/*" "*/catch.hpp" "*/catch_main.cpp" "*_tests.cpp" -o "coverage.info"
|
lcov -r "coverage.info" "*/usr/*" "*/catch.hpp" "*/catch_main.cpp" "*_tests.cpp" "*_examples.cpp" -o "coverage.info"
|
||||||
lcov -l "coverage.info"
|
lcov -l "coverage.info"
|
||||||
|
|
||||||
bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
|
bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
|
||||||
|
|||||||
@@ -1,510 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* This file is part of the "https://github.com/blackmatov/invoke.hpp"
|
|
||||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
|
||||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#define CATCH_CONFIG_FAST_COMPILE
|
|
||||||
#include <catch2/catch.hpp>
|
|
||||||
|
|
||||||
#include <promise.hpp/invoke.hpp>
|
|
||||||
namespace inv = invoke_hpp;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void simple_static_function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
int simple_static_function_r() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
int simple_static_function_r_with_arg(int v) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int& simple_static_function_r_with_ref_arg(const int& v) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
class obj_t {
|
|
||||||
public:
|
|
||||||
int value = 42;
|
|
||||||
const int value_c = 42;
|
|
||||||
|
|
||||||
void member() {
|
|
||||||
}
|
|
||||||
|
|
||||||
int member_r() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
int member_r_with_arg(int v) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int& member_r_with_ref_arg(const int& v) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class obj2_t {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("invoke"){
|
|
||||||
SECTION("invoke_functions"){
|
|
||||||
inv::invoke(simple_static_function);
|
|
||||||
REQUIRE(inv::invoke(simple_static_function_r) == 42);
|
|
||||||
REQUIRE(inv::invoke(simple_static_function_r_with_arg, 42) == 42);
|
|
||||||
{
|
|
||||||
int v = 42;
|
|
||||||
REQUIRE(&inv::invoke(simple_static_function_r_with_ref_arg, v) == &v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SECTION("invoke_members"){
|
|
||||||
obj_t o;
|
|
||||||
|
|
||||||
inv::invoke(&obj_t::member, o);
|
|
||||||
inv::invoke(&obj_t::member, &o);
|
|
||||||
inv::invoke(&obj_t::member, std::ref(o));
|
|
||||||
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r, o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r, &o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r, std::ref(o)) == 42);
|
|
||||||
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r_with_arg, o, 42) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r_with_arg, &o, 42) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::member_r_with_arg, std::ref(o), 42) == 42);
|
|
||||||
|
|
||||||
{
|
|
||||||
int v = 42;
|
|
||||||
REQUIRE(&inv::invoke(&obj_t::member_r_with_ref_arg, o, std::ref(v)) == &v);
|
|
||||||
REQUIRE(&inv::invoke(&obj_t::member_r_with_ref_arg, &o, std::ref(v)) == &v);
|
|
||||||
REQUIRE(&inv::invoke(&obj_t::member_r_with_ref_arg, std::ref(o), std::ref(v)) == &v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SECTION("invoke_member_objects"){
|
|
||||||
obj_t o;
|
|
||||||
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value, o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value, &o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value, std::ref(o)) == 42);
|
|
||||||
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value_c, o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value_c, &o) == 42);
|
|
||||||
REQUIRE(inv::invoke(&obj_t::value_c, std::ref(o)) == 42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("invoke_result"){
|
|
||||||
SECTION("invoke_result_functions"){
|
|
||||||
static_assert(
|
|
||||||
std::is_same<
|
|
||||||
void,
|
|
||||||
inv::invoke_result_t<decltype(simple_static_function)>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<
|
|
||||||
int,
|
|
||||||
inv::invoke_result_t<decltype(simple_static_function_r)>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<
|
|
||||||
int,
|
|
||||||
inv::invoke_result_t<decltype(simple_static_function_r_with_arg), int>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<
|
|
||||||
const int&,
|
|
||||||
inv::invoke_result_t<decltype(simple_static_function_r_with_ref_arg), const int&>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("invoke_result_members"){
|
|
||||||
static_assert(
|
|
||||||
std::is_same<void,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member), obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<void,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member), obj_t*>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<void,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member), std::reference_wrapper<obj_t>>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r), obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r), obj_t*>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_arg), obj_t, int>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_arg), obj_t*, int>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<int,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
std::is_same<const int&,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), obj_t, const int&>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<const int&,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), obj_t*, const int&>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
std::is_same<const int&,
|
|
||||||
inv::invoke_result_t<decltype(&obj_t::member_r_with_ref_arg), std::reference_wrapper<obj_t>, const int&>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("is_invocable"){
|
|
||||||
SECTION("is_invocable_functions"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(simple_static_function)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(simple_static_function_r)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(simple_static_function_r_with_arg), int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_functions"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(simple_static_function), int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(simple_static_function_r), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(simple_static_function_r_with_arg)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_invocable_members"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_members"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member), int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member), std::reference_wrapper<obj_t>*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r), obj_t**>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r), obj2_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r), std::reference_wrapper<obj2_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t, char*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj2_t>, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_invocable_objects"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value_c), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value_c), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable<decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_objects"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value), obj2_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value), obj_t, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value_c), obj_t**>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value_c), obj_t*, obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable<decltype(&obj_t::value_c), std::reference_wrapper<obj_t**>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("is_invocable_r"){
|
|
||||||
SECTION("is_invocable_r_functions"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(simple_static_function)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(simple_static_function_r)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(simple_static_function_r)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<const int&, decltype(simple_static_function_r_with_arg), const int&>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_r_functions"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<void, decltype(simple_static_function), int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(simple_static_function_r), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<const int&, decltype(simple_static_function_r_with_arg), const obj2_t&>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(simple_static_function)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(simple_static_function_r)>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(simple_static_function_r_with_arg), const int&>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_invocable_r_members"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::member), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::member), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::member_r), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_r_members"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(&obj_t::member), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(&obj_t::member), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member_r), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(&obj_t::member_r), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(&obj_t::member_r), std::reference_wrapper<obj2_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::member_r_with_arg), obj_t, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(&obj_t::member_r_with_arg), obj_t*, int>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(&obj_t::member_r_with_arg), std::reference_wrapper<obj_t>, obj2_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_invocable_r_objects"){
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::value), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<int, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
inv::is_invocable_r<void, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
SECTION("is_not_invocable_r_objects"){
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::value), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(&obj_t::value), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int, decltype(&obj_t::value), std::reference_wrapper<obj_t>, obj2_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<void, decltype(&obj_t::value), std::reference_wrapper<obj_t>, obj2_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj_t, decltype(&obj_t::value_c), obj_t>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<int*, decltype(&obj_t::value_c), obj_t*>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<obj2_t, decltype(&obj_t::value_c), std::reference_wrapper<obj_t>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
static_assert(
|
|
||||||
!inv::is_invocable_r<void, decltype(&obj_t::value_c), std::reference_wrapper<obj_t**>>::value,
|
|
||||||
"unit test fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("apply"){
|
|
||||||
SECTION("apply_functions"){
|
|
||||||
inv::apply(simple_static_function, std::make_tuple());
|
|
||||||
REQUIRE(inv::apply(simple_static_function_r, std::make_tuple()) == 42);
|
|
||||||
REQUIRE(inv::apply(simple_static_function_r_with_arg, std::make_tuple(42)) == 42);
|
|
||||||
{
|
|
||||||
int v = 42;
|
|
||||||
REQUIRE(&inv::apply(simple_static_function_r_with_ref_arg, std::make_tuple(std::ref(v))) == &v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SECTION("apply_members"){
|
|
||||||
obj_t o;
|
|
||||||
|
|
||||||
inv::apply(&obj_t::member, std::make_tuple(o));
|
|
||||||
inv::apply(&obj_t::member, std::make_tuple(&o));
|
|
||||||
inv::apply(&obj_t::member, std::make_tuple(std::ref(o)));
|
|
||||||
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r, std::make_tuple(o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r, std::make_tuple(&o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r, std::make_tuple(std::ref(o))) == 42);
|
|
||||||
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r_with_arg, std::make_tuple(o, 42)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r_with_arg, std::make_tuple(&o, 42)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::member_r_with_arg, std::make_tuple(std::ref(o), 42)) == 42);
|
|
||||||
|
|
||||||
{
|
|
||||||
int v = 42;
|
|
||||||
REQUIRE(&inv::apply(&obj_t::member_r_with_ref_arg, std::make_tuple(o, std::ref(v))) == &v);
|
|
||||||
REQUIRE(&inv::apply(&obj_t::member_r_with_ref_arg, std::make_tuple(&o, std::ref(v))) == &v);
|
|
||||||
REQUIRE(&inv::apply(&obj_t::member_r_with_ref_arg, std::make_tuple(std::ref(o), std::ref(v))) == &v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SECTION("apply_member_objects"){
|
|
||||||
obj_t o;
|
|
||||||
|
|
||||||
REQUIRE(inv::apply(&obj_t::value, std::make_tuple(o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::value, std::make_tuple(&o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::value, std::make_tuple(std::ref(o))) == 42);
|
|
||||||
|
|
||||||
REQUIRE(inv::apply(&obj_t::value_c, std::make_tuple(o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::value_c, std::make_tuple(&o)) == 42);
|
|
||||||
REQUIRE(inv::apply(&obj_t::value_c, std::make_tuple(std::ref(o))) == 42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user