mirror of
https://github.com/BlackMATov/promise.hpp.git
synced 2025-12-13 03:46:29 +07:00
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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([¬_call_then_on_reject](const int& c){
|
}).then([¬_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),
|
||||||
|
|||||||
Reference in New Issue
Block a user