Exercise 6. Futures from scratch.

Open this wandbox (b, b, b, b). It contains an implementation of std::promise<T> and std::future<T> for object types (i.e., not references or void types).

Exercise 6a. shared_future from scratch

1. There are two test files provided: "test-shared.cc" and "test-unshared.cc". The latter works. The former doesn't work, because shared_future<T> is not implemented. A synopsis for shared_future is provided in "shared-future.h". Implement shared_future from scratch.

2. Compare the signatures T future::get() and const T& shared_future::get(). Why are they different?

3. Recall our discussion of what it means to "move-from" an object. Recall that the move-constructor of shared_ptr nulls out its source operand. What should the move-constructor of shared_future do: preserve its source, null it out, or leave it in an unspecified state? What are the pros and cons of each approach? What does the standard library actually do? (Check cppreference.)

Exercise 6b (optional). ~promise from scratch

1. (Optional) There is code in ~promise() to satisfy the standard's requirement that a future should never wait forever on a destroyed promise, but instead the future should become ready with a broken_promise exception. (Yes, that's really the name of the error code!) However, the code in the wandbox is commented out, because it depends on the function promise::ready(), which is not implemented. Uncomment this code and get it working. If you can get it working without implementing ready(), tell Arthur about it!

Exercise 6c (optional). Running user code under a lock

Recall from Exercise 4b that running user-supplied code under a lock is not generally safe.

1. (Optional) Read the bug report at the bottom of this page. Reproduce it using our toy implementation of promise/future. Then, fix it!


You're done with this set of exercises! Sit back and relax, or optionally, browse the following bug report.