interned_string
as a sequential processnamespace v0 {
class interned_string {
struct shared_pool {
mutex _mutex;
unordered_set<string> _pool;
const string* insert(const string& a) {
lock_guard<mutex> lock(_mutex);
return &*_pool.insert(a).first;
}
};
static auto pool() -> shared_pool& {
static shared_pool result;
return result;
}
const std::string* _string;
public:
interned_string(const string& a) : _string(pool().insert(a)) {}
const string& str() const { return *_string; }
};
} // namespace v0
struct shared_pool {
unordered_set<string> _pool;
sequential_process _process;
const string* insert(const string& a) {
_process.async([&, _a = a]{
_pool.insert(a).first;
});
return ???;
}
};
struct shared_pool {
unordered_set<string> _pool;
sequential_process _process;
template <class F> // F models void(const string*)
void insert(string a, F&& f) {
_process.async([this, _a = move(a), _f = forward<F>(f)]{
_f(&*_pool.insert(_a).first);
});
}
};
interned_string
?class interned_string {
// struct shared_pool
static auto pool() -> shared_pool& {
static shared_pool result;
return result;
}
const std::string* _string;
public:
interned_string(const string& a) : _string(pool().insert(a, ???)) {}
const string& str() const { return *_string; }
};
interned_string
becomes asynchronous...namespace v1 {
class interned_string {
// struct shared_pool
static auto pool() -> shared_pool& {
static shared_pool result;
return result;
}
const std::string* _string;
interned_string(const string* s) : _string(s) {}
public:
template <class F> // F models void(interned_string)
static void make(string a, F&& f) {
pool().insert(move(a), [_f = forward<F>(f)](const string* s) {
_f(interned_string(s));
});
}
const string& str() const { return *_string; }
};
} // namespace v1
{
using namespace v1;
interned_string::make(
"Hello World"s, [](const interned_string& s) { cout << s.str() << endl; });
this_thread::sleep_for(1s);
}
std::future<>
¶std::future<>
is a mechanism to separate a task result, from a taskfuture
future
promise
for the sending side of a future
which is associated with some task{
packaged_task<int()> task([]{
cout << "executing...\n";
return 42;
});
future<int> result = task.get_future();
cout << "begin\n";
task(); // execute the task
cout << "answer: " << result.get() << '\n';
}
{
packaged_task<int()> task([]{
cout << "executing...\n";
throw "failure"s;
return 42;
});
future<int> result = task.get_future();
cout << "begin\n";
task(); // execute the task
try {
cout << "answer: " << result.get() << '\n';
} catch (const string& error) {
cout << "error: " << error << '\n';
}
}
future
std::promise
std::packaged_task
std::async
std::async
allows for a launch policy which can be async, deferred, or eitherfuture
from std::async
with std::launch::async
future
from std::async
with std::launch::deferred
future::get()
future
returned from async()
using a promise
sequential_process::async()
void sequential_process::async(task f);
async()
and pass a packaged_task
template <class F> // F models R()
auto async_packaged(sequential_process& process, F&& f) {
using result_t = std::result_of_t<std::decay_t<F>()>;
packaged_task<result_t()> task{std::forward<F>(f)};
auto result = task.get_future();
process.async(move(task));
return result;
}
{
sequential_process process;
auto future = async_packaged(process, []{ return "Hello World!"s; });
cout << future.get() << endl;
}
In file included from input_line_5:1:
In file included from /Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/xeus/xinterpreter.hpp:12:
In file included from /Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:487:
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2056:9: error: call to deleted constructor of 'std::__1::packaged_task<std::__1::basic_string<char> ()>'
: __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2151:9: note: in instantiation of function template specialization 'std::__1::__compressed_pair_elem<std::__1::packaged_task<std::__1::basic_string<char>
()>, 0, false>::__compressed_pair_elem<const std::__1::packaged_task<std::__1::basic_string<char> ()> &, 0>' requested here
: _Base1(__pc, _VSTD::move(__first_args),
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1501:11: note: in instantiation of function template specialization 'std::__1::__compressed_pair<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> > >::__compressed_pair<const
std::__1::packaged_task<std::__1::basic_string<char> ()> &, std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()>
> &&>' requested here
: __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1528:26: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__func' requested here
::new (__hold.get()) __func(__f_.first(), _Alloc(__a));
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1491:14: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__clone' requested here
explicit __func(_Fp&& __f)
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1770:42: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__func' requested here
__f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f));
^
input_line_13:8:19: note: in instantiation of function template specialization 'std::__1::function<void
()>::function<std::__1::packaged_task<std::__1::basic_string<char> ()>, void>' requested here
process.async(move(task));
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/future:2047:5: note: 'packaged_task' has been explicitly marked deleted here
packaged_task(const packaged_task&) = delete;
^
In file included from input_line_5:1:
In file included from /Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/xeus/xinterpreter.hpp:12:
In file included from /Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:487:
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2151:9: error: no matching constructor for initialization of '__compressed_pair_elem<std::__1::packaged_task<std::__1::basic_string<char> ()>, 0>'
: _Base1(__pc, _VSTD::move(__first_args),
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1496:11: note: in instantiation of function template specialization 'std::__1::__compressed_pair<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> > >::__compressed_pair<const
std::__1::packaged_task<std::__1::basic_string<char> ()> &, const
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> > &>' requested here
: __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1536:17: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__func' requested here
::new (__p) __func(__f_.first(), __f_.second());
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1491:14: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__clone' requested here
explicit __func(_Fp&& __f)
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/functional:1770:42: note: in instantiation of member function 'std::__1::__function::__func<std::__1::packaged_task<std::__1::basic_string<char> ()>,
std::__1::allocator<std::__1::packaged_task<std::__1::basic_string<char> ()> >, void ()>::__func' requested here
__f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f));
^
input_line_13:8:19: note: in instantiation of function template specialization 'std::__1::function<void
()>::function<std::__1::packaged_task<std::__1::basic_string<char> ()>, void>' requested here
process.async(move(task));
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2054:3: note: candidate template ignored: substitution failure [with _Args = <const std::__1::packaged_task<std::__1::basic_string<char> ()> &>, _Indexes =
<0>]
__compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2049:3: note: candidate constructor template not viable: requires single argument '__u', but 3 arguments were provided
__compressed_pair_elem(_Up&& __u)
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2037:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 3 were provided
struct __compressed_pair_elem {
^
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2037:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 3 were provided
/Users/sean-parent/miniconda3/envs/sean-parent-notebook/include/c++/v1/memory:2043:13: note: candidate constructor not viable: requires 0 arguments, but 3 were provided
constexpr __compressed_pair_elem() : __value_() {}
^
The underlying issue is function<>
(our task type) requires:
const
function call operatorpackaged_task<>
is
std::function<>
but for movable types with a mutable call operatorvoid()