Changeset View
Changeset View
Standalone View
Standalone View
source/ps/tests/test_Future.h
Show All 13 Lines | |||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include "lib/self_test.h" | #include "lib/self_test.h" | ||||
#include "ps/Future.h" | #include "ps/Future.h" | ||||
#include <exception> | |||||
#include <functional> | #include <functional> | ||||
#include <type_traits> | #include <type_traits> | ||||
class TestFuture : public CxxTest::TestSuite | class TestFuture : public CxxTest::TestSuite | ||||
{ | { | ||||
public: | public: | ||||
void test_future_basic() | void test_future_basic() | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | void test_future_moving() | ||||
memset(&futureStorage, 0xFF, sizeof(decltype(futureStorage))); | memset(&futureStorage, 0xFF, sizeof(decltype(futureStorage))); | ||||
memset(&functionStorage, 0xFF, sizeof(decltype(functionStorage))); | memset(&functionStorage, 0xFF, sizeof(decltype(functionStorage))); | ||||
// Let's move the packaged task while at it. | // Let's move the packaged task while at it. | ||||
std::function<void()> task2 = std::move(task); | std::function<void()> task2 = std::move(task); | ||||
task2(); | task2(); | ||||
TS_ASSERT_EQUALS(future.Get(), 7); | TS_ASSERT_EQUALS(future.Get(), 7); | ||||
} | } | ||||
void test_exception() | |||||
{ | |||||
struct TestException : std::exception | |||||
{ | |||||
using std::exception::exception; | |||||
Stan: Not sure what the convention about using is. | |||||
Done Inline ActionsThis isn't a "normal" using. This only makes the constructor visible. I would avoid making a big namespace visible. phosit: This isn't a "normal" using. This only makes the constructor visible.
I would avoid making a… | |||||
}; | |||||
{ | |||||
Future<void> future; | |||||
auto packedTask = future.Wrap([] | |||||
{ | |||||
throw TestException{}; | |||||
}); | |||||
packedTask(); | |||||
TS_ASSERT(future.IsReady()); | |||||
TS_ASSERT_THROWS(future.Get(), TestException&); | |||||
} | |||||
{ | |||||
Future<int> future; | |||||
auto packedTask = future.Wrap([]() -> int | |||||
{ | |||||
throw TestException{}; | |||||
}); | |||||
packedTask(); | |||||
TS_ASSERT(future.IsReady()); | |||||
TS_ASSERT_THROWS(future.Get(), TestException&); | |||||
} | |||||
// If the function does not throw but it's the cause something is thrown the exception should | |||||
// be reported to the thread which is waiting on the future. | |||||
{ | |||||
class ThrowsOnMove | |||||
{ | |||||
public: | |||||
ThrowsOnMove() = default; | |||||
ThrowsOnMove(ThrowsOnMove&&) | |||||
{ | |||||
throw TestException{}; | |||||
} | |||||
}; | |||||
Future<ThrowsOnMove> future; | |||||
auto packedTask = future.Wrap([] | |||||
{ | |||||
return ThrowsOnMove{}; | |||||
}); | |||||
packedTask(); | |||||
TS_ASSERT(future.IsReady()); | |||||
TS_ASSERT_THROWS(future.Get(), TestException&); | |||||
} | |||||
} | |||||
}; | }; |
Wildfire Games · Phabricator
Not sure what the convention about using is.