MADNESS 0.10.1
Files | Namespaces
Collaboration diagram for Futures:

Files

file  future.h
 Implements Future and related items.
 

Namespaces

namespace  madness
 Namespace for all elements and tools of MADNESS.
 

Detailed Description

Todo:
Badly in need of a general description. There's a lot of jargon in the implementation's documentation – a future is assigned, etc. – that should be clarified. Just sayin'. There's some text in a comment (not doxygen) near the beginning of the Future class. Maybe move it here? Hell, I went ahead an copied (cut, really) it here, right here, just for you.
// This future object can exist in one of three states:
// - f == NULL && value == NULL : Default initialized state
// This state occurs when the future is constructed via
// Future::default_initializer().
// - f != NULL && value == NULL : FutureImpl object will hold the T object
// This state occurs when a future is constructed without a value,
// or from a remote reference.
// - f == NULL $$ value != NULL : T object is held in buffer
// This state occurs when a future is constructed with a value
// or from an input archive.
Gotchas
Todo:
This is taken from some crude remarks that used to be in worldfut.h (now future.h). It needs to be edited/verified before this goes live. It could probably use a better section heading than "Gotchas", too...

A common misconception is that STL containers initialize their contents by invoking the default constructor of each item in the container (since we are told that the items must be default constructable). But this is incorrect. The items are initialized by invoking the copy constructor for each element on a single object made with the default constructor. For futures this is a very bad problem. For instance,

vector< Future<double> > v(3);
static const double v
Definition hatom_sf_dirac.cc:20

is equivalent to the following with an array of three elements

Future<double> junk;
Future<double> v[3] = {junk,junk,junk};

Since the Future copy constructor is by necessity shallow, each element of v ends up referring to the future implementation that underlies junk. When you assign to an element of v, you'll also be assigning to junk. But since futures are single assignment variables, you can only do that once. Hence, when you assign a second element of v you'll get a runtime exception.

The fix (other than using arrays) is to initialize STL vectors and other containers from the special element returned by Future<T>::default_initializer(), which if passed into the copy constructor will cause it to behave just like the default constructor. Thus, the following code is what you actually need to use an STL vector of futures

vector< Future<double> > v(3, Future<double>::default_initializer());

which is laborious. Instead, we provide the factory function

template <typename T>
vector< Future<T> > future_vector_factory(std::size_t n);

which enables you to write

vector< Future<double> > v = future_vector_factory<double>(3);