Disallow conversion in Future return
Differential Revision: https://code.wildfiregames.com/D4812 This was SVN commit r27947.
This commit is contained in:
parent
6a43f91630
commit
1e3f11ff6d
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2022 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -280,7 +280,8 @@ template<typename ResultType>
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
PackagedTask<ResultType> Future<ResultType>::Wrap(T&& func)
|
PackagedTask<ResultType> Future<ResultType>::Wrap(T&& func)
|
||||||
{
|
{
|
||||||
static_assert(std::is_convertible_v<std::invoke_result_t<T>, ResultType>, "The return type of the wrapped function cannot be converted to the type of the Future.");
|
static_assert(std::is_same_v<std::invoke_result_t<T>, ResultType>,
|
||||||
|
"The return type of the wrapped function is not the same as the type the Future expects.");
|
||||||
m_SharedState = std::make_shared<SharedState>(std::move(func));
|
m_SharedState = std::make_shared<SharedState>(std::move(func));
|
||||||
return PackagedTask<ResultType>(m_SharedState);
|
return PackagedTask<ResultType>(m_SharedState);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2021 Wildfire Games.
|
/* Copyright (C) 2023 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -54,14 +54,6 @@ public:
|
|||||||
TS_ASSERT_EQUALS(future.Get(), 1);
|
TS_ASSERT_EQUALS(future.Get(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convertible type.
|
|
||||||
{
|
|
||||||
Future<int> future;
|
|
||||||
std::function<void()> task = future.Wrap([]() -> u8 { return 1; });
|
|
||||||
task();
|
|
||||||
TS_ASSERT_EQUALS(future.Get(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int destroyed = 0;
|
static int destroyed = 0;
|
||||||
// No trivial constructor or destructor. Also not copiable.
|
// No trivial constructor or destructor. Also not copiable.
|
||||||
struct NonDef
|
struct NonDef
|
||||||
@ -80,21 +72,21 @@ public:
|
|||||||
TS_ASSERT_EQUALS(destroyed, 0);
|
TS_ASSERT_EQUALS(destroyed, 0);
|
||||||
{
|
{
|
||||||
Future<NonDef> future;
|
Future<NonDef> future;
|
||||||
std::function<void()> task = future.Wrap([]() { return 1; });
|
std::function<void()> task = future.Wrap([]() { return NonDef{1}; });
|
||||||
task();
|
task();
|
||||||
TS_ASSERT_EQUALS(future.Get().value, 1);
|
TS_ASSERT_EQUALS(future.Get().value, 1);
|
||||||
}
|
}
|
||||||
TS_ASSERT_EQUALS(destroyed, 1);
|
TS_ASSERT_EQUALS(destroyed, 1);
|
||||||
{
|
{
|
||||||
Future<NonDef> future;
|
Future<NonDef> future;
|
||||||
std::function<void()> task = future.Wrap([]() { return 1; });
|
std::function<void()> task = future.Wrap([]() { return NonDef{1}; });
|
||||||
}
|
}
|
||||||
TS_ASSERT_EQUALS(destroyed, 1);
|
TS_ASSERT_EQUALS(destroyed, 1);
|
||||||
/**
|
/**
|
||||||
* TODO: find a way to test this
|
* TODO: find a way to test this
|
||||||
{
|
{
|
||||||
Future<NonDef> future;
|
Future<NonDef> future;
|
||||||
std::function<void()> task = future.Wrap([]() { return 1; });
|
std::function<void()> task = future.Wrap([]() { return NonDef{1}; });
|
||||||
future.CancelOrWait();
|
future.CancelOrWait();
|
||||||
TS_ASSERT_THROWS(future.Get(), const Future<NonDef>::BadFutureAccess&);
|
TS_ASSERT_THROWS(future.Get(), const Future<NonDef>::BadFutureAccess&);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user