Home

Awesome

Quantum Library : A scalable C++ coroutine framework

Build status

Quantum is a full-featured and powerful C++ framework build on top of the Boost coroutine library. The framework allows users to dispatch units of work (a.k.a. tasks) as coroutines and execute them concurrently using the 'reactor' pattern.

Features

Sample code

Quantum is very simple and easy to use:

using namespace Bloomberg::quantum;

// Define a coroutine
int getDummyValue(CoroContextPtr<int> ctx)
{
    int value;
    ...           //do some work
    ctx->yield(); //be nice and let other coroutines run (optional cooperation)
    ...           //do more work and calculate 'value'
    return ctx->set(value);
}

// Create a dispatcher
Dispatcher dispatcher;

// Dispatch a work item to do some work and return a value
int result = dispatcher.post(getDummyValue)->get();

Chaining tasks can also be straightforward. In this example we produce various types in a sequence.

using namespace Bloomberg::quantum;

// Create a dispatcher
Dispatcher dispatcher;

auto ctx = dispatcher.postFirst([](CoroContextPtr<int> ctx)->int {
    return ctx->set(55); //Set the 1st value
})->then([](CoroContextPtr<double> ctx)->int {
    // Get the first value and add something to it
    return ctx->set(ctx->getPrev<int>() + 22.33); //Set the 2nd value
})->then([](CoroContextPtr<std::string> ctx)->int {
    return ctx->set("Hello world!"); //Set the 3rd value
})->finally([](CoroContextPtr<std::list<int>> ctx)->int {
    return ctx->set(std::list<int>{1,2,3}); //Set 4th value
})->end();

int i = ctx->getAt<int>(0); //This will throw 'FutureAlreadyRetrievedException'
                            //since future was already read in the 2nd coroutine
double d = ctx->getAt<double>(1); //returns 77.33
std::string s = ctx->getAt<std::string>(2); //returns "Hello world!";
std::list<int>& listRef = ctx->getRefAt<std::list<int>>(3); //get list reference
std::list<int>& listRef2 = ctx->getRef(); //get another list reference.
                                          //The 'At' overload is optional for last chain future
std::list<int> listValue = ctx->get(); //get list value

Chaining with the new V2 api:

using namespace Bloomberg::quantum;

// Create a dispatcher
Dispatcher dispatcher;

auto ctx = dispatcher.postFirst([](VoidContextPtr ctx)->int {
    return 55; //Set the 1st value
})->then([](VoidContextPtr ctx)->double {
    // Get the first value and add something to it
    return ctx->getPrev<int>() + 22.33; //Set the 2nd value
})->then([](VoidContextPtr ctx)->std::string {
    return "Hello world!"; //Set the 3rd value
})->finally([](VoidContextPtr ctx)->std::list<int> {
    return {1,2,3}; //Set 4th value
})->end();

Building and installing

Quantum is a header-only library and as such no targets need to be built. To install simply run:

> cmake -Bbuild <options> .
> cd build
> make install

CMake options

Various CMake options can be used to configure the output:

Note: options must be preceded with -D when passed as arguments to CMake.

Running tests

Run the following from the top directory:

> cmake -Bbuild -DQUANTUM_ENABLE_TESTS=ON <options> .
> cd build
> make quantum_test && ctest

Using

To use the library simply include <quantum/quantum.h> in your application. Also, the following libraries must be included in the link:

Quantum library is fully is compatible with C++11, C++14 and C++17 language features. See compiler options below for more details.

Compiler options

The following compiler options can be set when building your application:

Application-wide settings

Various application-wide settings can be configured via ThreadTraits, AllocatorTraits and StackTraits.

Documentation

Please see the wiki page for a detailed overview of this library, use-case scenarios and examples.

For class description visit the API reference page.