Merge pull request #26 from BlackMATov/dev

Dev
This commit is contained in:
2019-07-07 08:51:03 +07:00
committed by GitHub
3 changed files with 53 additions and 44 deletions

View File

@@ -246,14 +246,14 @@ namespace promise_hpp
} }
template < typename ResolveF > template < typename ResolveF >
auto then_any(ResolveF&& on_resolve) { auto then_race(ResolveF&& on_resolve) {
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 = invoke_hpp::invoke(
std::forward<decltype(f)>(f), std::forward<decltype(f)>(f),
std::forward<decltype(v)>(v)); std::forward<decltype(v)>(v));
return make_any_promise(std::move(r)); return make_race_promise(std::move(r));
}); });
} }
@@ -328,11 +328,12 @@ namespace promise_hpp
return state_->get(); return state_->get();
} }
const T& get_or_default(const T& def) const noexcept { template < typename U >
T get_or_default(U&& def) const {
try { try {
return get(); return get();
} catch (...) { } catch (...) {
return def; return std::forward<U>(def);
} }
} }
@@ -678,13 +679,13 @@ namespace promise_hpp
} }
template < typename ResolveF > template < typename ResolveF >
auto then_any(ResolveF&& on_resolve) { auto then_race(ResolveF&& on_resolve) {
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 = invoke_hpp::invoke(
std::forward<decltype(f)>(f)); std::forward<decltype(f)>(f));
return make_any_promise(std::move(r)); return make_race_promise(std::move(r));
}); });
} }
@@ -757,7 +758,7 @@ namespace promise_hpp
state_->get(); state_->get();
} }
void get_or_default() const noexcept { void get_or_default() const {
try { try {
return get(); return get();
} catch (...) { } catch (...) {
@@ -1144,15 +1145,15 @@ namespace promise_hpp
} }
// //
// make_any_promise // make_race_promise
// //
template < typename Iter template < typename Iter
, typename SubPromise = typename Iter::value_type , typename SubPromise = typename Iter::value_type
, typename SubPromiseResult = typename SubPromise::value_type > , typename SubPromiseResult = typename SubPromise::value_type >
auto make_any_promise(Iter begin, Iter end) { auto make_race_promise(Iter begin, Iter end) {
if ( begin == end ) { if ( begin == end ) {
throw std::logic_error("at least one input promise must be provided for make_any_promise"); throw std::logic_error("at least one input promise must be provided for make_race_promise");
} }
return make_promise<SubPromiseResult>([begin, end](auto&& resolver, auto&& rejector){ return make_promise<SubPromiseResult>([begin, end](auto&& resolver, auto&& rejector){
for ( Iter iter = begin; iter != end; ++iter ) { for ( Iter iter = begin; iter != end; ++iter ) {
@@ -1164,8 +1165,8 @@ namespace promise_hpp
} }
template < typename Container > template < typename Container >
auto make_any_promise(Container&& container) { auto make_race_promise(Container&& container) {
return make_any_promise( return make_race_promise(
std::begin(container), std::begin(container),
std::end(container)); std::end(container));
} }
@@ -1270,11 +1271,12 @@ namespace promise_hpp
try { try {
auto context = std::make_shared<tuple_promise_context_t< auto context = std::make_shared<tuple_promise_context_t<
std::tuple_element_t<Is, ResultTuple>...>>(); std::tuple_element_t<Is, ResultTuple>...>>();
std::make_tuple(make_tuple_sub_promise_impl<Is>( auto promises = std::make_tuple(make_tuple_sub_promise_impl<Is>(
tuple, tuple,
resolver, resolver,
rejector, rejector,
context)...); context)...);
(void)promises;
} catch (...) { } catch (...) {
result.reject(std::current_exception()); result.reject(std::current_exception());
} }

View File

@@ -3,18 +3,9 @@ cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
project(promise.hpp.untests) project(promise.hpp.untests)
set(CATCH_BUILD_TESTING OFF CACHE BOOL "" FORCE) #
# coverage
include(FetchContent) #
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/catch2)
FetchContent_GetProperties(catch2)
if(NOT catch2_POPULATED)
FetchContent_Populate(catch2)
add_subdirectory(${catch2_SOURCE_DIR} ${catch2_BINARY_DIR})
endif()
option(BUILD_WITH_COVERAGE "Build with coverage" OFF) option(BUILD_WITH_COVERAGE "Build with coverage" OFF)
if(BUILD_WITH_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")) if(BUILD_WITH_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang"))
@@ -24,16 +15,13 @@ if(BUILD_WITH_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang"))
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${COVERAGE_FLAGS}") set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} ${COVERAGE_FLAGS}")
endif() endif()
#
# executable
#
file(GLOB UNTESTS_SOURCES "*.cpp" "*.hpp") file(GLOB UNTESTS_SOURCES "*.cpp" "*.hpp")
add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES})
target_link_libraries(${PROJECT_NAME} promise.hpp)
target_link_libraries(${PROJECT_NAME}
Catch2
promise.hpp)
find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME}
Threads::Threads)
target_compile_options(${PROJECT_NAME} target_compile_options(${PROJECT_NAME}
PRIVATE PRIVATE
@@ -44,3 +32,22 @@ target_compile_options(${PROJECT_NAME}
-Wall -Wextra -Wpedantic>) -Wall -Wextra -Wpedantic>)
add_test(${PROJECT_NAME} ${PROJECT_NAME}) add_test(${PROJECT_NAME} ${PROJECT_NAME})
#
# dependencies
#
find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME} Threads::Threads)
include(FetchContent)
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/catch2)
FetchContent_GetProperties(catch2)
if(NOT catch2_POPULATED)
FetchContent_Populate(catch2)
target_include_directories(${PROJECT_NAME}
PRIVATE ${catch2_SOURCE_DIR}/single_include)
endif()

