summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriam <igor.murashkin+github@gmail.com>2018-10-27 13:12:45 -0700
committerKirk Shoop <kirk.shoop@gmail.com>2018-10-27 13:12:45 -0700
commit4aa52e42579cbd9e2cef6c0a6c2b0d8edf73ac5d (patch)
tree2b4a574fcd4a62d8b59174646b76c53fa9c15b2d
parented3fe6418276781e662e5113ee3cee1bee4f0998 (diff)
downloadRxCpp-4aa52e42579cbd9e2cef6c0a6c2b0d8edf73ac5d.tar.gz
Add support for compiling rxcpp with -fno-exceptions (#456)
* Minor compilation/test fixes for compiling on android Change-Id: Id623455d32e9323355744a240c2813d0411d1dac * Rx: Add support for compiling code without exceptions (-fno-exceptions) std::exception_ptr usage is replaced with rxcpp::util::error_ptr which will typedef to std::exception_ptr when exceptions are enabled. When exceptions are disabled this will typedef to an internal error type that can retain the "what" error message. Additionally std::current_exception() and similar usages are replaced with rxu::current_exception which uses error_ptr instead. Lastly all try/catch/throw keywords are replaced with either RXCPP_TRY, RXCPP_CATCH, rxu::throw_exception or similar. Note that try/catch/throw keywords cause a compilation error with -fno-exceptions. Trying to access most of the std::*exception* functions will call std::terminate at runtime. Tests using exceptions must be disabled by passing --nothrow to the check2 test runner. Change-Id: I0b95ae2e323653a17c3b733d165ecf87a014c315 * update to catch2 and add RX_USE_EXCEPTIONS cmake option * fix bugs in doxygen examples * replace [[noreturn]] with RXCPP_NORETURN * removes support for VS 2013
-rw-r--r--.travis.yml43
-rw-r--r--Rx/v2/examples/doxygen/composite_exception.cpp2
-rw-r--r--Rx/v2/examples/doxygen/create.cpp7
-rw-r--r--Rx/v2/examples/doxygen/error.cpp14
-rw-r--r--Rx/v2/examples/doxygen/finally.cpp7
-rw-r--r--Rx/v2/examples/doxygen/group_by.cpp2
-rw-r--r--Rx/v2/examples/doxygen/math.cpp14
-rw-r--r--Rx/v2/examples/doxygen/merge_delay_error.cpp20
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-all.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-amb.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-any.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-buffer_count.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-buffer_time.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-buffer_time_count.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-combine_latest.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-concat.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-concat_map.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-debounce.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-delay.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-distinct.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-distinct_until_changed.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-element_at.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-filter.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-finally.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-flat_map.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-group_by.hpp10
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-map.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-merge.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-merge_delay_error.hpp12
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-observe_on.hpp9
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-on_error_resume_next.hpp10
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-pairwise.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-reduce.hpp14
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-repeat.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-retry.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-sample_time.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-scan.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-skip.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-skip_last.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-skip_until.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-skip_while.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-switch_on_next.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-take.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-take_last.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-take_until.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-take_while.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-tap.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-time_interval.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-timeout.hpp4
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-timestamp.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-window.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-window_time.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp6
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp2
-rw-r--r--Rx/v2/src/rxcpp/operators/rx-zip.hpp2
-rw-r--r--Rx/v2/src/rxcpp/rx-composite_exception.hpp4
-rw-r--r--Rx/v2/src/rxcpp/rx-coordination.hpp2
-rw-r--r--Rx/v2/src/rxcpp/rx-includes.hpp26
-rw-r--r--Rx/v2/src/rxcpp/rx-notification.hpp32
-rw-r--r--Rx/v2/src/rxcpp/rx-observable.hpp19
-rw-r--r--Rx/v2/src/rxcpp/rx-observer.hpp40
-rw-r--r--Rx/v2/src/rxcpp/rx-subscriber.hpp10
-rw-r--r--Rx/v2/src/rxcpp/rx-trace.hpp4
-rw-r--r--Rx/v2/src/rxcpp/rx-util.hpp146
-rw-r--r--Rx/v2/src/rxcpp/schedulers/rx-test.hpp2
-rw-r--r--Rx/v2/src/rxcpp/sources/rx-error.hpp25
-rw-r--r--Rx/v2/src/rxcpp/subjects/rx-subject.hpp4
-rw-r--r--Rx/v2/src/rxcpp/subjects/rx-synchronize.hpp10
-rw-r--r--Rx/v2/test/CMakeLists.txt14
-rw-r--r--Rx/v2/test/operators/buffer.cpp20
-rw-r--r--Rx/v2/test/operators/combine_latest.cpp25
-rw-r--r--Rx/v2/test/operators/concat.cpp6
-rw-r--r--Rx/v2/test/operators/concat_map.cpp10
-rw-r--r--Rx/v2/test/operators/filter.cpp6
-rw-r--r--Rx/v2/test/operators/flat_map.cpp10
-rw-r--r--Rx/v2/test/operators/group_by.cpp5
-rw-r--r--Rx/v2/test/operators/lift.cpp12
-rw-r--r--Rx/v2/test/operators/merge.cpp6
-rw-r--r--Rx/v2/test/operators/merge_delay_error.cpp2
-rw-r--r--Rx/v2/test/operators/observe_on.cpp2
-rw-r--r--Rx/v2/test/operators/on_error_resume_next.cpp6
-rw-r--r--Rx/v2/test/operators/publish.cpp2
-rw-r--r--Rx/v2/test/operators/reduce.cpp11
-rw-r--r--Rx/v2/test/operators/scan.cpp6
-rw-r--r--Rx/v2/test/operators/subscribe_on.cpp6
-rw-r--r--Rx/v2/test/operators/tap.cpp2
-rw-r--r--Rx/v2/test/operators/with_latest_from.cpp8
-rw-r--r--Rx/v2/test/operators/zip.cpp8
-rw-r--r--Rx/v2/test/sources/defer.cpp2
-rw-r--r--Rx/v2/test/sources/interval.cpp8
-rw-r--r--Rx/v2/test/sources/scope.cpp8
-rw-r--r--Rx/v2/test/sources/timer.cpp4
-rw-r--r--Rx/v2/test/subjects/subject.cpp32
-rw-r--r--Rx/v2/test/subscriptions/coroutine.cpp12
-rw-r--r--Rx/v2/test/subscriptions/observer.cpp14
-rw-r--r--Rx/v2/test/subscriptions/subscription.cpp16
-rw-r--r--appveyor.yml2
m---------ext/catch0
-rw-r--r--projects/CMake/CMakeLists.txt5
-rw-r--r--projects/CMake/shared.cmake22
105 files changed, 577 insertions, 323 deletions
diff --git a/.travis.yml b/.travis.yml
index 20a2197..daa4800 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,15 +10,15 @@ env:
matrix:
include:
- - env: BUILD_TYPE=Debug ASAN=Off RUN_TEST=On
+ - env: BUILD_TYPE=Debug ASAN=Off RUN_TEST=On EXCEPTIONS=On
os: osx
osx_image: xcode8
- - env: BUILD_TYPE=Debug ASAN=Off LLVM_VERSION=3.8.0 RUN_TEST=On
+ - env: BUILD_TYPE=Debug ASAN=Off LLVM_VERSION=3.8.0 RUN_TEST=On EXCEPTIONS=On
os: linux
compiler: clang
- - env: BUILD_TYPE=Release ASAN=Off GCC_VERSION=4.9 RUN_TEST=On
+ - env: BUILD_TYPE=Release ASAN=Off GCC_VERSION=4.9 RUN_TEST=On EXCEPTIONS=On
os: linux
compiler: gcc
addons:
@@ -28,7 +28,37 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- - env: BUILD_TYPE=Debug ASAN=Off LLVM_VERSION=3.8.0 RUN_TEST=Off PROJECT=doc PUBLISH_DOCS=On DOXYGEN_VERSION=1.8.11
+ - env: BUILD_TYPE=Release ASAN=Off GCC_VERSION=7 RUN_TEST=On EXCEPTIONS=On
+ os: linux
+ compiler: gcc
+ addons: &gcc7
+ apt:
+ packages:
+ - g++-7
+ sources:
+ - ubuntu-toolchain-r-test
+
+ - env: BUILD_TYPE=RelWithDebInfo ASAN=Off GCC_VERSION=8 RUN_TEST=On EXCEPTIONS=Off
+ os: linux
+ compiler: gcc
+ addons: &gcc8
+ apt:
+ packages:
+ - g++-8
+ sources:
+ - ubuntu-toolchain-r-test
+
+ - env: BUILD_TYPE=Release ASAN=Off GCC_VERSION=8 RUN_TEST=On EXCEPTIONS=On
+ os: linux
+ compiler: gcc
+ addons: &gcc8
+ apt:
+ packages:
+ - g++-8
+ sources:
+ - ubuntu-toolchain-r-test
+
+ - env: BUILD_TYPE=Debug ASAN=Off LLVM_VERSION=3.8.0 RUN_TEST=Off EXCEPTIONS=On PROJECT=doc PUBLISH_DOCS=On DOXYGEN_VERSION=1.8.11
os: linux
compiler: clang
addons:
@@ -127,6 +157,9 @@ before_script:
if [ -z "$BUILD_TYPE" ]; then
BUILD_TYPE=Release;
fi;
+ if [ -z "$EXCEPTIONS" ]; then
+ EXCEPTIONS=On;
+ fi;
if [[ "${ASAN}" == "On" ]]; then
export CXXFLAGS="${CXXFLAGS} -fsanitize=address,undefined,integer -fno-omit-frame-pointer -fno-sanitize=unsigned-integer-overflow";
fi;
@@ -138,7 +171,7 @@ before_script:
# generate build
############################################################################
- cd ${TRAVIS_BUILD_DIR}
- - cmake . -DCMAKE_BUILD_TYPE=$BUILD_TYPE
+ - cmake . -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DRX_USE_EXCEPTIONS=${EXCEPTIONS}
script:
############################################################################
diff --git a/Rx/v2/examples/doxygen/composite_exception.cpp b/Rx/v2/examples/doxygen/composite_exception.cpp
index 697b83f..6cbfce3 100644
--- a/Rx/v2/examples/doxygen/composite_exception.cpp
+++ b/Rx/v2/examples/doxygen/composite_exception.cpp
@@ -4,6 +4,7 @@ namespace rxu=rxcpp::util;
#include "rxcpp/rx-test.hpp"
#include "catch.hpp"
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("composite_exception sample"){
printf("//! [composite_exception sample]\n");
auto o1 = rxcpp::observable<>::error<int>(std::runtime_error("Error from source o1\n"));
@@ -29,3 +30,4 @@ SCENARIO("composite_exception sample"){
);
printf("//! [composite_exception sample]\n");
}
+#endif
diff --git a/Rx/v2/examples/doxygen/create.cpp b/Rx/v2/examples/doxygen/create.cpp
index f8d024f..1f707c6 100644
--- a/Rx/v2/examples/doxygen/create.cpp
+++ b/Rx/v2/examples/doxygen/create.cpp
@@ -90,11 +90,8 @@ SCENARIO("Create great code"){
[](int v){
printf("OnNext: %d\n", v);
},
- [](std::exception_ptr ep){
- try {std::rethrow_exception(ep);}
- catch (const std::exception& ex) {
- printf("OnError: %s\n", ex.what());
- }
+ [](rxcpp::util::error_ptr ep){
+ printf("OnError: %s\n", rxcpp::util::what(ep).c_str());
},
[](){
printf("OnCompleted\n");
diff --git a/Rx/v2/examples/doxygen/error.cpp b/Rx/v2/examples/doxygen/error.cpp
index 8d5b000..87b5b78 100644
--- a/Rx/v2/examples/doxygen/error.cpp
+++ b/Rx/v2/examples/doxygen/error.cpp
@@ -9,11 +9,8 @@ SCENARIO("error sample"){
values.
subscribe(
[](int v){printf("OnNext: %d\n", v);},
- [](std::exception_ptr ep){
- try {std::rethrow_exception(ep);}
- catch (const std::exception& ex) {
- printf("OnError: %s\n", ex.what());
- }
+ [](rxcpp::util::error_ptr ep){
+ printf("OnError: %s\n", rxcpp::util::what(ep).c_str());
},
[](){printf("OnCompleted\n");});
printf("//! [error sample]\n");
@@ -26,11 +23,8 @@ SCENARIO("threaded error sample"){
as_blocking().
subscribe(
[](int v){printf("OnNext: %d\n", v);},
- [](std::exception_ptr ep){
- try {std::rethrow_exception(ep);}
- catch (const std::exception& ex) {
- printf("OnError: %s\n", ex.what());
- }
+ [](rxcpp::util::error_ptr ep){
+ printf("OnError: %s\n", rxcpp::util::what(ep).c_str());
},
[](){printf("OnCompleted\n");});
printf("//! [threaded error sample]\n");
diff --git a/Rx/v2/examples/doxygen/finally.cpp b/Rx/v2/examples/doxygen/finally.cpp
index 3f25196..253d3a9 100644
--- a/Rx/v2/examples/doxygen/finally.cpp
+++ b/Rx/v2/examples/doxygen/finally.cpp
@@ -26,11 +26,8 @@ SCENARIO("error finally sample"){
values.
subscribe(
[](int v){printf("OnNext: %d\n", v);},
- [](std::exception_ptr ep){
- try {std::rethrow_exception(ep);}
- catch (const std::exception& ex) {
- printf("OnError: %s\n", ex.what());
- }
+ [](rxcpp::util::error_ptr ep){
+ printf("OnError: %s\n", rxcpp::util::what(ep).c_str());
},
[](){printf("OnCompleted\n");});
printf("//! [error finally sample]\n");
diff --git a/Rx/v2/examples/doxygen/group_by.cpp b/Rx/v2/examples/doxygen/group_by.cpp
index b716d6f..74ef859 100644
--- a/Rx/v2/examples/doxygen/group_by.cpp
+++ b/Rx/v2/examples/doxygen/group_by.cpp
@@ -3,6 +3,8 @@
#include "rxcpp/rx-test.hpp"
#include "catch.hpp"
+#include <sstream>
+
SCENARIO("group_by sample"){
printf("//! [group_by sample]\n");
auto values = rxcpp::observable<>::range(0, 8).
diff --git a/Rx/v2/examples/doxygen/math.cpp b/Rx/v2/examples/doxygen/math.cpp
index 376cf97..d430953 100644
--- a/Rx/v2/examples/doxygen/math.cpp
+++ b/Rx/v2/examples/doxygen/math.cpp
@@ -13,6 +13,7 @@ SCENARIO("first sample"){
printf("//! [first sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("first empty sample"){
printf("//! [first empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().first();
@@ -28,6 +29,7 @@ SCENARIO("first empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [first empty sample]\n");
}
+#endif
SCENARIO("last sample"){
printf("//! [last sample]\n");
@@ -39,6 +41,7 @@ SCENARIO("last sample"){
printf("//! [last sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("last empty sample"){
printf("//! [last empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().last();
@@ -54,6 +57,7 @@ SCENARIO("last empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [last empty sample]\n");
}
+#endif
SCENARIO("count sample"){
printf("//! [count sample]\n");
@@ -65,6 +69,7 @@ SCENARIO("count sample"){
printf("//! [count sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("count error sample"){
printf("//! [count error sample]\n");
auto values = rxcpp::observable<>::range(1, 3).
@@ -82,6 +87,7 @@ SCENARIO("count error sample"){
[](){printf("OnCompleted\n");});
printf("//! [count error sample]\n");
}
+#endif
SCENARIO("sum sample"){
printf("//! [sum sample]\n");
@@ -93,6 +99,7 @@ SCENARIO("sum sample"){
printf("//! [sum sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("sum empty sample"){
printf("//! [sum empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().sum();
@@ -108,6 +115,7 @@ SCENARIO("sum empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [sum empty sample]\n");
}
+#endif
SCENARIO("sum error sample"){
printf("//! [sum error sample]\n");
@@ -137,6 +145,7 @@ SCENARIO("average sample"){
printf("//! [average sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("average empty sample"){
printf("//! [average empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().average();
@@ -152,6 +161,7 @@ SCENARIO("average empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [average empty sample]\n");
}
+#endif
SCENARIO("average error sample"){
printf("//! [average error sample]\n");
@@ -181,6 +191,7 @@ SCENARIO("max sample"){
printf("//! [max sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("max empty sample"){
printf("//! [max empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().max();
@@ -196,6 +207,7 @@ SCENARIO("max empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [max empty sample]\n");
}
+#endif
SCENARIO("max error sample"){
printf("//! [max error sample]\n");
@@ -225,6 +237,7 @@ SCENARIO("min sample"){
printf("//! [min sample]\n");
}
+#if RXCPP_USE_EXCEPTIONS
SCENARIO("min empty sample"){
printf("//! [min empty sample]\n");
auto values = rxcpp::observable<>::empty<int>().min();
@@ -240,6 +253,7 @@ SCENARIO("min empty sample"){
[](){printf("OnCompleted\n");});
printf("//! [min empty sample]\n");
}
+#endif
SCENARIO("min error sample"){
printf("//! [min error sample]\n");
diff --git a/Rx/v2/examples/doxygen/merge_delay_error.cpp b/Rx/v2/examples/doxygen/merge_delay_error.cpp
index 7a94570..ae75926 100644
--- a/Rx/v2/examples/doxygen/merge_delay_error.cpp
+++ b/Rx/v2/examples/doxygen/merge_delay_error.cpp
@@ -4,6 +4,8 @@ namespace rxu=rxcpp::util;
#include "rxcpp/rx-test.hpp"
#include "catch.hpp"
+#include <sstream>
+
SCENARIO("merge_delay_error sample"){
printf("//! [merge_delay_error sample]\n");
auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(15)).map([](int) {return 1;});
@@ -38,19 +40,19 @@ SCENARIO("implicit merge_delay_error sample"){
SCENARIO("threaded merge_delay_error sample"){
printf("//! [threaded merge_delay_error sample]\n");
printf("[thread %s] Start task\n", get_pid().c_str());
- auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {
+ auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](long) -> long {
printf("[thread %s] Timer1 fired\n", get_pid().c_str());
return 1;
});
- auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).flat_map([](int) {
+ auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).flat_map([](long) -> rxcpp::observable<long> {
std::stringstream ss;
ss << "[thread " << get_pid().c_str() << "] Timer2 failed\n";
printf("%s\n", ss.str().c_str());
ss.str(std::string());
ss << "(Error from thread: " << get_pid().c_str() << ")\n";
- return rxcpp::observable<>::error<int>(std::runtime_error(ss.str()));
+ return rxcpp::observable<>::error<long>(std::runtime_error(ss.str()));
});
- auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](int) {
+ auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](long) -> long {
printf("[thread %s] Timer3 fired\n", get_pid().c_str());
return 3;
});
@@ -68,19 +70,19 @@ SCENARIO("threaded merge_delay_error sample"){
SCENARIO("threaded implicit merge_delay_error sample"){
printf("//! [threaded implicit merge_delay_error sample]\n");
printf("[thread %s] Start task\n", get_pid().c_str());
- auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](int) {
+ auto o1 = rxcpp::observable<>::timer(std::chrono::milliseconds(10)).map([](long) -> long {
printf("[thread %s] Timer1 fired\n", get_pid().c_str());
return 1;
});
- auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).flat_map([](int) {
+ auto o2 = rxcpp::observable<>::timer(std::chrono::milliseconds(20)).flat_map([](long) -> rxcpp::observable<long> {
std::stringstream ss;
ss << "[thread " << get_pid().c_str() << "] Timer2 failed\n";
printf("%s\n", ss.str().c_str());
ss.str(std::string());
ss << "(Error from thread: " << get_pid().c_str() << ")\n";
- return rxcpp::observable<>::error<int>(std::runtime_error(ss.str()));
+ return rxcpp::observable<>::error<long>(std::runtime_error(ss.str()));
});
- auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](int) {
+ auto o3 = rxcpp::observable<>::timer(std::chrono::milliseconds(30)).map([](long) -> long {
printf("[thread %s] Timer3 fired\n", get_pid().c_str());
return 3;
});
@@ -89,7 +91,7 @@ SCENARIO("threaded implicit merge_delay_error sample"){
values.
as_blocking().
subscribe(
- [](int v){printf("[thread %s] OnNext: %d\n", get_pid().c_str(), v);},
+ [](long v){printf("[thread %s] OnNext: %ld\n", get_pid().c_str(), v);},
[](std::exception_ptr eptr) { printf("[thread %s] OnError %s\n", get_pid().c_str(), rxu::what(eptr).c_str()); },
[](){printf("[thread %s] OnCompleted\n", get_pid().c_str());});
printf("[thread %s] Finish task\n", get_pid().c_str());
diff --git a/Rx/v2/src/rxcpp/operators/rx-all.hpp b/Rx/v2/src/rxcpp/operators/rx-all.hpp
index 65bec46..a0f6a3e 100644
--- a/Rx/v2/src/rxcpp/operators/rx-all.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-all.hpp
@@ -83,7 +83,7 @@ struct all
dest.on_completed();
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-amb.hpp b/Rx/v2/src/rxcpp/operators/rx-amb.hpp
index 595dc4d..56bfbe9 100644
--- a/Rx/v2/src/rxcpp/operators/rx-amb.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-amb.hpp
@@ -183,7 +183,7 @@ struct amb
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -196,7 +196,7 @@ struct amb
selectedSource.subscribe(std::move(selectedSinkInner));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-any.hpp b/Rx/v2/src/rxcpp/operators/rx-any.hpp
index 4488375..19fca6e 100644
--- a/Rx/v2/src/rxcpp/operators/rx-any.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-any.hpp
@@ -90,7 +90,7 @@ struct any
dest.on_completed();
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-buffer_count.hpp b/Rx/v2/src/rxcpp/operators/rx-buffer_count.hpp
index a4dea3b..79eb30e 100644
--- a/Rx/v2/src/rxcpp/operators/rx-buffer_count.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-buffer_count.hpp
@@ -96,7 +96,7 @@ struct buffer_count
chunks.pop_front();
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-buffer_time.hpp b/Rx/v2/src/rxcpp/operators/rx-buffer_time.hpp
index 7e54eb8..aa94f7b 100644
--- a/Rx/v2/src/rxcpp/operators/rx-buffer_time.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-buffer_time.hpp
@@ -197,7 +197,7 @@ struct buffer_with_time
}
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-buffer_time_count.hpp b/Rx/v2/src/rxcpp/operators/rx-buffer_time_count.hpp
index 346a6ef..6d4b9a4 100644
--- a/Rx/v2/src/rxcpp/operators/rx-buffer_time_count.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-buffer_time_count.hpp
@@ -179,7 +179,7 @@ struct buffer_with_time_or_count
}
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-combine_latest.hpp b/Rx/v2/src/rxcpp/operators/rx-combine_latest.hpp
index 0f94fde..06ff3d1 100644
--- a/Rx/v2/src/rxcpp/operators/rx-combine_latest.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-combine_latest.hpp
@@ -173,7 +173,7 @@ struct combine_latest : public operator_base<rxu::value_type_t<combine_latest_tr
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-concat.hpp b/Rx/v2/src/rxcpp/operators/rx-concat.hpp
index 57b42fa..457b9cf 100644
--- a/Rx/v2/src/rxcpp/operators/rx-concat.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-concat.hpp
@@ -143,7 +143,7 @@ struct concat
state->out.on_next(ct);
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -207,7 +207,7 @@ struct concat
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-concat_map.hpp b/Rx/v2/src/rxcpp/operators/rx-concat_map.hpp
index edcdb26..546c1eb 100644
--- a/Rx/v2/src/rxcpp/operators/rx-concat_map.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-concat_map.hpp
@@ -183,7 +183,7 @@ struct concat_map
state->out.on_next(std::move(selectedResult));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -246,7 +246,7 @@ struct concat_map
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-debounce.hpp b/Rx/v2/src/rxcpp/operators/rx-debounce.hpp
index 5f56ff9..6fbedd7 100644
--- a/Rx/v2/src/rxcpp/operators/rx-debounce.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-debounce.hpp
@@ -158,7 +158,7 @@ struct debounce
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&) {
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-delay.hpp b/Rx/v2/src/rxcpp/operators/rx-delay.hpp
index 19bbed5..5986f79 100644
--- a/Rx/v2/src/rxcpp/operators/rx-delay.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-delay.hpp
@@ -131,7 +131,7 @@ struct delay
localState->worker.schedule(localState->worker.now() + localState->period, selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-distinct.hpp b/Rx/v2/src/rxcpp/operators/rx-distinct.hpp
index c3ca086..c90ebdb 100644
--- a/Rx/v2/src/rxcpp/operators/rx-distinct.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-distinct.hpp
@@ -61,7 +61,7 @@ struct distinct
dest.on_next(v);
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-distinct_until_changed.hpp b/Rx/v2/src/rxcpp/operators/rx-distinct_until_changed.hpp
index 7d8ef5a..3702185 100644
--- a/Rx/v2/src/rxcpp/operators/rx-distinct_until_changed.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-distinct_until_changed.hpp
@@ -74,7 +74,7 @@ struct distinct_until_changed
dest.on_next(v);
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-element_at.hpp b/Rx/v2/src/rxcpp/operators/rx-element_at.hpp
index 5cbe6dc..1d773ac 100644
--- a/Rx/v2/src/rxcpp/operators/rx-element_at.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-element_at.hpp
@@ -77,12 +77,12 @@ struct element_at {
dest.on_completed();
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
if(current <= this->index) {
- dest.on_error(std::make_exception_ptr(std::range_error("index is out of bounds")));
+ dest.on_error(rxu::make_error_ptr(std::range_error("index is out of bounds")));
}
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-filter.hpp b/Rx/v2/src/rxcpp/operators/rx-filter.hpp
index 86ce649..3a622bb 100644
--- a/Rx/v2/src/rxcpp/operators/rx-filter.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-filter.hpp
@@ -79,7 +79,7 @@ struct filter
dest.on_next(std::forward<Value>(v));
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-finally.hpp b/Rx/v2/src/rxcpp/operators/rx-finally.hpp
index 4e4416c..d6f5487 100644
--- a/Rx/v2/src/rxcpp/operators/rx-finally.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-finally.hpp
@@ -70,7 +70,7 @@ struct finally
void on_next(source_value_type v) const {
dest.on_next(v);
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-flat_map.hpp b/Rx/v2/src/rxcpp/operators/rx-flat_map.hpp
index 5b68b37..eb76198 100644
--- a/Rx/v2/src/rxcpp/operators/rx-flat_map.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-flat_map.hpp
@@ -198,7 +198,7 @@ struct flat_map
state->out.on_next(std::move(selectedResult));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -213,7 +213,7 @@ struct flat_map
selectedSource.subscribe(std::move(selectedSinkInner));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-group_by.hpp b/Rx/v2/src/rxcpp/operators/rx-group_by.hpp
index 8b451e5..d1c4ea4 100644
--- a/Rx/v2/src/rxcpp/operators/rx-group_by.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-group_by.hpp
@@ -200,7 +200,7 @@ struct group_by
auto selectedKey = on_exception(
[&](){
return this->keySelector(v);},
- [this](std::exception_ptr e){on_error(e);});
+ [this](rxu::error_ptr e){on_error(e);});
if (selectedKey.empty()) {
return;
}
@@ -215,7 +215,7 @@ struct group_by
auto durationObs = on_exception(
[&](){
return this->durationSelector(obs);},
- [this](std::exception_ptr e){on_error(e);});
+ [this](rxu::error_ptr e){on_error(e);});
if (durationObs.empty()) {
return;
}
@@ -237,20 +237,20 @@ struct group_by
auto robs = durationObs.get().take(1);
duration_sub.add(robs.subscribe(
[](const typename decltype(robs)::value_type &){},
- [=](std::exception_ptr ) {expire();},
+ [=](rxu::error_ptr) {expire();},
[=](){expire();}
));
}
auto selectedMarble = on_exception(
[&](){
return this->marbleSelector(v);},
- [this](std::exception_ptr e){on_error(e);});
+ [this](rxu::error_ptr e){on_error(e);});
if (selectedMarble.empty()) {
return;
}
g->second.on_next(std::move(selectedMarble.get()));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
for(auto& g : state->groups) {
g.second.on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp b/Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp
index 82fbe95..00b10a6 100644
--- a/Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-ignore_elements.hpp
@@ -56,7 +56,7 @@ struct ignore_elements {
// no-op; ignore element
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-map.hpp b/Rx/v2/src/rxcpp/operators/rx-map.hpp
index a670d88..7570376 100644
--- a/Rx/v2/src/rxcpp/operators/rx-map.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-map.hpp
@@ -77,7 +77,7 @@ struct map
}
dest.on_next(std::move(selected.get()));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-merge.hpp b/Rx/v2/src/rxcpp/operators/rx-merge.hpp
index ad8f7d0..cc1ea77 100644
--- a/Rx/v2/src/rxcpp/operators/rx-merge.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-merge.hpp
@@ -173,7 +173,7 @@ struct merge
state->out.on_next(std::move(ct));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -188,7 +188,7 @@ struct merge
selectedSource.subscribe(std::move(selectedSinkInner));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-merge_delay_error.hpp b/Rx/v2/src/rxcpp/operators/rx-merge_delay_error.hpp
index 43fdee3..51f8867 100644
--- a/Rx/v2/src/rxcpp/operators/rx-merge_delay_error.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-merge_delay_error.hpp
@@ -167,10 +167,10 @@ struct merge_delay_error
state->out.on_next(std::move(ct));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if(--state->pendingCompletions == 0) {
state->out.on_error(
- std::make_exception_ptr(std::move(state->exception.add(e))));
+ rxu::make_error_ptr(std::move(state->exception.add(e))));
} else {
state->exception.add(e);
}
@@ -180,7 +180,7 @@ struct merge_delay_error
if (--state->pendingCompletions == 0) {
if(!state->exception.empty()) {
state->out.on_error(
- std::make_exception_ptr(std::move(state->exception)));
+ rxu::make_error_ptr(std::move(state->exception)));
} else {
state->out.on_completed();
}
@@ -192,10 +192,10 @@ struct merge_delay_error
selectedSource.subscribe(std::move(selectedSinkInner));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if(--state->pendingCompletions == 0) {
state->out.on_error(
- std::make_exception_ptr(std::move(state->exception.add(e))));
+ rxu::make_error_ptr(std::move(state->exception.add(e))));
} else {
state->exception.add(e);
}
@@ -205,7 +205,7 @@ struct merge_delay_error
if (--state->pendingCompletions == 0) {
if(!state->exception.empty()) {
state->out.on_error(
- std::make_exception_ptr(std::move(state->exception)));
+ rxu::make_error_ptr(std::move(state->exception)));
} else {
state->out.on_completed();
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-observe_on.hpp b/Rx/v2/src/rxcpp/operators/rx-observe_on.hpp
index 274f3f1..b50b773 100644
--- a/Rx/v2/src/rxcpp/operators/rx-observe_on.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-observe_on.hpp
@@ -127,7 +127,7 @@ struct observe_on
auto drain = [keepAlive, this](const rxsc::schedulable& self){
using std::swap;
- try {
+ RXCPP_TRY {
for (;;) {
if (drain_queue.empty() || !destination.is_subscribed()) {
std::unique_lock<std::mutex> guard(lock);
@@ -151,8 +151,9 @@ struct observe_on
self();
if (lifetime.is_subscribed()) break;
}
- } catch(...) {
- destination.on_error(std::current_exception());
+ }
+ RXCPP_CATCH(...) {
+ destination.on_error(rxu::current_exception());
std::unique_lock<std::mutex> guard(lock);
finish(guard, mode::Errored);
}
@@ -188,7 +189,7 @@ struct observe_on
state->fill_queue.push_back(notification_type::on_next(std::move(v)));
state->ensure_processing(guard);
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
std::unique_lock<std::mutex> guard(state->lock);
if (state->current == mode::Errored || state->current == mode::Disposed) { return; }
state->fill_queue.push_back(notification_type::on_error(e));
diff --git a/Rx/v2/src/rxcpp/operators/rx-on_error_resume_next.hpp b/Rx/v2/src/rxcpp/operators/rx-on_error_resume_next.hpp
index 4ebee38..bc9beba 100644
--- a/Rx/v2/src/rxcpp/operators/rx-on_error_resume_next.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-on_error_resume_next.hpp
@@ -6,9 +6,9 @@
\brief If an error occurs, take the result from the Selector and subscribe to that instead.
- \tparam Selector the actual type of a function of the form `observable<T>(std::exception_ptr)`
+ \tparam Selector the actual type of a function of the form `observable<T>(rxu::error_ptr)`
- \param s the function of the form `observable<T>(std::exception_ptr)`
+ \param s the function of the form `observable<T>(rxu::error_ptr)`
\return Observable that emits the items from the source observable and switches to a new observable on error.
@@ -44,7 +44,7 @@ struct on_error_resume_next
{
typedef rxu::decay_t<T> value_type;
typedef rxu::decay_t<Selector> select_type;
- typedef decltype((*(select_type*)nullptr)(std::exception_ptr())) fallback_type;
+ typedef decltype((*(select_type*)nullptr)(rxu::error_ptr())) fallback_type;
select_type selector;
on_error_resume_next(select_type s)
@@ -58,7 +58,7 @@ struct on_error_resume_next
typedef on_error_resume_next_observer<Subscriber> this_type;
typedef rxu::decay_t<T> value_type;
typedef rxu::decay_t<Selector> select_type;
- typedef decltype((*(select_type*)nullptr)(std::exception_ptr())) fallback_type;
+ typedef decltype((*(select_type*)nullptr)(rxu::error_ptr())) fallback_type;
typedef rxu::decay_t<Subscriber> dest_type;
typedef observer<T, this_type> observer_type;
dest_type dest;
@@ -75,7 +75,7 @@ struct on_error_resume_next
void on_next(value_type v) const {
dest.on_next(std::move(v));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto selected = on_exception(
[&](){
return this->selector(std::move(e));},
diff --git a/Rx/v2/src/rxcpp/operators/rx-pairwise.hpp b/Rx/v2/src/rxcpp/operators/rx-pairwise.hpp
index 584a6bf..411cf27 100644
--- a/Rx/v2/src/rxcpp/operators/rx-pairwise.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-pairwise.hpp
@@ -67,7 +67,7 @@ struct pairwise
dest.on_next(std::make_tuple(remembered.get(), v));
remembered.reset(v);
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-reduce.hpp b/Rx/v2/src/rxcpp/operators/rx-reduce.hpp
index 7fc9d08..e5dc819 100644
--- a/Rx/v2/src/rxcpp/operators/rx-reduce.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-reduce.hpp
@@ -166,7 +166,7 @@ struct reduce : public operator_base<rxu::value_type_t<reduce_traits<T, Observab
state->current = std::move(next);
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
@@ -244,7 +244,7 @@ struct average {
}
return avg;
}
- throw rxcpp::empty_error("average() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("average() requires a stream with at least one value"));
}
};
@@ -264,7 +264,7 @@ struct sum {
}
T operator()(seed_type a) const {
if (a.empty())
- throw rxcpp::empty_error("sum() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("sum() requires a stream with at least one value"));
return *a;
}
};
@@ -283,7 +283,7 @@ struct max {
}
T operator()(seed_type a) {
if (a.empty())
- throw rxcpp::empty_error("max() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("max() requires a stream with at least one value"));
return *a;
}
};
@@ -302,7 +302,7 @@ struct min {
}
T operator()(seed_type a) {
if (a.empty())
- throw rxcpp::empty_error("min() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("min() requires a stream with at least one value"));
return *a;
}
};
@@ -320,7 +320,7 @@ struct first {
}
T operator()(seed_type a) {
if (a.empty()) {
- throw rxcpp::empty_error("first() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("first() requires a stream with at least one value"));
}
return *a;
}
@@ -339,7 +339,7 @@ struct last {
}
T operator()(seed_type a) {
if (a.empty()) {
- throw rxcpp::empty_error("last() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("last() requires a stream with at least one value"));
}
return *a;
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-repeat.hpp b/Rx/v2/src/rxcpp/operators/rx-repeat.hpp
index 97ba197..3b9ac89 100644
--- a/Rx/v2/src/rxcpp/operators/rx-repeat.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-repeat.hpp
@@ -47,7 +47,7 @@ using repeat_invalid_t = typename repeat_invalid<AN...>::type;
namespace repeat {
struct event_handlers {
template <typename State>
- static inline void on_error(State& state, std::exception_ptr& e) {
+ static inline void on_error(State& state, rxu::error_ptr& e) {
state->out.on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp b/Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp
index 373d9b3..30a71fe 100644
--- a/Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp
@@ -42,7 +42,7 @@ namespace rxcpp {
state->out.on_next(t);
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
EventHandlers::on_error(state, e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-retry.hpp b/Rx/v2/src/rxcpp/operators/rx-retry.hpp
index 3cee7d3..63e5c27 100644
--- a/Rx/v2/src/rxcpp/operators/rx-retry.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-retry.hpp
@@ -43,7 +43,7 @@ using retry_invalid_t = typename retry_invalid<AN...>::type;
namespace retry {
struct event_handlers {
template <typename State>
- static inline void on_error(State& state, std::exception_ptr& e) {
+ static inline void on_error(State& state, rxu::error_ptr& e) {
state->update();
// Use specialized predicate for finite/infinte case
if (state->completed_predicate()) {
diff --git a/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp b/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp
index fe1caa2..f50cbe4 100644
--- a/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp
@@ -150,7 +150,7 @@ struct sample_with_time
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&) {
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-scan.hpp b/Rx/v2/src/rxcpp/operators/rx-scan.hpp
index b03be30..73bcd87 100644
--- a/Rx/v2/src/rxcpp/operators/rx-scan.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-scan.hpp
@@ -90,7 +90,7 @@ struct scan : public operator_base<rxu::decay_t<Seed>>
state->out.on_next(state->result);
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp b/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp
index 06253b4..3350e44 100644
--- a/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-sequence_equal.hpp
@@ -161,7 +161,7 @@ struct sequence_equal : public operator_base<bool>
check_equal();
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
@@ -189,7 +189,7 @@ struct sequence_equal : public operator_base<bool>
check_equal();
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-skip.hpp b/Rx/v2/src/rxcpp/operators/rx-skip.hpp
index c7f6c11..b77c4da 100644
--- a/Rx/v2/src/rxcpp/operators/rx-skip.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-skip.hpp
@@ -109,7 +109,7 @@ struct skip : public operator_base<T>
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->mode_value = mode::errored;
state->out.on_error(e);
},
diff --git a/Rx/v2/src/rxcpp/operators/rx-skip_last.hpp b/Rx/v2/src/rxcpp/operators/rx-skip_last.hpp
index 6641bd8..9594715 100644
--- a/Rx/v2/src/rxcpp/operators/rx-skip_last.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-skip_last.hpp
@@ -103,7 +103,7 @@ struct skip_last : public operator_base<T>
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-skip_until.hpp b/Rx/v2/src/rxcpp/operators/rx-skip_until.hpp
index 02a2424..4df6671 100644
--- a/Rx/v2/src/rxcpp/operators/rx-skip_until.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-skip_until.hpp
@@ -139,7 +139,7 @@ struct skip_until : public operator_base<T>
state->trigger_lifetime.unsubscribe();
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if (state->mode_value != mode::skipping) {
return;
}
@@ -174,7 +174,7 @@ struct skip_until : public operator_base<T>
state->out.on_next(t);
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if (state->mode_value > mode::triggered) {
return;
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-skip_while.hpp b/Rx/v2/src/rxcpp/operators/rx-skip_while.hpp
index fdd06b6..643d867 100644
--- a/Rx/v2/src/rxcpp/operators/rx-skip_while.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-skip_while.hpp
@@ -75,7 +75,7 @@ struct skip_while
dest.on_next(v);
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp b/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
index b9bab52..8d3e57e 100644
--- a/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-switch_if_empty.hpp
@@ -76,7 +76,7 @@ struct switch_if_empty
is_empty = false;
dest.on_next(std::move(v));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(std::move(e));
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-switch_on_next.hpp b/Rx/v2/src/rxcpp/operators/rx-switch_on_next.hpp
index b18963a..4572121 100644
--- a/Rx/v2/src/rxcpp/operators/rx-switch_on_next.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-switch_on_next.hpp
@@ -155,7 +155,7 @@ struct switch_on_next
state->out.on_next(std::move(ct));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
//on_completed
@@ -171,7 +171,7 @@ struct switch_on_next
selectedSource.subscribe(std::move(selectedSinkInner));
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-take.hpp b/Rx/v2/src/rxcpp/operators/rx-take.hpp
index 054c136..1e4da4d 100644
--- a/Rx/v2/src/rxcpp/operators/rx-take.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-take.hpp
@@ -112,7 +112,7 @@ struct take : public operator_base<T>
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->mode_value = mode::errored;
state->out.on_error(e);
},
diff --git a/Rx/v2/src/rxcpp/operators/rx-take_last.hpp b/Rx/v2/src/rxcpp/operators/rx-take_last.hpp
index d59b355..12e28b6 100644
--- a/Rx/v2/src/rxcpp/operators/rx-take_last.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-take_last.hpp
@@ -100,7 +100,7 @@ struct take_last : public operator_base<T>
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-take_until.hpp b/Rx/v2/src/rxcpp/operators/rx-take_until.hpp
index 29aaf88..3fd9b71 100644
--- a/Rx/v2/src/rxcpp/operators/rx-take_until.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-take_until.hpp
@@ -147,7 +147,7 @@ struct take_until : public operator_base<T>
state->out.on_completed();
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if (state->mode_value != mode::taking) {return;}
state->mode_value = mode::errored;
state->out.on_error(e);
@@ -179,7 +179,7 @@ struct take_until : public operator_base<T>
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
if (state->mode_value > mode::clear) {return;}
state->mode_value = mode::errored;
state->out.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-take_while.hpp b/Rx/v2/src/rxcpp/operators/rx-take_while.hpp
index de1d57d..85630e7 100644
--- a/Rx/v2/src/rxcpp/operators/rx-take_while.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-take_while.hpp
@@ -73,7 +73,7 @@ struct take_while
dest.on_completed();
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-tap.hpp b/Rx/v2/src/rxcpp/operators/rx-tap.hpp
index 51bfb2f..550163a 100644
--- a/Rx/v2/src/rxcpp/operators/rx-tap.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-tap.hpp
@@ -92,7 +92,7 @@ struct tap
out.on_next(v);
dest.on_next(v);
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
out.on_error(e);
dest.on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-time_interval.hpp b/Rx/v2/src/rxcpp/operators/rx-time_interval.hpp
index 181c066..1a4c9a5 100644
--- a/Rx/v2/src/rxcpp/operators/rx-time_interval.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-time_interval.hpp
@@ -84,7 +84,7 @@ struct time_interval
dest.on_next(now - last);
last = now;
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-timeout.hpp b/Rx/v2/src/rxcpp/operators/rx-timeout.hpp
index 841df12..d100fa4 100644
--- a/Rx/v2/src/rxcpp/operators/rx-timeout.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-timeout.hpp
@@ -147,7 +147,7 @@ struct timeout
if(id != state->index)
return;
- state->dest.on_error(std::make_exception_ptr(rxcpp::timeout_error("timeout has occurred")));
+ state->dest.on_error(rxu::make_error_ptr(rxcpp::timeout_error("timeout has occurred")));
};
auto selectedProduce = on_exception(
@@ -178,7 +178,7 @@ struct timeout
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&) {
localState->dest.on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-timestamp.hpp b/Rx/v2/src/rxcpp/operators/rx-timestamp.hpp
index d1a11bf..923cf5d 100644
--- a/Rx/v2/src/rxcpp/operators/rx-timestamp.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-timestamp.hpp
@@ -78,7 +78,7 @@ struct timestamp
void on_next(source_value_type v) const {
dest.on_next(std::make_pair(v, coord.now()));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/src/rxcpp/operators/rx-window.hpp b/Rx/v2/src/rxcpp/operators/rx-window.hpp
index e5d2c6f..e033a84 100644
--- a/Rx/v2/src/rxcpp/operators/rx-window.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-window.hpp
@@ -103,7 +103,7 @@ struct window
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
for (auto s : subj) {
s.get_subscriber().on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/operators/rx-window_time.hpp b/Rx/v2/src/rxcpp/operators/rx-window_time.hpp
index 17d4dd2..57f7572 100644
--- a/Rx/v2/src/rxcpp/operators/rx-window_time.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-window_time.hpp
@@ -195,7 +195,7 @@ struct window_with_time
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
for (auto s : localState->subj) {
diff --git a/Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp b/Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp
index 39c64ad..9375737 100644
--- a/Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp
@@ -183,7 +183,7 @@ struct window_with_time_or_count
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
localState->subj.get_subscriber().on_error(e);
diff --git a/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp b/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp
index c17d4bc..b9f119a 100644
--- a/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp
@@ -176,7 +176,7 @@ struct window_toggle
innercs.unsubscribe();
},
// on_error
- [localState](std::exception_ptr e) {
+ [localState](rxu::error_ptr e) {
localState->dest.on_error(e);
},
// on_completed
@@ -186,7 +186,7 @@ struct window_toggle
source.subscribe(std::move(selectedSink));
},
// on_error
- [localState](std::exception_ptr e) {
+ [localState](rxu::error_ptr e) {
localState->dest.on_error(e);
},
// on_completed
@@ -218,7 +218,7 @@ struct window_toggle
localState->worker.schedule(selectedWork.get());
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
auto localState = state;
auto work = [e, localState](const rxsc::schedulable&){
for (auto s : localState->subj) {
diff --git a/Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp b/Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp
index febba99..616e5d8 100644
--- a/Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp
@@ -173,7 +173,7 @@ struct with_latest_from : public operator_base<rxu::value_type_t<with_latest_fro
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/operators/rx-zip.hpp b/Rx/v2/src/rxcpp/operators/rx-zip.hpp
index 90efe07..b8169fd 100644
--- a/Rx/v2/src/rxcpp/operators/rx-zip.hpp
+++ b/Rx/v2/src/rxcpp/operators/rx-zip.hpp
@@ -203,7 +203,7 @@ struct zip : public operator_base<rxu::value_type_t<zip_traits<Coordination, Sel
}
},
// on_error
- [state](std::exception_ptr e) {
+ [state](rxu::error_ptr e) {
state->out.on_error(e);
},
// on_completed
diff --git a/Rx/v2/src/rxcpp/rx-composite_exception.hpp b/Rx/v2/src/rxcpp/rx-composite_exception.hpp
index 333f291..cddd03e 100644
--- a/Rx/v2/src/rxcpp/rx-composite_exception.hpp
+++ b/Rx/v2/src/rxcpp/rx-composite_exception.hpp
@@ -11,7 +11,7 @@ namespace rxcpp {
struct composite_exception : std::exception {
- typedef std::vector<std::exception_ptr> exception_values;
+ typedef std::vector<rxu::error_ptr> exception_values;
virtual const char *what() const RXCPP_NOEXCEPT override {
return "rxcpp composite exception";
@@ -21,7 +21,7 @@ struct composite_exception : std::exception {
return exceptions.empty();
}
- virtual composite_exception add(std::exception_ptr exception_ptr) {
+ virtual composite_exception add(rxu::error_ptr exception_ptr) {
exceptions.push_back(exception_ptr);
return *this;
}
diff --git a/Rx/v2/src/rxcpp/rx-coordination.hpp b/Rx/v2/src/rxcpp/rx-coordination.hpp
index d2769e9..34e1223 100644
--- a/Rx/v2/src/rxcpp/rx-coordination.hpp
+++ b/Rx/v2/src/rxcpp/rx-coordination.hpp
@@ -227,7 +227,7 @@ class serialize_one_worker : public coordination_base
std::unique_lock<std::mutex> guard(*lock);
dest.on_next(v);
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
std::unique_lock<std::mutex> guard(*lock);
dest.on_error(e);
}
diff --git a/Rx/v2/src/rxcpp/rx-includes.hpp b/Rx/v2/src/rxcpp/rx-includes.hpp
index 5104565..1eb47db 100644
--- a/Rx/v2/src/rxcpp/rx-includes.hpp
+++ b/Rx/v2/src/rxcpp/rx-includes.hpp
@@ -23,6 +23,12 @@
#define RXCPP_USE_RTTI 1
#endif
+#if _HAS_EXCEPTIONS
+#define RXCPP_USE_EXCEPTIONS 1
+#endif
+
+#define RXCPP_NORETURN __declspec(noreturn)
+
#elif defined(__clang__)
#if __has_feature(cxx_rvalue_references)
@@ -34,6 +40,15 @@
#if __has_feature(cxx_variadic_templates)
#define RXCPP_USE_VARIADIC_TEMPLATES 1
#endif
+#if __has_feature(cxx_exceptions)
+#define RXCPP_USE_EXCEPTIONS 1
+#endif
+
+#if __has_feature(cxx_attributes)
+#define RXCPP_NORETURN [[noreturn]]
+#else
+#define RXCPP_NORETURN __attribute__ ((noreturn))
+#endif
#elif defined(__GNUG__)
@@ -53,6 +68,12 @@
#define RXCPP_USE_RTTI 1
#endif
+#if defined(__EXCEPTIONS)
+#define RXCPP_USE_EXCEPTIONS 1
+#endif
+
+#define RXCPP_NORETURN __attribute__ ((noreturn))
+
#endif
//
@@ -95,6 +116,11 @@
#define RXCPP_USE_RTTI RXCPP_FORCE_USE_RTTI
#endif
+#if defined(RXCPP_FORCE_USE_EXCEPTIONS)
+#undef RXCPP_USE_EXCEPTIONS
+#define RXCPP_USE_EXCEPTIONS RXCPP_FORCE_USE_EXCEPTIONS
+#endif
+
#if defined(RXCPP_FORCE_USE_WINRT)
#undef RXCPP_USE_WINRT
#define RXCPP_USE_WINRT RXCPP_FORCE_USE_WINRT
diff --git a/Rx/v2/src/rxcpp/rx-notification.hpp b/Rx/v2/src/rxcpp/rx-notification.hpp
index c071e67..20e0c69 100644
--- a/Rx/v2/src/rxcpp/rx-notification.hpp
+++ b/Rx/v2/src/rxcpp/rx-notification.hpp
@@ -106,7 +106,7 @@ auto equals(const T& lhs, const T& rhs, int)
template<class T>
bool equals(const T&, const T&, ...) {
- throw std::runtime_error("value does not support equality tests");
+ rxu::throw_exception(std::runtime_error("value does not support equality tests"));
return false;
}
@@ -146,26 +146,20 @@ private:
};
struct on_error_notification : public base {
- on_error_notification(std::exception_ptr ep) : ep(ep) {
+ on_error_notification(rxu::error_ptr ep) : ep(ep) {
}
on_error_notification(const on_error_notification& o) : ep(o.ep) {}
on_error_notification(const on_error_notification&& o) : ep(std::move(o.ep)) {}
on_error_notification& operator=(on_error_notification o) { ep = std::move(o.ep); return *this; }
virtual void out(std::ostream& os) const {
os << "on_error(";
- try {
- std::rethrow_exception(ep);
- } catch (const std::exception& e) {
- os << e.what();
- } catch (...) {
- os << "<not derived from std::exception>";
- }
+ os << rxu::what(ep);
os << ")";
}
virtual bool equals(const typename base::type& other) const {
bool result = false;
// not trying to compare exceptions
- other->accept(make_subscriber<T>(make_observer_dynamic<T>([](T){}, [&result](std::exception_ptr){
+ other->accept(make_subscriber<T>(make_observer_dynamic<T>([](T){}, [&result](rxu::error_ptr){
result = true;
})));
return result;
@@ -173,7 +167,7 @@ private:
virtual void accept(const typename base::observer_type& o) const {
o.on_error(ep);
}
- const std::exception_ptr ep;
+ const rxu::error_ptr ep;
};
struct on_completed_notification : public base {
@@ -199,20 +193,14 @@ private:
template<typename Exception>
static
type make_on_error(exception_tag&&, Exception&& e) {
- std::exception_ptr ep;
- try {
- throw std::forward<Exception>(e);
- }
- catch (...) {
- ep = std::current_exception();
- }
+ rxu::error_ptr ep = rxu::make_error_ptr(std::forward<Exception>(e));
return std::make_shared<on_error_notification>(ep);
}
struct exception_ptr_tag {};
static
- type make_on_error(exception_ptr_tag&&, std::exception_ptr ep) {
+ type make_on_error(exception_ptr_tag&&, rxu::error_ptr ep) {
return std::make_shared<on_error_notification>(ep);
}
@@ -229,7 +217,7 @@ public:
template<typename Exception>
static type on_error(Exception&& e) {
return make_on_error(typename std::conditional<
- std::is_same<rxu::decay_t<Exception>, std::exception_ptr>::value,
+ std::is_same<rxu::decay_t<Exception>, rxu::error_ptr>::value,
exception_ptr_tag, exception_tag>::type(),
std::forward<Exception>(e));
}
@@ -280,8 +268,6 @@ std::ostream& operator<< (std::ostream& out, const recorded<T>& r) {
}
namespace rxn=notifications;
-}
-
inline std::ostream& operator<< (std::ostream& out, const std::vector<rxcpp::notifications::subscription>& vs) {
return rxcpp::notifications::detail::ostreamvector(out, vs);
}
@@ -290,4 +276,6 @@ inline std::ostream& operator<< (std::ostream& out, const std::vector<rxcpp::not
return rxcpp::notifications::detail::ostreamvector(out, vr);
}
+}
+
#endif
diff --git a/Rx/v2/src/rxcpp/rx-observable.hpp b/Rx/v2/src/rxcpp/rx-observable.hpp
index 037f375..97bcabd 100644
--- a/Rx/v2/src/rxcpp/rx-observable.hpp
+++ b/Rx/v2/src/rxcpp/rx-observable.hpp
@@ -174,7 +174,7 @@ class blocking_observable
std::mutex lock;
std::condition_variable wake;
bool disposed = false;
- std::exception_ptr error;
+ rxu::error_ptr error;
auto dest = make_subscriber<T>(std::forward<ArgN>(an)...);
@@ -182,7 +182,7 @@ class blocking_observable
auto scbr = make_subscriber<T>(
dest,
[&](T t){dest.on_next(t);},
- [&](std::exception_ptr e){
+ [&](rxu::error_ptr e){
if (do_rethrow) {
error = e;
} else {
@@ -208,7 +208,7 @@ class blocking_observable
return disposed;
});
- if (error) {std::rethrow_exception(error);}
+ if (error) {rxu::rethrow_exception(error);}
}
public:
@@ -288,7 +288,7 @@ public:
cs,
[&](T v){result.reset(v); cs.unsubscribe();});
if (result.empty())
- throw rxcpp::empty_error("first() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("first() requires a stream with at least one value"));
return result.get();
static_assert(sizeof...(AN) == 0, "first() was passed too many arguments.");
}
@@ -314,7 +314,7 @@ public:
subscribe_with_rethrow(
[&](T v){result.reset(v);});
if (result.empty())
- throw rxcpp::empty_error("last() requires a stream with at least one value");
+ rxu::throw_exception(rxcpp::empty_error("last() requires a stream with at least one value"));
return result.get();
static_assert(sizeof...(AN) == 0, "last() was passed too many arguments.");
}
@@ -431,14 +431,13 @@ struct safe_subscriber
safe_subscriber(SourceOperator& so, Subscriber& o) : so(std::addressof(so)), o(std::addressof(o)) {}
void subscribe() {
- try {
+ RXCPP_TRY {
so->on_subscribe(*o);
- }
- catch(...) {
+ } RXCPP_CATCH(...) {
if (!o->is_subscribed()) {
- throw;
+ rxu::rethrow_current_exception();
}
- o->on_error(std::current_exception());
+ o->on_error(rxu::make_error_ptr(rxu::current_exception()));
o->unsubscribe();
}
}
diff --git a/Rx/v2/src/rxcpp/rx-observer.hpp b/Rx/v2/src/rxcpp/rx-observer.hpp
index 62aed3c..92321f1 100644
--- a/Rx/v2/src/rxcpp/rx-observer.hpp
+++ b/Rx/v2/src/rxcpp/rx-observer.hpp
@@ -25,14 +25,14 @@ struct OnNextEmpty
};
struct OnErrorEmpty
{
- void operator()(std::exception_ptr) const {
+ void operator()(rxu::error_ptr) const {
// error implicitly ignored, abort
std::terminate();
}
};
struct OnErrorIgnore
{
- void operator()(std::exception_ptr) const {
+ void operator()(rxu::error_ptr) const {
}
};
struct OnCompletedEmpty
@@ -76,7 +76,7 @@ struct OnErrorForward
OnErrorForward() : onerror() {}
explicit OnErrorForward(onerror_t oe) : onerror(std::move(oe)) {}
onerror_t onerror;
- void operator()(state_t& s, std::exception_ptr ep) const {
+ void operator()(state_t& s, rxu::error_ptr ep) const {
onerror(s, ep);
}
};
@@ -85,7 +85,7 @@ struct OnErrorForward<State, void>
{
using state_t = rxu::decay_t<State>;
OnErrorForward() {}
- void operator()(state_t& s, std::exception_ptr ep) const {
+ void operator()(state_t& s, rxu::error_ptr ep) const {
s.on_error(ep);
}
};
@@ -129,7 +129,7 @@ struct is_on_error
{
struct not_void {};
template<class CF>
- static auto check(int) -> decltype((*(CF*)nullptr)(*(std::exception_ptr*)nullptr));
+ static auto check(int) -> decltype((*(CF*)nullptr)(*(rxu::error_ptr*)nullptr));
template<class CF>
static not_void check(...);
@@ -141,7 +141,7 @@ struct is_on_error_for
{
struct not_void {};
template<class CF>
- static auto check(int) -> decltype((*(CF*)nullptr)(*(State*)nullptr, *(std::exception_ptr*)nullptr));
+ static auto check(int) -> decltype((*(CF*)nullptr)(*(State*)nullptr, *(rxu::error_ptr*)nullptr));
template<class CF>
static not_void check(...);
@@ -169,7 +169,7 @@ struct is_on_completed
\tparam T - the type of value in the stream
\tparam State - the type of the stored state
\tparam OnNext - the type of a function that matches `void(State&, T)`. Called 0 or more times. If `void` State::on_next will be called.
- \tparam OnError - the type of a function that matches `void(State&, std::exception_ptr)`. Called 0 or 1 times, no further calls will be made. If `void` State::on_error will be called.
+ \tparam OnError - the type of a function that matches `void(State&, rxu::error_ptr)`. Called 0 or 1 times, no further calls will be made. If `void` State::on_error will be called.
\tparam OnCompleted - the type of a function that matches `void(State&)`. Called 0 or 1 times, no further calls will be made. If `void` State::on_completed will be called.
\ingroup group-core
@@ -244,7 +244,7 @@ public:
void on_next(T&& t) const {
onnext(state, std::move(t));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
onerror(state, e);
}
void on_completed() const {
@@ -260,7 +260,7 @@ public:
\tparam T - the type of value in the stream
\tparam OnNext - the type of a function that matches `void(T)`. Called 0 or more times. If `void` OnNextEmpty<T> is used.
- \tparam OnError - the type of a function that matches `void(std::exception_ptr)`. Called 0 or 1 times, no further calls will be made. If `void` OnErrorEmpty is used.
+ \tparam OnError - the type of a function that matches `void(rxu::error_ptr)`. Called 0 or 1 times, no further calls will be made. If `void` OnErrorEmpty is used.
\tparam OnCompleted - the type of a function that matches `void()`. Called 0 or 1 times, no further calls will be made. If `void` OnCompletedEmpty is used.
\ingroup group-core
@@ -291,7 +291,7 @@ private:
public:
static_assert(detail::is_on_next_of<T, on_next_t>::value, "Function supplied for on_next must be a function with the signature void(T);");
- static_assert(detail::is_on_error<on_error_t>::value, "Function supplied for on_error must be a function with the signature void(std::exception_ptr);");
+ static_assert(detail::is_on_error<on_error_t>::value, "Function supplied for on_error must be a function with the signature void(rxu::error_ptr);");
static_assert(detail::is_on_completed<on_completed_t>::value, "Function supplied for on_completed must be a function with the signature void();");
observer()
@@ -332,7 +332,7 @@ public:
void on_next(T&& t) const {
onnext(std::move(t));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
onerror(e);
}
void on_completed() const {
@@ -352,7 +352,7 @@ struct virtual_observer : public std::enable_shared_from_this<virtual_observer<T
virtual ~virtual_observer() {}
virtual void on_next(T&) const {};
virtual void on_next(T&&) const {};
- virtual void on_error(std::exception_ptr) const {};
+ virtual void on_error(rxu::error_ptr) const {};
virtual void on_completed() const {};
};
@@ -371,7 +371,7 @@ struct specific_observer : public virtual_observer<T>
virtual void on_next(T&& t) const {
destination.on_next(std::move(t));
}
- virtual void on_error(std::exception_ptr e) const {
+ virtual void on_error(rxu::error_ptr e) const {
destination.on_error(e);
}
virtual void on_completed() const {
@@ -439,7 +439,7 @@ public:
destination->on_next(std::forward<V>(v));
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
if (destination) {
destination->on_error(e);
}
@@ -640,10 +640,10 @@ template<class F, class OnError>
auto on_exception(const F& f, const OnError& c)
-> typename std::enable_if<detail::is_on_error<OnError>::value, typename detail::maybe_from_result<F>::type>::type {
typename detail::maybe_from_result<F>::type r;
- try {
+ RXCPP_TRY {
r.reset(f());
- } catch (...) {
- c(std::current_exception());
+ } RXCPP_CATCH(...) {
+ c(rxu::current_exception());
}
return r;
}
@@ -652,10 +652,10 @@ template<class F, class Subscriber>
auto on_exception(const F& f, const Subscriber& s)
-> typename std::enable_if<is_subscriber<Subscriber>::value, typename detail::maybe_from_result<F>::type>::type {
typename detail::maybe_from_result<F>::type r;
- try {
+ RXCPP_TRY {
r.reset(f());
- } catch (...) {
- s.on_error(std::current_exception());
+ } RXCPP_CATCH(...) {
+ s.on_error(rxu::current_exception());
}
return r;
}
diff --git a/Rx/v2/src/rxcpp/rx-subscriber.hpp b/Rx/v2/src/rxcpp/rx-subscriber.hpp
index abdb7b6..3d6c515 100644
--- a/Rx/v2/src/rxcpp/rx-subscriber.hpp
+++ b/Rx/v2/src/rxcpp/rx-subscriber.hpp
@@ -50,11 +50,11 @@ class subscriber : public subscriber_base<T>
template<class U>
void operator()(U u) {
trace_activity().on_next_enter(*that, u);
- try {
+ RXCPP_TRY {
that->destination.on_next(std::move(u));
do_unsubscribe = false;
- } catch(...) {
- auto ex = std::current_exception();
+ } RXCPP_CATCH(...) {
+ auto ex = rxu::current_exception();
trace_activity().on_error_enter(*that, ex);
that->destination.on_error(std::move(ex));
trace_activity().on_error_return(*that);
@@ -75,7 +75,7 @@ class subscriber : public subscriber_base<T>
: that(that)
{
}
- inline void operator()(std::exception_ptr ex) {
+ inline void operator()(rxu::error_ptr ex) {
trace_activity().on_error_enter(*that, ex);
that->destination.on_error(std::move(ex));
}
@@ -180,7 +180,7 @@ public:
nextdetacher protect(this);
protect(std::forward<V>(v));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
if (!is_subscribed()) {
return;
}
diff --git a/Rx/v2/src/rxcpp/rx-trace.hpp b/Rx/v2/src/rxcpp/rx-trace.hpp
index a148953..bf0abaf 100644
--- a/Rx/v2/src/rxcpp/rx-trace.hpp
+++ b/Rx/v2/src/rxcpp/rx-trace.hpp
@@ -93,8 +93,8 @@ struct trace_noop
template<class Subscriber>
inline void on_next_return(const Subscriber&) {}
- template<class Subscriber>
- inline void on_error_enter(const Subscriber&, const std::exception_ptr&) {}
+ template<class Subscriber, class ErrorPtr>
+ inline void on_error_enter(const Subscriber&, const ErrorPtr&) {}
template<class Subscriber>
inline void on_error_return(const Subscriber&) {}
diff --git a/Rx/v2/src/rxcpp/rx-util.hpp b/Rx/v2/src/rxcpp/rx-util.hpp
index d4d5536..e5867e5 100644
--- a/Rx/v2/src/rxcpp/rx-util.hpp
+++ b/Rx/v2/src/rxcpp/rx-util.hpp
@@ -28,6 +28,18 @@
#define RXCPP_MAKE_IDENTIFIER(Prefix) RXCPP_CONCAT_EVALUATE(Prefix, __LINE__)
+// Provide replacements for try/catch keywords, using which is a compilation error
+// when exceptions are disabled with -fno-exceptions.
+#if RXCPP_USE_EXCEPTIONS
+#define RXCPP_TRY try
+#define RXCPP_CATCH(...) catch(__VA_ARGS__)
+// See also rxu::throw_exception for 'throw' keyword replacement.
+#else
+#define RXCPP_TRY if ((true))
+#define RXCPP_CATCH(...) if ((false))
+// See also rxu::throw_exception, which will std::terminate without exceptions.
+#endif
+
namespace rxcpp {
namespace util {
@@ -530,11 +542,16 @@ auto print_followed_by(OStream& os, DelimitValue dv)
}
inline std::string what(std::exception_ptr ep) {
+#if RXCPP_USE_EXCEPTIONS
try {std::rethrow_exception(ep);}
catch (const std::exception& ex) {
return ex.what();
+ } catch (...) {
+ return std::string("<not derived from std::exception>");
}
- return std::string();
+#endif
+ (void)ep;
+ return std::string("<exceptions are disabled>");
}
namespace detail {
@@ -699,9 +716,9 @@ public:
{
if (!!function)
{
- try {
+ RXCPP_TRY {
(*function)();
- } catch (...) {
+ } RXCPP_CATCH(...) {
std::terminate();
}
}
@@ -811,6 +828,129 @@ template <class T>
struct negation : detail::not_value<T> {};
}
+
+#if !RXCPP_USE_EXCEPTIONS
+namespace util {
+
+namespace detail {
+
+struct error_base {
+ virtual const char* what() = 0;
+ virtual ~error_base() {}
+};
+
+// Use the "Type Erasure" idiom to wrap an std::exception-like
+// value into an error pointer.
+//
+// Supported types:
+// exception, bad_exception, bad_alloc.
+template <class E>
+struct error_specific : public error_base {
+ error_specific(const E& e) : data(e) {}
+ error_specific(E&& e) : data(std::move(e)) {}
+
+ virtual ~error_specific() {}
+
+ virtual const char* what() {
+ return data.what();
+ }
+
+ E data;
+};
+
+}
+
+}
+#endif
+
+namespace util {
+
+#if RXCPP_USE_EXCEPTIONS
+using error_ptr = std::exception_ptr;
+#else
+// Note: std::exception_ptr cannot be used directly when exceptions are disabled.
+// Any attempt to 'throw' or to call into any of the std functions accepting
+// an std::exception_ptr will either fail to compile or result in an abort at runtime.
+using error_ptr = std::shared_ptr<util::detail::error_base>;
+
+inline std::string what(error_ptr ep) {
+ return std::string(ep->what());
+}
+#endif
+
+// TODO: Do we really need an identity make?
+// (It was causing some compilation errors deep inside templates).
+inline error_ptr make_error_ptr(error_ptr e) {
+ return e;
+}
+
+// Replace std::make_exception_ptr (which would immediately terminate
+// when exceptions are disabled).
+template <class E>
+error_ptr make_error_ptr(E&& e) {
+#if RXCPP_USE_EXCEPTIONS
+ return std::make_exception_ptr(std::forward<E>(e));
+#else
+ using e_type = rxcpp::util::decay_t<E>;
+ using pointed_to_type = rxcpp::util::detail::error_specific<e_type>;
+ auto sp = std::make_shared<pointed_to_type>(std::forward<E>(e));
+ return std::static_pointer_cast<rxcpp::util::detail::error_base>(sp);
+#endif
+}
+
+// Replace std::rethrow_exception to be compatible with our error_ptr typedef.
+RXCPP_NORETURN inline void rethrow_exception(error_ptr e) {
+#if RXCPP_USE_EXCEPTIONS
+ std::rethrow_exception(e);
+#else
+ // error_ptr != std::exception_ptr so we can't use std::rethrow_exception
+ //
+ // However even if we could, calling std::rethrow_exception just terminates if exceptions are disabled.
+ //
+ // Therefore this function should only be called when we are completely giving up and have no idea
+ // how to handle the error.
+ (void)e;
+ std::terminate();
+#endif
+}
+
+// A replacement for the "throw" keyword which is illegal when
+// exceptions are disabled with -fno-exceptions.
+template <typename E>
+RXCPP_NORETURN inline void throw_exception(E&& e) {
+#if RXCPP_USE_EXCEPTIONS
+ throw std::forward<E>(e);
+#else
+ // "throw" keyword is unsupported when exceptions are disabled.
+ // Immediately terminate instead.
+ (void)e;
+ std::terminate();
+#endif
+}
+
+// TODO: Do we really need this? rxu::rethrow_exception(rxu::current_exception())
+// would have the same semantics in either case.
+RXCPP_NORETURN inline void rethrow_current_exception() {
+#if RXCPP_USE_EXCEPTIONS
+ std::rethrow_exception(std::current_exception());
+#else
+ std::terminate();
+#endif
+}
+
+// If called during exception handling, return the currently caught exception.
+// Otherwise return null.
+inline error_ptr current_exception() {
+#if RXCPP_USE_EXCEPTIONS
+ return std::current_exception();
+#else
+ // When exceptions are disabled, we can never be inside of a catch block.
+ // Return null similar to std::current_exception returning null outside of catch.
+ return nullptr;
+#endif
+}
+
+}
namespace rxu=util;
diff --git a/Rx/v2/src/rxcpp/schedulers/rx-test.hpp b/Rx/v2/src/rxcpp/schedulers/rx-test.hpp
index 3f73e52..aaa073d 100644
--- a/Rx/v2/src/rxcpp/schedulers/rx-test.hpp
+++ b/Rx/v2/src/rxcpp/schedulers/rx-test.hpp
@@ -200,7 +200,7 @@ subscriber<T, rxt::testable_observer<T>> test_type::test_type_worker::make_subsc
recorded_type(ts->sc->clock(), notification_type::on_next(value)));
},
// on_error
- [ts](std::exception_ptr e)
+ [ts](rxu::error_ptr e)
{
ts->m.push_back(
recorded_type(ts->sc->clock(), notification_type::on_error(e)));
diff --git a/Rx/v2/src/rxcpp/sources/rx-error.hpp b/Rx/v2/src/rxcpp/sources/rx-error.hpp
index 461c081..f245d02 100644
--- a/Rx/v2/src/rxcpp/sources/rx-error.hpp
+++ b/Rx/v2/src/rxcpp/sources/rx-error.hpp
@@ -46,17 +46,17 @@ struct error : public source_base<T>
struct error_initial_type
{
- error_initial_type(std::exception_ptr e, coordination_type cn)
+ error_initial_type(rxu::error_ptr e, coordination_type cn)
: exception(e)
, coordination(std::move(cn))
{
}
- std::exception_ptr exception;
+ rxu::error_ptr exception;
coordination_type coordination;
};
error_initial_type initial;
- error(std::exception_ptr e, coordination_type cn)
+ error(rxu::error_ptr e, coordination_type cn)
: initial(e, std::move(cn))
{
}
@@ -93,7 +93,7 @@ struct throw_ptr_tag{};
struct throw_instance_tag{};
template <class T, class Coordination>
-auto make_error(throw_ptr_tag&&, std::exception_ptr exception, Coordination cn)
+auto make_error(throw_ptr_tag&&, rxu::error_ptr exception, Coordination cn)
-> observable<T, error<T, Coordination>> {
return observable<T, error<T, Coordination>>(error<T, Coordination>(std::move(exception), std::move(cn)));
}
@@ -101,26 +101,29 @@ auto make_error(throw_ptr_tag&&, std::exception_ptr exception, Coordination cn)
template <class T, class E, class Coordination>
auto make_error(throw_instance_tag&&, E e, Coordination cn)
-> observable<T, error<T, Coordination>> {
- std::exception_ptr exception;
- try {throw e;} catch(...) {exception = std::current_exception();}
- return observable<T, error<T, Coordination>>(error<T, Coordination>(std::move(exception), std::move(cn)));
+ rxu::error_ptr ep = rxu::make_error_ptr(e);
+ return observable<T, error<T, Coordination>>(error<T, Coordination>(std::move(ep), std::move(cn)));
+}
+
}
}
+namespace sources {
+
/*! @copydoc rx-error.hpp
*/
template<class T, class E>
auto error(E e)
- -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate())) {
- return detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate());
+ -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<rxu::error_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate())) {
+ return detail::make_error<T>(typename std::conditional<std::is_same<rxu::error_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), identity_immediate());
}
/*! @copydoc rx-error.hpp
*/
template<class T, class E, class Coordination>
auto error(E e, Coordination cn)
- -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn))) {
- return detail::make_error<T>(typename std::conditional<std::is_same<std::exception_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn));
+ -> decltype(detail::make_error<T>(typename std::conditional<std::is_same<rxu::error_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn))) {
+ return detail::make_error<T>(typename std::conditional<std::is_same<rxu::error_ptr, rxu::decay_t<E>>::value, detail::throw_ptr_tag, detail::throw_instance_tag>::type(), std::move(e), std::move(cn));
}
}
diff --git a/Rx/v2/src/rxcpp/subjects/rx-subject.hpp b/Rx/v2/src/rxcpp/subjects/rx-subject.hpp
index a77c0c4..4ce96b4 100644
--- a/Rx/v2/src/rxcpp/subjects/rx-subject.hpp
+++ b/Rx/v2/src/rxcpp/subjects/rx-subject.hpp
@@ -40,7 +40,7 @@ class multicast_observer
}
std::mutex lock;
typename mode::type current;
- std::exception_ptr error;
+ rxu::error_ptr error;
composite_subscription lifetime;
};
@@ -191,7 +191,7 @@ public:
}
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
std::unique_lock<std::mutex> guard(b->state->lock);
if (b->state->current == mode::Casting) {
b->state->error = e;
diff --git a/Rx/v2/src/rxcpp/subjects/rx-synchronize.hpp b/Rx/v2/src/rxcpp/subjects/rx-synchronize.hpp
index 161b422..858eef3 100644
--- a/Rx/v2/src/rxcpp/subjects/rx-synchronize.hpp
+++ b/Rx/v2/src/rxcpp/subjects/rx-synchronize.hpp
@@ -56,7 +56,7 @@ class synchronize_observer : public detail::multicast_observer<T>
auto keepAlive = this->shared_from_this();
auto drain_queue = [keepAlive, this](const rxsc::schedulable& self){
- try {
+ RXCPP_TRY {
std::unique_lock<std::mutex> guard(lock);
if (!destination.is_subscribed()) {
current = mode::Disposed;
@@ -74,8 +74,8 @@ class synchronize_observer : public detail::multicast_observer<T>
guard.unlock();
notification->accept(destination);
self();
- } catch(...) {
- destination.on_error(std::current_exception());
+ } RXCPP_CATCH(...) {
+ destination.on_error(rxu::current_exception());
std::unique_lock<std::mutex> guard(lock);
current = mode::Empty;
}
@@ -110,7 +110,7 @@ class synchronize_observer : public detail::multicast_observer<T>
}
wake.notify_one();
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
if (lifetime.is_subscribed()) {
std::unique_lock<std::mutex> guard(lock);
fill_queue.push_back(notification_type::on_error(e));
@@ -150,7 +150,7 @@ public:
void on_next(V v) const {
state->on_next(std::move(v));
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
state->on_error(e);
}
void on_completed() const {
diff --git a/Rx/v2/test/CMakeLists.txt b/Rx/v2/test/CMakeLists.txt
index dcb998f..c2d1530 100644
--- a/Rx/v2/test/CMakeLists.txt
+++ b/Rx/v2/test/CMakeLists.txt
@@ -88,6 +88,15 @@ set(TEST_SOURCES
${TEST_DIR}/operators/zip.cpp
)
+set(TEST_COMPILE_DEFINITIONS "")
+set(TEST_COMMAND_ARGUMENTS "")
+
+if (NOT RX_USE_EXCEPTIONS)
+ MESSAGE( STATUS "no exceptions" )
+ list(APPEND TEST_COMPILE_DEFINITIONS CATCH_CONFIG_DISABLE_EXCEPTIONS)
+ list(APPEND TEST_COMMAND_ARGUMENTS -e)
+endif()
+
add_executable(rxcppv2_test ${TEST_DIR}/test.cpp ${TEST_SOURCES})
add_executable(rxcpp::tests ALIAS rxcppv2_test)
@@ -98,6 +107,7 @@ set_target_properties(
)
target_compile_options(rxcppv2_test PUBLIC ${RX_COMPILE_OPTIONS})
target_compile_features(rxcppv2_test PUBLIC ${RX_COMPILE_FEATURES})
+target_compile_definitions(rxcppv2_test PUBLIC ${TEST_COMPILE_DEFINITIONS})
target_include_directories(rxcppv2_test
PUBLIC ${RX_SRC_DIR} ${RX_CATCH_DIR}
)
@@ -110,7 +120,7 @@ foreach(ONE_TEST_SOURCE ${TEST_SOURCES})
set(ONE_TEST_FULL_NAME "rxcpp_test_${ONE_TEST_NAME}")
add_executable( ${ONE_TEST_FULL_NAME} ${ONE_TEST_SOURCE} )
add_executable( rxcpp::${ONE_TEST_NAME} ALIAS ${ONE_TEST_FULL_NAME})
- target_compile_definitions(${ONE_TEST_FULL_NAME} PUBLIC "CATCH_CONFIG_MAIN")
+ target_compile_definitions(${ONE_TEST_FULL_NAME} PUBLIC "CATCH_CONFIG_MAIN" ${TEST_COMPILE_DEFINITIONS})
target_compile_options(${ONE_TEST_FULL_NAME} PUBLIC ${RX_COMPILE_OPTIONS})
target_compile_features(${ONE_TEST_FULL_NAME} PUBLIC ${RX_COMPILE_FEATURES})
target_include_directories(${ONE_TEST_FULL_NAME}
@@ -118,7 +128,7 @@ foreach(ONE_TEST_SOURCE ${TEST_SOURCES})
)
target_link_libraries(${ONE_TEST_FULL_NAME} ${CMAKE_THREAD_LIBS_INIT})
- add_test(NAME ${ONE_TEST_NAME} COMMAND ${ONE_TEST_FULL_NAME})
+ add_test(NAME ${ONE_TEST_NAME} COMMAND ${ONE_TEST_FULL_NAME} ${TEST_COMMAND_ARGUMENTS})
endforeach(ONE_TEST_SOURCE ${TEST_SOURCES})
diff --git a/Rx/v2/test/operators/buffer.cpp b/Rx/v2/test/operators/buffer.cpp
index 51aba17..e1b980c 100644
--- a/Rx/v2/test/operators/buffer.cpp
+++ b/Rx/v2/test/operators/buffer.cpp
@@ -455,7 +455,7 @@ SCENARIO("buffer count error 2", "[buffer][operators]"){
}
}
-SCENARIO("buffer with time on intervals", "[buffer_with_time][operators][long][hide]"){
+SCENARIO("buffer with time on intervals", "[buffer_with_time][operators][long][!hide]"){
GIVEN("7 intervals of 2 seconds"){
WHEN("the period is 2sec and the initial is 5sec"){
// time: |-----------------|
@@ -489,7 +489,7 @@ SCENARIO("buffer with time on intervals", "[buffer_with_time][operators][long][h
});
printf("\n");
},
- [](std::exception_ptr){
+ [](rxu::error_ptr){
printf("on_error\n");
},
[](){
@@ -500,7 +500,7 @@ SCENARIO("buffer with time on intervals", "[buffer_with_time][operators][long][h
}
}
-SCENARIO("buffer with time on intervals, implicit coordination", "[buffer_with_time][operators][long][hide]"){
+SCENARIO("buffer with time on intervals, implicit coordination", "[buffer_with_time][operators][long][!hide]"){
GIVEN("7 intervals of 2 seconds"){
WHEN("the period is 2sec and the initial is 5sec"){
// time: |-----------------|
@@ -532,7 +532,7 @@ SCENARIO("buffer with time on intervals, implicit coordination", "[buffer_with_t
});
printf("\n");
},
- [](std::exception_ptr){
+ [](rxu::error_ptr){
printf("on_error\n");
},
[](){
@@ -543,7 +543,7 @@ SCENARIO("buffer with time on intervals, implicit coordination", "[buffer_with_t
}
}
-SCENARIO("buffer with time on overlapping intervals", "[buffer_with_time][operators][long][hide]"){
+SCENARIO("buffer with time on overlapping intervals", "[buffer_with_time][operators][long][!hide]"){
GIVEN("5 intervals of 2 seconds"){
WHEN("the period is 2sec and the initial is 5sec"){
// time: |-------------|
@@ -576,7 +576,7 @@ SCENARIO("buffer with time on overlapping intervals", "[buffer_with_time][operat
});
printf("\n");
},
- [](std::exception_ptr){
+ [](rxu::error_ptr){
printf("on_error\n");
},
[](){
@@ -587,7 +587,7 @@ SCENARIO("buffer with time on overlapping intervals", "[buffer_with_time][operat
}
}
-SCENARIO("buffer with time on overlapping intervals, implicit coordination", "[buffer_with_time][operators][long][hide]"){
+SCENARIO("buffer with time on overlapping intervals, implicit coordination", "[buffer_with_time][operators][long][!hide]"){
GIVEN("5 intervals of 2 seconds"){
WHEN("the period is 2sec and the initial is 5sec"){
// time: |-------------|
@@ -620,7 +620,7 @@ SCENARIO("buffer with time on overlapping intervals, implicit coordination", "[b
});
printf("\n");
},
- [](std::exception_ptr){
+ [](rxu::error_ptr){
printf("on_error\n");
},
[](){
@@ -631,7 +631,7 @@ SCENARIO("buffer with time on overlapping intervals, implicit coordination", "[b
}
}
-SCENARIO("buffer with time on intervals, error", "[buffer_with_time][operators][long][hide]"){
+SCENARIO("buffer with time on intervals, error", "[buffer_with_time][operators][long][!hide]"){
GIVEN("5 intervals of 2 seconds"){
WHEN("the period is 2sec and the initial is 5sec"){
// time: |-------------|
@@ -667,7 +667,7 @@ SCENARIO("buffer with time on intervals, error", "[buffer_with_time][operators][
});
printf("\n");
},
- [](std::exception_ptr){
+ [](rxu::error_ptr){
printf("on_error\n");
},
[](){
diff --git a/Rx/v2/test/operators/combine_latest.cpp b/Rx/v2/test/operators/combine_latest.cpp
index ec47823..198fb2f 100644
--- a/Rx/v2/test/operators/combine_latest.cpp
+++ b/Rx/v2/test/operators/combine_latest.cpp
@@ -1465,7 +1465,7 @@ SCENARIO("combine_latest error after completed right", "[combine_latest][join][o
}
}
-SCENARIO("combine_latest selector throws", "[combine_latest][join][operators]"){
+SCENARIO("combine_latest selector throws", "[combine_latest][join][operators][!throws]"){
GIVEN("2 hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1491,8 +1491,25 @@ SCENARIO("combine_latest selector throws", "[combine_latest][join][operators]"){
[&]() {
return o1
.combine_latest(
+ // Note for trying to handle this test case when exceptions are disabled
+ // with RXCPP_USE_EXCEPTIONS == 0:
+ //
+ // It seems that this test is in particular testing that the
+ // combine_latest selector (aggregate function) thrown exceptions
+ // are being translated into an on_error.
+ //
+ // Since there appears to be no way to give combine_latest
+ // an Observable that would call on_error directly (as opposed
+ // to a regular function that's converted into an observable),
+ // this test is meaningless when exceptions are disabled
+ // since any selectors with 'throw' will not even compile.
+ //
+ // Attempting to change this to e.g.
+ // o1.combineLatest(o2).map ... unconditional onError
+ // would defeat the purpose of the test since its the combineLatest
+ // implementation that's supposed to be doing the error forwarding.
[&ex](int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
o2
)
@@ -1528,7 +1545,7 @@ SCENARIO("combine_latest selector throws", "[combine_latest][join][operators]"){
}
}
-SCENARIO("combine_latest selector throws N", "[combine_latest][join][operators]"){
+SCENARIO("combine_latest selector throws N", "[combine_latest][join][operators][!throws]"){
GIVEN("N hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1555,7 +1572,7 @@ SCENARIO("combine_latest selector throws N", "[combine_latest][join][operators]"
return e[0]
.combine_latest(
[&ex](int, int, int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
e[1], e[2], e[3]
)
diff --git a/Rx/v2/test/operators/concat.cpp b/Rx/v2/test/operators/concat.cpp
index 86f4a7e..88dcac7 100644
--- a/Rx/v2/test/operators/concat.cpp
+++ b/Rx/v2/test/operators/concat.cpp
@@ -5,7 +5,7 @@
const int static_onnextcalls = 1000000;
-SCENARIO("synchronize concat ranges", "[hide][range][synchronize][concat][perf]"){
+SCENARIO("synchronize concat ranges", "[!hide][range][synchronize][concat][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
@@ -33,7 +33,7 @@ SCENARIO("synchronize concat ranges", "[hide][range][synchronize][concat][perf]"
}
}
-SCENARIO("observe_on concat ranges", "[hide][range][observe_on][concat][perf]"){
+SCENARIO("observe_on concat ranges", "[!hide][range][observe_on][concat][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
@@ -61,7 +61,7 @@ SCENARIO("observe_on concat ranges", "[hide][range][observe_on][concat][perf]"){
}
}
-SCENARIO("serialize concat ranges", "[hide][range][serialize][concat][perf]"){
+SCENARIO("serialize concat ranges", "[!hide][range][serialize][concat][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
diff --git a/Rx/v2/test/operators/concat_map.cpp b/Rx/v2/test/operators/concat_map.cpp
index e6551d6..cfd6f4f 100644
--- a/Rx/v2/test/operators/concat_map.cpp
+++ b/Rx/v2/test/operators/concat_map.cpp
@@ -8,7 +8,7 @@
static const int static_tripletCount = 100;
-SCENARIO("concat_transform pythagorian ranges", "[hide][range][concat_transform][pythagorian][perf]"){
+SCENARIO("concat_transform pythagorian ranges", "[!hide][range][concat_transform][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -43,7 +43,7 @@ SCENARIO("concat_transform pythagorian ranges", "[hide][range][concat_transform]
.take(tripletCount)
.subscribe(
rxu::apply_to([&ct](int /*x*/,int /*y*/,int /*z*/){++ct;}),
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
auto finish = clock::now();
auto msElapsed = duration_cast<milliseconds>(finish.time_since_epoch()) -
duration_cast<milliseconds>(start.time_since_epoch());
@@ -53,7 +53,7 @@ SCENARIO("concat_transform pythagorian ranges", "[hide][range][concat_transform]
}
}
-SCENARIO("synchronize concat_transform pythagorian ranges", "[hide][range][concat_transform][synchronize][pythagorian][perf]"){
+SCENARIO("synchronize concat_transform pythagorian ranges", "[!hide][range][concat_transform][synchronize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -101,7 +101,7 @@ SCENARIO("synchronize concat_transform pythagorian ranges", "[hide][range][conca
}
}
-SCENARIO("observe_on concat_transform pythagorian ranges", "[hide][range][concat_transform][observe_on][pythagorian][perf]"){
+SCENARIO("observe_on concat_transform pythagorian ranges", "[!hide][range][concat_transform][observe_on][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -150,7 +150,7 @@ SCENARIO("observe_on concat_transform pythagorian ranges", "[hide][range][concat
}
}
-SCENARIO("serialize concat_transform pythagorian ranges", "[hide][range][concat_transform][serialize][pythagorian][perf]"){
+SCENARIO("serialize concat_transform pythagorian ranges", "[!hide][range][concat_transform][serialize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
diff --git a/Rx/v2/test/operators/filter.cpp b/Rx/v2/test/operators/filter.cpp
index 70c997b..08dd6ee 100644
--- a/Rx/v2/test/operators/filter.cpp
+++ b/Rx/v2/test/operators/filter.cpp
@@ -212,7 +212,9 @@ SCENARIO("filter stops on error", "[where][filter][operators]"){
}
}
-SCENARIO("filter stops on throw from predicate", "[where][filter][operators]"){
+// filter cannot possibly catch an exception when exceptions are disabled,
+// so this test is meaningless when exceptions are disabled.
+SCENARIO("filter stops on throw from predicate", "[where][filter][operators][!throws]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -248,7 +250,7 @@ SCENARIO("filter stops on throw from predicate", "[where][filter][operators]"){
.filter([ex, &invoked](int x) {
invoked++;
if (x > 5) {
- throw ex;
+ rxu::throw_exception(ex);
}
return IsPrime(x);
})
diff --git a/Rx/v2/test/operators/flat_map.cpp b/Rx/v2/test/operators/flat_map.cpp
index 2e01a30..e1837b0 100644
--- a/Rx/v2/test/operators/flat_map.cpp
+++ b/Rx/v2/test/operators/flat_map.cpp
@@ -8,7 +8,7 @@
static const int static_tripletCount = 100;
-SCENARIO("pythagorian for loops", "[hide][for][pythagorian][perf]"){
+SCENARIO("pythagorian for loops", "[!hide][for][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("a for loop"){
WHEN("generating pythagorian triplets"){
@@ -45,7 +45,7 @@ SCENARIO("pythagorian for loops", "[hide][for][pythagorian][perf]"){
}
}
-SCENARIO("merge_transform pythagorian ranges", "[hide][range][merge_transform][pythagorian][perf]"){
+SCENARIO("merge_transform pythagorian ranges", "[!hide][range][merge_transform][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -89,7 +89,7 @@ SCENARIO("merge_transform pythagorian ranges", "[hide][range][merge_transform][p
}
}
-SCENARIO("synchronize merge_transform pythagorian ranges", "[hide][range][merge_transform][synchronize][pythagorian][perf]"){
+SCENARIO("synchronize merge_transform pythagorian ranges", "[!hide][range][merge_transform][synchronize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -137,7 +137,7 @@ SCENARIO("synchronize merge_transform pythagorian ranges", "[hide][range][merge_
}
}
-SCENARIO("observe_on merge_transform pythagorian ranges", "[hide][range][merge_transform][observe_on][pythagorian][perf]"){
+SCENARIO("observe_on merge_transform pythagorian ranges", "[!hide][range][merge_transform][observe_on][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
@@ -185,7 +185,7 @@ SCENARIO("observe_on merge_transform pythagorian ranges", "[hide][range][merge_t
}
}
-SCENARIO("serialize merge_transform pythagorian ranges", "[hide][range][merge_transform][serialize][pythagorian][perf]"){
+SCENARIO("serialize merge_transform pythagorian ranges", "[!hide][range][merge_transform][serialize][pythagorian][perf]"){
const int& tripletCount = static_tripletCount;
GIVEN("some ranges"){
WHEN("generating pythagorian triplets"){
diff --git a/Rx/v2/test/operators/group_by.cpp b/Rx/v2/test/operators/group_by.cpp
index 2c7c177..645bda4 100644
--- a/Rx/v2/test/operators/group_by.cpp
+++ b/Rx/v2/test/operators/group_by.cpp
@@ -9,8 +9,9 @@
#include <rxcpp/operators/rx-observe_on.hpp>
#include <locale>
+#include <sstream>
-SCENARIO("range partitioned by group_by across hardware threads to derive pi", "[hide][pi][group_by][observe_on][long][perf]"){
+SCENARIO("range partitioned by group_by across hardware threads to derive pi", "[!hide][pi][group_by][observe_on][long][perf]"){
GIVEN("a for loop"){
WHEN("partitioning pi series across all hardware threads"){
@@ -92,7 +93,7 @@ SCENARIO("range partitioned by group_by across hardware threads to derive pi", "
}
}
-SCENARIO("range partitioned by dividing work across hardware threads to derive pi", "[hide][pi][observe_on][long][perf]"){
+SCENARIO("range partitioned by dividing work across hardware threads to derive pi", "[!hide][pi][observe_on][long][perf]"){
GIVEN("a for loop"){
WHEN("partitioning pi series across all hardware threads"){
diff --git a/Rx/v2/test/operators/lift.cpp b/Rx/v2/test/operators/lift.cpp
index 7d90bce..1f58c1d 100644
--- a/Rx/v2/test/operators/lift.cpp
+++ b/Rx/v2/test/operators/lift.cpp
@@ -31,17 +31,17 @@ struct liftfilter
}
void on_next(typename dest_type::value_type v) const {
bool filtered = false;
- try {
+ RXCPP_TRY {
filtered = !test(v);
- } catch(...) {
- dest.on_error(std::current_exception());
+ } RXCPP_CATCH(...) {
+ dest.on_error(rxu::current_exception());
return;
}
if (!filtered) {
dest.on_next(v);
}
}
- void on_error(std::exception_ptr e) const {
+ void on_error(rxu::error_ptr e) const {
dest.on_error(e);
}
void on_completed() const {
@@ -248,10 +248,10 @@ SCENARIO("lift lambda filter stops on disposal", "[where][filter][lift][lambda][
rx::make_observer_dynamic<int>(
[=](int n){
bool pass = false;
- try{pass = predicate(n);} catch(...){dest.on_error(std::current_exception());};
+ RXCPP_TRY {pass = predicate(n);} RXCPP_CATCH(...){dest.on_error(rxu::current_exception());};
if (pass) {dest.on_next(n);}
},
- [=](std::exception_ptr e){dest.on_error(e);},
+ [=](rxu::error_ptr e){dest.on_error(e);},
[=](){dest.on_completed();}));
})
// forget type to workaround lambda deduction bug on msvc 2013
diff --git a/Rx/v2/test/operators/merge.cpp b/Rx/v2/test/operators/merge.cpp
index 9a7f28c..917d74d 100644
--- a/Rx/v2/test/operators/merge.cpp
+++ b/Rx/v2/test/operators/merge.cpp
@@ -6,7 +6,7 @@
const int static_onnextcalls = 1000000;
-SCENARIO("synchronize merge ranges", "[hide][range][synchronize][merge][perf]"){
+SCENARIO("synchronize merge ranges", "[!hide][range][synchronize][merge][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
@@ -34,7 +34,7 @@ SCENARIO("synchronize merge ranges", "[hide][range][synchronize][merge][perf]"){
}
}
-SCENARIO("observe_on merge ranges", "[hide][range][observe_on][merge][perf]"){
+SCENARIO("observe_on merge ranges", "[!hide][range][observe_on][merge][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
@@ -62,7 +62,7 @@ SCENARIO("observe_on merge ranges", "[hide][range][observe_on][merge][perf]"){
}
}
-SCENARIO("serialize merge ranges", "[hide][range][serialize][merge][perf]"){
+SCENARIO("serialize merge ranges", "[!hide][range][serialize][merge][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("some ranges"){
WHEN("generating ints"){
diff --git a/Rx/v2/test/operators/merge_delay_error.cpp b/Rx/v2/test/operators/merge_delay_error.cpp
index b53b884..83172ec 100644
--- a/Rx/v2/test/operators/merge_delay_error.cpp
+++ b/Rx/v2/test/operators/merge_delay_error.cpp
@@ -3,8 +3,6 @@
#include <rxcpp/operators/rx-merge_delay_error.hpp>
#include <rxcpp/operators/rx-observe_on.hpp>
-const int static_onnextcalls = 1000000;
-
//merge_delay_error must work the very same way as `merge()` except the error handling
SCENARIO("merge_delay_error completes", "[merge][join][operators]"){
diff --git a/Rx/v2/test/operators/observe_on.cpp b/Rx/v2/test/operators/observe_on.cpp
index ffa85aa..aac2d40 100644
--- a/Rx/v2/test/operators/observe_on.cpp
+++ b/Rx/v2/test/operators/observe_on.cpp
@@ -5,7 +5,7 @@
const int static_onnextcalls = 100000;
-SCENARIO("range observed on new_thread", "[hide][range][observe_on_debug][observe_on][long][perf]"){
+SCENARIO("range observed on new_thread", "[!hide][range][observe_on_debug][observe_on][long][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a range"){
WHEN("multicasting a million ints"){
diff --git a/Rx/v2/test/operators/on_error_resume_next.cpp b/Rx/v2/test/operators/on_error_resume_next.cpp
index 3761094..e67b66e 100644
--- a/Rx/v2/test/operators/on_error_resume_next.cpp
+++ b/Rx/v2/test/operators/on_error_resume_next.cpp
@@ -30,7 +30,7 @@ SCENARIO("switch_on_error stops on completion", "[switch_on_error][on_error_resu
auto res = w.start(
[xs, ys, &invoked]() {
return xs
- .switch_on_error([ys, &invoked](std::exception_ptr) {
+ .switch_on_error([ys, &invoked](rxu::error_ptr) {
invoked++;
return ys;
})
@@ -101,7 +101,7 @@ SCENARIO("on_error_resume_next stops on completion", "[on_error_resume_next][ope
auto res = w.start(
[xs, ys, &invoked]() {
return xs
- .on_error_resume_next([ys, &invoked](std::exception_ptr) {
+ .on_error_resume_next([ys, &invoked](rxu::error_ptr) {
invoked++;
return ys;
})
@@ -174,7 +174,7 @@ SCENARIO("on_error_resume_next stops on error", "[on_error_resume_next][operator
auto res = w.start(
[xs, ys, &invoked]() {
return xs
- .on_error_resume_next([ys, &invoked](std::exception_ptr) {
+ .on_error_resume_next([ys, &invoked](rxu::error_ptr) {
invoked++;
return ys;
})
diff --git a/Rx/v2/test/operators/publish.cpp b/Rx/v2/test/operators/publish.cpp
index 87c8fff..c977597 100644
--- a/Rx/v2/test/operators/publish.cpp
+++ b/Rx/v2/test/operators/publish.cpp
@@ -4,7 +4,7 @@
#include <rxcpp/operators/rx-ref_count.hpp>
-SCENARIO("publish range", "[hide][range][subject][publish][subject][operators]"){
+SCENARIO("publish range", "[!hide][range][subject][publish][subject][operators]"){
GIVEN("a range"){
WHEN("published"){
auto published = rxs::range<int>(0, 10).publish();
diff --git a/Rx/v2/test/operators/reduce.cpp b/Rx/v2/test/operators/reduce.cpp
index 33a0644..46ad3cd 100644
--- a/Rx/v2/test/operators/reduce.cpp
+++ b/Rx/v2/test/operators/reduce.cpp
@@ -240,7 +240,11 @@ SCENARIO("max", "[reduce][max][operators]"){
}
}
-SCENARIO("max, empty", "[reduce][max][operators]"){
+// Does not work because calling max() on an empty stream throws an exception
+// which will crash when exceptions are disabled.
+//
+// TODO: the max internal implementation should be rewritten not to throw exceptions.
+SCENARIO("max, empty", "[reduce][max][operators][!throws]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -365,7 +369,10 @@ SCENARIO("min", "[reduce][min][operators]"){
}
}
-SCENARIO("min, empty", "[reduce][min][operators]"){
+// Does not work with exceptions disabled, min will throw when stream is empty
+// and this crashes immediately.
+// TODO: min implementation should be rewritten not to throw exceptions.
+SCENARIO("min, empty", "[reduce][min][operators][!throws]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
diff --git a/Rx/v2/test/operators/scan.cpp b/Rx/v2/test/operators/scan.cpp
index 5aa3c31..1cb38a5 100644
--- a/Rx/v2/test/operators/scan.cpp
+++ b/Rx/v2/test/operators/scan.cpp
@@ -3,7 +3,7 @@
#include <rxcpp/operators/rx-take.hpp>
#include <rxcpp/operators/rx-scan.hpp>
-SCENARIO("scan: issue 41", "[scan][operators][issue][hide]"){
+SCENARIO("scan: issue 41", "[scan][operators][issue][!hide]"){
GIVEN("map of scan of interval"){
auto sc = rxsc::make_current_thread();
auto so = rxcpp::synchronize_in_one_worker(sc);
@@ -253,7 +253,7 @@ SCENARIO("scan: seed, some data", "[scan][operators]"){
}
}
-SCENARIO("scan: seed, accumulator throws", "[scan][operators]"){
+SCENARIO("scan: seed, accumulator throws", "[scan][operators][!throws]"){
GIVEN("a test hot observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -279,7 +279,7 @@ SCENARIO("scan: seed, accumulator throws", "[scan][operators]"){
return xs
.scan(seed, [&](int sum, int x) {
if (x == 4) {
- throw ex;
+ rxu::throw_exception(ex);
}
return sum + x;
})
diff --git a/Rx/v2/test/operators/subscribe_on.cpp b/Rx/v2/test/operators/subscribe_on.cpp
index baa66e2..ef8a8c7 100644
--- a/Rx/v2/test/operators/subscribe_on.cpp
+++ b/Rx/v2/test/operators/subscribe_on.cpp
@@ -4,9 +4,11 @@
#include <rxcpp/operators/rx-subscribe_on.hpp>
#include <rxcpp/operators/rx-observe_on.hpp>
+#include <sstream>
+
static const int static_subscriptions = 50000;
-SCENARIO("for loop subscribes to map with subscribe_on and observe_on", "[hide][for][just][subscribe][subscribe_on][observe_on][long][perf]"){
+SCENARIO("for loop subscribes to map with subscribe_on and observe_on", "[!hide][for][just][subscribe][subscribe_on][observe_on][long][perf]"){
const int& subscriptions = static_subscriptions;
GIVEN("a for loop"){
WHEN("subscribe 50K times"){
@@ -46,7 +48,7 @@ SCENARIO("for loop subscribes to map with subscribe_on and observe_on", "[hide][
}
}
-SCENARIO("for loop subscribes to map with subscribe_on", "[hide][subscribe_on_only][for][just][subscribe][subscribe_on][long][perf]"){
+SCENARIO("for loop subscribes to map with subscribe_on", "[!hide][subscribe_on_only][for][just][subscribe][subscribe_on][long][perf]"){
const int& subscriptions = static_subscriptions;
GIVEN("a for loop"){
WHEN("subscribe 50K times"){
diff --git a/Rx/v2/test/operators/tap.cpp b/Rx/v2/test/operators/tap.cpp
index 9aad159..c9e8317 100644
--- a/Rx/v2/test/operators/tap.cpp
+++ b/Rx/v2/test/operators/tap.cpp
@@ -86,7 +86,7 @@ SCENARIO("tap stops on error", "[tap][operators]"){
auto res = w.start(
[xs, &invoked]() {
return xs
- .tap([&invoked](std::exception_ptr) {
+ .tap([&invoked](rxu::error_ptr) {
invoked++;
})
// forget type to workaround lambda deduction bug on msvc 2013
diff --git a/Rx/v2/test/operators/with_latest_from.cpp b/Rx/v2/test/operators/with_latest_from.cpp
index 4d03641..ae7092a 100644
--- a/Rx/v2/test/operators/with_latest_from.cpp
+++ b/Rx/v2/test/operators/with_latest_from.cpp
@@ -1463,7 +1463,7 @@ SCENARIO("with_latest_from error after completed right", "[with_latest_from][joi
}
}
-SCENARIO("with_latest_from selector throws", "[with_latest_from][join][operators]"){
+SCENARIO("with_latest_from selector throws", "[with_latest_from][join][operators][!throws]"){
GIVEN("2 hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1490,7 +1490,7 @@ SCENARIO("with_latest_from selector throws", "[with_latest_from][join][operators
return o2
.with_latest_from(
[&ex](int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
o1
)
@@ -1526,7 +1526,7 @@ SCENARIO("with_latest_from selector throws", "[with_latest_from][join][operators
}
}
-SCENARIO("with_latest_from selector throws N", "[with_latest_from][join][operators]"){
+SCENARIO("with_latest_from selector throws N", "[with_latest_from][join][operators][!throws]"){
GIVEN("N hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1553,7 +1553,7 @@ SCENARIO("with_latest_from selector throws N", "[with_latest_from][join][operato
return e[3]
.with_latest_from(
[&ex](int, int, int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
e[0], e[1], e[2]
)
diff --git a/Rx/v2/test/operators/zip.cpp b/Rx/v2/test/operators/zip.cpp
index 1bbdd86..c048006 100644
--- a/Rx/v2/test/operators/zip.cpp
+++ b/Rx/v2/test/operators/zip.cpp
@@ -1185,7 +1185,7 @@ SCENARIO("zip right completes first", "[zip][join][operators]"){
}
}
-SCENARIO("zip selector throws", "[zip][join][operators]"){
+SCENARIO("zip selector throws", "[zip][join][operators][!throws]"){
GIVEN("2 hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1212,7 +1212,7 @@ SCENARIO("zip selector throws", "[zip][join][operators]"){
return o1
.zip(
[&ex](int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
o2
)
@@ -1248,7 +1248,7 @@ SCENARIO("zip selector throws", "[zip][join][operators]"){
}
}
-SCENARIO("zip selector throws N", "[zip][join][operators]"){
+SCENARIO("zip selector throws N", "[zip][join][operators][!throws]"){
GIVEN("N hot observables of ints."){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -1275,7 +1275,7 @@ SCENARIO("zip selector throws N", "[zip][join][operators]"){
return e[0]
.zip(
[&ex](int, int, int, int) -> int {
- throw ex;
+ rxu::throw_exception(ex);
},
e[1], e[2], e[3]
)
diff --git a/Rx/v2/test/sources/defer.cpp b/Rx/v2/test/sources/defer.cpp
index 266380e..a8187ad 100644
--- a/Rx/v2/test/sources/defer.cpp
+++ b/Rx/v2/test/sources/defer.cpp
@@ -15,7 +15,7 @@ SCENARIO("defer stops on completion", "[defer][sources]"){
auto empty = rx::observable<>::empty<long>();
auto just = rx::observable<>::just(42);
auto one = rx::observable<>::from(42);
- auto error = rx::observable<>::error<long>(std::exception_ptr());
+ auto error = rx::observable<>::error<long>(rxu::error_ptr());
auto runtimeerror = rx::observable<>::error<long>(std::runtime_error("runtime"));
auto res = w.start(
diff --git a/Rx/v2/test/sources/interval.cpp b/Rx/v2/test/sources/interval.cpp
index 38f4ac3..9ab2fca 100644
--- a/Rx/v2/test/sources/interval.cpp
+++ b/Rx/v2/test/sources/interval.cpp
@@ -1,6 +1,6 @@
#include "../test.h"
-SCENARIO("schedule_periodically", "[hide][periodically][scheduler][long][perf][sources]"){
+SCENARIO("schedule_periodically", "[!hide][periodically][scheduler][long][perf][sources]"){
GIVEN("schedule_periodically"){
WHEN("the period is 1sec and the initial is 2sec"){
using namespace std::chrono;
@@ -21,7 +21,7 @@ SCENARIO("schedule_periodically", "[hide][periodically][scheduler][long][perf][s
}
}
-SCENARIO("schedule_periodically by duration", "[hide][periodically][scheduler][long][perf][sources]"){
+SCENARIO("schedule_periodically by duration", "[!hide][periodically][scheduler][long][perf][sources]"){
GIVEN("schedule_periodically_duration"){
WHEN("the period is 1sec and the initial is 2sec"){
using namespace std::chrono;
@@ -64,7 +64,7 @@ SCENARIO("schedule_periodically by duration", "[hide][periodically][scheduler][l
}
}
-SCENARIO("intervals", "[hide][periodically][interval][scheduler][long][perf][sources]"){
+SCENARIO("intervals", "[!hide][periodically][interval][scheduler][long][perf][sources]"){
GIVEN("10 intervals of 1 seconds"){
WHEN("the period is 1sec and the initial is 2sec"){
using namespace std::chrono;
@@ -84,7 +84,7 @@ SCENARIO("intervals", "[hide][periodically][interval][scheduler][long][perf][sou
std::cout << "interval : period " << counter << ", " << nsDelta.count() << "ms delta from target time" << std::endl;
if (counter == 5) {cs.unsubscribe();}
},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
}
}
}
diff --git a/Rx/v2/test/sources/scope.cpp b/Rx/v2/test/sources/scope.cpp
index 383544b..1389344 100644
--- a/Rx/v2/test/sources/scope.cpp
+++ b/Rx/v2/test/sources/scope.cpp
@@ -318,7 +318,7 @@ SCENARIO("scope, dispose", "[scope][sources]"){
}
}
-SCENARIO("scope, throw resource selector", "[scope][sources]"){
+SCENARIO("scope, throw resource selector", "[scope][sources][!throws]"){
GIVEN("a test cold observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -339,7 +339,7 @@ SCENARIO("scope, throw resource selector", "[scope][sources]"){
scope(
[&]() -> resource {
++resource_factory_invoked;
- throw ex;
+ rxu::throw_exception(ex);
//return resource(sc.clock());
},
[&](resource){
@@ -371,7 +371,7 @@ SCENARIO("scope, throw resource selector", "[scope][sources]"){
}
}
-SCENARIO("scope, throw resource usage", "[scope][sources]"){
+SCENARIO("scope, throw resource usage", "[scope][sources][!throws]"){
GIVEN("a test cold observable of ints"){
auto sc = rxsc::make_test();
auto w = sc.create_worker();
@@ -396,7 +396,7 @@ SCENARIO("scope, throw resource usage", "[scope][sources]"){
},
[&](resource) -> rx::observable<int> {
++observable_factory_invoked;
- throw ex;
+ rxu::throw_exception(ex);
}
)
// forget type to workaround lambda deduction bug on msvc 2013
diff --git a/Rx/v2/test/sources/timer.cpp b/Rx/v2/test/sources/timer.cpp
index 9141f2e..3f46b21 100644
--- a/Rx/v2/test/sources/timer.cpp
+++ b/Rx/v2/test/sources/timer.cpp
@@ -1,6 +1,6 @@
#include "../test.h"
-SCENARIO("timer", "[hide][periodically][timer][scheduler][long][perf][sources]"){
+SCENARIO("timer", "[!hide][periodically][timer][scheduler][long][perf][sources]"){
GIVEN("the timer of 1 sec"){
WHEN("the period is 1 sec"){
using namespace std::chrono;
@@ -17,7 +17,7 @@ SCENARIO("timer", "[hide][periodically][timer][scheduler][long][perf][sources]")
auto nsDelta = duration_cast<milliseconds>(sc.now() - (start + (period * counter)));
std::cout << "timer : period " << counter << ", " << nsDelta.count() << "ms delta from target time" << std::endl;
},
- [](std::exception_ptr){abort();},
+ [](rxu::error_ptr){abort();},
[](){std::cout << "completed" << std::endl;});
}
}
diff --git a/Rx/v2/test/subjects/subject.cpp b/Rx/v2/test/subjects/subject.cpp
index b6c6d67..09318a3 100644
--- a/Rx/v2/test/subjects/subject.cpp
+++ b/Rx/v2/test/subjects/subject.cpp
@@ -10,7 +10,7 @@
const int static_onnextcalls = 10000000;
static int aliased = 0;
-SCENARIO("for loop locks mutex", "[hide][for][mutex][long][perf]"){
+SCENARIO("for loop locks mutex", "[!hide][for][mutex][long][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("locking mutex 100 million times"){
@@ -52,7 +52,7 @@ public:
}
};
}
-SCENARIO("for loop calls void on_next(int)", "[hide][for][asyncobserver][baseline][perf]"){
+SCENARIO("for loop calls void on_next(int)", "[!hide][for][asyncobserver][baseline][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("calling on_next 100 million times"){
@@ -137,7 +137,7 @@ public:
}
};
}
-SCENARIO("for loop calls ready on_next(int)", "[hide][for][asyncobserver][ready][perf]"){
+SCENARIO("for loop calls ready on_next(int)", "[!hide][for][asyncobserver][ready][perf]"){
static const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("calling on_next 100 million times"){
@@ -191,7 +191,7 @@ public:
onnext(v); return ready.get_future();}
};
}
-SCENARIO("for loop calls std::future<unit> on_next(int)", "[hide][for][asyncobserver][future][long][perf]"){
+SCENARIO("for loop calls std::future<unit> on_next(int)", "[!hide][for][asyncobserver][future][long][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("calling on_next 100 million times"){
@@ -218,7 +218,7 @@ SCENARIO("for loop calls std::future<unit> on_next(int)", "[hide][for][asyncobse
}
}
-SCENARIO("for loop calls observer", "[hide][for][observer][perf]"){
+SCENARIO("for loop calls observer", "[!hide][for][observer][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("observing 100 million ints"){
@@ -232,7 +232,7 @@ SCENARIO("for loop calls observer", "[hide][for][observer][perf]"){
auto start = clock::now();
auto o = rx::make_observer<int>(
[](int){++c;},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
for (int i = 0; i < onnextcalls; i++) {
o.on_next(i);
}
@@ -244,7 +244,7 @@ SCENARIO("for loop calls observer", "[hide][for][observer][perf]"){
}
}
-SCENARIO("for loop calls subscriber", "[hide][for][subscriber][perf]"){
+SCENARIO("for loop calls subscriber", "[!hide][for][subscriber][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop"){
WHEN("observing 100 million ints"){
@@ -258,7 +258,7 @@ SCENARIO("for loop calls subscriber", "[hide][for][subscriber][perf]"){
auto start = clock::now();
auto o = rx::make_subscriber<int>(
[](int){++c;},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
for (int i = 0; i < onnextcalls && o.is_subscribed(); i++) {
o.on_next(i);
}
@@ -270,7 +270,7 @@ SCENARIO("for loop calls subscriber", "[hide][for][subscriber][perf]"){
}
}
-SCENARIO("range calls subscriber", "[hide][range][subscriber][perf]"){
+SCENARIO("range calls subscriber", "[!hide][range][subscriber][perf]"){
const int& onnextcalls = static_onnextcalls;
GIVEN("a range"){
WHEN("observing 100 million ints"){
@@ -287,7 +287,7 @@ SCENARIO("range calls subscriber", "[hide][range][subscriber][perf]"){
[](int){
++c;
},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
auto finish = clock::now();
auto msElapsed = duration_cast<milliseconds>(finish-start);
@@ -296,7 +296,7 @@ SCENARIO("range calls subscriber", "[hide][range][subscriber][perf]"){
}
}
-SCENARIO("for loop calls subject", "[hide][for][subject][subjects][long][perf]"){
+SCENARIO("for loop calls subject", "[!hide][for][subject][subjects][long][perf]"){
static const int& onnextcalls = static_onnextcalls;
GIVEN("a for loop and a subject"){
WHEN("multicasting a million ints"){
@@ -337,7 +337,7 @@ SCENARIO("for loop calls subject", "[hide][for][subject][subjects][long][perf]")
[cs](int){
cs.unsubscribe();
},
- [](std::exception_ptr){abort();}));
+ [](rxu::error_ptr){abort();}));
}
return 0;
});
@@ -346,7 +346,7 @@ SCENARIO("for loop calls subject", "[hide][for][subject][subjects][long][perf]")
[c, p](int){
++(*c);
},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
}
auto start = clock::now();
@@ -370,7 +370,7 @@ SCENARIO("for loop calls subject", "[hide][for][subject][subjects][long][perf]")
}
}
-SCENARIO("range calls subject", "[hide][range][subject][subjects][long][perf]"){
+SCENARIO("range calls subject", "[!hide][range][subject][subjects][long][perf]"){
static const int& onnextcalls = static_onnextcalls;
GIVEN("a range and a subject"){
WHEN("multicasting a million ints"){
@@ -407,7 +407,7 @@ SCENARIO("range calls subject", "[hide][range][subject][subjects][long][perf]"){
[cs](int){
cs.unsubscribe();
},
- [](std::exception_ptr){abort();});
+ [](rxu::error_ptr){abort();});
}
return 0;
});
@@ -417,7 +417,7 @@ SCENARIO("range calls subject", "[hide][range][subject][subjects][long][perf]"){
[c, p](int){
++(*c);
},
- [](std::exception_ptr){abort();}
+ [](rxu::error_ptr){abort();}
);
}
diff --git a/Rx/v2/test/subscriptions/coroutine.cpp b/Rx/v2/test/subscriptions/coroutine.cpp
index bf67c55..d678714 100644
--- a/Rx/v2/test/subscriptions/coroutine.cpp
+++ b/Rx/v2/test/subscriptions/coroutine.cpp
@@ -24,13 +24,13 @@ SCENARIO("coroutine completes", "[coroutine]"){
w.advance_to(rxsc::test::subscribed_time);
auto d = [&]() -> std::future<void> {
- try {
+ RXCPP_TRY {
for co_await (auto n : xs | rxo::as_dynamic()) {
messages.push_back(on.next(w.clock(), n));
}
messages.push_back(on.completed(w.clock()));
- } catch (...) {
- messages.push_back(on.error(w.clock(), std::current_exception()));
+ } RXCPP_CATCH(...) {
+ messages.push_back(on.error(w.clock(), rxu::current_exception()));
}
}();
@@ -85,13 +85,13 @@ SCENARIO("coroutine errors", "[coroutine]"){
w.advance_to(rxsc::test::subscribed_time);
auto d = [&]() -> std::future<void> {
- try {
+ RXCPP_TRY {
for co_await (auto n : xs | rxo::as_dynamic()) {
messages.push_back(on.next(w.clock(), n));
}
messages.push_back(on.completed(w.clock()));
- } catch (...) {
- messages.push_back(on.error(w.clock(), std::current_exception()));
+ } RXCPP_CATCH(...) {
+ messages.push_back(on.error(w.clock(), rxu::current_exception()));
}
}();
diff --git a/Rx/v2/test/subscriptions/observer.cpp b/Rx/v2/test/subscriptions/observer.cpp
index 57d4ad1..894e610 100644
--- a/Rx/v2/test/subscriptions/observer.cpp
+++ b/Rx/v2/test/subscriptions/observer.cpp
@@ -4,7 +4,7 @@ SCENARIO("subscriber traits", "[observer][traits]"){
GIVEN("given some subscriber types"){
int result = 0;
auto next = [&result](int i){result += i;};
- auto error = [&result](std::exception_ptr){result += 10;};
+ auto error = [&result](rxu::error_ptr){result += 10;};
auto completed = [&result](){result += 100;};
// auto ra = rx::rxu::detail::arg_resolver_n<0, rx::tag_resumption_resolution::template predicate, typename rx::tag_resumption_resolution::default_type, rx::resumption, decltype(next), decltype(error), decltype(completed), rx::rxu::detail::tag_unresolvable, rx::rxu::detail::tag_unresolvable>(rx::resumption(), next, error, completed, rx::rxu::detail::tag_unresolvable(), rx::rxu::detail::tag_unresolvable());
// auto ra = typename rx::rxu::detail::arg_resolver<rx::tag_resumption_resolution::template predicate, typename rx::tag_resumption_resolution::default_type, rx::resumption, decltype(next), decltype(error), decltype(completed)>::type(rx::resumption(), next, error, completed, rx::rxu::detail::tag_unresolvable(), rx::rxu::detail::tag_unresolvable());
@@ -45,7 +45,7 @@ SCENARIO("subscriber traits", "[observer][traits]"){
}
WHEN("after error"){
THEN("subscriber result is 10"){
- scrbResult.on_error(std::current_exception());
+ scrbResult.on_error(rxu::current_exception());
REQUIRE(result == 10);
}
}
@@ -102,7 +102,7 @@ SCENARIO("subscriber behavior", "[observer][traits]"){
GIVEN("given some subscriber types"){
int result = 0;
auto next = [&result](int i){result += i;};
- auto error = [&result](std::exception_ptr){result += 10;};
+ auto error = [&result](rxu::error_ptr){result += 10;};
auto completed = [&result](){result += 100;};
auto dob = rx::make_subscriber<int>(rx::make_observer_dynamic<int>(next, error, completed));
auto so = rx::make_subscriber<int>(next, error, completed);
@@ -143,19 +143,19 @@ SCENARIO("subscriber behavior", "[observer][traits]"){
}
WHEN("after error"){
THEN("dynamic_observer result is 10"){
- dob.on_error(std::current_exception());
+ dob.on_error(rxu::current_exception());
REQUIRE(result == 10);
}
THEN("static_observer result is 10"){
- so.on_error(std::current_exception());
+ so.on_error(rxu::current_exception());
REQUIRE(result == 10);
}
THEN("dynamic_observer is not subscribed"){
- dob.on_error(std::current_exception());
+ dob.on_error(rxu::current_exception());
REQUIRE(!dob.is_subscribed());
}
THEN("static_observer is not subscribed"){
- so.on_error(std::current_exception());
+ so.on_error(rxu::current_exception());
REQUIRE(!so.is_subscribed());
}
}
diff --git a/Rx/v2/test/subscriptions/subscription.cpp b/Rx/v2/test/subscriptions/subscription.cpp
index 2a9f15d..33218a7 100644
--- a/Rx/v2/test/subscriptions/subscription.cpp
+++ b/Rx/v2/test/subscriptions/subscription.cpp
@@ -6,7 +6,9 @@
#include "rxcpp/operators/rx-publish.hpp"
#include "rxcpp/operators/rx-ref_count.hpp"
-SCENARIO("observe subscription", "[hide]"){
+#include <sstream>
+
+SCENARIO("observe subscription", "[!hide]"){
GIVEN("observable of ints"){
WHEN("subscribe"){
auto observers = std::make_shared<std::list<rxcpp::subscriber<int>>>();
@@ -24,7 +26,7 @@ SCENARIO("observe subscription", "[hide]"){
static const int static_subscriptions = 10000;
-SCENARIO("for loop subscribes to map", "[hide][for][just][subscribe][long][perf]"){
+SCENARIO("for loop subscribes to map", "[!hide][for][just][subscribe][long][perf]"){
const int& subscriptions = static_subscriptions;
GIVEN("a for loop"){
WHEN("subscribe 100K times"){
@@ -69,7 +71,7 @@ SCENARIO("for loop subscribes to map", "[hide][for][just][subscribe][long][perf]
}
}
-SCENARIO("for loop subscribes to combine_latest", "[hide][for][just][combine_latest][subscribe][long][perf]"){
+SCENARIO("for loop subscribes to combine_latest", "[!hide][for][just][combine_latest][subscribe][long][perf]"){
const int& subscriptions = static_subscriptions;
GIVEN("a for loop"){
WHEN("subscribe 100K times"){
@@ -107,7 +109,7 @@ SCENARIO("for loop subscribes to combine_latest", "[hide][for][just][combine_lat
}
}
-SCENARIO("synchronized range debug", "[hide][subscribe][range][synchronize_debug][synchronize][long][perf]"){
+SCENARIO("synchronized range debug", "[!hide][subscribe][range][synchronize_debug][synchronize][long][perf]"){
GIVEN("range"){
WHEN("synchronized"){
using namespace std::chrono;
@@ -139,7 +141,7 @@ SCENARIO("synchronized range debug", "[hide][subscribe][range][synchronize_debug
++std::get<1>(*completionstate);
std::get<2>(*completionstate).on_next(n);
},
- [=](std::exception_ptr){
+ [=](rxu::error_ptr){
abort();
},
[=](){
@@ -216,7 +218,7 @@ SCENARIO("synchronized range debug", "[hide][subscribe][range][synchronize_debug
}
}
-SCENARIO("observe_on range debug", "[hide][subscribe][range][observe_on_debug][observe_on][long][perf]"){
+SCENARIO("observe_on range debug", "[!hide][subscribe][range][observe_on_debug][observe_on][long][perf]"){
GIVEN("range"){
WHEN("observed on"){
using namespace std::chrono;
@@ -248,7 +250,7 @@ SCENARIO("observe_on range debug", "[hide][subscribe][range][observe_on_debug][o
++std::get<1>(*completionstate);
std::get<2>(*completionstate).on_next(n);
},
- [=](std::exception_ptr){
+ [=](rxu::error_ptr){
abort();
},
[=](){
diff --git a/appveyor.yml b/appveyor.yml
index 68ea434..42882b2 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,8 +10,6 @@ image: Visual Studio 2017
environment:
matrix:
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- VSVER: Visual Studio 12 2013 Win64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
VSVER: Visual Studio 14 2015 Win64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
diff --git a/ext/catch b/ext/catch
-Subproject ad942885ceab72d421fc6b07aedf0c012ef90e4
+Subproject 9e1bdca4667295fcb16265eae00efa8423f0700
diff --git a/projects/CMake/CMakeLists.txt b/projects/CMake/CMakeLists.txt
index 542a91a..d15c57f 100644
--- a/projects/CMake/CMakeLists.txt
+++ b/projects/CMake/CMakeLists.txt
@@ -59,6 +59,7 @@ set(RX_SOURCES
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-ref_count.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-repeat.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-replay.hpp
+ ${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-retry-repeat-common.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-retry.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-sample_time.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-scan.hpp
@@ -83,13 +84,16 @@ set(RX_SOURCES
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-with_latest_from.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-window.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-window_time.hpp
+ ${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-window_toggle.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-window_time_count.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/operators/rx-zip.hpp
+ ${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-composite_exception.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-connectable_observable.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-coordination.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-coroutine.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-grouped_observable.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-includes.hpp
+ ${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-lite.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-notification.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-observable.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/rx-observer.hpp
@@ -114,6 +118,7 @@ set(RX_SOURCES
${RXCPP_DIR}/Rx/v2/src/rxcpp/schedulers/rx-virtualtime.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-create.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-defer.hpp
+ ${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-empty.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-error.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-interval.hpp
${RXCPP_DIR}/Rx/v2/src/rxcpp/sources/rx-iterate.hpp
diff --git a/projects/CMake/shared.cmake b/projects/CMake/shared.cmake
index ac0d09c..f7f7a31 100644
--- a/projects/CMake/shared.cmake
+++ b/projects/CMake/shared.cmake
@@ -1,5 +1,7 @@
FIND_PACKAGE(Threads)
+option(RX_USE_EXCEPTIONS "Use C++ exceptions" ON)
+
# define some compiler settings
MESSAGE( STATUS "CMAKE_CXX_COMPILER_ID: " ${CMAKE_CXX_COMPILER_ID} )
@@ -13,13 +15,21 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-Wno-error=unused-command-line-argument
-ftemplate-depth=1024
)
+ if (NOT RX_USE_EXCEPTIONS)
+ MESSAGE( STATUS "no exceptions" )
+ list(APPEND RX_COMPILE_OPTIONS -fno-exceptions)
+ endif()
elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
MESSAGE( STATUS "gnu compiler version: " ${CMAKE_CXX_COMPILER_VERSION} )
MESSAGE( STATUS "using gnu settings" )
set(RX_COMPILE_OPTIONS
-Wall -Wextra -Werror -Wunused
)
-elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ if (NOT RX_USE_EXCEPTIONS)
+ MESSAGE( STATUS "no exceptions" )
+ list(APPEND RX_COMPILE_OPTIONS -fno-exceptions)
+ endif()
+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
MESSAGE( STATUS "msvc compiler version: " ${CMAKE_CXX_COMPILER_VERSION} )
MESSAGE( STATUS "using msvc settings" )
set(RX_COMPILE_OPTIONS
@@ -29,9 +39,13 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
/bigobj
/DUNICODE /D_UNICODE # it is a new millenium
)
+ if (NOT RX_USE_EXCEPTIONS)
+ MESSAGE( STATUS "no exceptions" )
+ list(APPEND RX_COMPILE_OPTIONS /EHs-c-)
+ endif()
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0.23506.0")
- set(RX_COMPILE_OPTIONS
- ${RX_COMPILE_OPTIONS}
+ MESSAGE( STATUS "with coroutines" )
+ list(APPEND RX_COMPILE_OPTIONS
/await # enable coroutines
)
endif()
@@ -54,4 +68,4 @@ set(RX_COMPILE_FEATURES
set(IX_SRC_DIR ${RXCPP_DIR}/Ix/CPP/src)
set(RX_SRC_DIR ${RXCPP_DIR}/Rx/v2/src)
-set(RX_CATCH_DIR ${RXCPP_DIR}/ext/catch/include)
+set(RX_CATCH_DIR ${RXCPP_DIR}/ext/catch/single_include/catch2)