33 #include <type_traits> 35 using namespace folly;
37 #define EXPECT_TYPE(x, T) EXPECT_TRUE((std::is_same<decltype(x), T>::value)) 61 auto valid = makeSemiFuture<int>(42);
75 #define DOIT(CREATION_EXPR) \ 77 auto f1 = (CREATION_EXPR); \ 78 EXPECT_TRUE(f1.valid()); \ 79 auto f2 = std::move(f1); \ 80 EXPECT_FALSE(f1.valid()); \ 81 EXPECT_TRUE(f2.valid()); \ 84 auto const except = std::logic_error(
"foo");
96 DOIT(makeSemiFuture<int>(42));
97 DOIT(makeSemiFuture<int>(except));
98 DOIT(makeSemiFuture<int>(ewrap));
109 #define DOIT(CREATION_EXPR) \ 111 auto f1 = (CREATION_EXPR); \ 112 EXPECT_FALSE(f1.valid()); \ 113 auto f2 = std::move(f1); \ 114 EXPECT_FALSE(f1.valid()); \ 115 EXPECT_FALSE(f2.valid()); \ 130 auto f = makeValid(); \ 132 copy(std::move(f)); \ 133 EXPECT_NO_THROW(STMT); \ 146 auto other = makeValid();
150 auto other = makeInvalid();
163 auto f = makeValid(); \ 164 EXPECT_NO_THROW(STMT); \ 165 copy(std::move(f)); \ 166 EXPECT_THROW(STMT, FutureInvalid); \ 173 DOIT(
f.hasException());
184 auto f = makeValid(); \ 185 EXPECT_NO_THROW(STMT); \ 186 EXPECT_TRUE(f.valid()); \ 189 auto const swallow = [](
auto) {};
191 DOIT(swallow(
f.valid()));
192 DOIT(swallow(
f.isReady()));
193 DOIT(swallow(
f.hasValue()));
194 DOIT(swallow(
f.hasException()));
195 DOIT(swallow(
f.value()));
196 DOIT(swallow(
f.poll()));
197 DOIT(
f.raise(std::logic_error(
"foo")));
208 #define DOIT(CTOR, STMT) \ 211 EXPECT_NO_THROW(STMT); \ 212 EXPECT_FALSE(f.valid()); \ 221 auto other = makeValid();
225 auto other = makeInvalid();
228 DOIT(makeInvalid(), {
229 auto other = makeValid();
232 DOIT(makeInvalid(), {
233 auto other = makeInvalid();
239 auto const byval = [](
auto) {};
242 DOIT(makeInvalid(), {
243 auto const byval = [](
auto) {};
248 auto const swallow = [](
auto) {};
258 int onErrorHelperEggs(
const eggs_t&) {
303 auto fun = [] {
return 42; };
307 auto funf = [] {
return makeSemiFuture<int>(43); };
311 auto failfun = []() ->
int {
throw eggs; };
321 auto futurefun = [] {
return makeFuture<int>(44); };
392 std::atomic<int> result{0};
434 .then([&](
int value) {
438 .then([&](
int value) {
455 std::atomic<int> result{0};
501 std::move(sf).
via(&e2).getVia(&e2, std::chrono::milliseconds(100)),
517 std::move(sf).
via(&e2).getTryVia(&e2, std::chrono::milliseconds(100)),
552 std::atomic<int> innerResult{0};
555 auto sf =
std::move(
f).semi().defer([&](
auto&&) { innerResult = 17; });
566 auto sf =
std::move(
f).semi().defer([&](
auto&&) {
return 17; });
576 resultF.wait_for(std::chrono::milliseconds(100)),
577 std::future_status::timeout);
586 auto sf =
std::move(
f).semi().defer([&](
auto&&) {
return 17; }).
via(&e2);
595 resultF.wait_for(std::chrono::milliseconds(100)),
596 std::future_status::timeout);
604 std::atomic<int> innerResult{0};
607 auto sf =
std::move(
f).semi().defer([&](
auto&&) { innerResult = 17; });
614 std::atomic<int> innerResult{0};
618 auto sf =
std::move(
f).semi().defer([&](
auto&&) { innerResult = 17; });
627 std::atomic<int> innerResult{0};
628 std::atomic<int> result{0};
632 auto sf =
std::move(
f).semi().defer([&](
auto&&) { innerResult = 17; });
634 auto tf =
std::move(sf).via(&e2).thenValue([&](
auto&&) { result = 42; });
642 std::atomic<int> innerResult{0};
645 auto sf =
std::move(
f).semi().deferValue([&](
int a) { innerResult =
a; });
653 int deferValueHelper(
int a) {
661 auto sf =
std::move(
f).semi().deferValue(deferValueHelper);
668 std::atomic<int> innerResult{0};
669 std::atomic<int> result{0};
673 auto sf =
std::move(
f).semi().deferValue([&](
int a) {
678 auto tf =
std::move(sf).via(&e2).then([&](
int a) { result =
a; });
690 return Try<std::string>(err->what());
693 make_exception_wrapper<std::logic_error>(
"Exception"));
695 p.
setException(make_exception_wrapper<std::logic_error>(
"Try"));
707 std::atomic<int> innerResult{0};
708 std::atomic<int> result{0};
715 return makeSemiFuture<int>(
std::move(outer))
716 .deferValue([&, p4 =
std::move(p3)](
int inner)
mutable {
723 auto r = resultF.getVia(&e2);
730 bool theFlag =
false;
731 auto flag = [&] { theFlag =
true; };
732 #define EXPECT_FLAG() \ 734 EXPECT_TRUE(theFlag); \ 738 #define EXPECT_NO_FLAG() \ 740 EXPECT_FALSE(theFlag); \ 747 .defer([](
auto&&) {
throw eggs; })
748 .deferError<eggs_t>([&](
eggs_t const& ) {
flag(); });
764 .defer([](
auto&&) {
throw eggs; })
765 .deferError<eggs_t>([&](
auto& ) {
flag(); });
773 .defer([](
auto&&) {
throw eggs; })
774 .deferError<eggs_t>([&](
eggs_t ) {
flag(); });
782 .defer([](
auto&&) {
throw eggs; })
783 .deferError<eggs_t>([&](
auto ) {
flag(); });
792 .defer([](
auto&&) {
throw eggs; })
793 .deferError<std::exception>([&](
auto const& ) {
flag(); });
801 .defer([](
auto&&) {
throw - 1; })
802 .deferError<int>([&](
auto ) {
flag(); });
811 .defer([](
auto&&) {
throw eggs; })
812 .deferError<eggs_t>([&](
auto const& )
mutable {
flag(); });
820 .defer([](
auto &&) ->
int {
throw eggs; })
821 .deferError<eggs_t>(onErrorHelperEggs)
822 .deferError(onErrorHelperGeneric);
828 .defer([](
auto &&) ->
int {
throw std::runtime_error(
"test"); })
829 .deferError<eggs_t>(onErrorHelperEggs)
830 .deferError(onErrorHelperGeneric);
836 .defer([](
auto &&) ->
int {
throw std::runtime_error(
"test"); })
837 .deferError<eggs_t>(onErrorHelperEggs);
844 .defer([](
auto&&) {
return 42; })
845 .deferError<eggs_t>([&](
auto& ) {
857 .defer([](
auto&&) {
throw eggs; })
858 .deferError<std::runtime_error>(
859 [&](
auto const& ) {
flag(); });
867 .defer([](
auto &&) ->
int {
throw eggs; })
868 .deferError<eggs_t>([&](
auto const& ) {
return 42; });
875 .defer([](
auto &&) ->
int {
throw eggs; })
876 .deferError<eggs_t>([&](
auto const& e) ->
int {
throw e; });
883 .defer([](
auto &&) ->
int {
throw eggs; })
895 .defer([](
auto &&) ->
int {
throw eggs; })
907 .defer([](
auto&&) {
throw eggs; })
915 auto c = makePromiseContract<int>();
917 c.second =
std::move(
c.second).deferValue([](
int _) {
return _ + 1; });
923 int operator()(
int x) & {
926 int operator()(
int x)
const& {
929 int operator()(
int x) && {
947 std::weak_ptr<int> target;
950 auto input = std::make_shared<int>(1);
951 auto longEnough = std::chrono::milliseconds(1000);
957 folly::Try<std::shared_ptr<int>>&& callbackInput)
mutable {
958 target = callbackInput.value();
969 auto veryShort = std::chrono::milliseconds(1);
971 promise.
getSemiFuture().within(veryShort).toUnsafeFuture().then(
972 [](
folly::Try<std::shared_ptr<int>>&& callbackInput) {
974 EXPECT_EQ(0, callbackInput.value().use_count());
985 promise2.
getSemiFuture().deferValue([](
int x) {
return x * 2; }));
990 auto result =
std::move(future).getTry(std::chrono::milliseconds{100});
1003 promise1.
getSemiFuture().deferValue([](
int x) {
return x * 2; }),
1004 promise2.
getSemiFuture().deferValue([](
int x) {
return x * 2; }));
1021 std::vector<SemiFuture<int>>
futures;
1023 promise1.
getSemiFuture().deferValue([](
int x) {
return x * 2; }));
1025 promise2.
getSemiFuture().deferValue([](
int x) {
return x * 2; }));
1040 bool deferredDestroyed =
false;
1057 .deferValue([](
auto&&) {
static SemiFuture< T > makeEmpty()
#define EXPECT_NO_THROW(statement)
#define EXPECT_THROW(statement, expected_exception)
#define ASSERT_EQ(val1, val2)
#define EXPECT_EQ(val1, val2)
Future< Unit > sleep(Duration dur, Timekeeper *tk)
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
void setException(exception_wrapper ew)
SemiFuture< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAllSemiFuture(Fs &&...fs)
—— Concurrent Priority Queue Implementation ——
in_place_tag in_place(in_place_tag={})
#define EXPECT_GE(val1, val2)
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
std::enable_if< isFutureOrSemiFuture< invoke_result_t< F > >::value, SemiFuture< typename invoke_result_t< F >::value_type > >::type makeSemiFutureWith(F &&func)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
#define EXPECT_TYPE(x, T)
#define DOIT(CREATION_EXPR)
bool loopOnce(int flags=0)
GuardImpl guard(ErrorHandler &&handler)
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
std::exception * tryGetExceptionObject()
#define EXPECT_TRUE(condition)
std::enable_if< std::is_same< Unit, B >::value, void >::type setValue()
SemiFuture< T > getSemiFuture()
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
std::pair< Promise< T >, SemiFuture< T > > makePromiseContract()
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
auto via(Executor *x, Func &&func) -> Future< typename isFutureOrSemiFuture< decltype(std::declval< Func >()())>::Inner >
const internal::AnythingMatcher _
#define EXPECT_FALSE(condition)
static eggs_t eggs("eggs")
TEST(SequencedExecutor, CPUThreadPoolExecutor)
Future< typename std::decay< T >::type > makeFuture(T &&t)
std::enable_if< isFuture< invoke_result_t< F > >::value, invoke_result_t< F > >::type makeFutureWith(F &&func)
static Future< T > makeEmpty()
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)