View File

@@ -708,14 +708,14 @@ TEST_CASE("promise") {
}); });
} }
} }
SECTION("make_any_promise") { SECTION("make_race_promise") {
{ {
auto p1 = pr::promise<int>(); auto p1 = pr::promise<int>();
auto p2 = pr::promise<int>(); auto p2 = pr::promise<int>();
int check_42_int = 0; int check_42_int = 0;
int call_then_only_once = 0; int call_then_only_once = 0;
pr::make_any_promise(std::vector<pr::promise<int>>{p1, p2}) pr::make_race_promise(std::vector<pr::promise<int>>{p1, p2})
.then([&check_42_int, &call_then_only_once](const int& v){ .then([&check_42_int, &call_then_only_once](const int& v){
check_42_int = v; check_42_int = v;
++call_then_only_once; ++call_then_only_once;
@@ -735,7 +735,7 @@ TEST_CASE("promise") {
int check_42_int = 0; int check_42_int = 0;
int call_then_only_once = 0; int call_then_only_once = 0;
pr::make_any_promise(std::vector<pr::promise<int>>{p1, p2}) pr::make_race_promise(std::vector<pr::promise<int>>{p1, p2})
.then([&check_42_int, &call_then_only_once](const int& v){ .then([&check_42_int, &call_then_only_once](const int& v){
check_42_int = v; check_42_int = v;
++call_then_only_once; ++call_then_only_once;
@@ -757,7 +757,7 @@ TEST_CASE("promise") {
}; };
pr::promise<>() pr::promise<>()
.then_any([](){ .then_race([](){
return std::vector<pr::promise<o_t>>{ return std::vector<pr::promise<o_t>>{
pr::make_resolved_promise<o_t>(40), pr::make_resolved_promise<o_t>(40),
pr::make_resolved_promise<o_t>(2)}; pr::make_resolved_promise<o_t>(2)};
@@ -869,14 +869,14 @@ TEST_CASE("promise") {
REQUIRE(call_except_count == 1); REQUIRE(call_except_count == 1);
} }
} }
SECTION("make_any_promise_fail") { SECTION("make_race_promise_fail") {
REQUIRE_THROWS_AS( REQUIRE_THROWS_AS(
pr::make_any_promise(std::vector<pr::promise<int>>{}), pr::make_race_promise(std::vector<pr::promise<int>>{}),
std::logic_error); std::logic_error);
{ {
bool call_fail_with_logic_error = false; bool call_fail_with_logic_error = false;
bool not_call_then_on_reject = true; bool not_call_then_on_reject = true;
auto p = pr::make_any_promise(std::vector<pr::promise<int>>{ auto p = pr::make_race_promise(std::vector<pr::promise<int>>{
pr::make_rejected_promise<int>(std::logic_error("hello fail")), pr::make_rejected_promise<int>(std::logic_error("hello fail")),
pr::make_resolved_promise(10) pr::make_resolved_promise(10)
}).then([&not_call_then_on_reject](const int& c){ }).then([&not_call_then_on_reject](const int& c){
@@ -960,11 +960,11 @@ TEST_CASE("promise") {
REQUIRE(check_42_int2 == 42); REQUIRE(check_42_int2 == 42);
} }
} }
SECTION("then_any") { SECTION("then_race") {
{ {
int check_42_int = 0; int check_42_int = 0;
pr::make_resolved_promise() pr::make_resolved_promise()
.then_any([](){ .then_race([](){
return std::vector<pr::promise<int>>{ return std::vector<pr::promise<int>>{
pr::make_resolved_promise(42), pr::make_resolved_promise(42),
pr::make_rejected_promise<int>(std::logic_error("hello fail"))}; pr::make_rejected_promise<int>(std::logic_error("hello fail"))};
@@ -976,7 +976,7 @@ TEST_CASE("promise") {
{ {
bool call_fail_with_logic_error = false; bool call_fail_with_logic_error = false;
pr::make_resolved_promise() pr::make_resolved_promise()
.then_any([](){ .then_race([](){
return std::vector<pr::promise<int>>{ return std::vector<pr::promise<int>>{
pr::make_rejected_promise<int>(std::logic_error("hello fail")), pr::make_rejected_promise<int>(std::logic_error("hello fail")),
pr::make_resolved_promise(42)}; pr::make_resolved_promise(42)};
@@ -991,7 +991,7 @@ TEST_CASE("promise") {
int check_42_int2 = 0; int check_42_int2 = 0;
int call_then_only_once = 0; int call_then_only_once = 0;
pr::make_resolved_promise(42) pr::make_resolved_promise(42)
.then_any([&check_42_int](int v){ .then_race([&check_42_int](int v){
check_42_int = v; check_42_int = v;
return std::vector<pr::promise<int>>{ return std::vector<pr::promise<int>>{
pr::make_resolved_promise(42), pr::make_resolved_promise(42),